
تحليل فني لـ CVE-2026-52885: حالة سباق TOCTOU في Notepad++ v8.9.6.2 تسمح بتنفيذ أوامر عشوائية عبر تجاوز سلامة HMAC. يشمل السبب الجذري، سيناريو الهجوم، PoC، وتحليل التصحيح.
Notepad++ v8.9.6.2 — تنفيذ أوامر المستخدم المُتحكم بها من قبل المهاجم عبر حالة سباق HMAC
| GHSA | GHSA-qm4c-qg8p-qfcr |
| CVE | CVE-2026-52885 |
| الخطورة | عالية |
| المتأثر | v8.9.6.2 |
| المُصحَّح | v8.9.6.4 |
| التصحيح (Commit) | 4f7563c |
| الملف المتأثر | PowerEditor/src/NppCommands.cpp :4328–4359 |
| المنصة | Windows 11 Pro x64 |
| الصلاحية المطلوبة | مستخدم عادي (صلاحية الكتابة على shortcuts.xml) |
| الباحث | v3s9er |
| تاريخ الإفصاح | 2026-06-05 |
قدّم Notepad++ الإصدار v8.9.6.2 فحصاً للتكامل باستخدام HMAC-SHA256 على ملف shortcuts.xml لمنع حقن إدخالات UserCommand عشوائية.
يحتوي هذا الفحص على ثغرة من نوع TOCTOU: يتم التحقق من HMAC مقابل الملف الموجود على القرص في وقت التشغيل، ولكن الأمر الذي يُنفَّذ يُقرأ من المتجه _userCommands المخزّن في الذاكرة والمُحمّل عند بدء التشغيل. لا يتم إعادة مزامنة هذين المصدرين أبداً.
يمكن للمهاجم الذي يستطيع الكتابة على shortcuts.xml زرع أمر ضار قبل بدء التشغيل، والسماح لـ Notepad++ بتحميله إلى الذاكرة، ثم استعادة الملف الشرعي على القرص، ثم تشغيل الأمر. ينجح فحص HMAC (القرص نظيف)، ولكن الحمولة الضارة تُنفَّذ (الذاكرة قديمة).
تتحقق آلية التكامل من ملف shortcuts.xml الحالي على القرص، بينما يستخدم تنفيذ الأمر تمثيلاً تم تحميله سابقاً في الذاكرة. ونظراً لأن مصدري البيانات مستقلان، يمكن للمهاجم تغيير الملف قبل بدء التشغيل، والسماح بتحليله في الذاكرة، ثم استعادة الملف الأصلي قبل تنفيذ الأمر — مما يتسبب في نجاح فحص HMAC بينما تعمل الحمولة الضارة.
السطور 4328–4359 في ملف NppCommands.cpp:
// TIME OF CHECK — يقرأ الملف من القرص
std::string currentHMAC = computeHMAC(
getMachineGUID(),
getFileContent(nppParams.getShortcutsPath().c_str())
);
if (currentHMAC != nppGUI._shortcutsXmlHmacInConfig) { return; }
// تم التحقق مقابل الملف على القرص
// TIME OF USE — يقرأ من المتجه في الذاكرة (تم تحميله عند بدء التشغيل، لم يتم تحديثه أبداً)
int i = id - ID_USER_CMD;
const vector<UserCommand>& cmds = nppParams.getUserCommandList();
UserCommand ucmd = cmds[i];
Command cmd(string2wstring(ucmd.getCmd(), CP_UTF8));
cmd.run(_pPublicInterface->getHSelf()); // ينفذ الحمولة من الذاكرة
| العملية | المصدر | التوقيت |
|---|---|---|
| التحقق (HMAC) | ملف القرص | عند وقت التشغيل |
| الاستخدام (تنفيذ) | المتجه في الذاكرة | تم تحميله عند بدء التشغيل |
| الفجوة | يتحكم بها المهاجم | بدء التشغيل → وقت التشغيل |
الشرط المسبق: صلاحية الكتابة على shortcuts.xml
notepad++.exe%AppData%\Notepad++\الخطوات:
shortcuts.xml على القرص بنسخة ضارة (cmd = calc.exe)_userCommands من الملف الضارshortcuts.xml الشرعي على القرص — يصبح HMAC مطابقاً لـ config.xmlWM_COMMAND(21000) (ID_USER_CMD+0) أو الضغط على Ctrl+Alt+P_userCommands[0] من الذاكرة → يعمل calc.exeالنتيجة: تنفيذ أوامر يتحكم بها المهاجم تحت صلاحيات المستخدم الحالي. لا حاجة لصلاحية المسؤول، لا UAC، لا تحذير للمستخدم.
انظر poc_8962_toctou.ps1.
المتطلبات:
doLocalConf.xml في مجلد Notepad++ (الوضع المحمول)config.xml يحتوي على HMAC صالح لملف shortcuts.xml الشرعي.\poc_8962_toctou.ps1 -NppPath "C:\path\to\notepad++.exe"
تم التحقق: تم إنشاء calc.exe (PID 35932)، ويظهر القرص ملف shortcuts.xml شرعياً طوال الوقت.
ينقل الإصلاح (commit 4f7563c) التحقق من HMAC إلى وقت بدء التشغيل، إلى جانب عملية تحليل الملف الأولية. الآن يعمل كل من التحقق والاستخدام على نفس الكائن في نفس الوقت، مما يزيل نافذة TOCTOU.
| v8.9.6.2 (ضعيف) | v8.9.6.4 (مُصحَّح) | |
|---|---|---|
| فحص HMAC | عند وقت التشغيل، يُعيد قراءة القرص | عند بدء التشغيل، نفس البايتات التي تم تحليلها |
| مصدر الأمر | الذاكرة التي تم تحميلها عند بدء التشغيل | الذاكرة التي تم التحقق منها عند بدء التشغيل |
| نافذة TOCTOU |
| الوقت | الحدث | الحالة |
|---|
| T+0.0ث | المهاجم يكتب ملف shortcuts.xml ضاراً | disk=MALICIOUS |
| T+0.0ث | المهاجم يشغل Notepad++ | disk=MALICIOUS |
| T+0.1ث | Notepad++ يقرأ shortcuts.xml ← _userCommands[0]="calc.exe" | mem=MALICIOUS |
| T+4.2ث | Notepad++ يتم تحميله بالكامل | mem=MALICIOUS |
| T+4.2ث | المهاجم يستعيد ملف shortcuts.xml الشرعي | disk=LEGIT / mem=MAL |
| T+4.7ث | المهاجم يرسل WM_COMMAND(21000) | |
| T+4.7ث | فحص HMAC: يقرأ الملف الشرعي من القرص → ينجح | CHECK OK |
| T+4.7ث | التنفيذ: يقرأ _userCommands[0] من الذاكرة → calc.exe | استغلال |
| T+4.7ث | calc.exe يتم إنشاؤه (PID 35932) | مُؤكَّد |
| النوع | تنفيذ أوامر عشوائي |
| يتطلب مسؤولاً | لا |
| ظهور UAC | لا |
| قابلية الاكتشاف | منخفضة — يظهر القرص ملفاً شرعياً طوال الوقت؛ الحمولة موجودة في الذاكرة فقط |
| CVSS (تقديري) | AV:L / AC:H / PR:L / UI:N / S:U / C:H / I:H / A:H |
| بدء التشغيل → وقت التشغيل |
| تم القضاء عليها |