
أدوات بحثية لهجمات القناة الجانبية لإشعارات الملفات على 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 مع نواة مُرقّعة مسبقاً. لم يُستخدم هذا الجهاز الافتراضي لإنتاج نتائج تقييم الورقة البحثية وليس المقصود منه إعادة إنتاج حجمها الدقيق. قد يتم تحديث هذا المستودع لدمج المراجعات والملاحظات من مُقيّمي المخرجات لدينا. سنجعل الجهاز الافتراضي متاحاً للعموم عند اكتمال تقييم المخرجات.
استخدمنا Claude (Opus 4.8) لتغليف الكود الخاص بنا في مخرجات موثقة بشكل جيد وعالية الأداء (على سبيل المثال، كان إصدار Windows بطيئاً قليلاً). ومع ذلك، كان الكود والسكربتات وملفات makefiles التي أنشأها مبنية على
التعليمات لاختبار كود Linux أدناه خاصة بتشغيل الأوامر في الجهاز الافتراضي. يرجى
النظر إلى الكود بدلاً من ذلك في Linux/.
الجهاز الافتراضي موجود فقط للراحة، بحيث لا يتطلب تركيب كل هجوم إعداد بيئة من الصفر أو تخفيض إصدار النواة. الآلية الأساسية الموضحة في الجهاز الافتراضي مطابقة لتلك الموصوفة في الورقة البحثية، ولكن يرجى ملاحظة أننا لم نستخدم الجهاز الافتراضي لإنتاج الأرقام المذكورة في الورقة البحثية. قد تختلف التوقيتات المطلقة بسبب البيئة الافتراضية والعتاد الأساسي.
يتم إعادة إنتاج النتائج داخل جهاز افتراضي Debian 13 (linux-vm/)، مثبت من
قرص Debian ISO الرسمي المباشر مع KDE Plasma 6 (Wayland) مثبت مع نواة تسبق
إصلاح
fsnotify.
تم تثبيت inotify-tools وترويسات Qt6 dev وpkexec. لا يتم ترقية أي شيء آخر،
ولا يتم لمس النواة أبداً بعد التثبيت. يرجى عدم تشغيل apt upgrade أو محاولة
ترقية النواة. صورة الجهاز الافتراضي هذه قديمة عمداً، وليست محدثة، ولا تحتوي
على أحدث تصحيحات الأمان. صورة الجهاز الافتراضي هذه مخصصة فقط للتحقق السريع
والاختبار!
الكود والهجمات والعروض التوضيحية الموجودة داخل الجهاز الافتراضي منسوخة في
Linux/.
ملاحظة: نذكر المستخدم الذي يجب تشغيل الأوامر به في أعلى كل كتلة أوامر.
هناك [host]، وهو الجهاز المضيف الذي يشغل الجهاز الافتراضي، و[user] وهو ضحية
الهجمات في الجهاز الافتراضي، و[spyuser] الذي يتطلب إعداده وسيكون المهاجم في
معظم هجمات Linux.
يتم توفير صورة القرص باسم linux-vm-upload.qcow2، مضغوطة بـ zstd. أعد تسميتها
إلى linux-vm.qcow2 قبل تشغيل run.sh (الذي يتوقع اسم الملف هذا):
# Run As: [host]
cd linux-vm/
mv linux-vm-upload.qcow2 linux-vm.qcow2
./run.sh
تتطلب قراءة qcow2 المضغوط بـ zstd إصدار 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، عرض رسومي. بيانات تسجيل الدخول هي:
root، كلمة المرور password،user، كلمة المرور password،spyuser، كلمة المرور password (لا تسجل الدخول باسم spyuser!)الجهاز الافتراضي المقدم يشغل بالفعل نواة ضعيفة مُرقّعة مسبقاً
(6.12.43+deb13-amd64)، لذا لا حاجة لتخفيض الإصدار لاستخدامه. ستحتاج إلى QEMU
لتشغيل هذه الصورة (التي تحتوي على واجهة رسومية). توجد المخرجات في
/home/user/Linux-File-Notification-Attacks داخل الجهاز الافتراضي.
أمر واحد يعد كل شيء من جديد في الجهاز الافتراضي: (i) حساب spyuser غير
مميز (بدون sudo)، (ii) نسخته الخاصة من دليل المخرجات (لا يمكن لحساب غير مميز
منفصل التنقل إلى دليل home الخاص بـ 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 بين تسجيلي الطوابع
الزمنية ويطبع متوسط/الانحراف المعياري/الحد الأدنى للتأخير بين حدوث القراءة ووصول
الإشعار، أي الدقة الزمنية لـ inotify.
ليس الهجوم الكامل من الورقة البحثية، ولكن فقط البدائية التمهيدية لإثبات مفهوم
التصفية التي بُني عليها الهجوم: لكل مفتاح يُضغط في أي مكان على النظام، اطبع
إشعاراً واحداً بطابع زمني، دون قراءة /dev/input مباشرة أبداً.
# Run As: [spyuser]
cd ~/Linux-File-Notification-Attacks/inter-keystroke-timing
make
./find-keyboard.sh
اكتب في أي نافذة (ربما طرفية جديدة باسم user). كل ضغطة مفتاح تطبع سطر
KEYPRESS واحداً. نافذة الكبت (التي اخترناها بشكل استكشافي لهذا العرض التوضيحي
هي 130ms) تدمج عدة أحداث IN_ACCESS الناتجة عن ضغطة مفتاح فيزيائية واحدة. عملياً،
لاحظنا أن هذه النافذة تختلف باختلاف العتاد (مثل لوحات المفاتيح الميكانيكية،
أنماط الكتابة).
إذا اختار الاكتشاف التلقائي الجهاز الخطأ (أو لم يختر أي جهاز)، تحقق من
/proc/bus/input/devices وشغله مباشرة باستخدام ./build/keystroke-notify /dev/input event4.
نوضح القدرة على اكتشاف متى يتم تنفيذ
(pkexec)[https://polkit.pages.freedesktop.org/polkit/]، وكذلك رسم نافذة مزيفة
فوقها. كما أظهرنا في القسم 4.4.3، فإن 'هجوم تعديل واجهة المصادقة' هذا ممكن على
KDE Plasma 5 و6 مع Wayland. ننفذ هذا الهجوم في نموذج تهديد المهاجم من نفس
المستخدم: مقبس Wayland محصور في الجلسة المسجل دخولها، ولا يمكن لحساب غير مميز
منفصل الرسم عليه.
في تثبيت KDE القياسي يتم جلب pkexec بواسطة سطح المكتب، لكن قرص ISO المباشر هذا
صورة أخف، وبالتالي لا يحتوي عليه مثبتاً. لذلك، قمنا بتثبيته يدوياً أثناء محاولة
إبقاء صورة الجهاز الافتراضي صغيرة.
# Run As: [user]
cd ~/Linux-File-Notification-Attacks/auth-ui-redress
make
./inotify-watcher-with-gui
اتركه قيد التشغيل في طرفية. من طرفية أخرى (الدليل لا يهم)، أطلق مطالبة pkexec
حقيقية، مثل pkexec ls. يرى المراقب الوصول إلى /usr/bin/pkexec ويرسم مربع
حوار مزيف "Authentication Required" (window-launcher) على الشاشة فوق الحقيقي.
الكتابة في الحوار المزيف والضغط على Authenticate تطبع النص المُدخل إلى طرفية
المراقب، ثم تغلقه. يرجى ملاحظة أن النافذة المزيفة مختلفة عمداً عن النافذة الحقيقية
لسهولة المقارنة.
مراقبة أدلة الخطوط أثناء تحميل صفحة تكشف ملفات الخطوط التي لمستها. تسحب مواقع مختلفة خطوطاً مختلفة، لذا فإن مجموعة المسارات المطبوعة أثناء تحميل صفحة هي بالفعل بصمة، دون الحاجة إلى توقيت أو مصنف لهذه النسخة المبسطة.
أولاً، باسم user، افتح Firefox (انقر عليه عبر الأيقونة في شريط مهام مدير المهام
في أسفل الشاشة)، وتأكد من عدم وجود مواقع مفتوحة. ثم، في طرفية باسم spyuser:
# Run As: [spyuser]
cd ~/Linux-File-Notification-Attacks/website-fingerprinting-fonts
./compare-fonts.sh
يبني هذا font-spy الذي يبدأ بمراقبة أدلة الخطوط المستخدمة بواسطة Firefox.
يطلب منك سكربت compare-fonts زيارة موقعين.
أولاً، قم بزيارة موقع واحد (ربما wikipedia.com) وانتظر بضع ثوانٍ حتى يتم تحميله، افتح تبويباً جديداً، أغلق التبويب القديم (مع الموقع)، ثم اضغط ENTER في الطرفية.
ثانياً، افعل الشيء نفسه مع موقع آخر (ربما reddit.com): قم بزيارة الموقع وانتظر بضع ثوانٍ حتى يتم تحميله، افتح تبويباً جديداً، أغلق التبويب القديم، ثم اضغط ENTER في الطرفية.
يجب أن يطبع السكربت الفرق في الخطوط التي تم الوصول إليها لكل موقع. لاحظ أننا في الورقة البحثية استخدمنا أيضاً المعلومات الزمنية، أي متى تم الوصول إلى الخط. لإثبات مفهوم بسيط، نتجاهل هذه المعلومات ونطبع ببساطة الفرق بين مجموعتي الوصول إلى الخطوط. بينما قد تختلف مجموعة الوصول الدقيقة إلى الخطوط بين التشغيلات، هناك ملفات خطوط معينة يتم الوصول إليها دائماً وبشكل فريد بواسطة موقع.
لاحظ أن المواقع قد تتغير بمرور الوقت، وبالتالي قد تختلف عمليات الوصول إلى ملفات
الخطوط. في وقت صياغة هذه المخرجات، نلاحظ أن Wikipedia تصل دائماً إلى
/usr/share/fonts/truetype/liberation/LiberationSans-Bold.ttf وReddit تصل دائماً
إلى /usr/share/fonts/truetype/vlgothic/VL-Gothic-Regular.ttf.
جهاز فيزيائي أو محاكي يشغل إصدار Android الذي لا يزال نموذج Scoped Storage فيه
يسمح بتسجيل FileObserver (الغلاف على مستوى Java حول inotify) على أدلة
الوسائط المشتركة لـ WhatsApp، وجهاز/حساب ثانٍ ليعمل كمرسل الرسائل. إما أن تبني
المصدر المقدم (Android/source/) أو تثبت ملف APK المقدم مباشرة
(Android/app-release.apk).
يكشف Android نفس البدائية inotify المستخدمة في جميع نتائج Linux عبر
android.os.FileObserver. يوضح القسم 5.4.3 أن تطبيقاً غير مميز وبدون أذونات
يمكنه تسجيل مثل هذا المراقب على أدلة الوسائط لـ WhatsApp، ومن مجرد تدفق أحداث
الفتح/الإغلاق/الوصول الناتج، يستنتج أن وسائط خاصة تم استلامها، دون امتلاك أي
إذن يسمح له بقراءة المحتوى نفسه.
شغّل التطبيق وأطلق إجراء التحديث؛ تتصل خدمة المراقب وتبدأ بإصدار إدخالات حيوية
دورية. مرر إلى أسفل عرض السجل واستمر في التحديث حتى تظهر إدخالات متكررة
ObserverService: Still Running، مما يؤكد أن المراقبة نشطة ومستقرة.
من حساب ثانٍ، أرسل صورة أو مستنداً إلى المحادثة المراقبة، وإذا لم تكن مخزنة
مؤقتاً بالفعل، قم بتنزيلها على الجهاز المراقب. ينتج عن هذا دفعة من أسطر سجل
أحداث الملفات؛ مباشرة بعد آخر إدخال ObserverService: Still Running قبل الدفعة،
يجب أن يعرض السجل أحداث فتح/إغلاق/وصول تتوافق مساراتها مع الملف المستلم، مما
يوضح أن وصوله قابل للملاحظة من بيانات إشعار نظام الملفات فقط.
نوفر الكود المصدري الذي يمكن تجميعه باستخدام msys2. بخلاف ذلك، يمكن أيضاً استخدام ملف exe (Windows/firefox-fingerprint/monitor.exe).
جهاز Windows (أو جهاز افتراضي) مع تثبيت MSYS2،
وسلسلة أدوات MinGW-w64 g++ (pacman -S mingw-w64-ucrt-x86_64-gcc، تُشغل من
صدفة MSYS2). Firefox مثبت.
يستخدم إثبات المفهوم هذا
ReadDirectoryChangesW
لمراقبة كل C:\ بشكل تكراري، ويطبع فقط الأحداث التي يحتوي مسارها على http
(أدلة التخزين لكل أصل التي يسميها Firefox باسم مخطط/مضيف الموقع، مثل تحت
مجلدات cache/IndexedDB الخاصة به). لا تُطلب حقوق مسؤول لمراقبة دليل يمكنك
سرده. يتم الكتابة إلى هذا التخزين لكل أصل عند كل تحميل صفحة، لذا فإن المراقبة من
خارج عملية المتصفح لا تزال تكشف الموقع الذي تمت زيارته للتو.
إما أن تستخدم ملف exe الذي نوفره (Windows/firefox-fingerprint/monitor.exe) أو تجمعه من صدفة MSYS2 UCRT64:
# Run in an MSYS2 UCRT64 shell
cd Windows/firefox-fingerprint
g++ -municode -static -O2 -o monitor.exe monitor.cpp
استخدم g++، وليس gcc. شغّل أيضاً monitor.exe من طرفية (وليس بالنقر
المزدوج عليه)، وإلا لن تكون هناك وحدة تحكم متصلة للطباعة إليها.
يعمل المراقب كحساب محلي ثانٍ غير مميز، منفصل عن الحساب الذي يتصفح. أولاً، أنشئ ذلك الحساب عبر الإعدادات:
attacker، وكلمة مرور، ثم Next.ينشئ هذا حساباً محلياً (غير مرتبط بحساب Microsoft، بدون تسجيل دخول عبر الشبكة)، بصلاحيات قياسية (غير مسؤول) افتراضياً.
بعد ذلك، ضع monitor.exe في مكان يمكن للحساب الجديد قراءته وتنفيذه فعلاً. انسخ
الملف التنفيذي المبني إلى الدليل العام القابل للقراءة من الجميع بدلاً من ذلك:
copy monitor.exe C:\Users\Public\monitor.exe
الآن، من حسابك الرئيسي (الضحية)، شغّله تحت حساب attacker دون تبديل أسطح
المكتب أو تسجيل الخروج، باستخدام runas:
runas /user:attacker "cmd /k C:\Users\Public\monitor.exe"
أدخل كلمة مرور attacker عند المطالبة. يُبقي cmd /k (بدلاً من تشغيل
monitor.exe مباشرة) نافذة وحدة التحكم مفتوحة حتى تتمكن من مشاهدة مخرجاتها،
بينما يعمل أيضاً runas /user:attacker C:\Users\Public\monitor.exe ببساطة، لكن
نافذته تُغلق لحظة خروج العملية. هذا فقط للراحة.
اترك نافذة monitor.exe قيد التشغيل، ثم، بالعودة إلى حسابك الرئيسي، افتح
Firefox وقم بزيارة موقعين مختلفين، مثل،
arstechnica.com وreddit.com.
كل سطر مطبوع هو إنشاء/تعديل/إعادة تسمية ملف تحت مسار تخزين يطابق http. تحصل
المواقع المختلفة على أدلة أصل مختلفة، وبالتالي فإن مجموعة المسارات التي تم لمسها
أثناء تحميل صفحة هي بالفعل بصمة.
للتبسيط، نستخدم fswatch، وهي أداة
CLI موجودة، بسيطة، ومستخدمة على نطاق واسع وتغلف واجهة FSEvents الأصلية. يمكن
للمهاجم استخدام واجهة FSEvents API بدون هذه الأداة أيضاً.
قم بتثبيت fswatch، أو ابنه من المصدر:
brew install fswatch
راقب /Applications بشكل تكراري، كمستخدم غير مميز:
fswatch -xr /Applications
اتركه قيد التشغيل، ثم، من Finder أو متصفح، قم بتنزيل وتثبيت Zoom (أو أي تطبيق
آخر)، ثم قم بإلغاء تثبيته (قد تضطر إلى إفراغ سلة المهملات أيضاً). يطبع fswatch
كل مسار يبلغ عنه FSEvents تحت /Applications أثناء حدوثه. للتقييم السريع، يمكن
لنفس المستخدم مراقبة الدليل. بخلاف ذلك، يمكنك إعداد مستخدم جديد واستخدام fswatch
باسم ذلك المستخدم.
صدر تحت MIT License.