
محلل مجاني لاختراق سجلات الوصول: تفاعلات webshell وأنماط الاستغلال ورشقات القوة الغاشمة في سجلات Apache/nginx الخاصة بك - الخطورة والثقة والمعالجة. للقراءة فقط.
سجلات خادم الويب الخاص بك تعرف بالفعل ما إذا كنت قد تعرضت لهجوم. weblogchecker يقرأها.
phpscan يخبرك ما إذا كان PHP الخاص بك مكشوفًا. phpscan hunt يبحث في
جذر الويب عن القواقع. weblogchecker يجيب على السؤال الثالث — هل استخدمها أحدهم
فعليًا؟ — من السجل الوحيد الذي تمتلكه معظم المواقع بالفعل ولا يقرأه أحد: سجل الوصول.
يقوم ببث سجلات وصول Apache وnginx التي تملكها، ويكتشف التفاعلات التي تهم — قوقعة ويب تستجيب للطلبات، دفعة تخمين قوي تنتهي بإعادة توجيه، نمط استغلال حصل على استجابة 200 — ويبلّغ عن كل واحدة منها بـ درجة الخطورة، ودرجة الثقة، وأسطر السجل الفعلية كدليل، وما يجب فعله بشأنها.
weblogchecker analyze /var/log/apache2/access.log
رموز الخروج: 0 = لا مؤشرات، 1 = تم العثور على مؤشرات، 2 = خطأ في الاستخدام.
أضف --format json للحصول على مخرجات قابلة للقراءة آليًا، و--since 2026-10-01 لتحديد
نطاق الفترة الزمنية. تُقرأ سجلات .gz مباشرةً؛ ويقرأ - من stdin.
جديد في 0.2.0 — فرق خط الأساس. قوائم التوقيعات لا تعرف إلا الأصداف التي لها أسماء بالفعل. أما الصدفة التي تهبط على موقعك فلها اسم عشوائي. أعطِ weblogchecker سجلًا قديمًا موثوقًا من الموقع نفسه وسيُبلّغ عن الملفات التنفيذية التي لم تكن موجودة هناك من قبل:
weblogchecker analyze access.log --baseline access.log.last-month
كل مسار قابل للتنفيذ (.php، .phtml، .cgi، .asp، .jsp…) يظهر
للمرة الأولى يُقيَّم بناءً على خمس إشارات ضعيفة من السجل وحده —
استُجيب له بـ 2xx/3xx، واستُخدم معه POST/PUT، وبدون referrer، ووصل إليه
على الأكثر 2 من عناوين IP، ويقع تحت دليل upload/cache/temp — ويُبلَّغ عنه
بحالة NEW مع الإشارات والأعداد وأسطر السجل كأدلة. مجرد الظهور لأول مرة
هو ملاحظة منخفضة الخطورة؛ ولا ترتفع الخطورة إلا بتراكم الإشارات (التفاصيل
أدناه)، لذا فإن إضافةً ثبّتها الأسبوع الماضي لا تُقرأ على أنها
حادث.
سطر واحد، من PyPI (Python 3.11+، المكتبة القياسية فقط — بلا أي اعتماديات):
pip install weblogchecker
أول إصدار على PyPI قيد الانتظار. إلى أن يتم إعداد الناشر الموثوق على PyPI، ثبّت الكود نفسه من GitHub:
pip install git+https://github.com/PHPatch/weblogchecker.git(أو نزّل حزمة الإصدار الموقّعة أدناه). يعمل سطرpip install weblogcheckerأعلاه بمجرد صدور أول إصدار على PyPI.
على الأنظمة التي ترفض بـ "externally-managed-environment" (إصدارات Python على Debian/Ubuntu وHomebrew)، استخدم pipx بدلاً من ذلك:
python3 -m pip install --user pipx # if you don't have pipx yet
pipx install weblogchecker
الإصدارات الموقّعة (sdist + wheel + توقيعات PGP + SBOM) متاحة على
صفحة إصدارات GitHub.
تحقق من التوقيعات باستخدام المفتاح الموجود في pgp-key.asc — البصمة
BAA1 586A AD37 18C0 CE41 D288 FE23 A624 54E3 5307. راجع SECURITY.md.
| النمط في سجلك | الخطورة / الثقة | لماذا يهم |
|---|---|---|
| webshell معروف (c99، r57، FilesMan، b374k، WSO) يرد بـ 2xx | عالية / عالية | القشرة موجودة وقد خدمت طلبًا |
| الأسماء نفسها جرى فحصها لكن برد 404/403 | منخفضة / منخفضة | أحدهم نظر؛ لم يُعثر على شيء — سياق، لا إنذار |
eval-stdin.php (phpunit) يرد | عالية / عالية | قشرة UnitTest من موجة php2shell في أكتوبر 2026 تنفّذ الكود المُرسَل عبر POST |
ملف قابل للتنفيذ (.php وغيره) داخل /uploads/، /media/، /files/… يرد، خصوصًا على POST | عالية / عالية | مجلدات الرفع يجب ألا تنفّذ كودًا أبدًا |
| POST/PUT إلى ملف ثابت (.jpg، .css…) يُجاب بـ 2xx | عالية / متوسطة | المتصفحات لا ترسل POST إلى الصور؛ "الصورة" غالبًا سكربت |
نمط استغلال في URI (traversal، eval(، php://، رمز base64 طويل) يُجاب بـ 2xx | عالية / متوسطة | قد تكون المحاولة نجحت |
| الأنماط نفسها محجوبة / 404 | منخفضة / منخفضة | ضجيج خلفي؛ مفيد فقط كسياق حملة |
| اندفاع تخمين قسري على wp-login.php / xmlrpc.php (≥20 طلب POST / 10 دقائق) | متوسطة / متوسطة | عنوان IP واحد، بوتيرة غير بشرية |
| رد 302 داخل ذلك الاندفاع بعد إخفاقات متكررة | عالية / متوسطة | شكل كلمة مرور صحيحة — استيلاء محتمل |
| وكلاء مستخدم الماسحات (sqlmap، nuclei، nikto…) | منخفضة / منخفضة | معلوماتي؛ الفحص ليس اختراقًا |
مسار قابل للتنفيذ غائب عن سجل --baseline الخاص بك، يرد على الطلبات | منخفضة → عالية / ≤ متوسطة | القشرة مجهولة الاسم التي لا تعرفها أي قائمة حظر؛ تتراكم الخطورة مع POSTs، وغياب المُحيل، وقلة عناوين IP، ومجلدات الرفع |
كل فئة اكتشاف تحمل نص معالجة: اعزل الملف، بدّل بيانات الاعتماد،
راجع كل ما لمسه ذلك العنوان IP. تشير اكتشافات webshell إلى
الأداة المرافقة — phpscan hunt (pip install phpscan،
github.com/PHPatch/phpscan) — التي
تفحص جذر الويب نفسه بحثًا عن القشور التي تشير إليها أنماط السجل هذه.
بُنيت هذه الأداة وفق العقيدة نفسها التي بُني بها phpscan:
التحليل يعتمد على تدفق الأسطر: لا يتم تحميل الملف إلى الذاكرة أبدًا، ويحتفظ التجميع بخمسة أسطر أدلة كحد أقصى لكل اكتشاف. قياسًا على مولّد بيانات الاختبار الخاص بهذا المشروع (366,306 سطرًا، 72 ميغابايت من سجل مدمج واقعي): 7.6 ثانية، 12.8 ميغابايت ذروة RSS على جهاز افتراضي متواضع. سجل بحجم 2 غيغابايت يستهلك الذاكرة نفسها، ووقتًا أطول نسبيًا.
$ weblogchecker analyze access.log
weblogchecker 0.2.0 - access-log compromise analysis
Log: access.log
Lines read: 13 | parsed: 13 | unparseable (skipped): 0
Indicators found. These are leads for investigation, not proof of
compromise: work through the findings in severity order ...
SUMMARY: 10 findings (4 high, 1 medium, 5 low) across 9 incidents, 2 IPs flagged
INCIDENT TIMELINE (grouped by IP + path):
[HIGH] 198.51.100.66 /wp-content/uploads/2026/10/c99.php
classes: webshell-access, exec-in-upload-dir | requests: 6 | ...
...
1. [high severity / high confidence] Known webshell filename answered a request
198.51.100.66 /wp-content/uploads/2026/10/c99.php - 3 request(s), ...
| 198.51.100.66 - - [28/Oct/2026:03:13:40 +0000] "GET /wp-content/..." 200 ...
Remediation: Treat the named file as a live webshell until you have
proven otherwise. Locate it in the webroot and quarantine it ...
hunt بحثًا عن shells على القرص)جميعها مجانية، جميعها مفتوحة المصدر، ولا يرسل أي منها فحوصات استغلال.
MIT — راجع LICENSE. تقارير الأمان: راجع SECURITY.md.