
IPMI関連のDARPAプロジェクト成果物
私はIPMIを調査するためのソフトウェアをいくつか書きました。以下はその結果の一部です。通常の「検出、データ取得、監査」というサイクルを実行しようと考えました。これらのそれぞれは、少なくとも私にとっては、それ自体がかなり興味深い問題であることがわかりました。
ちなみに/参考までに - IPMIを調査するための新しいツールをリリースしました - https://github.com/zenfish/zipmi - また、BMCをQemu上の仮想システムとして実行するためのQemuレシピ/イメージ等のセットも https://github.com/zenfish/zbmc にあります。
http://fish2.com/ipmi にある論文や資料など
リモートBMC上のアカウントを推測し、そのハッシュを抽出して、 (HMACハッシュ化された)パスワードのクラッキングを試みる 小さなPerlプログラム を以下に示します。興味のある方のために 少し 解説を書きました。 コメントが豊富で、何らかの役に立つかもしれません。
IPMI仕様では、認証なしでリモートシステムの暗号スイートを取得できるとされていますが、 実際にこれを行うツールは私の知る限り存在しません(すべて認証が必要です。もちろん、必要なら 生の16進バイトを入力することもできますが!)。そこで、これを実行する小さなツールを書きました。 これは主にipmitoolの出力に従おうとしています。その過程で、そのユーティリティにバグがあると 思われる箇所を発見しました(最終行で、時々システムが誤って解釈されるように見える ガベージを出力することがあります)。しかし、誰にもわかりません。テストするのに十分な システムを持っていないからです。とにかく... ipmi-get-ciphers.py。
何はともあれ、Cipher0システムを見つけるのに役立ちます(注 - これは単に サポートされている暗号スイートを指摘するだけで、実際に有効になっていることを 意味するわけではありません)。しかし、世の中には興味深いものが存在します。
ここに2つのプログラムがあります。1つはシンプルなPythonによる リモートプローバー(Perlに嫌気がさしてきたところです、正直言って)で、もう1つは FreeIPMI のユーティリティを使用して 認証情報付きの設定データを取得するものです。
BMCに単一のパケットを送信し、その応答を解析する小さなPythonプログラムです (50%以上がインラインコメント、gzipで2.5k)。単一のパケットだけで何ができるのか、 と疑問に思うかもしれませんか? まず、IPMI用の10以上の異なるセキュリティテストが可能です。 まあ、最初から最後まで、それは単なるパケットです :) 動作にはpython、BMC、そして UDPポート623へのオープンパスが必要です。使用方法は単に "ipmi-get-auth.py target" です。
これを極限まで推し進めると... まあ、上記のメガバージョンとも言うべきもので、 すべてのチャンネル、すべての権限、すべての... まあ、お分かりでしょう。 偏執的な人のためのものです(なぜこのような動作をするのかは、コメントか私が書いた記事を 読んでください!)
mega_chan.py /
メガ メガ メガ ... チャン チャン チャン...
そして、システムにGet Device IDパケット(IPMI v2仕様のp250を参照)を送信する シンプルなプログラムを以下に示します。これは理論上、認証なしで動作するはずです。 私が行った小規模な調査では、約90%のシステムがこれに応答しました(ただし、すべてが 有効な情報を返したわけではありません!)。ベンダーやモデル番号などの情報を取得できる こともありますが、より興味深いのは、ネットワーク経由では伝統的に取得が難しい 一意のIDを実際に取得できることです。
get-ipmi-guid.py /
Get Device ID
Supermicroは、そのBMCからのパスワードファイル開示にいくつか問題を抱えています。 例えば、これや他の記事を参照してください:
a-penetration-testers-guide-to-ipmi
このスクリプトを使用するには、単に次のようにします:
dump_SM.py password_file
私の環境では動作します。保証はありません。
UDPポート623と通信できれば、リモートシステムがIPMIを実行しているかどうかを 確認するのは非常に簡単です。ただし、データセンター内にいない限り、ほとんどの人は UDPをブロックします。そして、たとえブロックしていなくても... UDPスキャンは 想像できる限り最も遅いものです。そこで、私は現在、老舗のNmapと ipmiping(FreeIPMI Gnuツールから)を活用した2つの基本的な方法を使用しています。 最も簡単な方法は次のとおりです:
</p> <p>
Nmapは大規模ネットワークのスキャンにおいてipmipingよりもはるかに効率的であるため、
この方法はNmapがホストのUDP 623がオープンであると示した場合にのみ使用されます。
</p> <p>
良くも悪くも、このポートはしばしばブロックされるため、多くの場合、
他の方法でIPMIが実行されているかどうかを間接的に見つける可能性が高くなります。
</p> <p>
ポートは、その指標となる能力と、Nmapがそれらをオープン、フィルタード、または
他の状態として検出するかどうかによって重み付けされます。
</p> <p>
Nmapはまた、接続先のサービスのバナーを表示できます。私はターゲットを探すために
正規表現を使用します - 例えば、"iLO" や "DRAC" という文字列は、システムが
HPのIntegrated Lights Outサービス、つまりiLOを実行している可能性がある
良い指標です。
</p> <p>
<strong>注:</strong> 現在、私はブロードキャストping方式(自分がいるサブネットを
高速にスキャンする方法)を使用していません。この方法の有効性に関するデータが
単にないからです。動作するときは非常に高速ですが、任意のスキャンの制御と信頼性が
確保できないと感じました。私の3つのシステムのうち2つ(DellとHP)はRMCP pingに
応答しました。idiscover(ipmiutil discover)によるブロードキャストpingに応答したものは
ありませんでした。ただし、すべてが私の以下のPython監査ツールには応答しました。
</p> <p>
残念ながら(もちろん!)通信とネットワークの亡霊が登場します - nmapはポートが
オープンかどうかについてさまざまな理由を示します(オープン、クローズド、
フィルタードなど)。さらに別のテーブルには、オープンポートに「open|filtered」
(Nmapが言うかもしれないように)ヒットよりも多くのポイントを与える一連の重みがあります。
nmapの解釈と重み付けはややイライラさせられますが、それが人生です。
</p> <p>
すべての重みを取得し、すべてのポイントを合計すると、IPMI確信度レベルが得られます。
アドホックなテストでは、15ポイント以上がシステムがIPMIを実行している強力な指標で
あることがわかりました。
</p> <p>
現在、私はさまざまなしきい値(いいえ、可能性あり、おそらく、はい)を持っています。
テストでは - 自分のサーバー以外に既知のアクセス権がない状態で - かなりうまく機能して
いるようです。つまり、私が疑わしいと思うものと、上記の私の基本的な思考モデルが、
確かに特定のサーバーを上位に浮上させ、ランダムなホストはそのままにします。
ただし、誤検知にはいくつかの実際の問題があります - 多くのファイアウォールは、
nmapに対してあらゆるポートに何かがあることを示唆しているようです(私は稀なポートを
1つか2つ追加することを考えました(例えば、ポート1や31313のようなものに
リッスンしている場合、おそらく*実際に*リッスンしているわけではありません!))
</p> <p>
しかし、これはこのトピックに関する最終的な言葉を意図したものではありません。
IPMIバナーに関する適切なデータを取得するのはかなり簡単なはずで、大量のシステムを
迅速にスキャンするには、それが断然最良の方法だろうと推測しています。
上記を実装するための4つのPerlスクリプトを以下に示します。1つはスキャン、1つは解釈、 残りの2つは重み付けに使用されます。これは研究ツールまたは概念実証であり、 本番用スキャナーではありませんが、それなりの出力を生成します。
必須: Nmapバージョン6。
使用方法はかなりシンプルですが、少し変則的です。rootとして実行する必要があります。 詳細な出力には冗長モード(-v)を使用します。
スキャンは、ターゲット名に対応する結果ファイルのペアを作成します(スラッシュは アンダースコアに変換されます)。それらに対して後処理プログラムを実行するだけです。 逆数値ソートに通すと、より興味深い順序になります。10を超えるものは疑わしいと 呼びます。20を超えるものはIPMIを実行しているとほぼ確実です。# 標準実行: ./ipmi_scan.pl -A -v -O yes 192.168.0.0/24 # 高速 ./ipmi_scan.pl -tcp -v 192.168.0.0/24 # 全部入り ./ipmi_scan.pl -A -v -O high 192.168.0.0/24
この場合、簡潔フラグ(-t)を使用して出力を必要最小限に削減しました。
./post_ipmi_scan.pl -t 192.168.0.0_24|sort -rn 96.3 192.168.0.69 16.25 192.168.0.46 10.8 192.168.0.23 7.33 192.168.0.202 5.4 192.168.0.189 5.4 192.168.0.179 1.7 192.168.0.9 1.23 192.168.0.1 1.1 192.168.0.8 0.9 192.168.0.251 0.63 192.168.0.55 0.43 silent/192.168.0.250 0.2 pi.fish2.com/192.168.0.14 0.2 fierce.fish2.com/192.168.0.6 0.2 192.168.0.88 0.01 192.168.0.16
上記の結果では、上位3つのシステムが実際にIPMIを実行していますが、NmapにUDPポート623が オープンであると伝えたのはHPだけでした。私のDellとSupermicroは、より曖昧な 「open|filtered」応答を返しました。これはかなり一般的に誤警報です。うーん。 おそらく、スキャナーと並行してIPMI pingを実行する(またはNmapで正しく実行するNSEを 書く)方が良いでしょう。
FreeIPMIツールを使用して、(a)サーバーの基本的なIPMI/BMC設定を取り込み、 (b)結果に対していくつかのセキュリティチェックを行う、いくつかの小さなPythonプログラムを 以下に示します。
なぜなら、私が... まあ、実際には特別な理由はありません。1つはpython3で、 もう1つはpython2です。あなたの準備ができているかテストしているのだと思います。 プログラム、特にipmifreely.pyにはかなり多くのコメントが含まれているので、 何が起こっているかの詳細についてはそれを確認してください。simplejsonと ConfigParser、おそらくもう少し必要です。
必須 FreeIPMI が インストールされている必要があります。これを書いている時点では、MacとWindowsでは サーバーからクールなJSONファイルを取得する機会が失われます。そして、本当に、 本当に最新バージョンが必要です。警告しなかったとは言わないでください。 しかし、人生は続きます。
データ取得は、データを取得するために有効な認証情報を必要とするPythonプログラム (I-check.py)を介して行われます。結果をJSONに変換し、それを監査ツール(ipmifreely.py)で チェックできます。「IPMI-policy.ini」にサンプルポリシーがあり、テスト用の値を いくつか入れています。
使用例:
# これは設定情報を取得します。ここではHP iLO 3サーバーに対して使用しています # 出力はファイルにリダイレクトされます $ ./ipmifreely.py -v -u admin -p admin 192.168.0.46 > hp.json # これはJSONファイルを受け取り、問題を探します $ ./I-check.py drac.json ./I-check.py hp.json Host: 192.168.0.46 [bmc-config] Serial_Channel Non_Volatile_Enable_Pef_Alerting = No [bmc-config] Serial_Channel Volatile_Enable_Pef_Alerting = No [bmc-config] Serial_Channel Volatile_Enable_Per_Message_Auth = No [bmc-config] Serial_Channel Non_Volatile_Enable_Per_Message_Auth = No [bmc-config] Lan_Conf_Security_Keys K_G = 0x0000000000000000000000000000000000000000 [bmc-config] SOL_Conf Force_SOL_Payload_Authentication = No [bmc-config] SOL_Conf Force_SOL_Payload_Encryption = No [bmc-config] Lan_Conf_Auth Callback_Enable_Auth_Type_None = Yes [bmc-config] Lan_Conf_Auth Operator_Enable_Auth_Type_None = Yes [bmc-config] Lan_Conf_Auth OEM_Enable_Auth_Type_None = Yes [bmc-config] Lan_Conf_Auth Admin_Enable_Auth_Type_None = Yes [bmc-config] Lan_Conf_Auth User_Enable_Auth_Type_None = Yes [bmc-config] Rmcpplus_Conf_Privilege Maximum_Privilege_Cipher_Suite_Id_1 = OEM_Proprietary [bmc-config] Rmcpplus_Conf_Privilege Maximum_Privilege_Cipher_Suite_Id_0 = OEM_Proprietary [bmc-config] Rmcpplus_Conf_Privilege Maximum_Privilege_Cipher_Suite_Id_2 = OEM_Proprietary [pef-config] Community_String Community_String = public [pef-config] PEF_Conf Enable_PEF_Event_Messages = No
何をチェックすべきか、セキュリティ上良いと思われることについての詳細は、 IPMIセキュリティベストプラクティス を参照してください。
| ipmi_scan.pl - 基本的なIPMIスキャナー。Nmapと、利用可能な場合はipmitoolを使用 |
| ipmi_scanマニュアルページ - 上記のマニュアルページ |
| post_ipmi_scan.pl - 上記の出力を解析し、重み付けされた結果を出力します |
| j_vendor.pl - 基本的なベンダーデータ... どのベンダーがどのポートを使用するか? |
| j_weights.pl - 上記のための基本的なベンダー重み |
| I-check.py - IPMI設定データを取得します |
| ipmifreely.py - 上記の出力を解析し、いくつかの結果を出力します |
| IPMI-policy.ini - IPMIポリシーファイル |