
Forschungsartefakte für Datei-Benachrichtigungs-Seitenkanalangriffe auf Linux, Windows und macOS, die inotify/FSEvents-Leckage, Tastenanschlag-Timing und Website-Fingerprinting demonstrieren.
Dieses Repository enthält die (noch in Überprüfung befindlichen!) Artefakte für das Paper "File Notification Attacks: Templating and Exploiting Side-Channel Leakage from the File-Notification Systems on Linux, Windows, and macOS", angenommen auf der CCS '26.
Besuchen Sie die Website mit Demos unter: https://inoti.fyi/
Lesen Sie das Paper unter: https://snee.la/pdf/pubs/file-notification-attacks.pdf oder http://inoti.fyi/pubs/file-notification-attacks.pdf
Als Teil der Artefakt-Evaluierung auf der CCS'26 (noch laufend!) haben wir eine Debian 13 + KDE Plasma 6 VM mit einem vorgepatchten Kernel bereitgestellt. Diese VM wurde nicht verwendet, um die Evaluierungsergebnisse des Papers zu erzeugen, und ist nicht dazu gedacht, deren exakte Größenordnung zu reproduzieren. Dieses Repository kann aktualisiert werden, um Reviews und Feedback unserer Artefakt-Evaluatoren zu berücksichtigen. Wir werden die VM öffentlich zugänglich machen, wenn unsere Artefakt-Evaluierung abgeschlossen ist.
Wir haben Claude (Opus 4.8) eingesetzt, um unseren Code in anständig dokumentierte und leistungsfähige Artefakte zu verpacken (zum Beispiel war das Windows-Artefakt etwas träge). Der Code, die Skripte und Makefiles, die es generiert hat, basierten jedoch auf
Die Anweisungen zum Testen des Linux-Codes unten beziehen sich speziell auf die Ausführung von Befehlen in
der VM. Bitte schauen Sie sich stattdessen den Code in Linux/ an.
Die VM existiert rein aus Bequemlichkeit, damit das Einhängen jedes Angriffs nicht eine Einrichtung der Umgebung von Grund auf oder ein Kernel-Downgrade erfordert. Der zugrunde liegende Mechanismus, der in der VM demonstriert wird, ist identisch mit dem im Paper beschriebenen, aber bitte beachten Sie, dass wir die VM nicht verwendet haben, um die im Paper berichteten Zahlen zu erzeugen. Absolute Timings können aufgrund der virtualisierten Umgebung und der zugrunde liegenden Hardware abweichen.
Die Ergebnisse werden in einer Debian 13 VM (linux-vm/) reproduziert, installiert vom
offiziellen Live-Debian-ISO mit KDE Plasma 6 (Wayland) und einem Kernel,
der älter ist als der fsnotify-
Fix.
inotify-tools, Qt6-Dev-Header und pkexec sind installiert. Nichts anderes wird
aktualisiert, und der Kernel wird nach der Installation nie angefasst. Bitte NICHT apt upgrade ausführen
oder versuchen, den Kernel zu aktualisieren. Dieses VM-Image ist
absichtlich alt, ist nicht auf dem neuesten Stand und hat nicht die neuesten Sicherheits-
patches. Dieses VM-Image ist nur für schnelle Validierung und Tests gedacht!
Der Code, die Angriffe und die Demonstrationen in der VM sind in Linux/ gespiegelt.
Hinweis: Wir erwähnen am Anfang jedes Befehlsblocks, als welcher Benutzer die Befehle ausgeführt werden sollen. Es gibt [host], den Host-Rechner, der die
VM ausführt, [user], das Opfer der Angriffe in der VM, und [spyuser], der
eingerichtet werden muss und in den meisten Linux-Angriffen der Angreifer sein wird.
Das Disk-Image wird als linux-vm-upload.qcow2 ausgeliefert, komprimiert mit zstd.
Benennen Sie es in linux-vm.qcow2 um, bevor Sie run.sh ausführen (das diesen Dateinamen erwartet):
# Run As: [host]
cd linux-vm/
mv linux-vm-upload.qcow2 linux-vm.qcow2
./run.sh
Das Lesen von zstd-komprimiertem qcow2 erfordert qemu-img/qemu-system-x86_64 Version
5.2 oder neuer (2020+), prüfen Sie mit qemu-img --version. Wenn Sie auf einem
älteren QEMU feststecken und es das Image nicht öffnen kann, dekomprimieren Sie es zuerst in ein flaches qcow2:
qemu-img convert -O qcow2 linux-vm-upload.qcow2 linux-vm.qcow2
4 Kerne, 4GB RAM, GUI-Anzeige. Die Logins sind:
root, Passwort password,user, Passwort password,spyuser, Passwort password (nicht als spyuser einloggen!)Die bereitgestellte VM führt bereits einen verwundbaren, vorgepatchten Kernel
(6.12.43+deb13-amd64) aus, sodass kein Downgrade erforderlich ist, um sie zu verwenden. Sie benötigen QEMU,
um dieses Image auszuführen (das eine GUI hat). Das Artefakt befindet sich unter
/home/user/Linux-File-Notification-Attacks innerhalb der VM.
Ein Befehl richtet alles frisch in der VM ein: (i) ein unprivilegiertes spyuser-
Konto (nicht-sudo), (ii) seine eigene Kopie des Artefaktverzeichnisses (ein separates
unprivilegiertes Konto kann sonst nicht in das Home-Verzeichnis von user eindringen),
(iii) und jedes Skript in beiden Kopien ausführbar gemacht.
# In the VM, Run As: [user]
sudo bash ~/Linux-File-Notification-Attacks/setup_attacks.sh
Jeder Angriff unten läuft als spyuser (su - spyuser, Passwort password),
außer auth-ui-redress, der als user läuft (unten erklärt).
Beweist, dass Dateioperations-Benachrichtigungen für Dateien zugestellt werden, die nicht direkt gelesen werden können, solange ihr übergeordnetes Verzeichnis lesbar ist.
# 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
Lassen Sie es laufen und erzeugen Sie dann von einem anderen Terminal als user eine Log-Zeile:
# Run As: [user]
logger "hello"
Dieses Debian 13 Image hat kein rsyslog, daher gibt es keine /var/log/syslog-Datei wie
im Paper gezeigt. Das Skript weicht stattdessen darauf aus, /var/log/journal/<machine-id>/ zu überwachen. Dies ist dieselbe Idee, da die
überwachten .journal-Dateien root (Benutzer) und
systemd-journal (Gruppe) gehören, von denen keiner spyuser ist.
Misst die Benachrichtigungsverzögerung von 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 öffnet eine inotify-Überwachung auf eine Testdatei und versieht jedes empfangene IN_ACCESS
mit einem Zeitstempel. accessor liest dieselbe Datei 1000 Mal mit einer zufälligen 5-10ms-
Verzögerung zwischen den Lesevorgängen und versieht jeden Lesevorgang selbst mit einem Zeitstempel. stats.py vergleicht die beiden
Zeitstempelaufzeichnungen und gibt die durchschnittliche/Standardabweichung/minimale Verzögerung zwischen dem stattfindenden Lesevorgang und dem Eintreffen der Benachrichtigung aus, d.h. die zeitliche Auflösung von
inotify.
Nicht der vollständige Angriff aus dem Paper, sondern nur das Filter-Proof-of-Concept-
Primitiv, auf dem der Angriff aufbaut: für jede Taste, die irgendwo auf dem
System gedrückt wird, eine zeitgestempelte Benachrichtigung ausgeben, ohne jemals /dev/input
direkt zu lesen.
# Run As: [spyuser]
cd ~/Linux-File-Notification-Attacks/inter-keystroke-timing
make
./find-keyboard.sh
Tippen Sie in ein beliebiges Fenster (vielleicht ein neues Terminal als user). Jeder Tastendruck gibt eine
KEYPRESS-Zeile aus. Das Unterdrückungsfenster (das wir heuristisch für diese
Demonstration gewählt haben, beträgt 130ms) führt mehrere IN_ACCESS-Ereignisse zusammen, die durch einen einzelnen
physischen Tastendruck erzeugt werden. In der Praxis haben wir festgestellt, dass dieses Fenster für unterschiedliche Hardware unterschiedlich ist (z.B. mechanische Tastaturen, Tippstile).
Wenn die Auto-Erkennung das falsche Gerät (oder keines) auswählt, prüfen Sie
/proc/bus/input/devices und führen Sie es direkt mit ./build/keystroke-notify /dev/input event4 aus.
Wir demonstrieren, dass es möglich ist zu erkennen, wann
(pkexec)[https://polkit.pages.freedesktop.org/polkit/] ausgeführt wird, und
darüber hinaus ein gefälschtes Fenster darüber zu zeichnen. Wie wir in Abschnitt 4.4.3 gezeigt haben, ist dieser
'Authentication-UI-Redress-Angriff' auf KDE Plasma 5 und 6 mit Wayland möglich. Wir führen diesen Angriff im Bedrohungsmodell eines Angreifers mit demselben Benutzer aus: Der Wayland-
Socket ist auf die angemeldete Sitzung beschränkt, und ein separates unprivilegiertes Konto
kann nicht darauf zeichnen.
Bei einer Standard-KDE-Installation wird pkexec vom Desktop mitgebracht, aber dieses Live-ISO
ist ein schlankeres Image und hat es daher nicht installiert. Deshalb haben wir es manuell installiert, während wir (versucht haben) das VM-Image klein zu halten.
# Run As: [user]
cd ~/Linux-File-Notification-Attacks/auth-ui-redress
make
./inotify-watcher-with-gui
Lassen Sie es in einem Terminal laufen. Lösen Sie von einem anderen Terminal aus (das Verzeichnis spielt keine
Rolle) eine echte pkexec-Aufforderung aus, z.B. pkexec ls. Der Watcher sieht
den Zugriff auf /usr/bin/pkexec und zeichnet einen gefälschten "Authentication Required"-
Dialog (window-launcher) auf den Bildschirm über den echten. Wenn Sie in den
gefälschten Dialog tippen und auf Authenticate drücken, wird der eingegebene Text im Terminal des Watchers ausgegeben und dieser dann geschlossen. Bitte beachten Sie, dass das gefälschte Fenster absichtlich
vom echten Fenster abweicht, um einen einfachen Vergleich zu ermöglichen.
Die Überwachung von Font-Verzeichnissen während des Ladens einer Seite zeigt, welche Font-Dateien sie berührt hat. Verschiedene Websites ziehen verschiedene Fonts heran, daher ist die Menge der während des Ladens einer Seite ausgegebenen Pfade bereits ein Fingerabdruck; für diese minimale Version sind weder Timing noch Klassifikator erforderlich.
Öffnen Sie zunächst als Benutzer Firefox (klicken Sie darauf über das Symbol im Task-Manager-Dock am
unteren Bildschirmrand) und stellen Sie sicher, dass keine Websites geöffnet sind. Dann in einem
Terminal als spyuser:
# Run As: [spyuser]
cd ~/Linux-File-Notification-Attacks/website-fingerprinting-fonts
./compare-fonts.sh
Dies baut font-spy, das mit der Überwachung der von
Firefox verwendeten Font-Verzeichnisse beginnt. Das compare-fonts-Skript fordert Sie auf, zwei Websites zu besuchen.
Besuchen Sie zuerst eine Website (vielleicht wikipedia.com) und warten Sie ein paar Sekunden, bis sie geladen ist, öffnen Sie einen neuen Tab, schließen Sie den alten Tab (mit der Website) und drücken Sie dann ENTER im Terminal.
Zweitens machen Sie dasselbe mit einer anderen Website (vielleicht reddit.com): Besuchen Sie die Website und warten Sie ein paar Sekunden, bis sie geladen ist, öffnen Sie einen neuen Tab, schließen Sie den alten Tab, und drücken Sie dann ENTER im Terminal.
Das Skript sollte die Differenz der pro Website zugegriffenen Fonts ausgeben. Beachten Sie, dass wir im Paper auch die zeitlichen Informationen verwendet haben, d.h., wann auf den Font zugegriffen wurde. Für ein einfaches Proof-of-Concept ignorieren wir diese Informationen und geben einfach die Differenz zwischen den beiden Mengen von Font-Zugriffen aus. Während die genaue Menge der Font-Zugriffe zwischen den Durchläufen variieren kann, gibt es bestimmte Font-Dateien, auf die immer und ausschließlich von einer Website zugegriffen wird.
Beachten Sie, dass sich Websites im Laufe der Zeit ändern können und daher die Font-Datei-Zugriffe
abweichen können. Zum Zeitpunkt der Erstellung dieses Artefakts stellen wir fest, dass Wikipedia immer
auf /usr/share/fonts/truetype/liberation/LiberationSans-Bold.ttf zugreift und
Reddit immer auf
/usr/share/fonts/truetype/vlgothic/VL-Gothic-Regular.ttf.
Ein physisches Gerät oder einen Emulator mit einer Android-Version, deren Scoped-Storage-
Modell es noch erlaubt, einen FileObserver (den Java-Level-Wrapper um
inotify) auf WhatsApps geteilten Medienverzeichnissen zu registrieren, und ein zweites Gerät/Konto,
das als Nachrichtensender fungiert. Bauen Sie entweder den bereitgestellten Quellcode
(Android/source/) oder installieren Sie direkt das mitgelieferte APK
(Android/app-release.apk).
Android stellt dasselbe inotify-Primitiv, das in den Linux-
Erkenntnissen verwendet wird, über android.os.FileObserver bereit. Abschnitt 5.4.3 zeigt, dass eine
unprivilegierte App ohne Berechtigungen einen solchen Observer auf
WhatsApps Medienverzeichnissen registrieren und allein aus dem resultierenden Strom von
Open/Close/Access-Ereignissen ableiten kann, dass private Medien empfangen wurden, ohne
eine Berechtigung zu besitzen, die es ihr erlauben würde, den Inhalt selbst zu lesen.
Starten Sie die App und lösen Sie die Aktualisierungsaktion aus; der Observer-Dienst verbindet sich
und beginnt, periodische Liveness-Einträge auszugeben. Scrollen Sie zum Ende der
Log-Ansicht und aktualisieren Sie weiter, bis wiederholte ObserverService: Still Running-Einträge erscheinen, was bestätigt, dass die Überwachung aktiv und stabil ist.
Senden Sie von einem zweiten Konto aus ein Bild oder Dokument an die beobachtete
Konversation und laden Sie es, falls noch nicht zwischengespeichert, auf dem beobachteten
Gerät herunter. Dies erzeugt einen Schwall von Dateiereignis-Logzeilen; unmittelbar nach
dem letzten ObserverService: Still Running-Eintrag vor dem Schwall sollte das Log
Open/Close/Access-Ereignisse zeigen, deren Pfade der empfangenen
Datei entsprechen, was demonstriert, dass ihr Eintreffen allein aus Dateisystem-
Benachrichtigungs-Metadaten beobachtbar ist.
Wir stellen den Quellcode bereit, der mit msys2 kompiliert werden kann. Andernfalls kann auch die exe- Datei (Windows/firefox-fingerprint/monitor.exe) verwendet werden.
Eine Windows-Maschine (oder VM) mit installiertem MSYS2 und
der MinGW-w64 g++-Toolchain (pacman -S mingw-w64-ucrt-x86_64-gcc, ausgeführt in
einer MSYS2-Shell). Firefox installiert.
Dieses Proof of Concept verwendet
ReadDirectoryChangesW,
um rekursiv ganz C:\ zu überwachen, und gibt nur Ereignisse aus, deren Pfad
http enthält (Per-Origin-Speicherverzeichnisse, die Firefox nach dem Schema/Host der Website benennt, z.B. unter seinen Cache-/IndexedDB-Ordnern). Es sind keine Admin-Rechte
erforderlich, um ein Verzeichnis zu überwachen, das Sie auflisten können. Dieser Per-Origin-Speicher wird
bei jedem Seitenladen beschrieben, sodass die Überwachung von außerhalb des Browserprozesses immer noch
offenlegt, welche Website gerade besucht wurde.
Verwenden Sie entweder die von uns bereitgestellte exe (Windows/firefox-fingerprint/monitor.exe) oder kompilieren Sie aus einer MSYS2 UCRT64-Shell:
# Run in an MSYS2 UCRT64 shell
cd Windows/firefox-fingerprint
g++ -municode -static -O2 -o monitor.exe monitor.cpp
Verwenden Sie g++, nicht gcc. Führen Sie monitor.exe außerdem von einem Terminal aus (nicht durch
Doppelklick darauf), da sonst keine Konsole zum Ausgeben angehängt ist.
Der Watcher läuft als ein zweites, unprivilegiertes lokales Konto, getrennt von dem, das browst. Erstellen Sie zunächst dieses Konto über die Einstellungen:
attacker, und ein Passwort, dann Weiter.Dies erstellt ein lokales Konto (nicht an ein Microsoft-Konto gebunden, keine Netzwerkanmeldung), standardmäßig mit Standardberechtigungen (nicht Admin).
Als Nächstes platzieren Sie monitor.exe irgendwo, wo das neue Konto es tatsächlich lesen und
ausführen kann. Kopieren Sie die kompilierte Binärdatei stattdessen in das öffentliche, weltweit lesbare Verzeichnis:
copy monitor.exe C:\Users\Public\monitor.exe
Starten Sie es nun von Ihrem Hauptkonto (Opfer) aus unter dem attacker-
Konto, ohne den Desktop zu wechseln oder sich abzumelden, mit runas:
runas /user:attacker "cmd /k C:\Users\Public\monitor.exe"
Geben Sie bei Aufforderung das Passwort von attacker ein. cmd /k (anstatt
monitor.exe direkt auszuführen) hält das Konsolenfenster offen, sodass Sie dessen
Ausgabe beobachten können, während einfach runas /user:attacker C:\Users\Public\monitor.exe ebenfalls
funktioniert, aber sein Fenster schließt sich in dem Moment, in dem der Prozess beendet wird. Dies dient rein der
Bequemlichkeit.
Lassen Sie das monitor.exe-Fenster laufen und öffnen Sie dann, zurück in Ihrem Hauptkonto,
Firefox und besuchen Sie ein paar verschiedene Websites, z.B.
arstechnica.com und reddit.com.
Jede ausgegebene Zeile ist ein Datei-Create/Modify/Rename unter einem Speicherpfad, der
http entspricht. Verschiedene Websites erhalten verschiedene Origin-Verzeichnisse, und somit ist die Menge der
während des Ladens einer Seite berührten Pfade bereits ein Fingerabdruck.
Der Einfachheit halber verwenden wir fswatch, ein
existierendes, minimales, weit verbreitetes CLI-Tool, das die native FSEvents-API umschließt. Ein
Angreifer kann die FSEvents-API auch ohne dieses Tool verwenden.
Installieren Sie fswatch oder bauen Sie es aus dem Quellcode:
brew install fswatch
Überwachen Sie /Applications rekursiv als unprivilegierter Benutzer:
fswatch -xr /Applications
Lassen Sie es laufen und laden Sie dann vom Finder oder einem Browser aus Zoom
(oder eine andere Anwendung) herunter und installieren Sie es, und deinstallieren Sie es dann (möglicherweise müssen Sie auch den Papierkorb leeren).
fswatch gibt jeden Pfad aus, den FSEvents unter /Applications meldet, sobald er auftritt. Für eine schnelle Evaluierung kann derselbe Benutzer das Verzeichnis überwachen.
Andernfalls können Sie einen neuen Benutzer einrichten und fswatch als dieser Benutzer verwenden.
Veröffentlicht unter der MIT-Lizenz.