Skip to content
KitploitKITPLOIT
أدواتالمدونة
إرسال
أدواتالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
obsidian-note-toolbar-PoC — PoC — تنفيذ JavaScript عشوائي مدفوع بـ frontmatter في Note Toolbar لـ Obsidian (GHSA-q8cw-3m8c-5pf2, CVE-2026-87002, CVSS 7.0). | Kitploit
أدوات/GitHubGitHub/squeeze440/obsidian-note-toolbar-poc
التحليل الثابتتحليل الثغرات الأمنيةتحليل الكودالاستغلالاستغلال تطبيقات الويبالأوراق والأبحاثالتعلم والتعليمتطوير الحمولات

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
GitHub
squeeze440/obsidian-note-toolbar-poc

obsidian-note-toolbar-PoC

PoC — تنفيذ JavaScript عشوائي مدفوع بـ frontmatter في Note Toolbar لـ Obsidian (GHSA-q8cw-3m8c-5pf2, CVE-2026-87002, CVSS 7.0).

عرض المستودع
منذ 7 أياملم تتم المراجعة بعد
مشاركة

تنفيذ تعليمات برمجية عشوائية مدفوع بـ Frontmatter في Note Toolbar عبر سلسلة المتغيرات {{prop_NAME}} → {{js:}}

حالة CVE: مطلوبة، بانتظار الإسناد. تم نشر هذا الاكتشاف باسم GHSA-q8cw-3m8c-5pf2. عند إسناد CVE يُعاد تسمية هذا المستودع CVE-YYYY-NNNNN-obsidian-note-toolbar-PoC وتُستبدل هذه اللافتة برابط CVE.

الباحثDostxodjayev Abdullox (@squeeze440)
الاستشارةGHSA-q8cw-3m8c-5pf2
CVSS 3.17.0 (مرتفع)
الضعفCWE-94, CWE-1336

تنفيذ تعليمات برمجية عشوائية مدفوع بـ Frontmatter في Note Toolbar عبر سلسلة المتغيرات {{prop_NAME}} → {{js:}}

الملخص

يسمح ضعف تحييد المخرجات في محرك استبدال المتغيرات في Note Toolbar (إضافة Obsidian) للمهاجم الذي يتحكم في YAML frontmatter الخاص بملاحظة (مثل متعاون في خزنة متزامنة/مشتركة) بتحقيق تنفيذ تعليمات برمجية عشوائية على جهاز الضحية عندما يفتح الضحية الملاحظة ببساطة، عبر حقن حمولة {{js: ...}} في خاصية frontmatter يشير إليها عنصر شريط أدوات موجود مسبقًا وغير نصي عبر {{prop_NAME}} في التسمية/التلميح/الرابط.

المنتج

Note Toolbar (note-toolbar) — إضافة مجتمعية لـ Obsidian المستودع: https://github.com/chrisgurney/obsidian-note-toolbar

الإصدار المُختبَر

v1.34.12 (commit 520271c3027eb6da38bab10a686b21e14c664c13، 2026-07-29)، مقابل Obsidian desktop 1.13.4 على Linux.

تقدير CVSS v3.1

