
إضافة BianryNinja لتحديد الثغرات الأمنية في الملفات الثنائية المفكّكة، مع دعم كلٍّ من الفحوصات البرمجية ونماذج LLM.
بحث الثغرات بمساعدة LLM لـ Binary Ninja.
يضيف VulnFanatic-NG لوحة جانبية تفحص الثنائي الحالي وتطلب من LLM — نموذج مستضاف محليًا متوافق مع OpenAI افتراضيًا، أو Anthropic Claude أو Google Gemini أو Azure OpenAI (انظر محركات LLM الخلفية) — لتقرير ما إذا كان الكود المشبوه ضعيفًا فعلًا. يعمل بشكل أساسي على مخرجات المُفكِّك (HLIL)، ويعود إلى لغة التجميع عند الحاجة، ويبلغ فقط بالمشكلات المؤكدة مع مراجع قابلة للنقر تعيد إلى الكود.
تعمل عملية الفحص في مراحل يصل عددها إلى ثلاث (المرحلة 3 اختيارية وتعتمد على الإنترنت حصريًا):
يجد مواقع استدعاء الدوال الخطرة المعرّفة في
rules/phase1_rules.json — strcpy،
memcpy، sprintf/سلاسل التنسيق، system، alloca، scanf، واجهات برمجة الأوامر/التنفيذ،
خوارزميات RNG ضعيفة، عائلة free/delete (استخدام بعد التحرير / تحرير مزدوج)،
قراءات مدخلات غير موثوقة في مخازن ثابتة (recv/read/fread/ReadFile)،
حقن SQL (sqlite3_exec/mysql_query/PQexec)، تعطيل التحقق من شهادة TLS
(SSL_CTX_set_verify/curl)، SSRF، وإدارة امتيازات غير سليمة
(setuid/setresgid)، وعائلة memset/bzero، و
مقارنات بطول يتحكم فيه المهاجم (memcmp/strncmp →
تجاوز المصادقة)، عبر C/C++ وWin32 وRust FFI (بأقصى جهد ممكن). التغطية
تشمل المتغيرات المحصّنة _chk (FORTIFY) ومتغيرات Annex-K _s. دوال الإخراج المنسّق المحدودة
(snprintf وما يشابهها) لها قاعدة افتراضية آمنة خاصة بها
حتى لا يُبلَّغ عن وسيط حجم صحيح على أنه تجاوز. تُكتشف مواقع الاستدعاء
بثلاث طرق: استدعاءات مباشرة للرموز المسماة؛ استدعاءات تُوجَّه عبر
thunks مُمرِّرة / PLT stubs (يُستعاد المستدعون الحقيقيون، لذا لا يُفوَّت استيراد
لا يُوصَل إليه إلا عبر stub)؛ و— ما لم يكن
vulnfanatic.scanIndirectCalls معطّلًا — استدعاءات غير مباشرة تُرسَل عبر
مؤشر دالة أو vtable حُلّت بواسطة Binary Ninja إلى دالة خطيرة.
لكل موقع استدعاء، يبني سياقًا بين الإجراءات متمحورًا حول المُفكِّك،
محدودًا بحد أقصى للتوكنات (افتراضيًا 100k):
__*_chk والمتغيرات ذات التحقق من الحدود *_s تأخذ وسائط
إضافية في البداية، مما يغيّر موضع التنسيق/الحجم/الوجهة،s->buf
إلى الحجم الحقيقي لمصفوفة الحقل بدلًا من حجم مؤشر s؛
تعريفات البنيات في قسم الأنواع تحمل أيضًا أحجامًا بالبايت لكل حقل،0x40
أو محصور في [0, 0xff])، ويستخدمه النموذج كحقيقة قاطعة عند مقارنة
الحجم بسعة المخزن بدلًا من التخمين،vulnfanatic.includeStackLayout)،if/الحلقة/switch التي تحرس الاستدعاء)،MAIN→ABCD→strcpy، أيضًا الدوال التي يستدعيها MAIN وABCD في أماكن أخرى)، لأنها
قد تحتوي على فحوصات الحدود/التحقق التي تُحكِم القيمة الخطرة
(vulnfanatic.includeCallPathSiblings، تُمتلأ طالما تسمح الميزانية)، وrecv/read/getenv تُستدعى في
نفس الدالة).يُرسل هذا السياق مع موجه خاص بالقاعدة إلى النموذج، الذي يعيد حكمًا منظمًا. يتم تجاهل غير المشكلات. وقد ضُبطت الموجّهات لنموذج كود محلي قوي (مثل Qwen2.5-Coder) وتطلب منه تحليل التدفق بالكامل وإخراج JSON فقط.
يُطلب من النموذج تفضيل الاسترجاع — الإبلاغ عن المشكلات المحتملة وذات الصلة بالأمان والتعبير عن عدم اليقين عبر Confidence بدلًا من تجاهل أي شيء لا يستطيع إثباته تمامًا. يعرض عمله في مسودة تقتبس حرفيًا مقتطفات الكود التي اعتمد عليها (مصدر الإدخال، كل حارس، الحجم/الطول، النوع ذي الصلة، والمغسلة)، ويُخزَّن ذلك في النتيجة حتى يمكنك مراجعة الاستدلال.
تحمل كل نتيجة Confidence (عالية/متوسطة/منخفضة): عالية = السلسلة كاملة
ظاهرة في السياق؛ متوسطة = محتملة، مع استنتاج رابط أو رابطين؛ منخفضة = خيط
يستحق مراجعة يدوية. هذا هو المقياس الرئيسي (تقدير النموذج لشدة الخطورة هو
حقل ثانوي). اضبط vulnfanatic.minConfidence لتجاهل أي شيء يقل عن حد معيّن.
افتراضيًا يفضّل VulnFanatic-NG الاسترجاع (اكتشاف المشكلات الحقيقية). إذا حصلت على عدد كبير جدًا من النتائج الإيجابية الخاطئة، فشدّد باستخدام أيٍّ من:
vulnfanatic.validationPass (افتراضيًا معطّل) — يشغّل تمريرة LLM ثانية
تتحقق مرة أخرى من كل مشكلة تم الإبلاغ عنها مقابل نفس السياق (التحقق من
مقتطفات المسودة وإعادة تتبع التدفق) ويمكنها تصحيح الحكم أو
الثقة. يضاعف استدعاءات LLM للمرشحين المبلَّغ عنهم.
vulnfanatic.validatorModel (بالإضافة إلى validatorProvider / validatorBaseUrl /
validatorApiKey) لتشغيل التمريرة الثانية على نموذج مختلف. الرأي الثاني
أكثر فائدة بكثير من نموذج مستقل — فهو يشارك نقاطًا عمياء أقل
ومن غير المرجح كثيرًا أن يصدّق الحكم الأول تلقائيًا (تميل النماذج إلى
تفضيل إجاباتها الخاصة). النمط الجيد هو تسلسل متتالٍ: نموذج سريع بصفته
المحلل (استرجاع واسع) وأقوى نموذج لديك بصفته المدقّق، الذي يعمل فقط
على المرشحين المبلَّغ عنهم. اترك نموذج المدقّق فارغًا للتحقق باستخدام
نموذج المحلل. يجب أن يكون المدقّق بقدرة المحلل على الأقل — فالنموذج
الأضعف يضيف في الغالب رفضًا خاطئًا. كل شيء ما عدا المزوّد/عنوان URL الأساسي/المفتاح/
النموذج موروث من إعدادات اتصال المحلل؛ والمفتاح الفارغ للمدقّق
يعيد استخدام مفتاح المحلل؛ وإذا كانت نقطة نهاية المدقّق غير قابلة للوصول، يُحتفظ بالحكم
الأول (لا تُفقد النتيجة أبدًا بسبب انقطاع المدقّق).vulnfanatic.minConfidence (افتراضيًا low) — ارفعه إلى medium/high للإبلاغ
فقط عن النتائج الأقوى.vulnfanatic.skipConstantArgCalls (افتراضيًا معطّل) — يتخطى مواقع استدعاءات
فئة التجاوز التي تكون جميع وسائطها ثوابت وقت الترجمة.السرعة. معظم زمن الانتظار لكل استدعاء هو الاستدلال المكتوب، لذا
يتحكم vulnfanatic.verdictReasoning في مقدار ما يكتبه النموذج:
concise (افتراضيًا) — مبرر موجز من 1–3 جمل، دون اقتباس كود. أسرع
بكثير من full مع خسارة قليلة في الدقة؛ يمكنك أيضًا خفض
vulnfanatic.maxResponseTokens.full — المسودة المفصلة مع المقتطفات المقتبسة (الأكثر قابلية للتدقيق، والأبطأ).none — الحكم فقط. الأسرع؛ اقرنه بنهاية خلفية تدعم الاستدلال
(vulnfanatic.reasoningEffort) حتى يقوم تفكير النموذج الداخلي بالعمل.
على نموذج محلي عادي، يفقد none الدقة (لا يوجد سلسلة أفكار على الإطلاق).ميزات دعم الدقة التي تعمل دائمًا (تُعلم النموذج دون إخفاء النتائج):