首页 > 解决方案 > Debug.setlocal() 安全问题

问题描述

debug.setlocal 是否存在任何安全问题?如果是这样,你能告诉我它是如何工作的。

标签: securitydebuggingluaexploit

解决方案


Lua 线程在“堆栈”之上运行,堆栈是构成语言中大部分内存的项目列表。从“全局”变量到表格,一切都在这个列表中。

当您创建局部变量并执行代码时,堆栈将如下所示:

local a = "the letter a"
STACK
+---+----------------+
| 1 | "the letter a" |
+---+----------------+

现在,假设我们是恶意代码。我们知道下面的代码是用来运行我们的程序的:

local isAdministrator = false
local Code = "malicious code here!"
loadstring(Code)()

好吧,这意味着加载器的堆栈看起来像这样:

+---+-------+
| 1 | false | isAdministrator
+---+-------+----------------+
| 2 | "malicious code here!" | Code
+---+---------------------+--+
| 3 | function loadstring |
+---+---------------------+--+
| 4 | function MaliciousCode |
+---+------------------------+

现在,假设改变isAdministrator对我们有一些价值。让我们看看我们将如何做到这一点。

1我们需要获取 lua 来修改我们函数上方的“堆栈”。想象一下 lua 是一棵树,就像这样:

otherScript
 + loader
    + maliciousCode

这棵树中的每个步骤都有自己的堆栈,并且它上面的堆栈中的每个变量都可以“访问”到它下面的堆栈,这要归功于debug库。

如果我们当前所在的“堆栈”是堆栈#1(始终为真),那么调用当前函数的函数位于堆栈#2(几乎总是为真)

现在,查看我们要更改的函数的堆栈,isAdministrator它位于 slot1中,第一个。因此,要改变这一点,我们需要:

debug.setlocal(2,1,true)

和砰。isAdministrator现在是true。我们可以随意破坏您的计算机!

不要担心 - 有办法阻止这种情况。带走调试库真的很容易:

local func = loadstring("malicious code!")
setfenv(func, {
    --  Here we insert what functions our baby function can use. Let's give it the string, table, and math libraries- which are pretty safe
    math = math, table = table, string = string,
    --  Oh, and let's give it the `os.time` function as well.
    os = { time = os.time }
})
func()

现在,func无法访问调试库,你可以isAdministrator放心地使用你的傻本地人了。


推荐阅读