回归最本质的信息安全

Source引擎的远程代码执行漏洞,可能影响千万游戏玩家

2017年7月25日发布

14,939
0
2

导语:目前多款主流游戏,如CS、绝地要塞等都在使用Source引擎,Source引擎由Valve软件公司开发,这个引擎提供关于渲染、声效、动画、消锯齿、界面、美工创意和物理模拟方面的支持。

1500887916137259.jpg

目前多款主流游戏,如CS、绝地要塞等都在使用Source引擎,Source引擎由Valve软件公司开发,这个引擎提供关于渲染、声效、动画、消锯齿、界面、美工创意和物理模拟方面的支持。 

其实Source引擎存在漏洞已经不是什么秘密了,早在去年的GeekPwn2016黑客大赛中,就有参赛队员在不接触对方设备,不知道对方账号信息的情况下,侵入了正在游戏的电脑,还通过电脑摄像头监控了游戏者的实时活动。

最近曝出的漏洞是Source SDK中出现了一个缓冲区溢出漏洞,会导致攻击者在客户端和服务器上能执行任意代码。该漏洞可以导致加载特定的躲避攻击(Ragdoll Avalanche) (比如一个玩家被射杀),目前包括CS、绝地要塞等游戏已经修复了这个漏洞。

缺少Bounds Check

BoundsChecker是一个运行时错误检测工具,它主要定位程序运行时期发生的各种错误。当函数nexttoken用于Token的一个字符串时,可以看到,只要找不到NULL字符或者分隔符sep,就会导致str这个buffer被复制到token的buffer中,压根就没有边界检查。

const char *nexttoken(char *token, const char *str, char sep)
{
    ...
    while ((*str != sep) && (*str != ''))
    {
        *token++ = *str++;
    }
    ...
}

漏洞介绍

当以Ragdoll Avalanche处理数据时,像ParseKeyValue就会被调用。这个方法调用nexttoken来Token那些待处理的规则。通过创建一个大于256字符的collisionpair规则,缓冲区szToken就会溢出。因为szToken存储在栈上,所以ParseKeyValue的返回地址就会被覆盖。

class CRagdollCollisionRulesParse : public IVPhysicsKeyHandler
{
    virtual void ParseKeyValue( void *pData, const char *pKey, const char *pValue )
    {
        ...
        else if ( !strcmpi( pKey, "collisionpair" ) )
            ...
            char szToken[256];
            const char *pStr = nexttoken(szToken, pValue, ',');
            ...
    }
}

漏洞预防

ASLR会将可执行文件加载到内存中的地址随机化,并且一个进程内所有加载到内存的可执行文件都必须开启这个功能才能起到漏洞预防的作用。

由于动态库steamclient.dll并没有开启ASLR。这意味着steamclient.dll加载到内存中的地址是可预测的,攻击者可以很方便地定位并使用可执行文件内存中的Token。

mona-noaslr.png

ROPgadget的使用

一个更有效的方法就是使用特定的识别gadgets的工具。举个例子,ROPgadget就是个很棒的工具,它可以被用于识别所有的gadgets。如果你能找到一系列retn指令结尾的指令,就能把ROP链的第一条指令的地址插入到栈,当函数返回地址被pop到指令寄存器时,Token就开始执行。由于x86和x64的Token不需要在内存对齐的情况下执行,所以任何地址都能作为Token。我可以把Token指针指向其中一条指令,这样就可以得到更多的指令。

Immunity Debugger插件Mona提供了查找gadget的工具。但是这个插件无法找到所有有用的gadget,如rep movs。Immunity Debugger软件专门用于加速漏洞利用程序的开发,辅助漏洞挖掘以及恶意软件分析。

1500888028951513.png

启动cmd.exe

由于有效载荷的处理方式不同,NULL字符不能被使用,并且大写字符需要转化为小写字符。这意味着我的ROP gadget地址资源及有效载荷的处理方式都很有限。为了解决这个问题,我用一个gadget链来引导shellcode,以定位内存中未修改的原始缓冲区,然后将未修改的有效载荷通过rep movs gadget复制到栈。

这样,Steamclient.dll就导入了LoadLibraryA和GetProcAddressA。现在,我就能往内存中加载任意DLL了,并得到其他的导出函数。比如,导入shell32.dll以获得ShellExecuteA函数,这个函数能启动其他程序。

有效载荷的获取

Source引擎允许将自定义内容打包到地图文件中,因为这样可以在地图中添加一些额外的内容,比如声音或者文字。于是我将Ragdoll Avalanche模型文件打包到一个地图文件中,而且使用与Ragdoll Avalanche模型文件一样的路径。

555.png

总结

视频游戏很容易成为黑客进行漏洞利用的目标, 因为视频游戏通常会在用户的家中或者工作中进行,攻击者就是通过漏洞利用进入到组织的公共网络或家中的私人网络。另外,在流行的视频游戏中发现的这个远程代码执行漏洞可以用来创建僵尸网络或者传播勒索软件。

所以建议各位玩家,不要在工作中玩游戏或在不受信任的网络环境中进行游戏。

对那些Source的玩家而言,需要禁用第三方内容的下载以减少攻击。通过cl_allowdownload 0 和 cl_downloadfilter all Token就可以实现禁用第三方内容下载。

由于是在Source SDK中发现的漏洞,可以推测,在其他的第三方模块也很可能存在漏洞。但如果玩家在所有模块下都启用了ASLR,就只有泄漏的内存漏洞才能利用了,从而加大了攻击者漏洞利用的难度。

所以为了防止缓冲区溢出发生,请不要在缓冲区中存储过多的数据。nexttoken函数应该有一个token长度来作为参考,这个参数用来进行Bounds Check。

对于Source游戏的开发者来说,可以使用补丁进行修复,也可以使用chromium团队开发的checkbins.py工具来完成。

除此以外,Source游戏应该可以进行沙箱设置以限制访问并阻止新进程的启动。比如,当利用web浏览器的内存破环漏洞时经常会要用到内核利用,如果进行沙箱设置,则访问用户层的浏览器进程就要受限。

本文翻译自:https://oneupsecurity.com/research/remote-code-execution-in-source-games ,如若转载,请注明来源于嘶吼: http://www.4hou.com/technology/6806.html

点赞 2
取消

感谢您的支持,我会继续努力的!

扫码支持

打开微信扫一扫后点击右上角即可分享哟

xiaohui

xiaohui

嘶吼编辑

发私信

发表评论