
こんにちは同僚!
本日は、
Citrix XenServer 5.6およびその操作のさまざまな側面に関する私の話を続けたいと思います。 今回は、かなり単純な(どうやら!)問題を解決する必要がありました:
SSHを使用せずに
dom0でコマンドを実行します。 実装の可能性を検討した結果、このOSのHTTP APIの面白いニュアンスが発見されました。/etc/passwdの取得方法、
rsyncのリモート実行、
XenSourceシンCLIプロトコルの概要。 次に、1つのストーリーのストーリーと呼ばれるものについて説明します。
まず、同様の問題がどのように発生したかを説明したいと思います。
前のシリーズでは、
XenServerのセキュリティガイドのパブリックベータ版を
紹介しました。わかりやすいガイドを作成することを期待して「見ました」。 1つの推奨事項(
VMWare ESXiの セキュリティ強化ガイドと同様)は、SSHデーモンを無効にすることです。 動機は、Xenの企業バージョンがActive Directoryを介した認証で
RBACシステムを使用する機能を持っていることです。 ベンダーの推奨によると、このパスはセキュリティの観点から望ましいです。
私のマニュアルで説明され
ている dom0のコンソールスタートアップスクリプトを変更した後、パスワードなしでシステムに
アクセスすることは除外されています。 したがって、
dom0コンソールに直接
アクセスするには、
pool-admin特権を持つユーザーのパスワードだけでなく、
rootアカウント情報も知っている必要があります。
わかった ここで、自動化ツールを使用したオペレーティングシステムのリモート監査のタスクに直面しています。 私たちが持っているのは、
XenAPIにつながる
XML-RPC 、そのドキュメント、および優れたOCaml言語のXen-orgソースコードだけです。 bashでコマンドを実行し、さらに処理するために「排気」を取得します。 どうやってやるの?
まず、これが通常の方法では機能しない理由を理解する必要があります(APIの一部として提供されるコンソールを使用)。 クライアント側からコンソールを呼び出す技術を思い出してください:コンソールに接続し(
https://<xen_host>/console?ref=OpaqueRef:console_id
)、有効なsession_idを持ち、
vncterm RFB端末に 到達します。 このプロトコルを使用すると、マウス操作とボタン押下をリモートサーバーに送信し、代わりに画面のビットマップイメージを受信できることが明らかです。 さらに明らかなのは、最新バージョンのRFBプロトコルでは、とりわけファイル転送が可能なことです。 コマンドの実行も習得すれば十分です-問題ありません。 しかし、それは簡単すぎるでしょう。 Citrixは
vncterm端末で
RFBプロトコルバージョン003.003を使用
します。ファイル転送はまだ実装されていません。
この悲しいニュースを考慮して、開発チームは
1998年の RFBサンプルを通じてトランスポートを実装するための可能な方法を分析し始めました。 2つのアイデアが浮上しました。 1つ目は、
ABBYY FineReaderとの統合
です (
dom0で受信したビットマップ上のテキストを認識します)。 2つ目は、マウスの動きのエミュレーションです。これにより、画面上のテキストを選択して、プロトコルで使用可能なクリップボードに送信できます。
どちらのオプションも、詳しく調べると、狂った狂人を連想させる:)悲観的な見通しにより、私は
XenAPIのドキュメントを読むことに戻りました。 そして、プラグインアーキテクチャ、つまりRPC呼び出し
call_pluginを介して自分の実行可能ファイルにアクセスする機能など、これまでに遭遇したことのないものに注目し
ました 。 モジュールは
/etc/xapi.d/plugins/ディレクトリにあります。

その後、すべてが簡単です。作成したプラグインは
XML-RPCを介して呼び出され、適切な
Pythonスクリプトを実行します。このスクリプトは、
subprocessを使用して必要なコマンドの実行を実装します。 いいね! dom0でコマンドを実行し、それらからコマンドを受け取る方法が明らかになりました。
次の問題はそれ自体で現れました:プラグインはどのようにしてサーバーに到達する必要がありますか? 実際、この問題を解決する際に
、 XenAPIの 「水中の熊手」がいくつか
発見されました 。
もちろん、私は関数に興味がありました。標準ユーティリティxe.exe、-patch
-uploadを使用してアクセスできます。 これにより、ファイルをリモートで
XenServerにアップロードし、サーバープール全体にインストールできます。 パッチのプレゼンテーション形式は非常に単純です。これは
sharで、zipでパッケージ化され、Citrixによって署名されています(!)。 パッチを調べて手動でインストールする方法は、会社のメモ「Selectel」で読むことができます。 パッチがダウンロードされると、その署名は
gpg keyringの公開鍵の対応するセットで検証されます。 したがって、一般的なバンドルに独自の署名を追加するだけで十分です-プラグインのキャストの問題はなくなります。 同様の設計を組み立てることは難しくありませんが、鍵を束にしてキーを埋めるには、コンソールにアクセスする必要があります。 結果は悪循環でした。 そこで、標準の方法をバイパスしてプラグインを埋める方法を探し始めました。
この呼び出しを使用して、
https://<xen_host>/pool_patch_upload
はAPIの公式の説明にはないことに注意しました。 これには論理的な説明があります。実際にはAPIの一部ではありません。 自然な好奇心が質問を促し
ます。 「。 答えを見つける方法は非常に簡単です:
Wireshark 。

