主要观点:数月前在《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
的编码方式与官方不同影响了地址转换。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。