7.0 (مرتفع) — CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H

  • AV:L — المكوّن المصاب (مُقيّم JS الخاص بالإضافة، الذي يعمل داخل Electron renderer الخاص بـ Obsidian) ليس مواجهًا للشبكة؛ تصل الحمولة كمحتوى خزنة/ملف محلي تتم مزامنته بأي وسيلة يستخدمها الضحية (Git، Syncthing، Obsidian Sync، مجلد مشترك)، بما يتوافق مع اكتشافات سابقة في هذه العائلة (مثل obsidian-syncthing-integration، obsidian-codescript-toolkit).
  • AC:H — يعتمد الاستغلال على شروط خارج سيطرة المهاجم يجب أن تكون موجودة مسبقًا على تثبيت الضحية: (1) يجب أن يكون إعداد "Scripting" الخاص بالإضافة مُفعّلًا مسبقًا (معطّل افتراضيًا)، و(2) يجب أن يكون الضحية قد أعدّ مسبقًا عنصر شريط أدوات تكون تسميته أو تلميحه أو رابطه مرجعًا مجردًا {{prop_NAME}} لمفتاح frontmatter ما. كلاهما نمطا استخدام واقعيان وموثقان، لكن لا أحدهما هو الافتراضي.
  • PR:N — لا يحتاج المهاجم إلى أي وصول إلى نظام الضحية، فقط القدرة على إدخال ملاحظة إلى خزنة الضحية بـ frontmatter يتحكم به المهاجم.
  • UI:R — يجب أن يفتح الضحية/يعرض الملاحظة المحددة؛ لا يُطلب النقر على عنصر شريط الأدوات، إذ يُعرض شريط الأدوات تلقائيًا.
  • S:U, C:H/I:H/A:H — تُنفَّذ التعليمات البرمجية بوصول كامل إلى Node.js (require('child_process')، نظام الملفات، إلخ) بحساب المستخدم المحلي الذي يشغّل Obsidian.

التفاصيل

يدعم Note Toolbar متغيرًا موثقًا {{prop_NAME}} يستبدل قيمة frontmatter الخاصة بملاحظة في تسمية عنصر شريط أدوات أو تلميحه أو رابطه (skills/note-toolbar-variables/SKILL.md، ويكي Variables.md). كما يدعم متغيرًا {{js: <expr>}} يقيّم التعبير كـ JavaScript حي عند تفعيل إعداد "Scripting" الخاص بالإضافة.

الخلل في ترتيب العمليات في src/Toolbar/VariableResolver.ts::replaceVars():

  1. الأسطر 74–92: تُستبدل عناصر {{prop_KEY}} النائبة بالقيمة الخام لـ frontmatter[KEY] من الملاحظة الحالية — دون شرط، بغض النظر عن إعداد scriptingEnabled، وبغض النظر عن مصدر قيمة frontmatter تلك.
  2. الأسطر 94–104 (داخل if (this.ntb.settings.scriptingEnabled)): تتحقق الدالة بعد ذلك من s.trim().startsWith('{{js:') على السلسلة s المستبدلة بالفعل، وإذا صحّ ذلك، تُزيل غلاف {{js:/}} وتمرر الباقي إلى JavaScriptAdapter.use() للتقييم.

لأن الخطوة 1 تُنفَّذ قبل الخطوة 2 وتعيد كتابة s في مكانها، فإن قيمة frontmatter تبدأ بنفسها بـ {{js: وتنتهي بـ }} تُرقّى من "نص معروض" إلى "سكربت منفَّذ" — حتى وإن لم يُؤلف عنصر شريط الأدوات قط كعنصر سكربت. مالك عنصر شريط الأدوات لم يكتب سوى {{prop_status}}؛ والحمولة القابلة للتنفيذ تأتي بالكامل من frontmatter الخاص بالملاحظة نفسها.

يشغّل JavaScriptAdapter.evaluate() (src/Adapters/JavaScriptAdapter.ts:143-205) التعبير باستخدام AsyncFunction حقيقي غير معزول:

root@kitploit:~
src/Adapters/Adapter.ts:11
protected static readonly AsyncFunction = (Object.getPrototypeOf(async function(){}) as { constructor: typeof Function }).constructor;

src/Adapters/JavaScriptAdapter.ts:164
const func = new JavaScriptAdapter.AsyncFunction("input", expression);
...
result = await Promise.resolve((func as (...args: unknown[]) => unknown)(args));

هذا هو مُنشئ AsyncFunction الحقيقي لمحرك JS، وليس مفسّرًا/بيئة معزولة — داخل Electron renderer الخاص بـ Obsidian يتمتع بوصول كامل إلى require()/Node.js، وهو ما تم تأكيده في PoC أدناه عبر require('child_process').execSync(...).

