StrutsのCVE-2023-50164について

2024/01/07に公開

昨年末Strutsで脆弱性が出ました。利用しているWEBアプリで利用しているため、対応も兼ねて攻撃の原理や内容について確認してみます。

脆弱性の内容はakamaiの記事が非常に丁寧でわかりやすかったです
https://www.akamai.com/blog/security-research/apache-struts-cve-exploitation-attempts

すでに色々なサイトで攻撃コードが公開されているため、以下を参考に環境を構築してみます
https://github.com/jakabakos/CVE-2023-50164-Apache-Struts-RCE

環境の整備

OS

$ cat /etc/amazon-linux-release
Amazon Linux release 2023 (Amazon Linux)
$ uname -a
Linux ip-172-31-48-253.ap-northeast-1.compute.internal 6.1.66-91.160.amzn2023.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Dec 13 04:50:24 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
$ yum update

サンプルアプリの要件

Strtusアプリは6.3.0.1のため、踏まえて環境を整備する
https://github.com/jakabakos/CVE-2023-50164-Apache-Struts-RCE/blob/main/struts-app/pom.xml#L18

Struts6.X系だとJava8以上、ServletAPI3.1以上を満たすソフトウェアを使う

Java、Tomcat、Mavenを導入する

特に指定がなければ最新版とする。Tomcatは10.X系で試したところサンプルアプリが起動しなかったので8.5.X系の最新を導入する。

$ yum install java-17-amazon-corretto-devel
$ wget https://dlcdn.apache.org/tomcat/tomcat-8/v8.5.97/bin/apache-tomcat-8.5.97.tar.gz
$ https://dlcdn.apache.org/maven/maven-3/3.9.6/binaries/apache-maven-3.9.6-bin.tar.gz

Pythonとpipの導入

攻撃コードはpythonで動いているがデフォルトで入ってた

$ pip --version
pip 21.3.1 from /usr/lib/python3.9/site-packages/pip (python 3.9)
$ Python3 -V
Python 3.9.16

Javaアプリのビルド

サンプルアプリをmavenでビルドする。mavenを展開したのでwarファイルを作成する

$ /home/ec2-user/apache-maven-3.9.6/bin/mvn package

Tomcatも展開してwebappsディレクトリにwafファイルをコピーする

$ cp upload-1.0.0.war /home/ec2-user/apache-tomcat-8.5.97/webapps/

Tomcatを起動して動かす

/home/ec2-user/apache-tomcat-8.5.97/bin/startup.sh

攻撃コードの実行

攻撃コードをざっと見るとRCE用のwarファイルをアップロードして、tomcatのwebappsに配置する動きになっています。以下実行するとwebappsにwarファイルが増える想定です。

 python3 exploit.py --url http://localhost:8080/upload-1.0.0/upload.action

実行したところ、ログにエラーが出ました。CATALINA_HOMEの指定が間違えてそう。

$ tail /home/ec2-user/apache-tomcat-8.5.97/logs/catalina.out
java.io.IOException: Cannot create directory '/home/ec2-user/uploads/../../opt/tomcat/webapps'

https://github.com/jakabakos/CVE-2023-50164-Apache-Struts-RCE/blob/main/exploit/exploit.py#L15
確かに自分の環境とは違うので /home/ec2-user/apache-tomcat-8.5.97/ に修正して、再度実行したところ、webappsに攻撃用アプリのパスが追加されました。

これで攻撃は成立しました。

Strutsのバージョンアップ

脆弱性の確認はできたのでStrutsをバージョンアップして攻撃が防げていることを確認します。

https://github.com/jakabakos/CVE-2023-50164-Apache-Struts-RCE/blob/main/struts-app/pom.xml#L18
Struts6.3.0.1から6.3.0.2にバージョンアップします。

$ diff pom.xml pom.xml_20240107 
18c18
<         <struts2.version>6.3.0.2</struts2.version>
---
>         <struts2.version>6.3.0.1</struts2.version>

ビルド+デプロイする。webappsから攻撃用アプリも削除する。

$ ls -l /home/ec2-user/apache-tomcat-8.5.97/webapps/
drwxr-x---.  3 ec2-user ec2-user      42 Jan  6 18:27 webshell
-rw-r-----.  1 ec2-user ec2-user     723 Jan  6 18:27 webshell.war
$ rm -rf /home/ec2-user/apache-tomcat-8.5.97/webapps/webshell.war
$ rm -rf /home/ec2-user/apache-tomcat-8.5.97/webapps/webshell

再度攻撃コードを実行する。今度は攻撃用アプリが追加されず攻撃が成立しないことが確認できました。

攻撃の手法

今回のアプリのケースではmultipart/form-dataでファイルをアップロードする際に、HTTPのボディ内にファイル名を定義しますが、階層構造を持たせた場合にパスとラバーサルの脆弱性となっています。

指定文字列 ../../file.jpg
期待動作 「../../file.jpg」というファイル名になる
挙動 「../../」がパスと解釈され、配置ディレクトリの2階層上にファイルを置いてしまう

Chromeのネットワークで見ると、この部分にパスの文字列を追記するものと思います。

実際のどのような修正が入ったか、は以下などを読もうと思います。
https://github.com/apache/struts/compare/STRUTS_6_3_0_1...STRUTS_6_3_0_2

すでにクラウドベンダーやマネージドWAFサービスなどでは対応完了の発信が出ているようです。
https://dev.classmethod.jp/articles/azure-waf-cve-2023-50164/
https://www.securesky-tech.com/2023/12/11/6860/

今回のケースは攻撃の成立条件が難しいですが、外部からコード実行される脆弱性で、ログ出力のユーザーによっては、攻撃のログを削除される可能性もあるので、一刻も早い対応が必要だと再認識しました。

Discussion