
Linux、Windows、macOSにおけるファイル通知サイドチャネル攻撃の研究資料。inotify/FSEventsの情報漏洩、キーストロークタイミング、ウェブサイトフィンガープリンティングを実証。
このリポジトリには、論文「File Notification Attacks: Templating and Exploiting Side-Channel Leakage from the File-Notification Systems on Linux, Windows, and macOS」(CCS '26 採択) の成果物 (まだ査読中!) が含まれています。
デモを掲載したウェブサイトはこちら: https://inoti.fyi/
論文はこちら: https://snee.la/pdf/pubs/file-notification-attacks.pdf または http://inoti.fyi/pubs/file-notification-attacks.pdf
CCS'26 の成果物評価 (まだ進行中!) の一環として、パッチを適用済みのカーネルを備えた Debian 13 + KDE Plasma 6 の VM を提供しました。この VM は論文の評価結果を生成するために使用されたものではなく、その正確な規模を再現することを意図したものでもありません。このリポジトリは、成果物評価者からのレビューやフィードバックを取り入れて更新される可能性があります。成果物評価が完了した時点で、VM を公開する予定です。
私たちは Claude (Opus 4.8) を使用して、コードを適度に文書化され高性能な成果物にラップしました (例えば、Windows のものは少し動作が重かったです)。ただし、それが生成したコード、スクリプト、makefile は以下に基づいています
以下の Linux コードをテストするための手順は、VM 内でコマンドを実行する場合に固有のものです。代わりに Linux/ 内のコードを参照してください。
VM は純粋に利便性のために存在しており、各攻撃をマウントするたびにゼロからの環境セットアップやカーネルのダウングレードを必要としません。VM で実証される基盤となるメカニズムは論文で説明されているものと同一ですが、論文で報告された数値を生成するために VM を使用したわけではないことに注意してください。絶対的なタイミングは、仮想化環境と基盤となるハードウェアにより異なる場合があります。
知見は Debian 13 VM (linux-vm/) 内で再現されます。これは公式の live Debian ISO からインストールされ、KDE Plasma 6 (Wayland) がインストールされ、fsnotify 修正 より前のカーネルを備えています。inotify-tools、Qt6 dev ヘッダー、pkexec がインストールされています。それ以外はアップグレードされておらず、インストール後にカーネルは一切触れられていません。絶対に apt upgrade を実行したり、カーネルをアップグレードしようとしないでください。この VM イメージは意図的に古く、最新ではなく、最新のセキュリティパッチが適用されていません。この VM イメージは迅速な検証とテストのみを目的としています!
VM 内にあるコード、攻撃、デモンストレーションは Linux/ にミラーされています。
注: 各コマンドブロックの先頭に、どのユーザーとしてコマンドを実行するかを記載しています。[host] は VM を実行するホストマシン、[user] は VM 内の攻撃の被害者、[spyuser] はセットアップが必要で、ほとんどの Linux 攻撃で攻撃者となるユーザーです。
ディスクイメージは linux-vm-upload.qcow2 として提供され、zstd で圧縮されています。run.sh (このファイル名を想定しています) を実行する前に linux-vm.qcow2 に名前を変更してください:
# Run As: [host]
cd linux-vm/
mv linux-vm-upload.qcow2 linux-vm.qcow2
./run.sh
zstd 圧縮された qcow2 を読み取るには、qemu-img/qemu-system-x86_64 バージョン 5.2 以降 (2020 年以降) が必要です。qemu-img --version で確認してください。古い QEMU を使っていてイメージを開けない場合は、まずフラットな qcow2 に展開してください:
qemu-img convert -O qcow2 linux-vm-upload.qcow2 linux-vm.qcow2
4 コア、4GB RAM、GUI ディスプレイ。ログイン情報は以下の通りです:
root、パスワード password、user、パスワード password、spyuser、パスワード password (spyuser としてログインしないでください!)提供された VM はすでに脆弱な、パッチ適用済みのカーネル (6.12.43+deb13-amd64) を実行しているため、使用するためにダウングレードは不要です。このイメージ (GUI 付き) を実行するには QEMU が必要です。成果物は VM 内の /home/user/Linux-File-Notification-Attacks にあります。
1 つのコマンドで VM 内を新たにセットアップします: (i) 非特権の spyuser アカウント (非 sudo)、(ii) 成果物ディレクトリの独自のコピー (そうしないと、別の非特権アカウントは user のホームディレクトリに侵入できません)、(iii) 両方のコピーで全てのスクリプトを実行可能にします。
# In the VM, Run As: [user]
sudo bash ~/Linux-File-Notification-Attacks/setup_attacks.sh
以下のすべての攻撃は spyuser (su - spyuser、パスワード password) として実行されますが、auth-ui-redress は例外で、user として実行されます (以下で説明します)。
親ディレクトリが読み取り可能であれば、直接読み取ることができないファイルに対してもファイル操作通知が配信されることを証明します。
# Run As: [spyuser]
# To switch to spyuser, in a new terminal type `su - spyuser`. The password
# is `password`.
cd ~/Linux-File-Notification-Attacks/unreadable-file-bypass
./watch-syslog.sh
実行したままにして、別のターミナルから user としてログ行を生成します:
# Run As: [user]
logger "hello"
この Debian 13 イメージには rsyslog がないため、論文に示されているような /var/log/syslog ファイルはありません。スクリプトは代わりに /var/log/journal/<machine-id>/ の監視にフォールバックします。監視対象の .journal ファイルは root (ユーザー) と systemd-journal (グループ) によって所有されており、どちらも spyuser ではないため、これは同じ考え方です。
inotify の通知遅延を測定します。
# Run As: [user], ensure numpy is installed (or pip3)
sudo apt install python3-numpy
# Run As: [spyuser]
cd ~/Linux-File-Notification-Attacks/temporal-resolution
./run.sh
watcher はテストファイルに inotify ウォッチを開き、受け取ったすべての IN_ACCESS にタイムスタンプを付けます。accessor は同じファイルを 1000 回読み取り、読み取り間にランダムな 5-10ms の遅延を挟み、各読み取り自体にタイムスタンプを付けます。stats.py は 2 つのタイムスタンプ記録を差分し、読み取りが発生してから通知が到着するまでの平均/標準偏差/最小遅延、つまり inotify の時間分解能を出力します。
論文の完全な攻撃ではなく、攻撃の基盤となるフィルタリングの概念実証プリミティブのみです: システム上のどこかで押されたすべてのキーについて、/dev/input を直接読むことなく、タイムスタンプ付きの通知を 1 つ出力します。
# Run As: [spyuser]
cd ~/Linux-File-Notification-Attacks/inter-keystroke-timing
make
./find-keyboard.sh
任意のウィンドウ (おそらく user としての新しいターミナル) で入力してください。各キーストロークは 1 行の KEYPRESS を出力します。抑制ウィンドウ (このデモンストレーションでヒューリスティックに選択したのは 130ms) は、1 回の物理的なキー押下によって生成される複数の IN_ACCESS イベントを統合します。実際には、このウィンドウはハードウェア (例えば、メカニカルキーボード、タイピングスタイル) によって異なることに気付きました。
自動検出が間違ったデバイス (または何も) を選択した場合は、/proc/bus/input/devices を確認し、./build/keystroke-notify /dev/input event4 で直接実行してください。
(pkexec)[https://polkit.pages.freedesktop.org/polkit/] が実行されたことを検出し、さらにその上に偽のウィンドウを描画できることを実証します。セクション 4.4.3 で示したように、この「認証 UI リドレス攻撃」は Wayland を使用する KDE Plasma 5 および 6 で可能です。この攻撃は同一ユーザー攻撃者の脅威モデルで実行します: Wayland ソケットはログインセッションにスコープされており、別の非特権アカウントはそれに描画できません。
標準の KDE インストールでは pkexec はデスクトップによって導入されますが、この live ISO はより軽量なイメージであるため、インストールされていません。したがって、VM イメージを小さく保つ (ように努めながら) 手動でインストールしました。
# Run As: [user]
cd ~/Linux-File-Notification-Attacks/auth-ui-redress
make
./inotify-watcher-with-gui
ターミナルで実行したままにしてください。別のターミナル (ディレクトリは問いません) から、実際の pkexec プロンプトをトリガーします (例: pkexec ls)。watcher は /usr/bin/pkexec へのアクセスを検出し、偽の「Authentication Required」ダイアログ (window-launcher) を本物の上に画面に描画します。偽のダイアログに入力して Authenticate を押すと、入力されたテキストが watcher のターミナルに出力され、その後閉じます。偽のウィンドウは比較しやすいように本物のウィンドウとは意図的に異なっていることに注意してください。
ページの読み込み中にフォントディレクトリを監視すると、どのフォントファイルに触れたかが明らかになります。サイトごとに異なるフォントを読み込むため、ページの読み込み中に出力されるパスの集合はすでにフィンガープリントであり、この最小限のバージョンではタイミングや分類器は不要です。
まず、user として Firefox を開き (画面下部のタスクマネージャードックのアイコンからクリック)、ウェブサイトが開いていないことを確認します。次に、spyuser としてターミナルで:
# Run As: [spyuser]
cd ~/Linux-File-Notification-Attacks/website-fingerprinting-fonts
./compare-fonts.sh
これは font-spy をビルドし、Firefox が使用するフォントディレクトリの監視を開始します。compare-fonts スクリプトは 2 つのウェブサイトを訪問するよう促します。
まず、1 つのウェブサイト (おそらく wikipedia.com) を訪問し、読み込まれるまで数秒待ち、新しいタブを開き、古いタブ (ウェブサイトのあるもの) を閉じ、ターミナルで ENTER を押します。
次に、別のウェブサイト (おそらく reddit.com) で同じことを行います: ウェブサイトを訪問し、読み込まれるまで数秒待ち、新しいタブを開き、古いタブを閉じ、ターミナルで ENTER を押します。
スクリプトはウェブサイトごとにアクセスされたフォントの差分を出力するはずです。論文では、時間情報、つまり フォントがアクセスされた時刻も使用したことに注意してください。単純な概念実証では、この情報を無視し、2 つのフォントアクセス集合の差分を単純に出力するだけです。正確なフォントアクセス集合は実行ごとに異なる場合がありますが、ウェブサイトによって常に一意にアクセスされる特定のフォントファイルがあります。
ウェブサイトは時間とともに変化する可能性があるため、フォントファイルのアクセスは異なる場合があることに注意してください。この成果物の起草時点では、Wikipedia は常に /usr/share/fonts/truetype/liberation/LiberationSans-Bold.ttf にアクセスし、Reddit は常に /usr/share/fonts/truetype/vlgothic/VL-Gothic-Regular.ttf にアクセスすることに気付きました。
Scoped Storage モデルが WhatsApp の共有メディアディレクトリに FileObserver (inotify の Java レベルのラッパー) を登録することを依然として許可している Android バージョンを実行する物理デバイスまたはエミュレータ、およびメッセージ送信者として機能する 2 台目のデバイス/アカウント。提供されたソース (Android/source/) をビルドするか、提供された APK (Android/app-release.apk) を直接インストールします。