بشكل حاسم، محوّل JS مدمج ولا يتطلب إضافة مرافقة (src/Adapters/AdapterManager.ts:59: adapter = this.js; // built-in, doesn't rely on plugin)، بخلاف بادئات متغيرات Dataview/Templater/JS-Engine التي تحتاج إلى تثبيت تلك الإضافات. فقط مفتاح "Scripting" الخاص بالإضافة نفسها (scriptingEnabled، الافتراضي false، src/Settings/NoteToolbarSettings.ts:300) هو ما يتحكم به.

أخيرًا، مسار العرض الذي يُفعّل الاستبدال تلقائي، وليس مشروطًا بالنقر: يستدعي ToolbarRenderer.ts::renderLItems() الدالة this.ntb.vars.resolveText(toolbar, file) (src/Toolbar/ToolbarRenderer.ts:418) في كل مرة يُعرض فيها شريط أدوات لملاحظة — أي عند فتح/عرض الملاحظة — مما يحل تسمية وتلميح كل عنصر عبر replaceVars(). لا يُطلب النقر على عنصر شريط الأدوات المتأثر.

إسناد شريط الأدوات إلى الملاحظة مدفوع هو نفسه بـ frontmatter (إعداد toolbarProp، المفتاح الافتراضي notetoolbar، src/Settings/NoteToolbarSettings.ts:317)، لذا يمكن لملاحظة متزامنة اختيار شريط الأدوات الذي يُعرض عليها — لكن هذا غير مطلوب للاستغلال إذا كان الضحية يستخدم بالفعل شريط أدوات افتراضيًا أو تعيين مجلد يتضمن العنصر المصاب.

هذا متميز عن المخاطر التي يوثقها SECURITY.md الخاص بالمشرف ("User scripts... executes JavaScript provided by the user... intentional and by design") — فذلك يصف مستخدمًا يؤلف عن قصد عنصر شريط أدوات {{js:}}، أو يستورد عن قصد إعداد شريط أدوات مشتركًا يحتوي على واحد. هنا، عنصر شريط الأدوات ليس عنصر سكربت على الإطلاق من منظور المُعدّ (إنه تسمية عرض خاصية عادية)، وتصل الحمولة القابلة للتنفيذ عبر محتوى/frontmatter ملاحظة عادي — نفس نموذج تهديد محتوى الخزنة غير الموثوق كما في اكتشافات تنفيذ التعليمات البرمجية الأخرى المتعلقة بمزامنة/إعدادات Obsidian (obsidian-syncthing-integration، obsidian-codescript-toolkit).

إثبات المفهوم

تم التحقق منه ديناميكيًا مقابل نسخة Obsidian 1.13.4 desktop حقيقية (Xvfb + fluxbox)، بتحميل الإضافة المبنية الفعلية (main.js المبني من المصدر المُدقَّق)، وليس استخراج دالة مجردة.

  1. خزنة PoCVault/ مع Project Alpha.md:

    root@kitploit:~
    ---
    status: "{{js: require('child_process').execSync('id > /tmp/ntb_poc_proof.txt; date >> /tmp/ntb_poc_proof.txt; whoami >> /tmp/ntb_poc_proof.txt'); return 'ok';}}"
    notetoolbar: Toolbar
    ---
    
  2. تثبيت إضافة Note Toolbar، والثقة بالإضافات المجتمعية، وإنشاء شريط أدوات واحد باسم "Toolbar" عبر واجهة إعدادات الإضافة نفسها بعنصر واحد حقل Label الخاص به هو {{prop_status}} (تسمية عرض خاصية عادية — لم يُعد قط كعنصر سكربت).

  3. تفعيل إعداد الإضافة Scripting (موافقة الضحية، معطّل افتراضيًا).

  4. مجرد فتح/عرض Project Alpha.md — دون النقر على عنصر شريط الأدوات — يعرض شريط الأدوات مُظهرًا ok (قيمة إرجاع تعبير JS)، وتُنفَّذ أوامر shell المحقونة فعليًا:

    إثبات الطرفية (~/engagements/obsidian-note-toolbar/evidence/02_terminal_proof_of_execution.png):

    root@kitploit:~
    $ cat /tmp/ntb_poc_proof.txt
    uid=1000(kali) gid=1000(kali) groups=1000(kali),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),100(users),105(docker),992(kvm)
    Fri Jul 31 09:31:33 PM +05 2026
    kali
    

    لقطة شاشة Obsidian تُظهر حمولة frontmatter الخام وشريط الأدوات المعروض ok (~/engagements/obsidian-note-toolbar/evidence/01_obsidian_toolbar_rce_trigger.png).

    الملاحظة المصدرية محفوظة في ~/engagements/obsidian-note-toolbar/evidence/poc_note_frontmatter.md.

