> ## Content Index
> Fetch the complete content index at: https://arabroot.io/llms.txt
> Use this file to discover other available public pages before exploring further.

# قواعد الكشف Detection Rules بلغة Sigma: من السلوك إلى تنبيه
- URL: https://arabroot.io/articles/قواعد-الكشف-detection-rules-بلغة-sigma-من-السلوك-الى-تنبيه/
- Published: 2026-10-28T10:48:54.000Z
- Updated: 2026-10-28T11:49:03.000Z
- Description: ولدنا حركة اعتداء حقيقية الشكل، وحولنا قواعد SigmaHQ وقواعد كتبناها إلى SQL بمكتبة pySigma، فرأينا ما أصابت وما فاتها قاعدة بفلتر 404.
- Author: فريق عرب رووت
- Tags: الأدلة التقنية, الأمن السيبراني, Docker والحاويات, لينكس والسيرفرات, Sigma

وصلت السجلات إلى مكان واحد كما بنينا في المقال السابق، وأمامك الآن ملف فيه آلاف الأسطر في اليوم: من دخل، وأي صفحة طلب، وبأي ترويسة. وتعرف أن في هذا الكم محاولات حقيقية لاختراق متجرك، ولكنك لا تستطيع أن تقرأ كل سطر، فالسؤال العملي: كيف تحول هذا الكم إلى عدد صغير من التنبيهات تستحق أن يقرأها إنسان؟ الإجابة هي قاعدة الكشف Detection Rule، أي منطق مكتوب يقول «إذا ظهر هذا النمط في السجل فأطلق تنبيهاً».

ولكن هنا مشكلتان. الأولى أن كل أداة تكتب قواعدها بلغتها: Wazuh بصيغة XML، وElasticsearch باستعلامه، وsplunk بلغته، فالقاعدة التي تكتبها لأداة لا تعمل في غيرها، وتبدأ من الصفر كلما غيرت الأداة. والثانية أن القاعدة قد تبدو صحيحة وهي لا تطلق على شيء، أو تطلق على كل شيء، ولا تعرف ذلك حتى تشغلها على سجلات حقيقية. ولغة Sigma تحل الأولى: قاعدة واحدة بصيغة قياسية يترجمها محول Backend إلى لغة أي أداة. والحل للثانية هو هذا المقال: نكتب قواعد، ونحولها، ونشغلها على سجلات مختبر ولدناها بأنفسنا، ونعد ما أصابت وما فاتت.

