This post is also available in: English (英語)
概要
近年、攻撃者がリモートデスクトッププロトコル(RDP)を悪用してセキュリティの甘いサーバーやエンタープライズネットワークにアクセスするケースが増えています。また2017年以降RDPはランサムウェアを使用するマルウェア攻撃の重要な攻撃ベクトルにもなっています。セキュリティ専門家もRDPの脆弱性を検出して攻撃を防ぐためのシグネチャを作成しており、このプロトコルには多くの注目が向けられています。
RDPはMicrosoftによるプロプラエタリなプロトコルで、ネットワークトラフィックを暗号化するための動作モードをいくつかサポートしています。残念ながら、暗号化されてRDPコンテンツが非表示になるとRDP用シグネチャの作成はむずかしくなりますが、復号用の秘密鍵ファイルを用意したテスト環境があればWiresharkのRDPトラフィックを含むパケットキャプチャ(pcap)を復号できるようになります。
そこで本稿では、テスト環境を用意して復号用秘密鍵でRDPトラフィックを復号する方法について解説します。
前提条件
本講座は以下の条件を満たした場合にもっとも高い学習効果を期待できます。
- VirtualBoxやVMwareなど2台のWindowsホストを実行できる仮想環境があること
- RDPをセットアップして使用する方法を理解していること
- RDPクライアントがあること(本稿ではWindows 10 Professionalを実行するホストを使用)
- RDPサーバーがあること(RDPを有効にした別のWindowsホストかFreeRDPを実行するWindows以外のホストを用意する)
- これら2台のホスト間のネットワークトラフィックがキャプチャ可能であること(仮想環境内でやるのがもっとも容易)
- Wiresharkバージョン3.0またはそれ以降があること
- ネットワークトラフィックの基礎知識があること
全体的な手順
全体的な手順はおおまかに次の7つに分けられます。
- 手順1: 2台のホストがある仮想環境をセットアップします。1台はRDPクライアントとして、もう1台はRDPサーバーとして機能させます。
- 手順2: RDPクライアントからForward Secrecy暗号を削除します。
- 手順3: RDPサーバーの秘密鍵を取得します。
- 手順4: RDPサーバーとWindowsクライアント間のRDPトラフィックをキャプチャします。
- 手順5: Wiresharkでpcapを開きます。
- 手順6: Wiresharkに秘密鍵を読み込みます。
- 手順7: RDPデータを調べます。
手順1: 仮想環境をセットアップする
この種の分析で最も一般的に使われる仮想環境はVirtualBoxとWindows/Linux用VMware Workstationの2つでしょう。Mac OSではVMWare Fusionも使われています。VirtualBoxは無料ですが、VMwareは商用製品です。
本講座では仮想環境上で仮想マシン(VM)をセットアップする部分についてはふれません。本稿で利用したラボ環境の基本構造は図1の通りです。
今回のラボ環境には2つのWindows10ホストが含まれています。1台はRDPクライアントとして、もう1台はRDPサーバーとして機能するものです。仮想LAN上でこれら2台のホストの間にRDPセッションを張り、そのネットワークトラフィックをキャプチャしていきます。
手順2: RDPクライアントからForward Secrecy暗号を削除する
暗号化アルゴリズムのなかにはForward Secrecy(「前方秘匿性」とも呼ばれる。以下、「FS」と表記)を提供するものがあります。これらの種類の暗号化アルゴリズムは、SSL/TLS接続用にセッション鍵を複数作成します。こうした暗号アルゴリズムを利用されてしまうと、RDPサーバーから1つ秘密鍵をもらっただけではSSL/TLSトラフィックを復号できません。そこで、RDPクライアントでFSをサポートする構成オプションを削除しておく必要があります。
本講座用で私たちが用意したRDPクライアントはWindows 10 Professionalを実行するホストです。このホストには組み込みのRDPクライアントがあります。
MicrosoftはFSをサポートする構成オプションの削除方法の詳細を『トランスポート層セキュリティ (TLS) を管理する』、『Prioritizing Schannel Cipher Suites(Schannel暗号スイートの優先順位付け)』という2つの記事で公開しています。以下は私たちが実際に行った内容を1ステップずつ説明したものです。
Windowsの検索ボックスに「gpedit.msc」と記入し、グループポリシー管理コンソールを検索します。「gpedit.msc」が [最も一致する検索結果] に表示されるので、この項目を右クリックしてコンテキストメニューから [管理者として実行] をクリックします(図2参照)。
コンソールの左ペインを次の順にクリックして展開します(カッコ内は日本語のUI表記)。
- Computer Configuration (コンピューターの構成)
- Administrative Templates(管理用テンプレート)
- Network(ネットワーク)
- SSL Configuration Settings(SSL 構成設定)
図3は、[SSL Configuration Settings(SSL構成設定)] まで展開したところを示しています。
次に暗号リストの上にカーソルを置いて右クリックし、コンテキストメニューから [Select All(すべて選択)] を選んでリスト全体を選択します(図6参照)。
リスト全体を選択した後、右クリックしてコンテキストメニューから [Copy(コピー)] を選択し、リストをコピーします(図7参照)。
コピーした暗号リストを任意のテキストエディタ(メモ帳など)にペーストします。「Diffie-Hellman Ephemeral(ECDHE)」ないし「Digital Signature Algorithm(ECDSA)」暗号を使う、楕円曲線暗号をサポートしている暗号アルゴリズムをすべて削除します。つまり名前に「ECDHE」と「ECDSA」のいずれかまたは両方を含むエントリを、すべて削除する必要があります。以下の図8の例からわかるとおり、これらの暗号アルゴリズムはすべて連なって配置されているのでテキスト内で簡単に削除できます。
図8で更新した暗号のリストは以下の通りです(訳注: 日本語環境で行う場合、暗号アルゴリズムの区切りにはカンマのかわりに読点(、)が使用されます)。
TLS_AES_256_GCM_SHA384,TLS_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_NULL_SHA256,TLS_RSA_WITH_NULL_SHA,TLS_PSK_WITH_AES_256_GCM_SHA384,TLS_PSK_WITH_AES_128_GCM_SHA256,TLS_PSK_WITH_AES_256_CBC_SHA384,TLS_PSK_WITH_AES_128_CBC_SHA256,TLS_PSK_WITH_NULL_SHA384,TLS_PSK_WITH_NULL_SHA256 |
表1 FS暗号アルゴリズムを削除して更新されたリスト
テキストエディタで変更後のテキストをすべて選択してからコピーします。その後、グループポリシー管理コンソールに戻り、コピー元の全テキストが選択された状態であることを確認してから、更新した暗号リストをSSL暗号スイートフィールドに貼り付けて元のリストを上書きします。[Apply(適用)] ボタンをクリックし、続けて [OK] をクリックしてウィンドウを閉じます。これでリストが更新されたので、グループポリシーエディターを閉じます。
この手順を実行したら、次はRDPサーバーの秘密鍵を取得する必要があります。
手順3: RDPサーバーの秘密鍵を取得する
FreeRDPはRDPサーバーとして使える選択肢の1つです。FreeRDPはこのGitHubリポジトリで入手できます。ビルド手順はこちらから入手できます。サーバーをビルドするときは必ずWITH_SERVER = ONフラグを設定してください。サーバーをビルドしたら、サーバーに秘密鍵を与えるかFreeRDPに付属している秘密鍵を使用する必要があります。
本講座では、Windows 10 Professionalを実行するもう1台のホストをRDPサーバーとして使用しています。次に、ホストのオペレーティングシステムから秘密鍵を抽出します。
2台目のWindowsホストがRDPサーバーとして機能するよう、RDPを有効にします。Windows 10 Professionalを実行しているホスト上でRDPを有効にするには、[スタート] メニューからWindows の[Settings(設定)] に移動し、[System(システム)] アイコンを選択します(図9参照)。
[System(システム)] を開いたら、[Remote Desktop(リモートデスクトップ)] を選択し、[Enable Remote Desktop(リモート デスクトップを有効にする)] スイッチをクリックします(図10参照)。
2台目のWindowsホストをRDPサーバーとして設定した後は、オペレーティングシステムから秘密鍵を抽出します。
サーバーの秘密鍵を抽出するには、JailbreakかMimikatzを使います。今回はJailbreakを使います。
Jailbreakは、iSECPartnersが作成した、サーバーのRDP証明書をエクスポートできるツールです。エクスポートされた証明書からは秘密鍵を抽出できます。
Jailbreakを使うためにさきほど立てたRDPサーバー上にこのGitHubリポジトリから以下のJailbreakバイナリをダウンロードしておきます。
- EasyHook64.dll
- jailbreak64.exe
- jailbreakhook64.dll
- jbstore2_64.exe
注: 上記のファイルは、2021年3月4日時点にダウンロードしたものをWindows 10 Professional 64ビットホスト上で使用しています。GitHubページのスクリーンショットを以下の図11に示します。
Jailbreakのバイナリをダウンロードしたら、図12で示すように管理者権限でコマンドプロンプトを開きます。
コマンドプロンプト上でダウンロードしたJailbreakバイナリのあるディレクトリに移動します。このディレクトリから次のコマンドを実行します。
1 |
jailbreak64.exe %WINDIR%\system32\mmc.exe %WINDIR%\system32\certlm.msc -64 |
32ビットバージョンのWindowsを実行している場合はかわりに次のコマンドを実行します。
1 |
jailbreak32.exe %WINDIR%\system32\mmc.exe %WINDIR%\system32\certlm.msc -32 |
RDPサーバーとして機能するWindowsホストで64ビット用コマンドを実行する例については、以下の図13を参照してください。
このコマンドを実行すると、ローカルマシンの証明書マネージャーが開きます。左ペインから[Remote Desktop(リモートデスクトップ )]、[Certificates(証明書)]フォルダの順に展開します。この図では証明書が示されています。証明書が複数ある場合は有効期限が最も後の証明書を選択します。証明書を右クリックし、[All Tasks(すべてのタスク)] を選択してから [Export(エクスポート)] を実行します(図14参照)。
今回のホストの場合、証明書のエクスポート形式として選択できるのはPKCS #12 (.PFX) ファイル形式のみでした(図16参照)。
証明書にはパスワードが必要です(図17参照)。さいわいとくにパスワードの複雑性については要件がなかったので、1文字のパスワードを使用しました。
これでようやく証明書を秘密鍵と一緒にエクスポートできました(図18参照)。
Jailbreakを使わずにMimikatzでサーバー証明書を抽出することもできます。Mimikatzを使用してRDPサーバー証明書を取得する手順は、こちらのGitHubを参照してください。
今回は証明書をJailbreakで取得したので、Linuxホストにこの証明書を移してOpenSSLで秘密鍵を抽出します。まずは次のOpenSSLコマンドでPEM形式でキーを抽出します。
1 |
openssl pkcs12 -in server_certificate.pfx -nocerts -out server_key.pem -nodes |
秘密鍵からパスフレーズを削除するため次のコマンドも実行します。
1 |
openssl rsa -in server_key.pem -out server.key |
これでRDPサーバーの秘密鍵を得られました(図19参照)。
サーバーの秘密鍵を使用する前に、2台のWindowsホスト間でRDPセッションをキャプチャし、pcapとして保存する必要があります。
手順4: RDPトラフィックをキャプチャする
同じ仮想環境に2台のWindowsホストがある場合、dumpcap、tcpdump、Wiresharkなどのツールを使って、プロミスキャスモードでVLAN内のネットワークトラフィックをキャプチャすることができます。キャプチャを開始したら、Windowsクライアント上からリモートデスクトップ接続アプリでRDPサーバーとして機能するもう1台のWindowsホストにログインします。ここでのRDPサーバーのホスト名はDESKTOP-USER1PCです。
pcapをキャプチャしながら、DESKTOP-USER1PCにログインし、ドキュメントを開いたり、Webをブラウジングするなどの一般的なタスクを実行します。
1分ほどそうしてタスクを実行した後で、リモートデスクトップ接続アプリからログオフし、VLANでのネットワークトラフィックキャプチャを停止します。
手順5: Wiresharkでpcapを開く
WiresharkでRDPセッションのpcapを開きます。ですが、Wiresharkの表示フィルタで「rdp」をフィルタリングしても、RDPトラフィックが暗号化されているために何も表示されません。図22は、pcapでRDPをフィルタリングしたときに表示される空白のページを示しています。
ここでサーバーの秘密鍵を使ってWiresharkのRDPトラフィックを復号してやるとこれとはまったく違う結果になります。
手順6: Wiresharkに秘密鍵を読み込む
今回キャプチャしたpcapsの場合、RDPサーバーであるDESKTOP-USER1PCのIPアドレスは「10.3.4.138」で、RDPトラフィックは「3389/tcp」経由で発生しています。WiresharkでRDPトラフィックを適切に復号するにはこの情報が必要になります。
Windows/Linux の場合は [編集]、[設定] の順に開きます。Mac OS の場合は [Wireshark]、[Preferences] の順に開きます。図23に示すとおりに[Protocols]セクションを展開します。
手順7: RDPデータを調べる
秘密鍵を読み込ませてからRDPをフィルタリングします。すると今度は列の表示が空白ではなくなり、図25に示すように複数の結果が得られます。
セキュリティ専門家がRDPの脆弱性や攻撃の発見のためにシグネチャを書くさいは、図25で明らかになったような情報が業務上重要になります。
結論
本稿ではRDPセッションのトラフィック復号にあたってどのように環境を整えればよいかについて見ていきました。これにはWindows 10 Professionalを実行するホストを2台仮想LAN環境に用意するのがいちばん簡単でしょう。クライアント側でForward Secrecy暗号アルゴリズムを削除してから、RDPサーバーとして機能させるWindowsホストの側で秘密鍵を抽出し、ネットワークトラフィックのpcapをキャプチャし、セッション終了後にサーバーの秘密鍵を使ってRDPトラフィックを復号しました。
こうした環境があれば、セキュリティ専門家は、RDPの脆弱性や攻撃を検出するシグネチャを作成しやすくなるでしょう。
『Wiresharkによるパケット解析講座』シリーズの以前の講座は以下から確認してください。
- Wireshark によるパケット解析講座 1: Wiresharkの表示列をカスタマイズする
- Wireshark によるパケット解析講座 2: 脅威インテリジェンス調査に役立つフィルタリング設定
- Wireshark によるパケット解析講座 3: ホストとユーザーを特定する
- Wireshark によるパケット解析講座 4: Pcapからのオブジェクトのエクスポート
- Wireshark によるパケット解析講座 5: Trickbot感染の調査
- Wireshark によるパケット解析講座 6: Ursnif感染の調査
- Wireshark によるパケット解析講座 7: Qakbot感染の調査
- Wireshark によるパケット解析講座 8: HTTPSトラフィックの復号
- Wireshark によるパケット解析講座 9: Dridex感染トラフィックの調査
- Wireshark によるパケット解析講座 10: Emotet 感染トラフィックの調査