このような単純なアプローチについて私を責めるかもしれませんが、残念ながら、XenServerオペレーティングシステムのHTTP APIについては、ほとんど何も説明されていません。 そして、この問題に取り組み始めた頃には、ソースコードを十分に効率的に分析できるレベルの
OCamlをまだ理解していませんでした。
TLSの復号化にすばらしい
Wireshark機能を使用し、
/ etc / xensource /の証明書を慎重に
省略したため、xe.exeユーティリティ(XenCenterから)とサーバー間の通信のダンプを受け取りました。

公式のドキュメントに記載されている
XML-RPC通信を期待していました。 しかし、そこにありました! 代わりに、「POST / cli HTTP / 1.0」がログに表示されました。 ユーティリティはコマンドとその属性を
https://<xen_host>/cli
し、
https://<xen_host>/cli
送信しました。 「
スープに何か不足しているようです。」 プロトコルの復号化から、ユーティリティが使用する特定の
XenSourceシンCLIプロトコルが存在することになります。 すべてのパスは、
Githubで
XenAPIソースにつながっています 。
ハイパーバイザーのこの素晴らしいコンポーネントのソースコードをしばらく読んだ後、リモートホストでxe.exeヘルパーコマンドの実行を実装する「
XenSourceシンCLIプロトコル 」APIバージョン0.2があることがわかりました。

これは
xapi / cli_protocol.mlファイルに記述されてい
ます 。 これが「将来のAPI」であり、xe.exeユーティリティを単にコマンド送信の手段にし、XenAPIでハンドラーを構築するように設計されていることは注目に値します。
一般に、このCLI APIの発見は重要でした
。XML-RPCレシーバーと
/コンソールスイッチだけがポート80 \ 443に存在するわけではないことがわかりました。 同様の呼び出しで利用できる他のモジュール-ソースコードファイル(
xen-api / ocaml / idl / constants.ml )の1つで見つかりました。 簡単に推測できるように、非常に興味深い情報を生み出す多くの課題がありました。
https://<xen-host>/syns_config_files
:
/ etc / passwdを取得するのに十分な権限(
pool-admin )があることに魅了されました(以前の記事で既に述べたように、XenServerはそこにパスワードハッシュを保存します)。
別の興味深い呼び出しは、「
CONNECT /remotecmd?cmd=rsync&arg=some_nice_arg &pool_secret=your_pool_secret
」を通じて行われます。
/ etc / xensource / ptokenの値を知って
いれば 、サーバーの
ルート権限で
rsyncコマンドをリモートで実行できます。 これにより、本質的に、ファイルシステムへのフルアクセスが可能になります。 しかし、あなたはおそらく尋ねるでしょう:「しかし、どうやって
ptokenを手に
入れるのか?」。
ここではまだ簡単です。
Xensource開発者
は 、プールデータベースのコンテンツをXMLファイルとしてリモートで受信する機能を作成しました。 サーバーで "
GET /pool/xmldbdump?session_id=
"の形式のリクエストを実行すると、
必要なpool_tokenを簡単に見つけることができるキーと値のペアの完全なセットを取得できます。
実際、リモートパッチのダウンロード自体は、「
PUT /pool_patch_upload?session_id=
」という呼び出しによって実行されます。 それに応じて、サーバーは「200、OK」と書き込みます。 そして、ソケットに情報をフラッディングし始めると待機します。 ファイルをアップロードするとすぐに、パッチは有効性のチェックを開始します。 ただし、1つの機能があります。接続を保持している間、APIはファイルをまだアップロードしていると見なし、それに触れません(ただし、ファイルは
/ var / patchに既に作成されています)。 見つけられなかったファイルの長さをチェックします。
/ var / patchはサーバーのルートセクションにあるため、
/ dev / urandomがそこに送信された場合、DoSは避けられません。
もちろん、これはすべてから遠いです。
ここで課題と必要な権利を詳しく見ることができ
ます 。
すべてのコードは十分に文書化されており、正確に定式化された質問があれば、その中の答えを見つけることは難しくないと思われます。
一般に、私が説明した方法の構成は、署名を確認せずにシステムにパッチを正常にアップロードするのに十分でした。 この方法論は「
脆弱性の悪用 」の概念に隣接しているため、詳細な説明は行いませんが、あなた自身がすべてを理解したと思います:)
ご清聴ありがとうございました!