التأثير

تنفيذ تعليمات برمجية عشوائية كامل بحساب المستخدم المحلي الذي يشغّل Obsidian، يُفعَّل بمجرد فتح ملاحظة — دون نقر، دون إجراء "تشغيل سكربت" صريح، دون حوار. في سير عمل فريق/خزنة مشتركة (Obsidian Sync، خزنة مدعومة بـ Git، Syncthing، Google Drive، إلخ)، يمكن لأي مساهم قادر على تحرير frontmatter ملاحظة تحقيق RCE على كل متعاون آخر لديه إعداد Scripting في Note Toolbar مُفعّلًا وأي عنصر شريط أدوات يعرض خاصية ملاحظة.

نقاط الضعف (CWE)

  • CWE-94: التحكم غير السليم في توليد التعليمات البرمجية ('حقن التعليمات البرمجية') — تُدمج بيانات frontmatter غير الموثوقة في سلسلة تُفسَّر لاحقًا كتوجيه سكربت قابل للتنفيذ.
  • CWE-1336: التحييد غير السليم للعناصر الخاصة المستخدمة في محرك القوالب — صيغة القالب/المتغير {{...}} لا تحيّد قيم الاستبدال التي يتحكم بها المهاجم والتي تحتوي هي نفسها على توجيهات قوالب إضافية.

المعالجة

في VariableResolver.replaceVars()، يجب تقييم فحوصات بادئة السكربت ({{js:، {{dv:، {{jse:، <%/{{tp:) مقابل السلسلة الأصلية، قبل الاستبدال، وليس السلسلة بعد تنفيذ استبدال {{prop_*}}/{{note_title}}/إلخ — أي تحديد مسبقًا ما إذا كان عنصر شريط الأدوات نفسه قد أُلّف كتوجيه سكربت، وعدم السماح أبدًا بإعادة تفسير قيمة frontmatter مستبدلة كواحد. بشكل ملموس: تنفيذ فحص بادئة السكربت بنمط hasVars قبل كتلة استبدال PROP/SELECTION/NOTE_TITLE/إلخ، وتخطي إعادة فحص startsWith('{{js:'/'{{dv:'/...) على السلسلة بعد الاستبدال. كدفاع في العمق، يمكن أيضًا تهريب/تحييد القيم القادمة من frontmatter بحيث لا يمكنها أبدًا إعادة الدخول إلى قواعد {{...}}.

الفضل

Dostxodjayev Abdullox

قناة الإبلاغ

يؤكد SECURITY.md في هذا المستودع أن الإبلاغ الخاص عن الثغرات في GitHub مُفعّل وهو القناة المفضلة ("GitHub private vulnerability reporting: use the 'Report a vulnerability' button under the Security tab of this repo")، مع نموذج Google كبديل للمُبلّغين بدون حساب GitHub. تم إعادة التحقق بشكل مستقل: gh api repos/chrisgurney/obsidian-note-toolbar/private-vulnerability-reporting --jq .enabled → true، وgh api repos/chrisgurney/obsidian-note-toolbar/security-advisories --jq 'length' → 0 (لا استشارات سابقة، لا خطر تكرار).

تنزيل الأداة