この投稿は、ホワイト ペーパーとしてダウンロード可能です。
はじめに
あまりにも多くのセキュリティ プロフェッショナルは、デバイスをネットワークやシステムに接続する際のリスクとしてソフトウェアの脆弱性だけに着目しています。
デバイスや Internet of Things を接続する際の潜在的なリスクは、ソフトウェアやファームウェア内に潜む脆弱性だけでなく、ハードウェアの物理的な脆弱性も含めて考慮する必要があります。
攻撃者はハードウェアを改ざんすることでシステムを物理的に変更し、悪意のある機能を導入することができます。たとえば、ソフトウェアに起因する脆弱性に頼らずデータを盗み出せる機能などです。
今回の記事では、一般的な KVM スイッチが改ざんされ、Arduino ベースのキー ロガーが密かに挿入される可能性について説明します。この作業に必要なのは、電子工学やプログラミングに関する最低限の知識と、市販のツールやコンポーネントのみです。
KVM スイッチは運用環境でよく使用されているハードウェア デバイスです。ユーザがスイッチを切り替えることで、1 組のキーボード、モニタとマウスから複数のコンポーネントを制御することができます。
これらのスイッチは、以下のようなカテゴリに分類されます。
- エントリレベルの家庭用および SoHo 用の KVM スイッチ:物理的なボタンで操作するため、ハッキングされる余地はわずかです。
- 「ホットキー対応」KVM スイッチ:キーを組み合わせて押すことで、接続先のコンピュータを切り替えます。押されたホットキーを識別するためのマイクロコントローラが搭載されているため、キー ロガーとして悪用される可能性があります。
- エンタープライズ向けの KVM スイッチ:より緊密にシステムと統合します。これらのスイッチの多くは非常に複雑で、小規模なオペレーティング システムをリアルタイムで実行するため、ハッキングの対象となる可能性があります。
ここでは、2 番目のカテゴリである KVM スイッチについて分析します。このカテゴリを選択した理由は、あるクライアントからの依頼がきっかけでした。このクライアントは KVM スイッチに RJ45 ポートが存在することに気付き、デバイスのセキュリティ評価を Talos に依頼しました。
Belkin E Series OmniView 2 ポート KVM スイッチは家庭/SoHo 向けで、ホットキーによる切り替え機能を備えています。このデバイスを選んだ理由は、このカテゴリを代表する製品だからです。この製品の分析結果は他社製の類似デバイスにも適用できると考えられます。低価格のユニット(10 ポンド未満)が eBay に出品されています。
Belkin E Series OmniView 2 ポート KVM スイッチ
筐体を開ける
筐体の中には以下のコンポーネントが含まれています。
- マイクロコントローラ PIC16C57C
Microchip Technology 製の OTP PIC マイクロコントローラです。下記の画像では PCB の右後方、円柱型の黒いブザーの隣にある大きなチップです。画像から分かるとおり、マイクロコントローラは DIP パッケージに格納されており、ソケットに取り付けられています。そのため、マイクロコントローラは非常に簡単に取り外してリバース エンジニアリングできます。
- 5 X 74HC4053D
NXP 製のトリプル 2:1 アナログ マルチプレクサです。トリプル 2:1 マルチプレクサは、1 つの入力を 2 つの出力先のいずれか一方から出力します。これら 5 個のチップにより、PS/2 キーボードとマウスの信号を 4 つの出力ポートの間で切り替えるコア ロジックが構築されていると考えられます。
Belkin E Series OmniView 2 ポート KVM スイッチの内部
PIC16C57C マイクロコントローラ
よく使用されている Microchip Technology 製のマイクロコントローラ ファミリです。これらのマイクロコントローラはホビー用途でも人気があるため、多数の資料が出回っています。PIC16C57C のデータシートは、次のマイクロコントローラ ファミリ向け資料に含まれています。
この中には、プログラミングや検証プロトコルに関する資料も含まれており、リバース エンジニアリングに役立ちます。
ファームウェアについての分析
プログラミングおよび検証プロトコル
PIC16C57C のプログラミングおよび検証の仕様には、このマイクロコントローラで「クイック検証」を行う方法の概要が記載されています。この手順は次のとおりです。
- 電圧を加える(5V Vdd、接地 Vss)。
- T0CKI を High に固定する。
- OSC1 を Low に固定する。
- Vpp をプログラミング電圧まで引き上げる(13 V)。
- (これにより PIC がプログラミング モードに切り替わり、プログラム カウンタがリセットされます)
- 現在のプログラム カウンタの値は、RA0-RA3 ピンおよび RB0-RB7 ピンから読み取り可能(PIC16C57C では 12 ビット ワードを使用)。
- OSC1 を High にセットする。これでプログラム カウンタが増加します。
- OSC1 を Low にセットし、ステップ 5 を繰り返す。
- すべてのロケーションを読み取るまで繰り返す。
この手順で最初に読み取られるロケーションは、疑似アドレス 0xFFF を持つ特殊なコンフィギュレーション レジスタです。OSC1 で 1 度クロックを発生させる(ステップ 6 および 7)と、次に読み取るロケーションはメモリ ロケーション 0x000 になり、その次は 0x001 ・・・ と順次増加します。
検証機能の作成
商用の PIC プログラムを使えば、この手順に従って PIC の内容を読み取ることができます。ただしこのプロトコルは比較的分かりやすいため、Arduino のような小型のマイクロコントローラ開発基板をベースに単一用途のシンプルな「PIC16C57C 検証機能」を作成することもできます(Raspberry Pi など、簡単に利用できる汎用 I/O ピンを十分に備えたシステムであればどれでも代用できます)。13 V のプログラミング電圧は外部から加える必要があります。Arduino や Raspberry Pi などの開発システムでは一般に、5 V 以下の低電圧しか利用できません。
下の画像は ZIF ソケットに接続された Arduino Uno 基板です。KVM スイッチから取り外した PIC16C57C を据え付けています。13 V のプログラミング電圧を供給する電源もあります。Arduino Uno の I/O の制約によって、PIC からは 4 ビットしか読み取ることができません。ただし、装置を再設定して他のビットも読み取り範囲に含めることで、PIC16C57C の内容全体を何回かのパスで読み取ることができます。Arduino Mega など、12 ビットを同時に読み取れる I/O を備えた開発基板もあります。
Arduino を使用した PIC16C57C の検証
コードの保護
PIC16C57C から読み取る最初のワードはコンフィギュレーション レジスタです。このワードには、ウォッチドッグおよびオシレータの設定データだけではなく、「コードの保護」ビットも含まれます。「コードの保護」ビットがゼロの場合、コードの保護は有効化されています。その場合、PIC16C57C メモリの内容を読み取ることはできません(検証操作は成功しますが、返される値は、関連付けられた PIC16C57C メモリ ロケーションの有効な値ではありません)。
Belkin KVM スイッチから取り外した PIC16C57C のコンフィギュレーション レジスタを調べたところ、コードの保護ビットが有効化されていました。つまり、PIC16C57C のファームウェアを読み取ることはできないということです。
ロジックの分析
理論的根拠
ここまでは、ファームウェアの分析手順を説明しました。今回取り上げたファームウェアは、PIC16C57 から読み取れませんでした。つまり、KVM スイッチをキーロガーとして悪用するには、以下に挙げる 2 つの方法のいずれかを採用する必要があります。
- PIC16C57C マイクロコントローラで実装されたロジックを分析し、同等の PIC デバイスでこのファームウェアを最初から再作成する。
- PIC16C57C マイクロコントローラで実装されたロジックを十分に分析する。この結果を基に、別のマイクロコントローラをデバイス ピンの一部にピギーバックし、タイピング データをモニタするためのキーロガーをそのマイクロコントローラに実装する。
ピン割り当ての判断
概要
PIC16C57C には、20 個の汎用 I/O ピンがあります。各ピンの機能は、マルチメータ、オシロスコープ、ロジック アナライザなどを使用して分析できます。KVM スイッチ内部における各ピンの機能を把握するには、さまざまなシナリオで KVM スイッチを使用しながら分析する必要があります。ピンにおける電圧の遷移は、低速の場合(LED のオン/オフなど)もあれば、高速の場合(キーボードやマウスのインターフェイスのクロック/データ信号線に対応)もあります。高速な遷移はオシロスコープやロジック アナライザでしか検出できない場合があります。
各ピンの役割は、以下のような KVM スイッチ機能を切り替えながら調べます。
- 出力を切り替える。
- 各出力がアクティブな状態でキーボードから入力する。
- 各出力がアクティブな状態でマウスを動かす。
- 出力ポートのいずれかにエンド システムを抜き差しする。
下記の画像は、キーボードからの入力時にピン機能を調べているオシロスコープの画像です。
オシロスコープを使用したピン機能の調査
マルチメータの「抵抗」モードを使用すれば、PCB のレイアウトをさらに詳細に分析し、どのピンが PCB の他のコンポーネントに直接接続されているかを判断することができます。Belkin KVM スイッチの PIC16C57C はソケットに取り付けられているため、この作業は簡単に行えます。ソケットから PIC を取り外すことで、ピンと他のコンポーネント間の抵抗をより正確に測定できるからです。
PIC16C57C の一部のピンは機能が固定(上記のピン割り当て図を参照)されていますが、ここで取り上げるのは 6 ~ 25 の汎用 I/O ピンです。オシロスコープおよびマルチメータを使用した調査から判明した内容は以下のとおりです。
ピン 6 ~ 14
- ピン 6 – RA0:通常は High ですが、プッシュボタン スイッチが押されている間は Low になります。
- おそらく、プッシュボタン スイッチで出力を変更するための入力ピンです。
- ピン 7 – RA1:KVM ポート 1 出力が選択された場合は Low になり、KVM ポート 2 出力が選択された場合は High になります。
- PCB 上のトレースを検査すると、これは 74HC4053D マルチプレクサ上の入力選択ピンの機能とも一致します。
- マルチメータを抵抗モードにしてピン 7 を調べると、IC U7、U8、U9、U10 が備えるマルチプレクス セレクタ入力 S1、S2、S3 に接続されていることが判明します(74HC4053D マルチプレクサ)。
- つまりピン 7 は、出力先をポート 1 とポート 2 で切り替える出力ピンとして機能します。
- ピン 8 – RA2:ピン 7 と同様に、出力先にポート 1 を選択すると Low になり、ポート 2 を選択すると High になります。
- マルチメータを抵抗モードにしてピン 8 を調べると、IC U2 上のマルチプレクス セレクタ入力 S1、S2、および S3 に接続されていることが分かります。また、IC U3 の OE1 に接続されていることも分かります(マルチプレクサと同様の機能)。
- つまりピン 8 は、出力先をポート 1 とポート 2 で切り替える別の出力ピンとして機能します。
- ピン 7 とピン 8 の機能が似ている理由は明確には分かっていません。1 つの可能性は、ピン 7 は PS/2(マウス、キーボード)の切り替えを制御しており、ピン 8 はビデオの切り替えを制御しているということです。これはさらに調査する必要があります。
- ピン 9 – RA3:通常は High ですが、KVM スイッチのポートを切り替える際にアクティビティが確認されます。
- 切り替え時に ピン 9 のアクティビティを詳細に観察すると、オシロスコープ画面では約 3 サイクル/cm の波形が表示されます(横軸が 1 ms/cm の場合。この場合は 3 kHz の波形が出力されます)。
- このため、ピン 9 はブザーを直接動作させる機能があると考えられます。特定の状況下(出力ポートの切り替え時など)には、KVM スイッチから高音のビープ音(約 3 kHz)が鳴ります。
- ピン 10 – RB0:KVM のポート 1 にデバイスを接続すると High になります。
- ポート 1 に接続されたデバイスに対して「出力対応」になっていると思われます。
- ポートの切り替え時に、このピンは相当期間(~ 1 秒)Low になった後、High に戻ります。
- ピンが Low になっている間、ポート 1 では出力は確認されませんが、ピン 20 ~ 23(マウス/キーボード)ではアクティビティが発生しています。
- 注目すべきなのは、選択されているポートを示す LED も、この ~ 1 秒の間は変化しないということです。
- ピン 11 – RB1:KVM のポート 2 にデバイスを接続すると High になります。
- ポート 2 に接続されたデバイスに対して「出力対応」になっていると思われます。
- ポートの切り替え時に、このピンは相当期間(~ 1 秒)Low になった後、High に戻ります。
- ピンが Low になっている間、ポート 2 では出力は確認されませんが、ピン 20 ~ 23(マウス/キーボード)ではアクティビティが発生しています。
- 注目すべきなのは、選択されているポートを示す LED も、この ~ 1 秒の間は変化しないということです。
- 12 – RB2 – HIGH:アクティビティなし(PCB での接続は確認されません)
- 13 – RB3 – LOW:アクティビティなし(PCB での接続は確認されません)
- 14 – RB4 – HIGH:アクティビティなし。
- PCB の配線を目で追うと、U9 のピン 14 にたどり着きます。これは抵抗モードのマルチメータで確認済みです。
- ピン 14 は 74HC4053 の「入力 1」、つまりマルチプレクサ経由で KVM のポート 1 とポート 2 の間でピンを切り替える役割があります。
- このピンは入力用か出力用のどちらかです。KVM スイッチは、KVM 出力ポートの PS/2 コネクタに信号を送信する場合もあれば、受信する場合もあります。ただし、どのシナリオでもピン 14 のアクティビティは確認できませんでした。
ピン 15 ~ 25
- ピン 15 – RB5 – HIGH:アクティビティなし(PCB での接続は確認されません)
- ピン 16 – RB6 – HIGH:アクティビティなし(PCB での接続は確認されません)
- ピン 17 – RB7 – HIGH:アクティビティなし(PCB での接続は確認されません)
- ピン 18 – RC0 – LOW:アクティビティなし(PCB での接続は確認されません)
- ピン 19 – RC1 – HIGH:アクティビティなし(PCB での接続は確認されません)
- ピン 20 – RC2:PS/2 マウス – クロック
- マウスを動かすと、オシロスコープには一定間隔のパルスが表示されます。
- パルスが一定間隔であるため、マウスの PS/2 クロックだと分かります。
- マウスが動いていない KVM ポートの切り替え時にもアクティビティが確認されています。ピン 10 およびピン 11 の用途に関する後述のコメントを参照してください。
- 21 – RC3:PS/2 マウス – データ
- マウスを動かすと、オシロスコープには不定間隔のパルスが表示されます。
- パルスが一定間隔でないため、これはマウスの PS/2 データだと分かります。
- マウスが動いていない KVM ポートの切り替え時にもアクティビティが確認されています。ピン 10 およびピン 11 の用途に関する後述のコメントを参照してください。
- 22 – RC4:PS/2 キーボード – クロック
- キーを押したり、離したりすると、オシロスコープには一定間隔のパルスが表示されます。
- パルスが一定間隔であるため、これはキーボードの PS/2 クロックだと分かります。
- 23 – RC5:PS/2 キーボード – データ
- キーを押したり、離したりすると、オシロスコープには不定間隔のパルスが表示されます。
- パルスが一定間隔でないため、これはキーボードの PS/2 データだと分かります。
- 24 – RC6:LED1
- このピンは、KVM ポート 1 の LED の状態に直結しています。したがって、これは LED 用の出力ドライバだと分かります。
- 25 – RC7:LED2
- このピンは、KVM ポート 2 の LED の状態に直結しています。したがって、これは LED 用の出力ドライバだと分かります。
ピン 10 ~ 11 の用途:出力の分離
前述したように、切り替え時にピン 10 および 11 は Low になります。また、PS/2 クロック/データ ピン(20 ~ 23)でも切り替え時にアクティビティが観察されています。この理由は、切り替えプロセスの一環として KVM スイッチが PS/2 の出力を一時的に無効化し、リセット信号をマウスおよびキーボードに送信しているためだと考えられます。PS/2 プロトコルは双方向のため、ホストがデバイス上の機能を制御することもできます。たとえば、キーボードにインジケータを設定して、CapsLock や NumLock の状態を表示するといったことが可能です。KVM スイッチは各デバイス(マウスおよびキーボード)上のこうした機能をホスト/ポートごとに常に追跡し、ポートを切り替える際にはホストごとに前回と同じ状態に設定しなおします。切り替え時にこれを行うには、ピン 10 または 11 を Low にして該当出力ポートへの出力を無効化した後、再設定に必要な信号を PS/2 バスで接続されたマウスやキーボードに送信します。ピン 10 または 11 を Low にする理由は、該当出力ポートに接続されたホストに対してマウスまたはキーボードの入力を遮断するためです。
さらに、KVM スイッチはホットキーでの切り替えをサポートしています。これは「Scroll Lock」キーを 2 回押すことで実行できます。この時点でユニットはビープ音を発し(ユニットが「ホットキー」状態になったことを示す)、さらに別のキーが押されるのを約 1 秒間待機します。待機中に押されたキーは KVM スイッチによって解釈され、接続されたコンピュータには転送されません。「ホットキー」状態の間、PS/2 出力ポートは無効化されます。これはピン 10 または 11 を Low にすることで実現されます。
分析が不完全な部分
ここまでの分析により、KVM スイッチの大部分の機能が明らかになりました。しかし、まだ解明していない部分も存在します。各種の KVM シナリオを実行しても、一部のピン(12 ~ 19)ではアクティビティが確認されませんでした。これらのピンがすべて High(通常は「デフォルト」または「非アクティブ」状態を意味する)であれば、未使用であると推定されます。ただしピンの一部は Low であるため、何らかの機能があると考えられます。PCB を見る限り接続されているのはピン 14 のみですが、その目的は判明していません。
分析が不完全であることから、実効性のあるファームウェアを自分で最初から作成することは困難です。キーロガーを実装するより現実的な方法(上記の「理論的根拠」セクションを参照)は、別のマイクロコントローラをピギーバックすることです。
PS/2 インターフェイス
KVM スイッチの PS/2 インターフェイスでキーボード データにアクセスするには、PS/2 プロトコルを理解する必要があります。PS/2 プロトコルについての説明は、次のリンクを参照してください。
PS/2 インターフェイスは、ホストまたはデバイスのいずれかによって動作します。また、このインターフェイスの電気的な特性によって、ホストとデバイスの両方が接続されている場合であっても、PS/2 バスにデータを投入することが可能です。KVM スイッチにセカンダリ マイクロコントローラをピギーバックしようとする場合は、この特性を利用できます。
キーロガーの実装
これまでの分析を考慮すると、PIC16C57C にセカンダリ マイクロコントローラをピギーバックしてキーロガーを実装することができそうです。これは、PIC16C57C 自体のピン信号のみを使用して行うのが理想です。これにより、別の PIC ファームウェアに同じ機能を実装することができます。
抽出は、KVM スイッチにある既存のインターフェイスから行われます。つまりデータを抽出するために必要なことは、KVM スイッチに本来の方法でアクセスすることだけです。このための 1 つの選択肢は、セカンダリ マイクロコントローラに別のホットキー シーケンスを追加することです。このホットキー シーケンスがトリガーされると、KVM スイッチに接続されているシステムを問わず、別のマイクロコントローラがキーボードの入力データを記録します。これによって攻撃者は(たとえば)ターゲット システムでテキスト エディタを開き、ホットキー シーケンスを入力することで、キー入力データをテキスト ファイルに記録できるようになります。
電気的な制約
PIC16C57C にピギーバックするには大きな制約があります。PIC16C57C で出力用に設定されているピンは、マイクロコントローラをピギーバックしても別の状態に遷移させることができません。PIC16C57C のデータシート(セクション 7.6.1)には、以下のように記載されています。
「アクティブに High または Low を出力するピンは、レベル(「wired-or」、「wired-and」)を変更するために外部デバイスから同時に動作させることはできません。これを行うと、高い出力電流によりチップが損傷する可能性があります」
つまり、キーロガーを実装して入力データを抽出するには、PIC16C57C で入力用に設定されているピンしか使用できません。
PS/2 バスの共有
キーロガーからデータを抽出するための選択肢の 1 つは、一連のキーボード入力データを接続先のコンピュータに送信することです。そのためには、KVM スイッチが PS/2 バス上の周辺機器(キーボード)として機能し、「偽の」キーボードとしてホスト コンピュータと通信する必要があります。ただし、PS/2 バスには本物のキーボードも接続されています。つまり、この方法で PS/2 バスを経由してデータを抽出できるか否かが問題となります。
PS/2 バスは、ホスト コンピュータと周辺機器の間をポイントツーポイントで接続するために設計されています。シンプルな 2 線式プロトコル(クロックとデータ)により双方向通信を実現しています。この仕組みは、クロック ピンとデータ ピンの両方を対象としたオープンコレクタ インターフェイス(「電気インターフェイス」のセクションを参照)で実現されており、ホスト コンピュータまたは周辺機器のどちらからでもピンの状態を Low にすることができます。
そのため電気的な観点から言えば、2 つ目の周辺機器(KVM スイッチ)から PS/2 インターフェイスのクロック ピンとデータ ピンを操作できます。ホスト コンピュータからは、両方の周辺機器(本物のキーボード、および「偽の」キーボードとして動作する KVM スイッチ)を見分けることはできません。ただし「偽の」キーボードからのアクティビティによって、本物のキーボードに予期しない動作を引き起こす可能性があります。
PS/2 プロトコルでは、通信の大部分は周辺機器とホストとの間で行われます。クロックは常に周辺機器側から生成されます。つまり周辺機器はほぼ常時、クロック信号とデータ信号を生成しています。ホストが周辺機器にデータを送信する必要がある場合(CapsLock の LED 状態を設定する場合など)、ホストはまず「送信要求」信号としてクロック ラインを 100 μ 秒以上 Low に保つことにより、周辺機器にデータを送信することを通知します。ここで懸念されるのは、「偽の」キーボードとして振る舞う KVM スイッチの PS/2 バスにおけるアクティビティを、本物のキーボードがホストからの送信要求として解釈してしまうことです。
PS/2 バスでデータが送信される場合、周辺機器は 10 ~ 16.7 kHz の範囲でクロック信号を生成します。そのため、最も低速なクロック速度(10 kHz)でのクロック サイクルは 100μs になります。「偽の」キーボードはクロックを最大 50 μs の間 Low にすることで、本物のキーボードからの「送信要求」との混同を避けています。これにより PS/2 バスは共有可能になります。
ホットキー シーケンスの検出
記録データからの抽出は、別のホットキー シーケンスによって発生します。この KVM スイッチは、特定のタイムフレーム内に「Scroll Lock」キーが 2 回押されるとトリガーされるホットキー シーケンスを実装しています。これにより PIC16C57C は該当する「出力対応」ピン(PIC16C57C のピン 10 または 11)を約 1 秒間 Low することでキーボードからの入力を遮断し、ホットキー シーケンスの後続のキーを待機します。たとえば、「1」または「2」のキーが押されると、出力がポート 1 と 2 の間で切り替わります。
記録データを抽出するためのホットキー シーケンスを実装するには 2 つの選択肢があります。
- キー シーケンスがトリガーされたことを(「Scroll Lock」が 2 回押さる)を、ピギーバック マイクロコントローラが単独で検出する。
- 「出力対応」ピンが Low になったことを検出し、ホットキー シーケンスがトリガーされたことを示す。
最初のオプション(ホットキー トリガー シーケンスを単独で検出)では、PIC16C57C とピギーバック マイクロコントローラのホットキー トリガー シーケンスの検出方法が完全に一致しないリスクがあります(たとえば、タイミングが異なるなど)。したがって、「出力対応」ピンの状態をベースにする 2 番目の選択肢を採用します。こちらの選択肢の方が、KVM スイッチがホットキー トリガー状態になったことを確実に検出できます。
概念実証用のハードウェア
キーロガーの概念実証を実装するために、Arduino Uno 開発基板を使用しました。この基板には各種の I/O 機能および分かりやすい「C」ベースのプログラミング環境が用意されており、プロトタイピング用の I/O ピンに簡単にアクセスすることができます。
概念実証用のキーロガー ハードウェア
上の画像は、KVM スイッチ PIC16C57C に対して以下のようにピギーバック接続している Arduino Uno 基板を示しています。
- 黒:PIC16C57C のピン 4(アース)。Arduino のアース。
- 青:PIC16C57C のピン 22(PS/2 キーボードのクロック)。Arduino のデジタル I/O のピン 2。
- 緑:PIC16C57C のピン 23(PS/2 キーボードのデータ)。Arduino のデジタル I/O のピン 8。
- 赤:PIC16C57C のピン 11(KVM スイッチのポート 2 に対する「出力対応」信号)。Arduino のデジタル I/O のピン 9。
この概念実証の実装のために使用しているのは、ポート 2 の「出力対応」線のみです。
概念実証用のソフトウェア
制御フロー
Arduino ソフトウェアによるキーロガーの実装には、大きく分けて以下の 3 つの段階があります。
- 「出力対応」が High(出力が有効)の場合に、キーボードの入力データを記録する。
- 「出力対応」が Low(ホットキー トリガー シーケンスによって出力が無効化)の場合に、抽出用ホットキー シーケンスを検出する。
- 抽出用ホットキー シーケンスが検出され、「出力対応」が Low から High に遷移した場合(再度有効化)、キーボードの入力データが抽出される。
抽出用ホットキー シーケンスが検出された場合は、「出力対応」が再度 High になるまで待機する必要があります。待機しない場合、PS/2 バスに投入された PS/2 キーボード入力データがホスト コンピュータによって認識されません。この概念実証で作成した抽出用ホットキー シーケンスは、「Q」を 2 回連続して押すことで起動します(「「Q」はクエリを表しています。2 回連続して押すことで、KVM スイッチの正当なユーザによる偶発的な呼び出しを防ぎます)。
キー ロギング
Arduino 開発基板を使用する利点の 1 つに、豊富なソフトウェア ライブラリを使用できるということがあります。今回は「PS2Keyboard」ライブラリを使用していますが、これは LGPL に基づいて利用できます。このライブラリを利用することで、割り込み駆動型の PS/2 キーボード読み取りライブラリを実装できます。これはスキャン コードを自動的に ASCII へ変換し、Shift キーの状態を踏まえて ASCII のキーボード入力データをアプリケーションに送信します。Arduino のピン 2 は PS/2 クロックに使用されます。これは、このピンが Arduino Uno 基板で割り込みをサポートするためです。
Arduino 基板を KVM PIC16C57C に接続する方式によっては、キー ロギング中の PS/2 キーボード データの読み取り時と、抽出中の PS/2 キーボード データの書き込み時のどちらも Arduino 上の同じピンを使用する必要があります。「PS2Keyboard」ライブラリは PS/2 データの読み取りのみをサポートするため、データを送信するには別のライブラリも必要です。これをサポートするために、「PS2Keyboard」ライブラリに end() メソッドを追加し、「PS2Keyboard」ライブラリがデータの読み取りに使用した割り込みをリリースする必要があります。これを追加しない場合、「PS2Keyboard」ライブラリは抽出中もデータの読み取りを続けることになります。
キー ロギングの間、ライブラリから受信したキーボード入力データはリング バッファに保管され、抽出の準備が行われます。抽出を実行する際は、キーボード入力データが PS/2 スキャン コードではなく ASCII であることに注意が必要です。
抽出
記録したキー データを PS/2 キーボード インターフェイス経由で抽出するには、PS/2 キーボード データを送信するためのライブラリが必要です。この概念実証には別のライブラリを作成する必要があります。無料で使用できる Arduino ライブラリは多数ありますが、その中から該当するライブラリは確認できませんでした。
PS/2 プロトコルは 10 ~ 16.7 kHz の範囲で実行されるクロックを使用し、以下のような特性を持つシリアル データを送信します。
- 開始ビット 1 ビット(データは Low に固定)
- データ ビット 8 ビット。最初は LSB
- パリティ ビット 1 ビット(奇数パリティ)
- 終了ビット 1 ビット(データは High に固定)
データはクロックの立ち下がりエッジ(High から Low に遷移)でホストによって読み取られます。
このデータ伝送形式は、Arduino の組み込みのデータ伝送プロトコルのいずれにも対応していません。つまり、カスタム ドライバを作成する必要があるということです。PS/2 プロトコルを実装するには、タイマーを使用して、10 ~ 16.7 kHz の範囲でソフトウェア割り込みを 2 回生成する必要があります(クロックの立ち上がりエッジと立ち下がりエッジの両方を生成するため)。Arduino Uno は、ソフトウェア割り込みを生成できる 3 つのハードウェア タイマーをサポートしていますが、今回はタイマー 2 を選択しました(タイマー 1 は標準の Arduino ライブラリの一部で使用されているため、利用できません)。
Arduino 基板のタイマー 2 が実行する 25 kHz の割り込み時に、PS/2 クロックおよびデータ ピンを手動で設定するドライバを作成しました。各割り込みで、クロック ピンは High または Low に順次遷移します。データ ピンは必要に応じて開始ビット、データ ビット、パリティ、および終了ビットを生成するように制御されます。
ホットキー シーケンスによって抽出がトリガーされると、リング バッファに記録されたデータが抽出されます。これは ASCII データであるため、PS/2 スキャン コードとして直接送信することはできません。代わりに、このデータは、記録されたキープレスの ASCII の 16 進表現として抽出されます。このデータは、抽出後も元のキーボード入力データへ簡単に復元できます。復元を簡単にするため、データは以下のように、Linux などのシステムで利用可能な「xxd」ユーティリティ プログラムと互換性のある形式で抽出されました。
7373682074617267657473797374656d 0a726f6f740a50617373773072643132 330a
16 進数文字の各出力に対して、「入力キー」のキーボード スキャン コード(0 ~ 9 および A ~ F の 16 進数文字に対応する)が PS/2 ドライバによって生成されます。その直後には、同じキーに対する「キー リリース」のスキャン コードが続きます。これは、リング バッファ全体が出力されるまで継続されます。
この抽出プロセスによって、接続先のコンピュータでは、記録されたデータの 16 進表現に対応する一連のキープレスを認識できるようになります。攻撃者は、ターゲット システムでテキスト エディタを開いて抽出プロセスをトリガーし、抽出したデータがテキスト エディタに入力されるのを見ているだけでデータを取得できます。
ソース コード
この概念実証用キーロガーのソース コードは、以下で確認できます。
- https://labs.portcullis.co.uk/whitepapers/hacking-the-belkin-e-series-omniview-2-port-kvm-switch/ [英語]
まとめ
組織にとって、ハードウェアの改ざんは真の脅威です。比較的シンプルなハードウェアであっても、相応の知識があれば、密かにデータを収集してデータを抽出るために悪用することができます。企業はこうした脅威の最新情報を入手し、機密エリアに導入されている各デバイスに対するセキュリティ評価の実施を検討する必要があります。
「通常」のネットワーク トラフィックを把握し、予期しないネットワーク トラフィックや異常なネットワーク トラフィック(新しいデバイスが突然外部に接続されるなど)に対して警戒を続けることで、ネットワーク経由でのデータ漏えいを検出し、ブロックすることができます。ただしビジネス クリティカルの場面では、重要なシステムへの接続を許可されているハードウェアを識別して追跡する必要があります。この中には、見逃されがちな周辺機器やシンプルなデバイスも含まれます。デバイスが物理的に改ざんされる危険性があるため、環境によっては、装置の物理的な検査により不正な改変を検出する必要もあります。
本稿は 2017年4月6日に Talos Group のブログに投稿された「Hacking the Belkin E Series OmniView 2-Port KVM Switch」の抄訳です。