字节码分解:揭示《Factorio》的 Lua 安全漏洞

主要观点:数月前在《Factorio》的 Lua 实现中发现漏洞,可让恶意服务器在客户端执行任意代码,现分享细节。Lua 在《Factorio》中用于实现游戏逻辑、创建模组和自定义地图,其多玩家模式采用确定性锁步同步,这使得玩家执行的 Lua 代码其他玩家也会执行,有两种途径到达 Lua 解释器,一是使用/c命令,二是创建包含 Lua 代码的自定义地图。通过研究发现可利用 Lua 字节码的漏洞来创建假对象,进而获取代码执行权,包括泄露地址、混淆 upvalues 等操作,最终在 Linux 上实现远程代码执行,还提到了在 Factorio 中测试时遇到的一些问题及解决办法,最后提供了一个实践挑战。

关键信息:

  • 《Factorio》是自动化工厂建造火箭逃离星球的游戏,销量超 350 万,模组社区活跃。
  • Lua 在游戏中用于多种功能,多玩家模式需同步执行相同代码。
  • 可通过特定途径到达 Lua 解释器,利用字节码漏洞创建假对象,如通过 FORLOOP 类型混淆泄露地址,通过混淆 upvalues 控制函数原型和 upvalues 指针等。
  • 在 Linux 上通过找到可从 Lua 代码控制参数的导入函数(如math_ldexp),将其地址替换为system地址并调用执行命令,实现远程代码执行,但在 Factorio 测试中遇到一些内存地址相关问题及解决办法。

重要细节:

  • Lua 是解释型语言,先编译为字节码再执行,字节码验证器曾存在但被移除,Factorio 开发者有自己的验证措施但存在 Off-By-One 问题。
  • 假对象创建有两种路径,可创建假Proto或假UpVal数组,能利用TStrings泄露数据、Tables写入数据、CCLosure/Light C Functions控制指令指针等。
  • 整数在 Lua 中以双精度浮点数形式存储,通过特定方法可将泄露的指针转换为整数,处理不同类型的浮点数时需注意精度问题。
  • 在 Factorio 中,Garbage Collected Objects 与官方 Lua 解释器在结构上有差异,导致一些偏移计算出错,同时 Factorio 中sprintf的编码方式与官方不同影响了地址转换。
阅读 10
0 条评论