これは ZOZO Advent Calendar 2023 カレンダーVol.4の3日目の記事です。昨日の投稿は@ymd_aaaさんの「AndroidStudioからのGit操作でJava to Kotlinの差分を見やすくする」でした。
はじめに
この記事はApache ActiveMQの脆弱性(CVE-2023-46604)をHacktheBoxの「Broker」(以下リンク参照)で検証した際のメモになります。
CVE-2023-46604
Apache ActiveMQにRCEの脆弱性CVE-2023-46604が10月末に公開されていました。
影響を受けるバージョン
- 5.18.3 以前の Apache ActiveMQ 5.18.0
- 5.17.6 以前の Apache ActiveMQ 5.17.0
- 5.16.7 以前の Apache ActiveMQ 5.16.0
- 5.15.16 以前の Apache ActiveMQ
- Apache ActiveMQ レガシー OpenWire モジュール 5.18.0 5.18.3 以前
- Apache ActiveMQ レガシー OpenWire モジュール 5.17.0 5.17.6 以前
- Apache ActiveMQ レガシー OpenWire モジュール 5.16.0 5.16.7 以前
- Apache ActiveMQ レガシー OpenWire モジュール 5.8.0 5.15.16 以前
実際の被害
以下のようにHelloKittyランサムウェアファミリーから悪用された疑いがあります。
修正バージョン
- Apache ActiveMQ 5.18.3
- Apache ActiveMQ 5.17.6
- Apache ActiveMQ 5.16.7
- Apache ActiveMQ 5.15.16
POC
POCについても同時期にGithubにてCommitされていることがわかります。
このPOCを皮切りに色々とPOCが出ています。今回は以下の2つのPOCを利用します。
POC by evkl1d
POC by VulnCheck
HacktheBox - Broker
このBOXは上記のCVE-2023-46604を内包したものになります。
EasyのBoxであり、初心者の方でも取り組みやすい内容になっています。是非ともRootフラグまでゲットしてもらえればと思います。
※今回はCVE-2023-46604の検証のために使うので、Rootフラグまでの攻略は割愛します。
ポートスキャン
rustscan
を用います。
┌──(root㉿kali-linux-2022-2)-[~]
└─# rustscan -a 10.10.11.243 --top --ulimit 5000
.----. .-. .-. .----..---. .----. .---. .--. .-. .-.
| {} }| { } |{ {__ {_ _}{ {__ / ___} / {} \ | `| |
| .-. \| {_} |.-._} } | | .-._} }\ }/ /\ \| |\ |
`-' `-'`-----'`----' `-' `----' `---' `-' `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: https://discord.gg/GFrQsGy :
: https://github.com/RustScan/RustScan :
--------------------------------------
Please contribute more quotes to our GitHub https://github.com/rustscan/rustscan
[~] The config file is expected to be at "/root/.rustscan.toml"
[~] Automatically increasing ulimit value to 5000.
Open 10.10.11.243:22
Open 10.10.11.243:80
Open 10.10.11.243:1337
Open 10.10.11.243:8161
Open 10.10.11.243:1883
Open 10.10.11.243:5672
Open 10.10.11.243:45043
Open 10.10.11.243:61613
Open 10.10.11.243:61614
Open 10.10.11.243:61616
[~] Starting Script(s)
[>] Script to be run Some("nmap -vvv -p {{port}} {{ip}}")
[~] Starting Nmap 7.94 ( https://nmap.org ) at 2023-11-13 02:01 EST
Initiating Ping Scan at 02:01
Scanning 10.10.11.243 [4 ports]
Completed Ping Scan at 02:01, 0.23s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 02:01
Completed Parallel DNS resolution of 1 host. at 02:01, 0.01s elapsed
DNS resolution of 1 IPs took 0.01s. Mode: Async [#: 1, OK: 0, NX: 1, DR: 0, SF: 0, TR: 1, CN: 0]
Initiating SYN Stealth Scan at 02:01
Scanning 10.10.11.243 [10 ports]
Discovered open port 1337/tcp on 10.10.11.243
Discovered open port 80/tcp on 10.10.11.243
Discovered open port 22/tcp on 10.10.11.243
Discovered open port 1883/tcp on 10.10.11.243
Discovered open port 5672/tcp on 10.10.11.243
Discovered open port 61616/tcp on 10.10.11.243
Discovered open port 61614/tcp on 10.10.11.243
Discovered open port 61613/tcp on 10.10.11.243
Discovered open port 45043/tcp on 10.10.11.243
Discovered open port 8161/tcp on 10.10.11.243
Completed SYN Stealth Scan at 02:01, 0.23s elapsed (10 total ports)
Nmap scan report for 10.10.11.243
Host is up, received echo-reply ttl 63 (0.21s latency).
Scanned at 2023-11-13 02:01:16 EST for 0s
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 63
80/tcp open http syn-ack ttl 63
1337/tcp open waste syn-ack ttl 63
1883/tcp open mqtt syn-ack ttl 63
5672/tcp open amqp syn-ack ttl 63
8161/tcp open patrol-snmp syn-ack ttl 63
45043/tcp open unknown syn-ack ttl 63
61613/tcp open unknown syn-ack ttl 63
61614/tcp open unknown syn-ack ttl 63
61616/tcp open unknown syn-ack ttl 63
Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 0.60 seconds
Raw packets sent: 14 (592B) | Rcvd: 11 (468B)
色々とPortが空いてますが、大体こういうのはhttpから探っていくことが多いです。
Webの確認
80番Portを確認していきます。nikto
コマンドでスキャンしてみます。
┌──(root㉿kali-linux-2022-2)-[~]
└─# nikto -h 10.10.11.243 -p 80
- Nikto v2.5.0
---------------------------------------------------------------------------
+ Target IP: 10.10.11.243
+ Target Hostname: 10.10.11.243
+ Target Port: 80
+ Start Time: 2023-11-16 13:26:49 (GMT9)
---------------------------------------------------------------------------
+ Server: nginx/1.18.0 (Ubuntu)
+ /: The anti-clickjacking X-Frame-Options header is not present. See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
+ /: The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type. See: https://www.netsparker.com/web-vulnerability-scanner/vulnerabilities/missing-content-type-header/
+ / - Requires Authentication for realm 'ActiveMQRealm'
+ /: Default account found for 'ActiveMQRealm' at (ID 'admin', PW 'admin'). Generic account discovered.. See: CWE-16
+ Root page / redirects to: http://10.10.11.243/index.html
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ nginx/1.18.0 appears to be outdated (current is at least 1.20.1).
何があるかもうある程度見えてますが、実際に80番ポートへアクセスしてみます。
Basic認証を要求されますが、nikto
にて見つけたadmin:admin
でログインできました。
バージョンを探ると、5.15.15
であることがわかります。脆弱ですね。
POC検証
上記で紹介した2つのPOCを試してみます。
その1
evkl1dさんのPOCを試します。
以下のようにGithubからクローンしてきます。
┌──(root㉿kali-linux-2022-2)-[~]
└─# git clone https://github.com/evkl1d/CVE-2023-46604
Cloning into 'CVE-2023-46604'...
remote: Enumerating objects: 22, done.
remote: Counting objects: 100% (22/22), done.
remote: Compressing objects: 100% (17/17), done.
remote: Total 22 (delta 5), reused 13 (delta 3), pack-reused 0
Receiving objects: 100% (22/22), 5.10 KiB | 5.10 MiB/s, done.
Resolving deltas: 100% (5/5), done.
このPOCをよく読むと、Pythonを実行してExploitするのですが、その際にClassPathXmlApplicationContext
のクラスを利用しています。
このインスタンスの生成時、リモートにあるXMLファイルの設定ファイルを参照してOSのコマンドを実行するといったものです。
CVE-2020-14882のPOCでもあったJavaでよく見るやつですね。
このクラス名とメッセージ(XMLのURL)をActiveMQで使われているOpenWireのプロトコル(今回はPort 61616)に送信し、BaseDataStreamMarshaller
クラス周りに叩き込めばRCEができるはずです。
詳細は以下の記事を参照してください。
実行
XMLを外部から参照できるようにhttpサーバを以下のように建てます。
┌──(root㉿kali-linux-2022-2)-[~]
└─# python3 -m http.server 80
次にXMLファイルを編集して以下のようにリバースシェルコマンドを叩き込むように変更します。
そして、PythonのPOCを実行します。
簡単ですね。3つ目の<value>
を編集すればどんなコマンドでも叩き込めます。
その2
VulnCheckさんのPOCを利用します。
と言ってもXMLとPOCコードを変更するだけで済みます。
XML以下のように編集します(一部マスクしてます)。
記載しているBase64コードの内容ですが、基本的にJavaのコードとなります。エンコード前は以下のようになります。
次にPythonのExploitコードを以下のように編集します。
class_name = "org.springframework.context.support.FileSystemXmlApplicationContext"
実行
変更したExploitコードを実行します。
プロンプトは帰ってきていませんが、コマンドは実行できているのがわかります。
2つのPOCの違い
2つのPOCの違いは、XMLファイルの内容と使うクラスです。
ClassPathXmlApplicationContext
ではなくFileSystemXmlApplicationContext
,SpEL
を利用します。
この違いは何かをpspyのToolを使って確認します。
その1のPOCでは以下のようにシェルジャンプを行うことで任意のコードが実行されます。
その2のPOCではメモリ上にJavaのコードが展開されて実行されるので、シェルジャンプを行う必要がありません。
要するにメモリ上であれこれするようにJavaコードを構築してしまえば色々できるということです。
BlueTeamからの検知回避に利用できます。
BlueTeamで確認すべき観点
- ActiveMQのバージョンが脆弱なのか
- OpenWireプロトコルを使用しており、外部からアクセス可能なのか
- ActiveMQから外部のXMLファイルを参照可能なのか(ActiveMQ発の通信ができるか)
まとめ
今回はCVE-2023-46604の検証をHacktheBoxの「Broker」で行いました。
脆弱性を検証できる環境は少ないのでこういうBOXはありがたいですね。
明日は@tippyさんです。