وقد شرحنا في [مقال السجلات الأمنية](https://arabroot.io/articles/%D8%A7%D9%84%D8%B3%D8%AC%D9%84%D8%A7%D8%AA-%D8%A7%D9%84%D8%A7%D9%85%D9%86%D9%8A%D8%A9-logs-%D9%85%D8%A7%D8%B0%D8%A7-%D8%AA%D8%AC%D9%85%D8%B9-%D9%88%D9%85%D9%86-%D8%A7%D9%8A%D9%86-%D9%82%D8%A8%D9%84-soc/) كيف تجمع السجلات وتوحدها، وفي [محرك كشف SIEM من الداخل](https://arabroot.io/articles/%D9%83%D9%8A%D9%81-%D9%8A%D8%B9%D9%85%D9%84-%D9%85%D8%AD%D8%B1%D9%83-%D9%83%D8%B4%D9%81-siem-%D9%85%D9%86-%D8%A7%D9%84%D8%AF%D8%A7%D8%AE%D9%84/) كيف يطبق المحرك القواعد ويجمع الأحداث. وهذا المقال عن القاعدة نفسها: كيف تكتب، وكيف تختبر، ومتى تخدعك.

[![](https://arabroot.io/content/images/2026/10/security-logging-cover-cover.webp)دليلالسجلات الأمنية Logs: ماذا تجمع ومن أين قبل أن تبني SOCجمعنا سجلات nginx وتطبيق صغير وSSH بأداة Vector، فرأينا كيف يقلب وقت بلا منطقة زمنية ترتيب الحادثة، وكيف ينجو السجل المركزي من المسح.](https://arabroot.io/articles/%D8%A7%D9%84%D8%B3%D8%AC%D9%84%D8%A7%D8%AA-%D8%A7%D9%84%D8%A7%D9%85%D9%86%D9%8A%D8%A9-logs-%D9%85%D8%A7%D8%B0%D8%A7-%D8%AA%D8%AC%D9%85%D8%B9-%D9%88%D9%85%D9%86-%D8%A7%D9%8A%D9%86-%D9%82%D8%A8%D9%84-soc/)[![](https://arabroot.io/content/images/2026/10/build-siem-cover-cover.webp)دليلكيف يعمل محرك كشف SIEM من الداخل؟كيف يجمع SIEM ملايين السجلات ويوحدها ويطبق قواعد الكشف، مع خط أنابيب Vector وLoki وقاعدة Sigma تطلق فعلاً.](https://arabroot.io/articles/%D9%83%D9%8A%D9%81-%D9%8A%D8%B9%D9%85%D9%84-%D9%85%D8%AD%D8%B1%D9%83-%D9%83%D8%B4%D9%81-siem-%D9%85%D9%86-%D8%A7%D9%84%D8%AF%D8%A7%D8%AE%D9%84/)[![](https://arabroot.io/content/images/2026/10/suricata-zeek-cover-cover.webp)دليلمراقبة الشبكة واكتشاف التسلل IDS مع Suricata وZeekمختبر حقيقي يقرأ الحركة نفسها بأداتين، فيكشف Suricata الهجمات المعروفة ويكتب Zeek سجلاً لكل اتصال، مع الضبط وفقد الحزم.](https://arabroot.io/articles/%D8%A7%D9%83%D8%AA%D8%B4%D8%A7%D9%81-%D8%A7%D9%84%D8%AA%D8%B3%D9%84%D9%84-%D9%81%D9%8A-%D8%A7%D9%84%D8%B4%D8%A8%D9%83%D8%A9-ids-%D9%85%D8%B9-suricata-%D9%88-zeek/)

وسوف نناقش في هذا المقال ما يلي:

- من أين جاءت فكرة قاعدة الكشف، ولماذا احتاج المدافعون لغة محايدة.
- ثلاث طرق تقرر بها القاعدة: التوقيع Signature والسلوك Behavior والشذوذ Anomaly.
- ما هي Sigma، ولماذا قاعدة واحدة بصيغة قياسية أفضل من قاعدة لكل أداة.
- تشريح قاعدة Sigma: المصدر والكشف والشرط والتصنيف، وكيف تربط خطوط المعالجة Pipelines أسماء حقولها بنظامك.
- تجربة عملية: مختبر يولد حركة اعتداء حقيقية الشكل، ونحول قواعد SigmaHQ وقواعد نكتبها إلى SQL، ونشغلها.
- الفلتر الذي يفوت: كيف أفلت طلب حقن من قاعدة لأنه رد 404، وما الدرس.
- قواعد الترابط Correlation: عد الأحداث في نافذة زمنية، وكيف تحولها Sigma إلى استعلام.
- من القاعدة إلى الإنتاج: الاختبار والضبط ودورة حياة القاعدة، وأخطاء شائعة.

## ثلاث طرق تقرر بها القاعدة

قبل أي أداة، القاعدة في جوهرها واحدة من ثلاث طرق للقرار، والصورة التالية تجمعها:

![ثلاث لوحات: التوقيع Signature يطابق نصاً معروفاً مثل ترويسة أداة فحص أو نمط حقن وهو دقيق ولا يرى الجديد، والسلوك Behavior يطابق تتابعاً من الأحداث مثل عدة محاولات فاشلة ثم نجاح ويرى أساليب لا توقيع لها، والشذوذ Anomaly يطابق ما يخرج عن المعتاد مثل حساب يرسل في ساعة ما يرسله في شهر ويحتاج خط أساس وتكثر إنذاراته](https://arabroot.io/content/images/2026/10/detection-rules-01-types.webp)

أغلب قواعد اليوم توقيع وسلوك، لأنها مكتوبة ومفهومة ويمكن اختبارها

- **التوقيع Signature:** تطابق نصاً معروفاً. ترويسة `sqlmap/` في طلب، أو نمط `UNION SELECT` في رابط، أو رسالة خطأ معينة من ثغرة. دقيقة وسريعة، وعيبها أنها لا ترى إلا ما كتب لها توقيع، فالمهاجم الذي يغير ترويسته يفلت.
- **السلوك Behavior:** تطابق تتابعاً أو تجمعاً من الأحداث. عشر محاولات دخول فاشلة من عنوان واحد، أو ملف تنفيذي جديد في مجلد الموقع، أو طلب يصل إلى مسار إداري غير موجود عدة مرات. ترى أساليب لا توقيع لها، لأنها تطابق ما يفعله المهاجم لا الأداة التي يستخدمها.
- **الشذوذ Anomaly:** تطابق ما يخرج عن المعتاد. حساب يرسل في ساعة ما يرسله في شهر، أو سيرفر يتصل بعنوان لم يتصل به من قبل. أقوى الأنواع نظرياً، وأكثرها إنذارات خاطئة عملياً، لأنها تحتاج خط أساس Baseline دقيقاً لما هو «معتاد»، وأي تغير طبيعي في العمل يبدو لها شذوذاً.

وقواعد اليوم أغلبها من النوعين الأولين، لأنها مكتوبة بوضوح، ويمكن أن يقرأها إنسان ويفهم لماذا أطلقت، والأهم أنه يمكن اختبارها كما سنفعل. أما الشذوذ فمكانه بعد أن يكون لديك خط أساس حقيقي، لا قبله.

## من أين جاءت فكرة قاعدة الكشف؟

فكرة أن برنامجاً يقرأ السجلات ويبحث فيها عن علامات الهجوم قديمة قدم أنظمة كشف التسلل IDS. ففي أواخر الثمانينيات ظهرت أولى الأدوات التي تراقب سجلات التدقيق بحثاً عن أنماط مشبوهة، ثم جاءت أدوات الشبكة التي تفحص الحزم المارة بحثاً عن توقيعات هجمات معروفة، مثل Snort في 1998 الذي ما زال سليله Suricata يعمل بنفس الفكرة كما في [مقال Suricata وZeek](https://arabroot.io/articles/%D8%A7%D9%83%D8%AA%D8%B4%D8%A7%D9%81-%D8%A7%D9%84%D8%AA%D8%B3%D9%84%D9%84-%D9%81%D9%8A-%D8%A7%D9%84%D8%B4%D8%A8%D9%83%D8%A9-ids-%D9%85%D8%B9-suricata-%D9%88-zeek/). وفي كل هذه الأدوات كان جوهر العمل واحداً: قاعدة تصف ما تبحث عنه، ومحرك يطبقها على تدفق من البيانات.

وبقيت كل أداة تكتب قواعدها بلغتها الخاصة عقوداً، فقاعدة Snort لا تعمل في Wazuh، وقاعدة Splunk لا تعمل في Elasticsearch. وهذا كان مقبولاً عندما كانت المؤسسة تشتري أداة واحدة وتبقى عليها سنوات. ولكن مع انتشار الأدوات مفتوحة المصدر، وتغير المؤسسات بينها، ومع أن الباحث الذي يكتشف هجوماً جديداً يريد أن يصل كشفه إلى أكبر عدد من المدافعين بأسرع وقت، ظهرت الحاجة إلى لغة محايدة. ومن هنا جاء مشروع Sigma المفتوح في 2017 بالفكرة نفسها التي قدمتها [MITRE ATT&CK](https://arabroot.io/articles/mitre-attack-%D9%83%D9%8A%D9%81-%D9%8A%D9%81%D9%83%D8%B1-%D8%A7%D9%84%D9%85%D9%87%D8%A7%D8%AC%D9%85-%D8%AE%D8%B7%D9%88%D8%A9-%D8%A8%D8%AE%D8%B7%D9%88%D8%A9/) للأساليب: لغة مشتركة يتفاهم بها المدافعون عبر الأدوات والمؤسسات.

وهذا التاريخ يفسر لماذا تبدو قواعد Sigma أحياناً مجردة: هي لا تريد أن تعرف أداتك، وإنما أن تصف الهجوم بطريقة تصلح لكل أداة. والثمن أنها تحتاج خط معالجة يربطها بنظامك، والمكسب أن نفس الوصف يخدم الجميع.

وبين هذه الطرق الثلاث حدود غير حادة في الواقع. فقاعدة «عشر محاولات فاشلة ثم نجاح» سلوك، ولكنها تطابق كل محاولة فاشلة بتوقيع. وقاعدة الشذوذ تحتاج أن تعرف المعتاد، والمعتاد يأتي من خط أساس بنيته أنت، فهي في جوهرها سلوك مقاس على تاريخك. والمهم ليس تصنيف القاعدة، وإنما أن تعرف على أي أساس تقرر، لأن ذلك يحدد ما تفوته: قاعدة التوقيع تفوت كل جديد، وقاعدة السلوك تفوت المهاجم الذي يبقى تحت العتبة، وقاعدة الشذوذ تفوت ما يشبه المعتاد. ومن يعرف ما تفوته قاعدته يعرف أين يحتاج قاعدة أخرى تكملها، وهذا هو التفكير بالتغطية لا بالقواعد.

## ما هي Sigma؟ قاعدة واحدة لكل الأدوات

المشكلة التي حلتها [Sigma](https://sigmahq.io/?ref=arabroot.io) بسيطة في وصفها: لكل أداة SIEM لغة قواعد خاصة، فإذا كتب باحث أمني قاعدة لكشف أسلوب هجوم جديد، فعليه أن يكتبها بلغة Splunk، ثم بلغة Elasticsearch، ثم لـ Wazuh، وإذا غيرت شركتك أداتها بدأت من الصفر. وSigma صيغة وصف Description Format محايدة بصيغة YAML: تصف ماذا تبحث عنه وفي أي سجل، دون أن تلتزم بأداة، ثم يترجمها محول Backend إلى لغة كل أداة. أي أنها للقواعد ما كانت Docker للتشغيل: اكتب مرة، وشغل في أي مكان.

ومستودع [SigmaHQ](https://github.com/SigmaHQ/sigma?ref=arabroot.io) يحتوي على آلاف القواعد الجاهزة التي كتبها باحثون من كل العالم، منظمة بحسب نوع السجل: قواعد Windows، وLinux، والويب، والسحابة. وهذه القيمة الحقيقية: عندما يظهر أسلوب هجوم جديد، ينشر من اكتشفه قاعدة Sigma له في أيام، فتأخذها أنت وتشغلها على أداتك دون أن تعرف لغتها الداخلية. وSigma مواصفة مفتوحة [موثقة](https://github.com/SigmaHQ/sigma-specification?ref=arabroot.io)، والقواعد والمكتبات تحت رخص مفتوحة.

### لماذا لا نكتب في الأداة مباشرة؟

قد يتساءل البعض: إذا كانت أداتي تقبل قواعد، فلماذا أكتب بصيغة وسيطة ثم أترجمها، بدل أن أكتب بلغة الأداة مباشرة؟ والإجابة في ثلاثة أسباب. الأول أنك لا تكتب قاعدة واحدة، وإنما تبني مكتبة من مئات القواعد عبر سنوات، وهذه المكتبة أثمن من أي أداة، فإذا ربطتها بلغة أداة واحدة خسرتها يوم تغير الأداة. والثاني أن المجتمع يكتب قواعده بـ Sigma، فإذا كتبت بلغة أداتك انقطعت عن آلاف القواعد الجاهزة، وعن كل قاعدة جديدة تنشر عند ظهور هجوم. والثالث أن الصيغة الوسيطة تجبرك على فصل المنطق عن تفاصيل الأداة، فتصبح القاعدة أوضح وأسهل مراجعة، كما رأينا في تشريحها.

ولمحول Sigma أكثر من هدف: فبجانب محول SQLite الذي استخدمناه، توجد محولات لـ Elasticsearch وSplunk وMicrosoft Sentinel وغيرها، وكلها تأخذ نفس القاعدة وتخرج استعلام أداتها. وهذا يعني أنك تستطيع أن تجرب قاعدة على مختبر SQLite صغير كما فعلنا، ثم تنشرها على أداتك في الإنتاج بنفس الملف وخط معالجة مختلف. والمحول الذي اخترناه ليس اعتباطاً: هو نفسه المحرك خلف أداة Zircolite التي تشغل قواعد Sigma على سجلات مسطحة دون أي بنية تحتية، وهي طريقة شائعة لفحص سجلات جهاز واحد في التحقيق الرقمي.

## تشريح قاعدة Sigma

قاعدة Sigma ملف YAML من أربعة أجزاء، والصورة التالية تبينها:

![أربع لوحات مع مثال: المصدر logsource يحدد أين تبحث بفئة مثل webserver أو منتج مثل linux sshd وتترجمها خطوط المعالجة إلى حقول نظامك، والكشف detection باختيارات selection بأسماء حقول وقيم وفلاتر filter، والشرط condition مثل selection and not filter، والوصف والتصنيف بالعنوان والمستوى level وأسلوب ATT&CK والإنذارات الخاطئة المتوقعة](https://arabroot.io/content/images/2026/10/detection-rules-02-anatomy.webp)

القاعدة واحدة، ومحول Backend يترجمها إلى استعلام كل أداة

- **المصدر logsource:** أين تبحث؟ بفئة Category مثل `webserver` أو `process_creation`، أو بمنتج Product مثل `linux` وخدمة `sshd`. وهذا الجزء لا يذكر أسماء حقول نظامك، وإنما فئة عامة، وخط المعالجة هو الذي يترجمها.
- **الكشف detection:** ماذا تبحث عنه؟ مجموعة اختيارات Selections، كل اختيار أسماء حقول وقيم، ومعها فلاتر Filters لإخراج الحالات المعروفة.
- **الشرط condition:** كيف تجمع الاختيارات؟ مثل `selection and not filter_main`، أي طابق هذا واستثن ذاك.
- **الوصف والتصنيف:** العنوان، والمستوى `level` من منخفض إلى حرج، وأسلوب [ATT&CK](https://arabroot.io/articles/mitre-attack-%D9%83%D9%8A%D9%81-%D9%8A%D9%81%D9%83%D8%B1-%D8%A7%D9%84%D9%85%D9%87%D8%A7%D8%AC%D9%85-%D8%AE%D8%B7%D9%88%D8%A9-%D8%A8%D8%AE%D8%B7%D9%88%D8%A9/)، والإنذارات الخاطئة المتوقعة `falsepositives`. وهذا الجزء ليس للأداة، وإنما للمحلل الذي سيقرأ القاعدة بعدك.

## خطوط المعالجة Pipelines: الجسر بين القاعدة ونظامك

الجزء الأذكى في Sigma هو فصل «ماذا نبحث عنه» عن «أين يقع في سجلي». فقاعدة SigmaHQ تقول `cs-user-agent|contains: 'sqlmap/'` باسم حقل قياسي، ونظامك قد يسمي ترويسة المتصفح `ua` أو `http.user_agent` أو `agent`. وخط المعالجة Pipeline هو ما يربط بينهما: يأخذ اسم الحقل في القاعدة ويحوله إلى اسم العمود في نظامك، وقد يضيف شروطاً، مثل أن فئة `process_creation` على Windows تعني رقم الحدث 1 في Sysmon.

ولنفهم لماذا فصل القاعدة عن الأداة بهذا الذكاء، تخيل ماذا لو لم يوجد. القاعدة التي تكشف ترويسة `sqlmap` تحتاج أن تعرف أن حقل الترويسة في سجل nginx اسمه كذا، وفي سجل Apache اسم آخر، وفي سحابة ما حقل متداخل، وفي Wazuh بعد التطبيع اسم ثالث. فلو كتبت اسم الحقل في القاعدة نفسها، لاحتجت نسخة من القاعدة لكل نظام، وعدنا إلى المشكلة التي هربنا منها. أما مع خط المعالجة، فالقاعدة تقول `cs-user-agent`، وخط معالجة nginx يحوله إلى عمودنا، وخط معالجة Apache يحوله إلى عموده، والقاعدة لا تتغير. وهذا هو معنى أن يكون المنطق في مكان والتفاصيل في مكان آخر.

وهذا يعني أن نفس القاعدة تعمل على أدوات مختلفة بخط معالجة مختلف لكل منها، دون أن تلمس القاعدة. وفي المختبر سنكتب خط معالجة صغيراً يربط حقول فئة `webserver` بأعمدة جدولنا، وهو ما سيجعل قواعد SigmaHQ الجاهزة تعمل على سجلات nginx عندنا دون تعديل.

## تجربة عملية: من قاعدة إلى إصابة

الآن نبني كل ما سبق. المختبر فيه متجر صغير: nginx أمام تطبيق Python، وسيرفر SSH. نولد عليه حركة من نوعين: تصفح عادي كثير، وطلبات شكلها اعتداء حقيقي، وترويسات أدوات فحص. ثم نحمل سجل nginx في قاعدة SQLite، ونحول قواعد Sigma إلى استعلامات بمكتبة [pySigma](https://github.com/SigmaHQ/pySigma?ref=arabroot.io) ومحول [SQLite](https://github.com/SigmaHQ/pySigma-backend-sqlite?ref=arabroot.io)، ونشغلها ونعد الإصابات. والصورة التالية تبين الطريق:

![أربع لوحات من اليمين: قاعدة Sigma من مستودع SigmaHQ أو نكتبها بصيغة YAML، ثم pySigma مع Pipeline تحول القاعدة وتربط أسماء حقول Sigma بأعمدة جدولنا، ثم استعلام SQL جملة SELECT واحدة لكل قاعدة، ثم تشغيل على السجلات في قاعدة SQLite فيها 138 حدثاً فأطلقت 6 قواعد](https://arabroot.io/content/images/2026/10/detection-rules-03-pipeline.webp)

نفس القاعدة التي يشاركها مركز على GitHub تعمل على سجلاتنا، لأن التوحيد في خط المعالجة لا في القاعدة

⚠️

كل حركة الاعتداء في هذا المختبر تذهب إلى Containers المختبر نفسها داخل شبكة Docker خاصة، ولا تخرج إلى الإنترنت ولا إلى شبكة الجهاز. والأنماط التي نرسلها، مثل `UNION SELECT` أو ترويسة `sqlmap`، هي نصوص في الرابط تولد سطر سجل، لا استغلال لثغرة، والهدف أن نختبر قواعد الكشف لا أن نخترق شيئاً. اختبر قواعدك على مختبرك أنت، بإذن مكتوب ونطاق واضح، لا على أي نظام لا تملكه.

### توليد الحركة

مولد الحركة يرسل مئة وعشرين طلباً عادياً أولاً، ليكون للمختبر خلفية طبيعية كأي موقع، ثم طلبات الاعتداء. وأنماط الاعتداء ليست من خيالنا، وإنما منسوخة من أمثلة قواعد SigmaHQ نفسها، في صورتها المرمزة Encoded كما يرسلها متصفح. ونرسلها بمقبس Socket خام حتى يصل إلى السجل نفس النص بالضبط:

```python
"""Sends lab web traffic through nginx: a lot of normal browsing, then requests shaped like real
   attacks (the payloads come straight from the SigmaHQ rule examples, in their URL-encoded form)
   and scanner User-Agents. Everything targets the lab's own nginx container; nothing leaves the Docker network."""
import socket, random, time

def send(line, ua="Mozilla/5.0 (Windows NT 10.0; Win64; x64)"):
    # raw request so the access log carries the exact bytes a scanner would send
    s = socket.create_connection(("scu-det-web", 80), timeout=5)
    s.sendall(f"GET {line} HTTP/1.1\r\nHost: shop.example.com\r\nUser-Agent: {ua}\r\nConnection: close\r\n\r\n".encode())
    s.recv(64); s.close()

pages = ["/", "/products", "/products?id=12", "/cart", "/search?q=shoes", "/login"]
for _ in range(120):
    send(random.choice(pages)); time.sleep(0.002)
send("/order?item=7&price=50")                    # a normal order
for p in ["/order?item=7&price=-100", "/order?item=7&price=0"]: send(p)   # price tampering

sqli = ["/products?id=1%20UNION%20SELECT%20username,password", "/products?id=1%27%20or%201=1#",
        "/search?q=order%20by%2010", "/products?id=-1%20UNION%20ALL%20SELECT%201,2,3",
        "/items?id=select%20version()"]
for p in sqli: send(p)

traversal = ["/download?file=../../../etc/passwd", "/static?p=..%252f..%252f..%252fetc%252fpasswd",
             "/view?f=../../../../windows/win.ini"]
for p in traversal: send(p)

for p in ["/.git/config", "/.git/HEAD"]: send(p)

scanners = {"sqlmap/1.8#stable (https://sqlmap.org)": "/products?id=1", "Nikto/2.5.0": "/scan",
            "Nmap Scripting Engine; https://nmap.org/book/nse.html": "/", "gobuster/3.6": "/admin",
            "feroxbuster/2.10.4": "/backup"}
for ua, p in scanners.items(): send(p, ua=ua)
print("done")
```

ولماذا نرسل الطلب بمقبس Socket خام بدل مكتبة HTTP عادية؟ لأن مكتبات HTTP ترفض أن ترسل رابطاً فيه مسافة أو حرف غريب، فتصلح الطلب قبل إرساله، بينما المهاجم وأداته يرسلان البايتات كما هي، ونحن نريد أن يصل إلى السجل نفس ما يصل في هجوم حقيقي. فالمقبس الخام يعطينا تحكماً كاملاً في سطر الطلب، فنرسل نفس النص الذي تختبره القاعدة. وهذا تفصيل صغير له أثر كبير في اختبار الكشف: لو أرسلنا الطلب بمكتبة تصلحه، لاختبرنا قاعدة على نص مختلف عما يراه السجل في الواقع، فنظن أنها تعمل وهي لا تعمل على الهجوم الحقيقي.

فيصل إلى سجل nginx خمسة طلبات تحمل أنماط حقن SQL، وثلاثة تحمل اجتياز مسار، وطلبان لمجلد `.git`، وطلبات بترويسات `sqlmap` و`Nikto` و`Nmap` و`gobuster` و`feroxbuster`، وطلبان يعبثان بحقل السعر. وأضفنا محاولات دخول SSH فاشلة لنختبر عليها قاعدة أخرى.

### تحميل السجل في SQLite

لماذا SQLite ولماذا الحقول بهذه الأسماء؟ لأن محول SQLite هو نفسه المحرك خلف أداة [Zircolite](https://github.com/wagga40/Zircolite?ref=arabroot.io) التي تشغل قواعد Sigma على سجلات مسطحة، ولأن قواعد SigmaHQ لفئة `webserver` تستخدم أسماء حقول قياسية مثل `cs-uri-query` و`cs-method` و`sc-status`. فنحمل كل سطر JSON من nginx في جدول أعمدته بهذه الأسماء، مع عمود نص للبحث الكامل، ونفصل مسار الطلب عن استعلامه:

```python
"""Flattens the lab's nginx JSON access log into a SQLite table whose columns are the field names
   the SigmaHQ webserver rules expect (cs-method, cs-uri-stem, cs-uri-query, cs-user-agent, sc-status, c-ip).
   One row per request; the raw line is kept for reference."""
import json, sqlite3, sys
from urllib.parse import urlsplit

db = sqlite3.connect(sys.argv[2])
db.execute("""CREATE TABLE logs ("c-ip" TEXT, "cs-method" TEXT, "cs-uri-stem" TEXT, "cs-uri-query" TEXT,
    "cs-user-agent" TEXT, "sc-status" INTEGER, "fulltext" TEXT, ts TEXT, raw TEXT)""")
n = 0
for line in open(sys.argv[1], encoding="utf-8"):
    line = line.strip()
    if not line.startswith("{"):
        continue
    try:
        p = json.loads(line)
    except json.JSONDecodeError:
        continue
    u = urlsplit(p["uri"])
    ft = f'{p["method"]} {p["uri"]} {p["ua"]}'                  # one column the keyword rules search
    db.execute("INSERT INTO logs VALUES (?,?,?,?,?,?,?,?,?)",
               (p["src_ip"], p["method"], u.path, u.query, p["ua"], int(p["status"]), ft, p["ts"], line))
    n += 1
db.commit()
print(f"loaded {n} rows into {sys.argv[2]}")
```

ولماذا نسطح السجل في جدول SQLite أصلاً، بدل أن نبحث في الملف مباشرة؟ لأن القاعدة ليست بحثاً عن نص، وإنما منطق على حقول: «اسم المستخدم كذا، ورمز الحالة ليس 404، والطريقة GET». وهذا المنطق يحتاج أن تكون الحقول مفصولة ومسماة، لا مدمجة في سطر نصي. فالتسطيح Flattening هو ما يحول السطر الخام إلى صف بأعمدة، والعمود هو ما تكتب عليه القاعدة شرطها. وهذه نفس الخطوة التي يفعلها أي محرك SIEM داخلياً عند الاستقبال، كما شرحنا في [محرك كشف SIEM من الداخل](https://arabroot.io/articles/%D9%83%D9%8A%D9%81-%D9%8A%D8%B9%D9%85%D9%84-%D9%85%D8%AD%D8%B1%D9%83-%D9%83%D8%B4%D9%81-siem-%D9%85%D9%86-%D8%A7%D9%84%D8%AF%D8%A7%D8%AE%D9%84/)، ونحن هنا نفعلها بأبسط صورة لنرى ما يحدث.

### تحويل القواعد وتشغيلها

السكربت يحمل القواعد، ويطبق خط معالجة يربط حقول `webserver` بأعمدتنا، ويحولها إلى SQL، ويشغل كل استعلام على القاعدة، ويعد الإصابات. ونسجل دالة `REGEXP` في SQLite لأن بعض القواعد تستخدم التعبير النمطي، وهو غير مدمج في SQLite:

```python
"""Converts Sigma rules to SQLite queries with pySigma and runs each against the lab database.
   A field-mapping pipeline turns the webserver-category field names into the table's columns,
   so the same rule a SOC shares on GitHub runs unchanged against our own logs."""
import sys, glob, sqlite3
from sigma.collection import SigmaCollection
from sigma.backends.sqlite import sqliteBackend
from sigma.processing.pipeline import ProcessingPipeline, ProcessingItem
from sigma.processing.transformations import FieldMappingTransformation
from sigma.processing.conditions import LogsourceCondition

# webserver category: Sigma's common field names -> our flattened column names
web_map = FieldMappingTransformation({
    "c-ip": "c-ip", "cs-method": "cs-method", "cs-uri-stem": "cs-uri-stem",
    "cs-uri-query": "cs-uri-query", "cs-user-agent": "cs-user-agent", "sc-status": "sc-status",
    "cs-uri": "cs-uri-query"})     # a few rules use cs-uri; point it at the query we stored
pipeline = ProcessingPipeline([ProcessingItem(web_map, rule_conditions=[LogsourceCondition(category="webserver")])])
backend = sqliteBackend(processing_pipeline=pipeline, fulltext_field="fulltext")

import re as _re
db = sqlite3.connect(sys.argv[1])
db.create_function("REGEXP", 2, lambda p, s: 1 if s is not None and _re.search(p, s) else 0)   # Sigma `re` modifier -> SQLite REGEXP
db.row_factory = sqlite3.Row
total_events = db.execute("SELECT count(*) FROM logs").fetchone()[0]
print(f"database: {total_events} events\n")
print(f"{'rule':52} {'level':7} {'hits':>5}  sample")
hits_any = 0
for path in sorted(glob.glob(sys.argv[2] + "/**/*.yml", recursive=True)):
    coll = SigmaCollection.load_ruleset([path])
    for rule in coll.rules:
        if rule.logsource.category != "webserver":
            continue                               # ssh rules are handled by a keyword grep, not SQL
        try:
            sql = backend.convert_rule(rule)[0]
        except Exception as e:
            print(f"{rule.title[:52]:52} {'-':7}  convert error: {str(e)[:40]}")
            continue
        rows = db.execute(sql).fetchall()
        hits_any += 1 if rows else 0
        sample = (rows[0]["cs-uri-stem"] + ("?" + rows[0]["cs-uri-query"] if rows[0]["cs-uri-query"] else ""))[:40] if rows else ""
        print(f"{rule.title[:52]:52} {str(rule.level)[:7]:7} {len(rows):5}  {sample}")
print(f"\nrules that fired: {hits_any}")
```

وشغلناه على خمس قواعد من SigmaHQ وقاعدتين كتبناهما، فكان المخرج:

```text
database: 138 events

rule                                                 level    hits  sample
Access to Sensitive Admin and Backup Paths           medium      2  /admin
Negative or Zero Price in Shop Order Request         medium      2  /order?item=7&price=-100
Path Traversal Exploitation Attempts                 medium      3  /download?file=../../../etc/passwd
Source Code Enumeration Detection by Keyword         medium      2  /.git/config
SQL Injection Strings In URI                         high        4  /products?id=1%20UNION%20SELECT%20userna
Suspicious User-Agents Related To Recon Tools        medium      5  /products?id=1

rules that fired: 6
```

![ست أعمدة أفقية لعدد الإصابات: ترويسات أدوات الفحص من SigmaHQ 5 إصابات، وحقن SQL في الرابط من SigmaHQ 4 إصابات بمستوى high، ومحاولات اجتياز المسار من SigmaHQ 3 إصابات، ومسارات إدارة وغير موجودة من قاعدتنا إصابتان، وتعداد الكود المصدري git من SigmaHQ إصابتان، وسعر سالب أو صفر في الطلب من قاعدتنا إصابتان](https://arabroot.io/content/images/2026/10/detection-rules-04-results.webp)

أربع قواعد من SigmaHQ عملت على سجلاتنا دون تعديل، وقاعدتان كتبناهما لمنطق متجرنا

في المخرج أعلاه لاحظ التالي:

- قاعدة ترويسات أدوات الفحص أصابت خمساً، وهي أبسط قاعدة توقيع: تطابق قائمة ترويسات معروفة. وهذا هو الاستعلام الذي ولدته pySigma منها:

```sql
SELECT * FROM logs WHERE `cs-user-agent` LIKE '%commix/%' ESCAPE '\' OR `cs-user-agent` LIKE '%feroxbuster/%' ESCAPE '\' OR `cs-user-agent` LIKE '%Fuzz Faster U Fool%' ESCAPE '\' OR `cs-user-agent` LIKE '%GIS - AppSec Team - Project Vision%' ESCAPE '\' OR `cs-user-agent` LIKE '%gobuster/%' ESCAPE '\' OR `cs-user-agent` LIKE '%Nikto/%' ESCAPE '\' OR `cs-user-agent` LIKE '%Nmap Scripting Engine%' ESCAPE '\' OR `cs-user-agent` LIKE '%Recon-ng/v%' ESCAPE '\' OR `cs-user-agent` LIKE '%sqlmap/%' ESCAPE '\' OR `cs-user-agent` LIKE '%WhatWeb/%' ESCAPE '\' OR `cs-user-agent` LIKE '%Wfuzz/%' ESCAPE '\' OR `cs-user-agent` LIKE '%WPScan v%' ESCAPE '\' OR `cs-user-agent` LIKE '%zgrab/%' ESCAPE '\'
```

وهذا الاستعلام يكشف تفصيلاً مهماً: كل قيمة صارت `LIKE '%value%'` مع `ESCAPE '\'`، وهذا يعني بحثاً عن النص في أي موضع من الحقل، وهو مريح ولكنه بطيء على الجداول الكبيرة لأنه لا يستطيع استخدام فهرس Index. وهنا يظهر فرق بين المختبر والإنتاج: على مئة وثمانية وثلاثين حدثاً لا فرق، وعلى مليارات الأحداث اليومية في مركز حقيقي يصبح شكل الاستعلام مسألة تكلفة، ولهذا تضيف المحركات الكبيرة فهارس نصية خاصة وتعيد كتابة هذه الاستعلامات. والدرس أن القاعدة نفسها لها ثمن تشغيل يختلف بحسب الأداة، وأن قاعدة تبحث عن نص في أي موضع أغلى من قاعدة تطابق بداية حقل أو قيمة دقيقة.

- كل اختيار صار `LIKE '%value%'`، والفلتر صار `NOT`، والشرط ربط بينها. وهذا استعلام يستطيع أي مطور أن يقرأه ويتحقق منه، وهذه فائدة ثانية لـ Sigma: المنطق مكشوف لا مخفي في الأداة.
- قاعدة حقن SQL أصابت أربعاً وهي بمستوى `high`، وهنا قصة تستحق قسماً خاصاً.

وقبل أن نمضي، لاحظ ما فعله المختبر من مصادر مختلفة: قاعدتان من قواعدنا، وأربع من SigmaHQ، كلها عملت على نفس السجل بنفس الطريقة، وأعطت أرقاماً نقارنها. فقاعدة اجتياز المسار Path Traversal أصابت ثلاثة، وهي الطلبات الثلاثة التي حملت `../../../etc/passwd` بصوره المختلفة، المرمزة وغير المرمزة، وهذا يبين قيمة قاعدة مكتوبة جيداً: كاتبها وضع كل صور الترميز التي يعرفها المهاجمون في قائمة واحدة، فأنت تستفيد من خبرته دون أن تعرفها. وقاعدة تعداد الكود المصدري أصابت طلبي `.git`، وهي قاعدة توقيع بسيطة جداً، كلمة واحدة `.git/`، ولكنها تكشف خطأ شائعاً خطيراً: نشر مجلد `.git` مع الموقع، وهو ما يسمح بتنزيل الكود المصدري كاملاً. وقاعدتنا عن المسارات الإدارية أصابت `/admin` و`/backup` اللذين ردهما 404، وتركت الصفحات الموجودة، لأن فلترها يستثني رد 200.

### الفلتر الذي يفوت: لماذا أربع لا خمس؟

أرسلنا خمسة طلبات تحمل أنماط حقن SQL، وأصابت القاعدة أربعة فقط. فأين الخامس؟ نسأل القاعدة نفسها: ما الطلبات التي تحمل نمط حقن، وما رد السيرفر على كل منها؟

```text
  200 /products?id=1%20UNION%20SELECT%20username,password
  200 /products?id=1%27%20or%201=1
  200 /search?q=order%20by%2010
  200 /products?id=-1%20UNION%20ALL%20SELECT%201,2,3
  404 /items?id=select%20version()  <-- MISSED: rule excludes 404
```

الطلب الذي فات هو `/items?id=select version()`، والسبب أن المسار `/items` غير موجود فرد السيرفر 404، وقاعدة SigmaHQ تحتوي على فلتر يستثني رد 404\. ومنطق كاتب القاعدة معقول: رد 404 يعني غالباً أن الطلب لم يصل إلى التطبيق أصلاً، فاستثناؤه يقلل الإنذارات الخاطئة. ولكنه يفوت مهاجماً يجرب الحقن على مسار لا يعرفه، وهذا فائت False Negative لا يظهر في أي طابور، كما شرحنا الأحكام في [يوم محلل SOC](https://arabroot.io/articles/%D9%8A%D9%88%D9%85-%D9%85%D8%AD%D9%84%D9%84-soc-%D9%81%D8%B1%D8%B2-%D8%A7%D9%84%D8%AA%D9%86%D8%A8%D9%8A%D9%87%D8%A7%D8%AA-%D9%85%D9%86-%D8%A7%D9%84%D8%AA%D9%86%D8%A8%D9%8A%D9%87-%D8%A7%D9%84%D9%89-%D8%A7%D9%84%D9%82%D8%B1%D8%A7%D8%B1/).

![لوحتان: خمسة طلبات تحمل نمط حقن SQL أربعة منها بردود 200 أصابتها القاعدة والخامس بمسار items رد 404 فات، وشرح أن شرط القاعدة طلب GET ونمط حقن وليس رد 404 وأن كاتب القاعدة افترض أن 404 يعني أن الطلب لم يصل إلى التطبيق فاستثناه ليقلل الإنذارات الخاطئة وأن هذا يفوت مهاجماً يجرب مساراً غير موجود](https://arabroot.io/content/images/2026/10/detection-rules-05-falseneg.webp)

اقرأ فلاتر القاعدة لا اختياراتها فقط، فالفلتر يقرر ما لا تراه

والدرس العملي: لا تقرأ اختيارات القاعدة فقط، واقرأ فلاترها، لأن الفلتر هو ما يقرر ما لا تراه القاعدة. وطريقة معرفة ذلك هي ما فعلناه: شغل القاعدة على حركة تعرف نتيجتها بالضبط، وقارن ما أصابت بما أرسلت، فالفرق هو ما تفوته في الإنتاج.

### قواعد نكتبها لمنطق متجرنا

قواعد SigmaHQ عامة، وتعرف الهجمات المعروفة، ولا تعرف شيئاً عن منطق تطبيقك أنت. فلا توجد قاعدة جاهزة تعرف أن متجرك لا يقبل سعراً سالباً، أو أن مجلد الإدارة عندك اسمه كذا. لذلك تكتب قواعد خاصة بك، بنفس الصيغة، فتعمل في نفس خط الأنابيب. كتبنا قاعدتين، الأولى تكشف العبث بالسعر:

```yaml
title: Negative or Zero Price in Shop Order Request
id: a1b2c3d4-0001-4a1a-9001-0000000a0001
status: experimental
description: Detects attempts to tamper with the price parameter of the lab shop (negative or zero amount)
author: فريق عرب رووت
date: 2026-10-28
tags:
    - attack.impact
    - attack.t1565
logsource:
    category: webserver
detection:
    selection:
        cs-uri-query|re: 'price=-?0*[0-9]'
    filter_positive:
        cs-uri-query|re: 'price=[1-9]'
    condition: selection and not filter_positive
falsepositives:
    - Legitimate free items or promotions
level: medium
```

وهذه القاعدة تطابق أي `price` سالب أو صفر، وتستثني بفلتر أي سعر موجب، فتصيب طلبي `price=-100` و`price=0` وتترك `price=50`. وولدت pySigma منها هذا الاستعلام بالتعبير النمطي:

```sql
SELECT * FROM logs WHERE `cs-uri-query` REGEXP 'price=-?0*[0-9]' AND (NOT COALESCE((`cs-uri-query` REGEXP 'price=[1-9]'), 0))
```

والقاعدة الثانية تكشف الطلبات إلى مسارات إدارة وإعداد شائعة لا توجد على متجرنا، مثل `/admin` و`/backup` و`/.env`، وتستثني ما رد عليه 200 لأنه قد يكون مساراً حقيقياً. وهذا هو جوهر هندسة الكشف Detection Engineering: قواعد عامة تأتيك من المجتمع، وقواعد خاصة تكتبها لمنطقك، وكلها بصيغة واحدة تختبرها بنفس الطريقة.

### قاعدة ترابط: عد الأحداث في نافذة

القواعد السابقة كلها تنظر إلى سطر واحد. ولكن أخطر الأنماط تظهر عبر عدة أحداث: عشر محاولات فاشلة، أو خمسون طلباً لمسارات غير موجودة في دقيقة، وهو مسح للمحتوى Content Discovery. وSigma تصف هذا بقاعدة ترابط Correlation تبني على قاعدة بسيطة وتضيف العد والنافذة الزمنية:

```yaml
title: Content Discovery Scan (Many 404s From One Source)
id: a1b2c3d4-0003-4a1a-9001-0000000a0003
status: experimental
description: A single source causing many 404 responses in a short window, a sign of directory or file scanning
author: فريق عرب رووت
date: 2026-10-28
logsource:
    category: webserver
detection:
    not_found:
        sc-status: 404
    condition: not_found
---
title: Content Discovery Scan (correlation)
id: a1b2c3d4-0004-4a1a-9001-0000000a0004
status: experimental
correlation:
    type: event_count
    rules:
        - a1b2c3d4-0003-4a1a-9001-0000000a0003
    group-by:
        - c-ip
    timespan: 10m
    condition:
        gte: 5
level: high
```

القاعدة الأولى تطابق أي رد 404، والثانية تعد ردود 404 لكل عنوان مصدر في نافذة عشر دقائق، وتطلق إذا بلغت خمسة. شغلناها على نفس القاعدة، فحولتها pySigma إلى استعلام SQL بنوافذ زمنية، وأطلقت:

```text
sqlite version: 3.46.1
  match alert_id=sigma_alert_…:1  group={"c-ip":"192.168.96.5"}  metric=event_count  value=12
        event_ids=["0:121","0:122","0:123","0:128","0:129","0:130","0:131","0:132","0:133","0:135","0:137","0:138"]
```

![لوحتان: القاعدة من نوع event_count تبني على قاعدة رد 404 وتجمع بالعنوان c-ip في نافذة 10 دقائق بشرط خمسة فأكثر، والنتيجة من المختبر 12 رد 404 من العنوان 192.168.96.5 تجاوزت الحد فأطلقت تنبيهاً واحداً مع قائمة معرفات الأحداث الاثني عشر دليلاً، من SQLite 3.46](https://arabroot.io/content/images/2026/10/detection-rules-06-correlation.webp)

التنبيه هنا نمط عبر أحداث، لا حدث واحد، وهذا ما يحول السجلات من أرشيف إلى كشف

وفكرة النافذة Timespan هنا جوهرية: القاعدة لا تسأل «كم رد 404 في السجل كله؟» لأن مئة رد 404 موزعة على شهر عادية تماماً، وإنما «كم رد 404 من العنوان نفسه في عشر دقائق؟»، لأن اثني عشر منها في دقائق تعني أداة تمسح المواقع بسرعة. وهذا ما يجعل الترابط أقوى من العد البسيط: الزمن جزء من الشرط. وتستطيع أن تبني عليها أنواعاً أخرى من الترابط: قيمة فريدة Value Count مثل حساب واحد يحاول الدخول إلى عشرين حساباً مختلفاً، أو تتابع زمني Temporal مثل محاولة فاشلة ثم ناجحة ثم إنشاء حساب جديد، وكلها تصفها Sigma بنفس الطريقة، ويترجمها المحول إلى استعلام.

أطلقت تنبيهاً واحداً على العنوان `192.168.96.5`، لأنه سبب اثني عشر رد 404 في النافذة، وهي طلبات أدوات الفحص والمسارات غير الموجودة. ولاحظ أن التنبيه يحمل معرفات الأحداث الاثني عشر دليلاً، فالمحلل يستطيع أن يرجع إلى كل حدث. واحتاج هذا الاستعلام إصدار SQLite 3.38 فأحدث، وعمل على 3.46 في المختبر، لأن نوافذ الترابط تحتاج دوال حديثة. والفكرة المهمة: التنبيه هنا ليس حدثاً واحداً، وإنما نمط عبر أحداث، وهذا ما يحول السجلات من أرشيف إلى كشف.

### اقرأ القاعدة قبل أن تثق بها: مثال SSH

قبل أن تشغل أي قاعدة جاهزة، اقرأ ماذا تطابق بالضبط، لأن عنوانها قد يخدعك. ففي سجل SSH عندنا خمس محاولات دخول فاشلة لحساب root ثم دخول ناجح، وأخذنا من SigmaHQ قاعدة اسمها «Suspicious OpenSSH Daemon Error»:

```yaml
    service: sshd
detection:
    keywords:
        - 'unexpected internal error'
        - 'unknown or unsupported key type'
        - 'invalid certificate signing key'
        - 'invalid elliptic curve value'
        - 'incorrect signature'
        - 'error in libcrypto'
        - 'unexpected bytes remain after decoding'
        - 'fatal: buffer_get_string: bad string'
        - 'Local: crc32 compensation attack'
        - 'bad client public DH value'
        - 'Corrupted MAC on input'
    condition: keywords
```

شغلناها على سجلنا فلم تطلق على شيء، وهذا صحيح لا خطأ: فهي تطابق رسائل خطأ في بروتوكول SSH تدل على محاولة استغلال ثغرة، مثل `Corrupted MAC on input`، لا محاولات تخمين كلمات المرور. وتخمين كلمات المرور له قاعدة أخرى تعد المحاولات الفاشلة، كالتي كتبناها للويب. والدرس أن «قاعدة SSH مشبوهة» اسم عام، وما تطابقه القاعدة محدد جداً، فمن أخذها ظاناً أنها تكشف التخمين ترك ثغرة في تغطيته دون أن يدري. لذلك اقرأ جسم القاعدة، وشغلها على حركة تعرفها، قبل أن تعتمد عليها.

💡

ما فعله المختبر هو اختبار الكشف على حركة ولدناها نحن ونعرف نتيجتها، وهذه أبسط صور التحقق وأوضحها. والخطوة التالية في النضج أن تولد أساليب المهاجمين الحقيقية لا أشكالها فقط، بأدوات اختبار معيارية تنفذ تعريفات أساليب ATT&CK في بيئة معزولة، ثم تقيس هل أطلقت قواعدك. وهذا موضوع مقال محاكاة الهجمات لاختبار الكشف في مرحلة اختبار الاختراق من هذا المسار، حيث ننفذ تعريفات Atomic Red Team الرسمية داخل Container معزول ونتحقق أي منها رأته قواعدنا.

### حذف المختبر

```bash
docker rm -f scu-det-web scu-det-app scu-det-ssh
docker network rm scu-det-net
docker image rm scu-det-ssh:1
```

### القاعدة الجيدة تشارك المعرفة

هناك فائدة في Sigma لا تظهر في المختبر ولكنها الأهم على المدى الطويل: القاعدة تحمل المعرفة، لا المنطق فقط. فحقول الوصف والمراجع والإنذارات الخاطئة والأسلوب في ATT&CK تجعل القاعدة وثيقة يقرؤها محلل بعد سنة فيفهم لماذا كتبت، وماذا تكشف، وماذا تفوت. قارن ذلك باستعلام مكتوب مباشرة في لوحة الأداة بلا شرح: بعد أن يترك كاتبه الفريق، لا أحد يجرؤ على تعديله لأن لا أحد يعرف ماذا يعطل. ولهذا تطلب فرق الكشف الناضجة أن تحمل كل قاعدة حقل مراجع يشير إلى تقرير التهديد أو أسلوب الهجوم الذي بنيت عليه، وحقل إنذارات خاطئة يقول لمن يفرز بعدك ما الحالات العادية التي قد تطلق القاعدة، فيوفر عليه نصف دقائق التحقيق.

وهذا يربط قواعد الكشف بموضوع أوسع هو معلومات التهديدات Threat Intelligence: فعندما ينشر تقرير عن حملة هجوم جديدة، يتحول وصف سلوك المهاجم فيه إلى قاعدة Sigma يستطيع الجميع تشغيلها، وهذا ما يجعل القاعدة جسراً بين من يحلل التهديد ومن يدافع، كما سنرى في مقال MISP وOpenCTI. والقاعدة التي تكتبها أنت لمنطق متجرك قد لا تشاركها مع أحد، ولكنها تبقى وثيقة لفريقك أنت، تقول ما الذي قررتم أنه غير طبيعي في نظامكم، ولماذا.

## من القاعدة إلى الإنتاج: دورة حياة القاعدة

القاعدة لا تكتب مرة وتنسى، فهي كالكود: لها دورة حياة. وأهم ما تعلمناه في المختبر أن الخطوة التي يقفز عنها الجميع هي الاختبار، والصورة تتكرر في كل مركز: قاعدة أضيفت لأنها تبدو منطقية، ولم تطلق على شيء لشهور، لأن اسم حقل تغير أو فلتر واسع يبتلع كل إصاباتها، ولا يكتشف أحد ذلك إلا بعد حادثة فاتت. لذلك تمر كل قاعدة بالخطوات التالية:

- **اكتب أو خذ:** من SigmaHQ لما هو عام، واكتب بنفسك لما يخص منطقك.
- **حول وافحص الاستعلام:** اقرأ SQL الذي يخرج، فقد يكشف أن الفلتر أوسع مما تظن، كما في فلتر 404.
- **اختبر على حركة معروفة:** ولد نمط الهجوم في مختبر، وولد حركة عادية تشبهه، وتأكد أن القاعدة تصيب الأول وتترك الثاني. وهذا ما يسمى اختبار الكشف Detection Validation، وسنوسعه في مقال محاكاة الهجمات باختبارات Atomic Red Team.
- **اضبط من الواقع:** كل إنذار خاطئ في الإنتاج يعود فلتراً أدق لا تعطيلاً للقاعدة، وكل حادثة فاتت تعود قاعدة جديدة.
- **أدرها كالكود:** القواعد في مستودع Git، بمراجعة زميل قبل الدمج، وبسجل تغييرات، فتعرف من غير ماذا ومتى، وتستطيع أن تعيد قاعدة أفسدها تعديل.

ولقياس تغطيتك استخدم [إطار MITRE ATT&CK](https://arabroot.io/articles/mitre-attack-%D9%83%D9%8A%D9%81-%D9%8A%D9%81%D9%83%D8%B1-%D8%A7%D9%84%D9%85%D9%87%D8%A7%D8%AC%D9%85-%D8%AE%D8%B7%D9%88%D8%A9-%D8%A8%D8%AE%D8%B7%D9%88%D8%A9/): أي أساليب المهاجمين لديك قاعدة تكشفها ومصدر بيانات يغذيها، وأيها اختبرت فعلاً. والفرق بين «لدينا قاعدة» و«اختبرنا أنها تطلق» هو الفرق الذي رأيناه بين أربع إصابات وخمس.

### الضبط: بين الفائت والإنذار الخاطئ

كل فلتر تضيفه يقلل الإنذارات الخاطئة ويزيد الفائت، وكل فلتر تحذفه يفعل العكس، ولا توجد قاعدة بلا هذا التوازن. فقاعدة الحقن التي رأيناها اختارت أن تستثني رد 404 لتقلل الضجيج، ودفعت الثمن فائتاً. والقرار الصحيح ليس «أي الخيارين أفضل؟» وإنما «ما الذي يناسب هذا الأصل؟»: على متجر يحمل بيانات بطاقات قد تقرر أن ترى كل محاولة حقن حتى على مسار غير موجود، فتحذف فلتر 404 وتتحمل إنذارات أكثر؛ وعلى موقع تعريفي ثابت قد يكفيك الفلتر. وهذا ما يجعل الضبط Tuning عملاً مستمراً لا إعداداً يكتب مرة، ويجعل القاعدة الواحدة قد تعيش بنسختين: واسعة على الأصول الحساسة، وضيقة على غيرها.

ومن أدوات الضبط المهمة قائمة السماح Allowlist التي بنيتها من خط الأساس: سيرفر الفحص الليلي المصرح به يرسل نفس أنماط الاعتداء التي ترسلها أداة مهاجم، والفرق أنه من عنوان معروف وفي وقت معروف. فبدل أن تعطل قاعدة أدوات الفحص لأنها تطلق على فحصك أنت، تضيف فلتراً يستثني عنوان الفاحص المصرح به وحده، بسبب مكتوب وتاريخ انتهاء، كما شرحنا في [يوم محلل SOC](https://arabroot.io/articles/%D9%8A%D9%88%D9%85-%D9%85%D8%AD%D9%84%D9%84-soc-%D9%81%D8%B1%D8%B2-%D8%A7%D9%84%D8%AA%D9%86%D8%A8%D9%8A%D9%87%D8%A7%D8%AA-%D9%85%D9%86-%D8%A7%D9%84%D8%AA%D9%86%D8%A8%D9%8A%D9%87-%D8%A7%D9%84%D9%89-%D8%A7%D9%84%D9%82%D8%B1%D8%A7%D8%B1/). وهكذا تبقى القاعدة ترى الفحص غير المصرح به، وتسكت عن المصرح به وحده.

ولهذا العمل سند في الضوابط الأساسية للأمن السيبراني: فالضابط 2-12-3-4 في [وثيقة ECC-2:2024](https://cdn.nca.gov.sa/api/files/public/upload/86e09090-44e4-481f-bc28-355673607654%5FECC--2024-EN.pdf?ref=arabroot.io) يطلب المراقبة المستمرة لسجلات الأحداث، والمراقبة لا تعني أن السجلات تجمع فقط، وإنما أن منطقاً يقرؤها ويحولها إلى تنبيهات، وهذا هو قاعدة الكشف. فالجهة التي تجمع السجلات ولا تكتب قواعد تكشف بها نصف طريق، والمدقق الذي يسأل «كيف تراقبون باستمرار؟» ينتظر أن يرى قواعد تطلق تنبيهات، ودليلاً على أن أحداً يفرزها. وقد شرحنا الضوابط وأيها ينطبق عليك في [الضوابط الأساسية بلغة بسيطة](https://arabroot.io/articles/%D8%A7%D9%84%D8%B6%D9%88%D8%A7%D8%A8%D8%B7-%D8%A7%D9%84%D8%A7%D8%B3%D8%A7%D8%B3%D9%8A%D8%A9-%D9%84%D9%84%D8%A7%D9%85%D9%86-%D8%A7%D9%84%D8%B3%D9%8A%D8%A8%D8%B1%D8%A7%D9%86%D9%8A-nca-ecc-%D8%A8%D9%84%D8%BA%D8%A9-%D8%A8%D8%B3%D9%8A%D8%B7%D8%A9/).

## أخطاء شائعة

- **إضافة قاعدة دون اختبارها:** فتبدو التغطية أوسع مما هي، وتكتشف الفجوة بعد الحادثة.
- **قراءة اسم القاعدة لا جسمها:** «قاعدة SSH مشبوهة» لا تكشف التخمين، وفاتنا الحقن لأن فلترها يستثني 404.
- **الثقة بقاعدة عامة في منطق خاص:** لا توجد قاعدة SigmaHQ تعرف أن متجرك يرفض السعر السالب، فاكتبها.
- **قواعد كثيرة بلا ضبط:** فتغرق الطابور، ويتوقف المحلل عن القراءة، وهو إرهاق التنبيهات.
- **قاعدة لكل أداة بدل Sigma:** فتبدأ من الصفر كلما غيرت الأداة، وتضيع القاعدة عند الترقية.
- **تعطيل القاعدة بدل تضييقها:** فيمر الهجوم الحقيقي يوماً ما مع الإنذار الخاطئ الذي أزعجك.
- **إهمال قواعد الترابط:** فترى السطر الواحد ولا ترى النمط عبر الأسطر، مثل اثني عشر رد 404.
- **قواعد خارج Git:** فلا تعرف من غيرها ولا متى ولا لماذا، ولا تستطيع التراجع.

## قائمة تحقق لكل قاعدة

| السؤال                       | كيف تتحقق                                     |
| ---------------------------- | --------------------------------------------- |
| ماذا تطابق القاعدة بالضبط؟   | اقرأ جسمها، لا عنوانها، خاصة الفلاتر          |
| ما الاستعلام الذي يخرج منها؟ | حولها واقرأ SQL أو استعلام أداتك              |
| هل تصيب الهجوم؟              | ولد نمط الهجوم في مختبر وشغلها عليه           |
| هل تترك الحركة العادية؟      | ولد حركة عادية تشبه الهجوم وتأكد أنها لا تطلق |
| ماذا تفوت؟                   | قارن ما أصابت بما أرسلت، والفرق فائت          |
| هل تناسب أسماء حقول نظامي؟   | تحقق من خط المعالجة، لا من القاعدة            |
| أي أسلوب ATT&CK تغطي؟        | اربطها بالإطار، واعرف ما لا تغطيه             |
| من يراجعها قبل الإنتاج؟      | في مستودع Git بمراجعة زميل وسجل تغييرات       |

## الخلاصة

- القاعدة تقرر بثلاث طرق: التوقيع والسلوك والشذوذ، وأغلب قواعد اليوم توقيع وسلوك لأنها تختبر.
- Sigma صيغة قياسية: اكتب القاعدة مرة، ويترجمها محول Backend إلى لغة أي أداة، ومستودع SigmaHQ فيه آلاف القواعد الجاهزة.
- خط المعالجة Pipeline يفصل «ماذا نبحث عنه» عن «أين يقع في سجلي»، فتعمل قاعدة المجتمع على نظامك دون تعديلها.
- في المختبر أطلقت أربع قواعد SigmaHQ وقاعدتان كتبناهما على 138 حدثاً حقيقياً، والأرقام إصابات على حركة ولدناها.
- قاعدة الحقن أصابت أربعاً من خمسة، وفاتها طلب رد 404 بسبب فلتر فيها، وهذا فائت لا يظهر إلا بالاختبار.
- قاعدة الترابط عدت اثني عشر رد 404 من عنوان واحد في نافذة، فرأت نمط المسح الذي لا يراه سطر واحد.
- الخطوة التي يقفز عنها الجميع هي الاختبار، وأدر القواعد كالكود في Git بمراجعة وسجل تغييرات.

وأقرب المقالات إلى هذا الموضوع في المسار:

[![](https://arabroot.io/content/images/2026/10/security-logging-cover-cover.webp)دليلالسجلات الأمنية Logs: ماذا تجمع ومن أين قبل أن تبني SOCجمعنا سجلات nginx وتطبيق صغير وSSH بأداة Vector، فرأينا كيف يقلب وقت بلا منطقة زمنية ترتيب الحادثة، وكيف ينجو السجل المركزي من المسح.](https://arabroot.io/articles/%D8%A7%D9%84%D8%B3%D8%AC%D9%84%D8%A7%D8%AA-%D8%A7%D9%84%D8%A7%D9%85%D9%86%D9%8A%D8%A9-logs-%D9%85%D8%A7%D8%B0%D8%A7-%D8%AA%D8%AC%D9%85%D8%B9-%D9%88%D9%85%D9%86-%D8%A7%D9%8A%D9%86-%D9%82%D8%A8%D9%84-soc/)[![](https://arabroot.io/content/images/2026/10/build-siem-cover-cover.webp)دليلكيف يعمل محرك كشف SIEM من الداخل؟كيف يجمع SIEM ملايين السجلات ويوحدها ويطبق قواعد الكشف، مع خط أنابيب Vector وLoki وقاعدة Sigma تطلق فعلاً.](https://arabroot.io/articles/%D9%83%D9%8A%D9%81-%D9%8A%D8%B9%D9%85%D9%84-%D9%85%D8%AD%D8%B1%D9%83-%D9%83%D8%B4%D9%81-siem-%D9%85%D9%86-%D8%A7%D9%84%D8%AF%D8%A7%D8%AE%D9%84/)[![](https://arabroot.io/content/images/2026/10/soc-triage-cover-cover.webp)دليليوم محلل SOC: فرز التنبيهات Alert Triage من التنبيه إلى القرارستة عشر تنبيهاً حقيقياً من Wazuh وSuricata نفرزها واحداً واحداً بالإثراء من Zeek حتى القرار والتصعيد.](https://arabroot.io/articles/%D9%8A%D9%88%D9%85-%D9%85%D8%AD%D9%84%D9%84-soc-%D9%81%D8%B1%D8%B2-%D8%A7%D9%84%D8%AA%D9%86%D8%A8%D9%8A%D9%87%D8%A7%D8%AA-%D9%85%D9%86-%D8%A7%D9%84%D8%AA%D9%86%D8%A8%D9%8A%D9%87-%D8%A7%D9%84%D9%89-%D8%A7%D9%84%D9%82%D8%B1%D8%A7%D8%B1/)[![](https://arabroot.io/content/images/2026/10/wazuh-lab-cover-cover.webp)دليلمراقبة السيرفرات مع Wazuh: من السجل Log إلى حظر المهاجمشغلنا Wazuh مع وكيل على سيرفر تجريبي، فكشف تخمين كلمات مرور SSH وحظر المهاجم تلقائياً، ونبه على ملف PHP دخيل خلال ثانية.](https://arabroot.io/articles/%D9%85%D8%B1%D8%A7%D9%82%D8%A8%D8%A9-%D8%A7%D9%84%D8%B3%D9%8A%D8%B1%D9%81%D8%B1%D8%A7%D8%AA-%D9%85%D8%B9-wazuh-%D9%85%D9%86-%D8%A7%D9%84%D8%B3%D8%AC%D9%84-%D8%A7%D9%84%D9%89-%D8%AD%D8%B8%D8%B1-%D8%A7%D9%84%D9%85%D9%87%D8%A7%D8%AC%D9%85/)[![](https://arabroot.io/content/images/2026/10/suricata-zeek-cover-cover.webp)دليلمراقبة الشبكة واكتشاف التسلل IDS مع Suricata وZeekمختبر حقيقي يقرأ الحركة نفسها بأداتين، فيكشف Suricata الهجمات المعروفة ويكتب Zeek سجلاً لكل اتصال، مع الضبط وفقد الحزم.](https://arabroot.io/articles/%D8%A7%D9%83%D8%AA%D8%B4%D8%A7%D9%81-%D8%A7%D9%84%D8%AA%D8%B3%D9%84%D9%84-%D9%81%D9%8A-%D8%A7%D9%84%D8%B4%D8%A8%D9%83%D8%A9-ids-%D9%85%D8%B9-suricata-%D9%88-zeek/)[![](https://arabroot.io/content/images/2026/10/mitre-attack-cover-cover.webp)دليلMITRE ATT&CK: كيف يفكر المهاجم خطوة بخطوةلغة موحدة لسلوك المهاجمين مبنية على حوادث موثقة، نقرأ بها هجوم فدية حقيقياً مرحلة بمرحلة ونربط كل خطوة بالدفاع المقابل.](https://arabroot.io/articles/mitre-attack-%D9%83%D9%8A%D9%81-%D9%8A%D9%81%D9%83%D8%B1-%D8%A7%D9%84%D9%85%D9%87%D8%A7%D8%AC%D9%85-%D8%AE%D8%B7%D9%88%D8%A9-%D8%A8%D8%AE%D8%B7%D9%88%D8%A9/)

## سجل التحديثات

- أكتوبر 2026: كتابة المقال، ومختبر يوم 28 أكتوبر 2026 حول قواعد SigmaHQ وقواعد خاصة إلى SQL بمكتبة pySigma 2.0.1 ومحول SQLite 2.1.1، وشغلها على سجلات nginx 1.31.6 في SQLite 3.46، مع قاعدة ترابط ومحاولات SSH.