
創造性はペネトレーションテストの核心であり、それが私たちの仕事を面白くしています。しかし、1つの落とし穴は、攻撃シナリオを「過剰設計」し、バグ(エラー条件)のみに焦点を当てる傾向があることです。しかし、欠陥(意図しない動作)も同様に壊滅的な結果をもたらす可能性があります。この記事は、そのような欠陥に対するペンテストの重要性を示すケーススタディを提供します。同時に、SDLC(セキュア開発ライフサイクル)プロセスの採用を提唱します。
この記事は、脆弱性CVE-2019-9745のRD(責任ある開示)の一部であり、ベンダーCloudCTIと緊密に協力して作成されました。この記事では、脆弱性の高レベルの概要を示した後、技術的詳細を深く掘り下げます。脆弱性の悪用を実証した後、学んだ教訓を添えた結論が提供されます。
私たちがペネトレーションテスト中に調査したCloudCTI Recognition Configuration Toolは、CRM(顧客関係管理)ソフトウェアから情報を取得するために使用されます。これにより、コールセンター担当者は顧客との通話中に関連情報を取得できます。ローカルシステムを完全に侵害するために連鎖させることができるいくつかの問題が特定されました。ベンダーは、これが他顧客のシステムや自社のシステムには影響しないことを強調したいと考えています。
多くのセキュリティ脆弱性と同様に、重要な問題は、自分の影響範囲外から来るデータの検証にあります。同様に重要なのは、システムとソフトウェアが敵対的な環境で動作するという認識です。時と経験から、盗聴はインターネット上の脅威であると学んできました。しかし、同じことは他の通信チャネルにも当てはまり、システム内部でさえも同様です。これが脆弱性の発見に決定的な役割を果たしました。
遭遇した問題の根本原因分析は、TM(脅威モデリング)などのプラクティスの重要性を示しています。TMは設計・開発の初期段階でリスクを特定するのに役立ちます。これにより、許容できないリスクの緩和や、再設計・再実装につながる可能性があります。読者には自分自身で分析を行うことを推奨しますが、参考としてベンダーの対策の説明を提供します。
ベンダーソフトウェアは、連携して動作する4つのアプリケーションで構成されています。最初のアプリケーションはグラフィカルユーザーインターフェース(GUI)です。これにより、ユーザーは複数のCRMソフトウェアパッケージから情報取得を開始できます。
GUIはメッセージを送信することで、情報取得をサービス(2番目のアプリケーション)に委任します。最初のセキュリティ問題はここに現れます。システム上の誰でもGUIとサービスの間のメッセージを観察してその形式と内容を判断できるだけでなく(機密性に影響)、自分自身のメッセージを送信することもできます(認可に影響)。さらに、サービスへのメッセージの送信元が検証されません(否認防止に影響)。STRIDE脅威モデリングの用語では、これはシステムが情報漏えいと改ざんに対して脆弱であることを意味します。実際、これらのメッセージから得られた情報は、脆弱性の発見に決定的な役割を果たしました。
3番目のアプリケーションは、多数の専門インポーターの1つです。サービスは、特定のCRMパッケージの情報取得を特定のインポーターにオフロードします。GUIから送信されるメッセージには、このインポーター向けの特定の指示が含まれています。Exquise CRMインポーターを見ると、情報取得がさらに外部(4番目)のアプリケーションに委任されていることがわかります。インポーターの内部ロジックを調査したところ、外部アプリケーションがGUIとサービスの間のメッセージで指定できることが判明しました。ここで顕在化する問題は、外部アプリケーションがその正体を検証されることなく実行されることです(否認防止に影響)。
これらの問題を連鎖させることで、メッセージを盗聴してその形式を判断し、悪意のある独自の外部アプリケーションを指定したメッセージを送信することができました。その外部アプリケーションは、インポーター/サービスと同じ権限で実行されます。これらの権限はシステム内で可能な限り最高であるため、完全な制御が達成され、システムが侵害されます。
これらの問題は、ベンダーによって次のように緩和されています。一意の共有シークレット(認可の問題を緩和)を使用してメッセージを暗号化し(機密性の問題を緩和)、その共有シークレットは、それを所有する認証済みシステムユーザーのみがアクセスできます(最初の否認防止の問題を緩和)。最後に、外部アプリケーションは暗号学的に署名されます(2番目の否認防止の問題を緩和)。これらの対策を組み合わせることで、この脆弱性は効果的に緩和されます。
CloudCTI Recognition Configuration Tool GUIアプリケーション(C:\Program Files (x86)\CloudCTI Recognition Configuration Tool\CloudCTI Recognition Configuration Tool.exe)がインストールされる際、Process Explorerで調査されます。これにより、コンパニオンサービス(Recognition Update Client Service)がインストールされ、NT AUTHORITY\SYSTEM権限で実行されていることが明らかになります:
サービス実行可能ファイル(C:\Program Files (x86)\CloudCTI Recognition Configuration Tool\RUCS\RecognitionUpdateClientServiceService.exe)を調査すると、.NETプログラミング言語で開発されていることが明らかになります。これは dnSpy を使用して逆コンパイルでき、その内部ロジックの洞察を得ることができます。詳細は以下で説明します。
RUCS2017Service(サービス実行可能ファイル内の内部 .NET 名前空間)は、RUCS2017 名前空間(C:\Program Files (x86)\CloudCTI Recognition Configuration Tool\RUCS\RUCS2017.dll)の薄いラッパーであることがわかります。これは、RUCS2017.dll:RUCS2017.TRUCS2017:902 に RUCS20151029 という名前の名前付きパイプサーバーを定義します:
その名前付きパイプサーバーは RUCS2017.dll:RUCS2017.TRUCS2017:833 で起動されます:
次の Powershell ワンライナーを使用して、このパイプが実際にシステム上でアクティブであることを確認します:``` PS C:\Users\hacker> [System.IO.Directory]::GetFiles("\.\pipe\") |Select-String -Pattern "RUCS20151029"
\.\pipe\RUCS20151029
[AccessChk](https://docs.microsoft.com/en-us/sysinternals/downloads/accesschk) を使用してパイプのアクセス権を調べます。これにより、パイプが任意のシステムユーザー (*Everyone*) によって読み取り (*R*) および書き込み (*W*) 可能であることが判明します:```
PS C:\Users\hacker> .\accesschk.exe \pipe\RUCS20151029
Accesschk v6.12 - Reports effective permissions for securable objects
Copyright (C) 2006-2017 Mark Russinovich
Sysinternals - www.sysinternals.com
\\.\Pipe\RUCS20151029
RW Everyone
RW BUILTIN\Administrators
GUI で アプリケーションの追加 機能を使用すると(図 01 を参照)、名前付きパイプ上で次の暗号化されていないトラフィックが IO Ninja を使用して観測されます:
これには次の JSON データが含まれています:```JSON { "Command":"WizardGetData", "Params": { "ReturnSize":50, "DatasourceType":"exquise exporter", "DatasourceSettings": { "ExquiseFolder":"C:\Users\hacker\Desktop"} } ,"Id":"76037453" }
パイプ上のメッセージ処理は[イベント](https://docs.microsoft.com/en-us/dotnet/standard/events/)ベースであり、サービスのコンストラクタ内(*RUCS2017.dll:RUCS2017.TRUCS2017:803*)でサブスクライブされます。

**<div style="text-align: right">図 06</div>**
この関数では、JSON は最初に *RUCS2017.dll:RUCS2017.TRUCS2017:267* で逆シリアル化されます。

**<div style="text-align: right">図 07</div>**
*WizardGetData* JSON メッセージ構造を処理する具体的なロジックは、*TFerbCommandType.WizardGetData* 列挙ケース内の *RUCS2017.dll:RUCS2017.TRUCS2017:315* にあります。

**<div style="text-align: right">図 08</div>**
次に、タスクマネージャは解析されたメッセージ構造を渡して、*RUCS2017.dll:RUCS2017.TRUCS2017.TTaskManager:614* で新しいスレッドを開始します。

**<div style="text-align: right">図 09</div>**
*DatasourceType*(特定の CRM パッケージ用)は、*RUCS2017.dll:RUCS2017.TRUCS2017.TTaskManager:177* で動的に読み込まれます。

**<div style="text-align: right">図 10</div>**