USBはコンピューターになんでも繋げられる魔法のコネクターです。なんでもということは便利なものだけでなく、もちろん悪意があるももの接続できます。今回はUSBGuardを使って、悪意のあるものを繋ぎにくくすることで、不要なトラウブルを回避できるようにしてみましょう。
BadUSB対策としてのUSBGuard
先に重要なことをお伝えしておきます。
USB
結果的にどんなデバイスでも
このようにUSBはその利便性からPCだけでなく、スマートフォンやあらゆるデバイスに搭載される、まさに名前の通り汎用的なバスとなりました。
ところでUSBにはDevice Classという概念があります。これはそのUSBデバイスがどんな種類のデバイスなのかを示すものです。USBメモリーならMass Storage Classですし、USBキーボードならHID Classになります。ひとつのUSBデバイスが複数のDevice Classを持つことも可能で、ウェブカメラなどの大元はMiscellaneous Device Classですが、内部的にはVideo Device ClassとAudio Device Classの複合となっています。
このDevice ClassはUSBデバイス側がPC
つまりあるUSBデバイスをUSBメモリーのつもりで接続したら、Ubuntu側ではただのUSBキーボードとして認識され、USBデバイスはキーイベントを送ることで、システム上の任意のデータをインターネット上の別のところに転送したり、悪意のあるプログラムをインストールしたり、その他の悪さをできてしまいます[3]。さらに最近のUSBデバイスは、内部にPCから書き換え可能なファームウェアを保持しているものもあり、悪意のあるファームウェアに置き換えられてしまう可能性があるのです。
要するに、最近の映画・
この手の攻撃手法はBadUSBとして話題になっています。
USBGuardの仕組み
USBGuard自体は非常にシンプルな作りであり、やっていることは主に次の2種類です。
- USBデバイスのホワイトリストを管理する
- ホワイトリストに所属しないUSBデバイスが繋がれたら拒否する
ホワイトリストでは
- USBデバイスのベンダーIDおよびプロダクトID
- USBデバイスディスクリプターのハッシュ値
- USBデバイスのデバイス名
- USBデバイスのシリアル番号
- USBデバイスが接続されたポート番号
- USBデバイスのデバイスクラスやサブクラス
- USBデバイスがホットプラグなのか直結なのか
つまりおおよそどんなUSBデバイスもこの組み合わせで指定可能です。USBデバイスが接続されると、カーネルからイベントが届きます。このイベントはueventと呼ばれるもので、たとえばUSBメモリーの自動マウントをはじめとする各種デバイスを認識した時に自動的に行われる処理を担うudevも、このueventを利用しています。ちなみにUSBGuardは以前はudev経由で動いていたようですが、現在ではueventを直接受け取って処理しているようです[5]。
「許可・
- allow:USBデバイスが利用可能な状態
- block:USBデバイスが利用不可な状態。USBGuardのCLIからallowへの変更も可能
- reject:USBデバイスがソフトウェア的に切断された状態。再接続するには物理的に繋ぎ直す必要がある
ちなみに、これらはsysfsでも操作可能です。具体的にはまずlsusb
でBus・
$ lsusb -t -v /: Bus 06.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 10000M ID 1d6b:0003 Linux Foundation 3.0 root hub |__ Port 2: Dev 2, If 0, Class=Video, Driver=uvcvideo, 5000M ID 046d:0893 Logitech, Inc. StreamCam (中略) /: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/16p, 480M ID 1d6b:0002 Linux Foundation 2.0 root hub |__ Port 4: Dev 3, If 1, Class=Human Interface Device, Driver=usbhid, 12M ID 0853:0142 Topre Corporation (中略) |__ Port 9: Dev 4, If 0, Class=Wireless, Driver=btusb, 12M ID 8087:0a2b Intel Corp. Bluetooth wireless interface
上記だと
/sys/
に0を書くとデバイスが利用不可になるbus/ usb/ devices/ 6-2/ authorized /sys/
に1を書くとデバイスが利用可能になるbus/ usb/ devices/ 6-2/ authorized /sys/
に1を書くとソフトウェア的に取り外し状態になるbus/ usb/ devices/ 6-2/ remove (ファイルパスも見えなくなる) /sys/
に1を書くと、Bus 6以下がすべて利用不可になるbus/ usb/ devices/ usb6/ authorized_ default
今回紹介するUSBGuardは、このあたりのファイルの操作を肩代わりしてくれるものだと思っておけば良いでしょう。
USBGuardのインストールと設定
USBGuardはパッケージをインストールするだけで使えるようになります。これはシンプルな操作用プログラム、デーモン、DBusサービスファイルなどの集合体です。もちろんUbuntuサーバーにもインストール可能です。
$ sudo apt install usbguard
インストール直後は
USBGuardの設定ファイルは次のとおりです。
/etc/
:USBGuard本体の設定。設定ファイルのパスやデフォルトの挙動を指定するusbguard/ usbguard-daemon. conf /etc/
:USBGuardを操作できるユーザー・usbguard/ IPCAccessControl. d グループとその権限の設定 /etc/
:USBGuardで設定したルール情報。インストール直後はその時つないでいたUSBデバイスが入っているusbguard/ rules. conf
普通に使う分にはこれらのファイルを直接編集する必要はないでしょう。USBGuardの設定はusbguard
コマンドで行い、このコマンドがrules.
の中身を更新してくれます。またusbguard-daemon.
がImplicitPolicyTarget=block
」
usbguard
コマンドを実行できるのは、plugdevグループに所属するユーザーのみです。これはIPCAccessControl.
以下の設定ファイルで変更可能です。Ubuntuをインストール時に作成したユーザーであれば、最初からplugdevグループに所属しています。
まずは既存のルールの適用状態を確認してみましょう。インストール直後はすべて
$ usbguard list-devices 15: allow id 1d6b:0002 (略) name "xHCI Host Controller" (略) 16: allow id 1d6b:0003 (略) name "xHCI Host Controller" (略) 17: allow id 1d6b:0002 (略) name "xHCI Host Controller" (略) 18: allow id 1d6b:0003 (略) name "xHCI Host Controller" (略) 19: allow id 1d6b:0002 (略) name "xHCI Host Controller" (略) 20: allow id 1d6b:0003 (略) name "xHCI Host Controller" (略) 21: allow id 046d:0ab7 (略) name "Blue Microphones" (略) 22: allow id 0853:0142 (略) name "REALFORCE 91 JP" (略) 23: allow id 8087:0a2b (略) name "" (略) 24: allow id 046d:0893 (略) name "Logitech StreamCam" (略) 25: allow id 046d:c52b (略) name "USB Receiver" (略) 26: allow id 045b:0209 (略) name "" (略) 27: allow id 04b4:5210 (略) name "Billboard Device" (略) 28: allow id 056d:4036 (略) name "EIZO USB HID Monitor" (略)
またルール自体はusbguard list-rules
」
USBGuardによるデバイスの管理
ここで例えば、何か別のUSBデバイスを繋いだ上で、もう一度デバイス一覧を見てみましょう。
$ usbguard list-devices (中略) 30: block id 046d:0a9b (略) name "G431 Gaming Headset" (略)
新規に繋いだデバイスはlsusb
コマンドからなら存在を確認できます。
$ lsusb (中略) Bus 003 Device 005: ID 046d:0a9b Logitech, Inc. G431 Gaming Headset $ cat /sys/bus/usb/devices/3-2/authorized 0
ただしusbguard list-rules
」
次にこのデバイスを許可してみましょう。これはallow-device
コマンドにlist-devices
でblockにされた行の先頭の数字を指定するだけです。ちなみにusbguard list-devices --blocked
」
$ usbguard list-devices --blocked 30: block id 046d:0a9b (略) name "G431 Gaming Headset" (略) $ usbguard allow-device 30 $ usbguard list-devices --blocked => 何も表示されなくなる
許可するとUSBデバイスが使えるようになっているはずです。ちなみに今回は数字で指定しましたが、list-devices
に表示されている各フィールドでも許可は可能です。
Vendor ID/Device IDで許可する $ usbguard allow-device id 046d:0a9b デバイス名で許可する(ダブルクオートの前にバックスラッシュが必要) $ usbguard allow-device name \"G431 Gaming Headset\"
ちなみにDevice IDにしろVendor IDにしろデバイス名にしろ、USBデバイス側が伝えてきた情報が使われます。つまり不正なUSBデバイスは、ルール上にある許可しているデバイスの名前を詐称することも原理的には可能なのです。繰り返しになってしまいますが、必ずしも不正なUSBデバイスをすべて弾ける仕組みでない旨を、理解しておきましょう。
恒久的に許可したい場合は-p
」
$ usbguard allow-device -p 30 $ usbguard list-rules | grep G431 31: allow id 046d:0a9b (略) name "G431 Gaming Headset" (略)
恒久的に許可されたルールは、再起動後も許可された状態が維持されます。同様にusbguard block-device
」usbguard reject-device
」
現在のusbguard
コマンドの-p
」
たとえばappend-rule
を使ってください。
$ usbguard append-rule "allow id 046d:0a9b"
これでルールファイルには、部分的なルールが追加されます。
$ usbguard list-rules | grep 0a9b 33: allow id 046d:0a9b
このようにUSBGuardを使えば、気軽に特定のUSBデバイスのみ許可したシステムを構築できます。意図しないUSBデバイスを接続してしまい、予期しない問題を起こさないよう、カジュアルに防止したい場合に便利でしょう。