
TryHackMeのルームSourceに関する解説と、脆弱性を悪用するPythonスクリプト
TryHackMeの「Source」ルームに関する解説と、脆弱性を悪用するPythonスクリプト
この脆弱性の発見について、私は一切の功績を主張しません。以下の方々がリソースを提供してくれたおかげで、私のような者も学ぶことができました。感謝します。
脆弱性発見: Özkan Mustafa Akkuş
MSFモジュール: https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/linux/http/webmin_backdoor.rb https://www.rapid7.com/db/modules/exploit/linux/http/webmin_backdoor/
MSFモジュール作成者: wvu
TryHackMeルーム: https://tryhackme.com/room/source
THM作成者: https://tryhackme.com/p/DarkStar7471
リソース: https://www.webmin.com/exploit.html https://github.com/webmin/webmin/issues/947 https://www.perlmonks.org/?node_id=301355
私は決して熟練したセキュリティ専門家ではありません。つまり、誤った情報を提供する可能性があるということです。もしあなたが熟練した専門家/経験豊富な研究者で、何か間違っている点を見つけたら、私に知らせてください。そうすれば、私は戻ってきて、間違っていた部分を勉強し、正しい情報を提供できます。これは私だけでなく、この解説に出くわすかもしれない他の初心者研究者にとっても有益です。もし私が書いた誤った情報を見つけたら、[email protected]までご連絡ください。修正します。ありがとうございます!
Webminは、Unix系システム管理のためのWebベースのツールです。2018年の第1四半期のある時点で、Webminはサプライチェーン攻撃を受けました。正体不明の攻撃者がファイルに悪意のあるコードを挿入し、デフォルト設定でそのバージョンのWebmin(1.890)をホストしているシステムにバックドアを開く脆弱性を作り出しました。これをサプライチェーン攻撃と呼ぶのは、ソフトウェアの開発者・配布者が製品のソースコードを侵害されたためです。サプライヤーが侵害された製品をリリースすると、ソフトウェアを更新したすべてのユーザーが脆弱なコードを実行することになり、攻撃者は脆弱なコードを実行しているシステムを侵害できるようになります。同年、Webmin開発者は事態に気づき、ファイルを元の状態に戻しましたが、攻撃者は再びコードを挿入することができました。今度は、期限切れパスワードを変更するオプションが有効になっている場合にのみ脆弱性が発生するようになりました。この脆弱性は2019年8月まで発見されませんでした。脆弱性はWebminバージョン1.930で修正されました。
password_change.cgi2. コード
いくつか検索した後、Webminバージョン1.890をコマンドインジェクションに対して脆弱にしているコード行を見つけることができました。正しい情報を見つけるのに苦労したのは、この問題に関連するCVEが実際に2つ存在するためです(CVE-2019-15231 / CVE-2019-15107)。CVE-2019-15231はバージョン1.890のデフォルト設定の脆弱性に関連し、CVE-2019-15107はバージョン1.920までの期限切れパスワード変更オプションを有効にする必要がある脆弱性に関連します。では、バージョン1.890のコードを見てみましょう。password_change.cgiの12行目に、次のコード行があります:
$in{'expired'} eq '' || die $text{'password_expired'},qx/$in{'expired'}/;
これを書いている時点で、私はPerlで何かを書いたことは一度もありません。検索エンジンを使ってこのコード行を解析し、コードの動作となぜ悪用に対して脆弱なのかをよりよく理解しましょう。||演算子の左側の最初のコード片は、変数($in)がパラメータ(expired)を受け取り、それが空文字列''と等しいか(eq)をチェックしているように見えます。中央には||演算子があります。||はPerlで論理演算子orを使用する別の方法です。Perlで||を使用する場合、左側が真であれば右側は評価されません。左側が偽であれば、右側が評価されます。||演算子の右側のコードの前半には、die $text{'password_expired'}とあります。Perlでは、dieはスクリプトプロセスを強制終了し、エラーメッセージを表示する関数です。そのメッセージはおそらく、パスワードが期限切れであることを示す$text変数でしょう。コードの最後の部分が面白いところです。カンマ,の後にqx/$in{'expired'}/があり、セミコロン;でコード行が終わっています。カンマはコードの区切り文字として機能し、左側が最初に評価され、次に右側が評価されます。Perlでは、qxはホスト上でシステムコマンドを実行できる関数です。//はパラメータを識別するためのデリミタです。この場合、qx/$in{'expired'}/は$in{'expired'}パラメータをシステムコマンドとして実行します。$in変数は、PHPの$_GETに似たものだと思います。その理由は、私が書いたエクスプロイトスクリプトでは、expiredというパラメータがあり、ペイロードを保存してからPOSTリクエストでサーバーに送信します。そのコードは次のようになります: data = {'expired':payload,}。$in変数は、私たちがexpiredに設定した値を取得し、qx関数でペイロードを実行できるようにする何かをしているはずです。このセクションをまとめると、脆弱なコード行は、POSTリクエスト内のexpiredパラメータが空文字列と等しくないことを検出し、||演算子がコードの右半分を評価して、expiredパラメータに格納されたペイロードを実行します。それでは、TryHackMe.comのSourceルームの解説に移りましょう。
まずはポートスキャンから始めましょう。nmapはひどく遅いことがあるので、rustscanを使って大まかな全体像を把握します。

2つのポートが開いているようです。22と10000です。次にnmapを使って、各ポートでどのサービスが動作しているかを調べます。

標準ポートでSSHが動作しており、ポート10000でHTTPサービスが動作しています。ポート10000のページに移動して、何があるか見てみましょう。

このページにアクセスするには、HTTPSを使用し、SSL証明書の警告を回避する必要があります。Webminサービスのログインページのようです。このボックスを最初にやったとき、いくつかディレクトリブルートフォースを試しましたが、特に面白いものは見つかりませんでした。searchsploitを使って、nmapスキャンで得たWebminのバージョンに脆弱性があるかどうか調べてみましょう。

いくつかの選択肢があるようですが、どれも私たちのバージョンと一致しません。MSFを開いて、何が使えるか見てみましょう。

いくつかの選択肢があります。nmapで得たWebminのバージョンを検索して、これを絞り込むのに役立つCVEが出てくるかどうか見てみましょう。

脆弱性の概要で、password_change.cgiファイルについて何か言及されているのがわかります。同じ開示日であり、password_change.cgiファイルにも言及しているMSF検索結果の番号5を使いましょう。

ふふ、実際にはMSFを使いません。MSFは便利ですが、自分のコードで何かを悪用する方法を理解するほど楽しくはありません!このエクスプロイトのリファレンスとしてRubyのソースコードを使い、Pythonで独自のエクスプロイトコードを作成しました。代わりにそれを使いましょう!

バダビンバダブーム、ルームでrootシェルを取得しました!フラグは公開しません。きっと見つけられるでしょう!読んでくれてありがとう。良い一日を!