ملخص ما حدث: توثق هذه الدراسة تجربة حقيقية ومفصلة لعملية استجابة لاختراق أمني معقد استهدف موقع ووردبريس عالي الزيارات، حيث تم اختراقه وتشويه واجهته وحقن قواعد بياناته بحسابات وهمية ومقالات خبيثة، وتعرضه لهجمات تخمين شبكات البوتات مكثفة. تتناول الدراسة الفحص الأمني الرقمي، استراتيجية النقل والتنظيف تحت مبدأ "انعدام الثقة" (Zero-Trust)، التنظيف الشامل للبيانات، فرض العزل الصارم على مستوى نظام التشغيل (Multi-Tenant Isolation)، والتأمين الشامل لطبقات الويب وطرف الشبكة عبر Cloudflare.
1. خلفية الحالة والمشهد الأمني
1.1 طبيعة النظام وبيئة العمل
الهدف كان منصة لإدارة المحتوى قائمة على WordPress تعمل ضمن بيئة استضافة مشتركة على خادم سحابي افتراضي (VPS) بنظام Linux (Ubuntu)، تعتمد على خادم الويب Nginx وخدمة PHP-FPM وقاعدة بيانات MySQL، وتستخدم شبكة توزيع المحتوى CDN وجدار حماية Cloudflare. هذه الحالة توضح لماذا لا يكفي تنظيف الملفات دون إنقاذ أمني كامل يغلق باب الدخول ويعزل الموقع عن جيرانه.
1.2 مؤشرات الاختراق الأولى (Indicators of Compromise - IoCs)
بدأت الأزمة بظهور سلوكيات غير معتادة تمثلت في:
- تشويه الواجهة (Defacement): ظهور شاشة سوداء كاملة تعلو الصفحة الرئيسية بعنوان هجومي صريح (
hacked by...) وتوقيع فريق اختراق آلي أجنبي، وحجب كامل لمحتوى الموقع الشرعي. - إنشاء حسابات إدارة خفية: إنشاء عشرات حسابات المسؤولين (Administrators) بأسماء وأنماط موحدة عبر روبوتات (
@wp2shell*). - حقن محتوى احتيالي وإعلاني (SEO Spam): نشر مسودات ومقالات خبيثة تشتمل على كلمات مرور سرية مشفرة، ونشر مئات التعليقات الاحتيالية التي تروج لمنصات وهمية وروابط تصيد.
- ارتفاع حاد لموارد المعالج (CPU Spikes): رصد قفزات مفاجئة في استهلاك المعالج ناجمة عن عمليات
php-fpmالمستمرة، حتى في الفترات التي ينخفض فيها الزوار المعتادون.
2. كيف كشفنا الاختراق وحللنا الهجوم
2.1 كيف دخل المهاجم أول مرة؟
أظهر الفحص الأمني في سجلات الطلبات أن الاختراق بدأ عبر استغلال ثغرة تنفيذ أوامر عن بُعد / تعديل معاملات غير مصرح به في إحدى الإضافات القديمة غير المحدثة (Unauthenticated Parameter Injection)، مما مكّن للمهاجم:
- تجاوز المصادقة ورفع باب خلفي Web Shell (Web Shell Dropper).
- إخفاء النص البرمجي التنفيذي داخل مجلد الملفات المرفوعة (
wp-content/uploads/) بأسماء ملفات مموهة وامتدادات مضللة تخدع أنظمة الفحص البسيطة.
2.2 كيف ثبّت المهاجم أقدامه داخل النظام؟
لم يكتفِ المهاجم بالملف المرفوع؛ إذ أدرك أن برامج فحص الملفات العادية قد ترصده، فلجأ إلى تثبيت الاختراق والبقاء في النظام عبر مستويين:
- إنشاء حسابات مسؤولين في قاعدة البيانات: استغل المهاجم صلاحيات النص البرمجي المنفذ لحقن استعلامات مباشرة في جدولي
wp_usersوwp_usermeta، منشئاً أكثر من 50 مستخدماً بصلاحياتadministratorكاملة تضمن له العودة في أي لحظة. - حقن مقالات التشويه تبدو شرعية: بدلاً من تعديل ملف
index.php(الذي يتم كشفه وإصلاحه سريعاً)، قام المهاجم بإنشاء مقالات حقيقية داخل جدولwp_postsبتواريخ نشر حديثة جداً، وضمن محتواها شيفرةHTML/CSSيفرض طبقة تغطي الشاشة أسود كامل الشاشة (position: fixed; z-index: 2147483647). وبما أن قوالب ووردبريس تعرض "أحدث المقالات" تلقائياً في الصفحة الرئيسية، ظهرت هذه المقالات المشبوهة في الواجهة مباشرة! - إنشاء مسودات خبيثة (Backdoor Payloads in Drafts): قام المهاجم بإنشاء صفحات ومسودات مغلقة بكلمات مرور سرية (
post_password) تحمل أكواد تستدعي أوامر عن بعد لا تظهر للزوار العاديين ولكن تستجيب لاتصالات البوتات الخارجي.
2.3 موجة البوتات التي لم تتوقف
حتى بعد إخراج بعض الملفات المشبوهة من الخدمة، استمرت شبكات البوتات الآلية موزعة تعمل على خوادم VPS خارجية (تم تتبعها إلى مزودي خوادم في أوروبا وآسيا) بإرسال كم هائل من الطلبات الموجهة إلى:
POST /wp-login.php: محاولات تخمين مكثفة (Brute-Force) لاختراق الحسابات الحقيقية.POST /xmlrpc.php: استغلال واجهة XML-RPC القديمة لإرسال مئات التخمينات في استدعاء واحد (Multicall Brute-Force Amplification).
تسببت هذه الطلبات المتتالية في تشغيل دوال التحقق المكلفة للمعالج (wp_check_password المعتمدة على bcrypt/phpass)، مما أدى إلى استهلاك قدرة أنوية المعالج (CPU) وارتفاع استهلاك خادم الويب وذاكرته.
3. استراتيجية النقل بمبدأ انعدام الثقة Zero-Trust
3.1 لماذا النقل العشوائي دون فحص خطر؟
الخطأ الأكثر شيوعاً وكارثية في إدارة الخوادم عند التعامل مع موقع مخترق هو تنفيذ نقل دون فحص للملفات (rsync -avz /old-site/ /new-site/). هذا الإجراء ينقل أبواب المهاجم الخلفية، نصوص برمجية التجسس، التعديلات الخبيثة في ملفات ووردبريس الأساسية، والملفات المخفية إلى البيئة الجديدة، مما يجعل الاختراق مستمراً وكأن شيئاً لم يكن. ولهذا يبدأ نقل المواقع عندنا بعد العزل والتنظيف، لا قبلهما.
3.2 إعادة البناء النظيفة على ثلاث مراحل
تم وضع خطة هندسية تقوم على عزل البيئة المصابة بالكامل ونقل البيانات وفق الخطوات التالية:
الخطوة 1: تثبيت نسخة نظيفة وموثوقة من البداية
تم تنزيل أحدث إصدار موثوق من ملفات ووردبريس الأساسية عبر WP-CLI مباشرة دون استخدام ملفات النسخة الأساسية القديمة:
wp core download --path=/home/siteuser/site.com/ --allow-root
الخطوة 2: النقل الانتقائي لمجلد الملفات المرفوعة مع تنقية صارمة
تم استخراج محتويات مجلد الرفع (wp-content/uploads) مع استبعاد أي ملف تنفيذي أو نص برمجي بصورة قاطعة أثناء النقل:
tar -czf - --exclude='*.php' --exclude='*.phtml' --exclude='*.phar' uploads | \
ssh root@new-server "tar -xzf - -C /home/siteuser/site.com/wp-content/"
الخطوة 3: إعادة بناء ملف الإعدادات ومنع التعديل عبر لوحة التحكم
تم إنشاء ملف wp-config.php نظيف تماماً ببيانات اتصال قاعدة بيانات جديدة ومفاتيح أمان جديدة (Unique Security Salts)، مع فرض القيدين الأمنيين الصارمين لمنع تعديل أو تثبيت أي إضافات أو قوالب عبر لوحة التحكم:
define('DISALLOW_FILE_EDIT', true);
define('DISALLOW_FILE_MODS', true);
define('DISABLE_WP_CRON', true);
4. التنظيف الكامل لقاعدة البيانات
يمثل تنظيف قاعدة البيانات الجزء الأهم، إذ إن إغفال سجل واحد قد يبقي الموقع مشوهاً أو يمنح المهاجم حق الدخول.
4.1 حذف حسابات المسؤولين الوهمية
باستخدام أداة WP-CLI واستعلامات SQL المباشرة، تم عرض قائمة المسؤولين وفرزها:
wp user list --role=administrator --fields=ID,user_login,user_email
تم كشف 53 حساباً وهمياً بطريقة بريد موحد تابع للمهاجم، وتم تنفيذ حذف جماعي فوري لجميع هذه الحسابات:
# حذف كافة حسابات المسؤولين غير المعتمدة نهائياً
wp user delete <ROGUE_IDS> --reassign=<LEGITIMATE_ADMIN_ID> --yes
4.2 حذف مقالات وصفحات التشويه الخبيثة
قام الفحص الأمني بفحص المقالات المنشورة حديثاً والمسودات الخفية:
SELECT ID, post_title, post_name, post_status, post_date
FROM wp_posts
WHERE post_title LIKE '%hacked%' OR post_content LIKE '%position:fixed%';
تم العثور على مقالات منشورة ومسودات خبيثة ونسخ مخزنة مؤقتاً روابط خبيثة (oembed_cache):
# الحذف النهائي دون المرور بسلة المهملات بدون سلة المهملات
wp post delete 460 473 459 472 455 461 464 466 470 474 --force
4.3 تنظيف تعليقات المزعجة Spam والتصيد الاحتيالي
كشف الفحص وجود 370 تعليق مزعجة Spam تمت الموافقة عليها آلياً أو تعليقها، تحتوي على روابط إعلانية للعملات الرقمية ومواقع التصيد:
# حذف التعليقات المشبوهة
wp db query "DELETE FROM wp_comments WHERE comment_approved = 'spam' OR comment_content LIKE '%http%';"
# تنظيف البيانات الوصفية غير المرتبطة المرتبطة بها
wp db query "DELETE FROM wp_commentmeta WHERE comment_id NOT IN (SELECT comment_ID FROM wp_comments);"
4.4 مسح التخزين المؤقت نهائياً
لضمان عدم بقاء أي نسخة مخزنة من التشويه في الذاكرة العشوائية أو ملفات التخزين المؤقت:
wp cache flush
rm -rf /dev/shm/nginx-cache*/* /var/run/nginx-cache/* 2>/dev/null
systemctl reload php8.4-fpm nginx
5. عزل المواقع عن بعضها على مستوى نظام التشغيل
5.1 ماذا يحدث عندما تتشارك المواقع مستخدماً واحداً؟
في الاستضافات العادية، توضع جميع المواقع التابعة لخادم واحد تحت مستخدم نظام واحد (مثل www-data أو apache أو nginx). في حال تعرض أي موقع صغير على الخادم لاختراق، يمتلك المخترق صلاحية القراءة والكتابة على مجلدات باقي المواقع الموجودة في /home/{shared-user}/، مما يسبب انتقال الاختراق تباعاً لكافة المواقع.
5.2 تطبيق مبدأ الحد الأدنى من الصلاحيات
1. إنشاء مستخدم مستقل لكل نطاق
تم تخصيص مستخدم نظام Linux مستقل تماماً لكل موقع منفصل:
# إنشاء المستخدم وتعيين المسار الرئيسي home المخصص
useradd -m -d /home/siteuser -s /bin/bash siteuser
2. ضبط الصلاحيات الصارمة
تم تقييد الوصول إلى المجلد الرئيسي للمستخدم home بصلاحيات 750، بحيث يُمنع أي مستخدم آخر على الخادم من الاطلاع على محتوياته، مع إعطاء مجموعة خادم الويب حق القراءة فقط:
chmod 750 /home/siteuser
chown -R siteuser:www-data /home/siteuser/site.com
3. مجمّع PHP-FPM خاص Pool مستقل لكل موقع
تم إنشاء مجمّع PHP-FPM خاص (Pool) مستقل تماماً في /etc/php/8.4/fpm/pool.d/siteuser.conf:
[siteuser]
user = siteuser
group = siteuser
listen = /run/php/php8.4-fpm-siteuser.sock
listen.owner = siteuser
listen.group = www-data
listen.mode = 0660
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
pm.process_idle_timeout = 10s
request_terminate_timeout = 60s
النتيجة: حتى لو نجح مهاجم في تنفيذ شيفرة عبر الموقع، فإن العملية تعمل بصلاحيات siteuser المقيد في /home/siteuser بصلاحيات 750، ويعجز تماماً عن الوصول إليه أو العبث به أي موقع آخر على نفس الخادم.
6. تأمين خادم الويب Nginx
تم تطبيق قواعد في ملف إعدادات أمنية مخصصة في مسار تكوين Nginx الخاص بالموقع (/etc/nginx/sites-available/site.com/security.conf):
6.1 منع تنفيذ PHP داخل مجلد الرفع
القاعدة الأهم رقم 1 في حماية ووردبريس: مجلد الرفع مخصص للصور والملفات الثابتة فقط، ويجب منع تشغيل أي شيفرة برمجية داخله قطعياً:
# منع تنفيذ ملفات PHP داخل مجلدات الرفع والملفات المرفوعة
location ~* /(?:uploads|files|wp-content/uploads)/.*\.php$ {
deny all;
access_log off;
log_not_found off;
return 403;
}
6.2 الحظر التام لواجهة XML-RPC
نظراً لعدم استخدام الموقع لتطبيقات النشر الخارجية عبر الهاتف، تم إغلاق xmlrpc.php كلياً على مستوى Nginx:
# إغلاق XML-RPC لمنع هجمات التخمين وDDoS Amplification
location = /xmlrpc.php {
deny all;
access_log off;
log_not_found off;
return 403;
}
6.3 منع الوصول للملفات الحساسة والنظامية
# حجب الملفات المخفية وملفات الإعدادات والنسخ الاحتياطي
location ~ /\.(?!well-known).* {
deny all;
}
location ~* (?:\.(?:bak|config|sql|fla|psd|ini|log|sh|inc|swp|dist)|~)$ {
deny all;
}
6.4 رؤوس الأمان
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
7. الحماية من طرف الشبكة عبر Cloudflare
7.1 لغز الخطأ 525: التشخيص والحل
عند تشغيل الموقع خلف Cloudflare بطريقة التشفير الكامل (Full/Strict SSL)، واجه الزوار خطأ Error 525 (فشل اتصال SSL بين Cloudflare والخادم) عند زيارة نطاق www.
ماذا كان يحدث؟
كان خادم Nginx يستمع للنطاق الرئيسي فقط بدون الـ Alias (www) في إعدادات النطاق البديل وشهادة Let's Encrypt، مما سبب فشل مطابقة SNI أثناء اتصال Cloudflare.
كيف حللناها؟
- إضافة النطاق البديل في إعداد Nginx:
server_name site.com www.site.com;
- تحديث شهادة SSL لتشمل النطاقين معاً (
site.comوwww.site.com). - نقل إعدادات التجديد التلقائي لشهادات Let's Encrypt وتفعيل التايمر المستمر:
systemctl enable --now snap.certbot.renew.timer
certbot renew --dry-run
7.2 إيقاف التخمين عند طرف الشبكة بقاعدة WAF
لمنع وصول طلبات البوتات إلى خادم Nginx وإنشاء أحمال على معالج الخادم عبر wp-login.php، تم إنشاء قاعدة حماية على جدار حماية كلاودفلير (WAF Custom Rule):
- اسم القاعدة:
Mitigate WordPress Login Brute-Force - المسار:
(http.request.uri.path eq "/wp-login.php") - الإجراء:
Managed Challenge(تحدي كابتشا ذكي لفرز البوتات)


الأثر المباشر: تراجعت اتصالات البوتات الواصلة للخادم إلى الصفر المطلق، حيث تقوم خوادم Cloudflare العالمية باعتراض وصد هجمات الـ Brute-Force قبل وصولها حتى للشبكة المحلية للخادم.
راسلنا على واتساب وسنحوّل هذا المقال إلى خطة عمل واضحة لموقعك.
تواصل عبر واتساب8. مراقبة الأداء وفهم استهلاك الموارد
8.1 هل رقم htop المرتفع يعني اختراقاً؟
أثناء المراقبة اللاحقة، لوحظ ظهور عمليات مثل php-fpm: pool www-site-8.4 تستهلك 7.8% من المعالج في برنامج htop، مما أثار اشتباهاً بوجود نشاط غير طبيعي.
ماذا تعني الأرقام فعلاً؟
- طبيعة مقياس
htop: يعرض برنامجhtopاستهلاك النسخة الأساسية الواحدة في نافذة زمنية لحظية (1 ثانية). وحيث إن الخادم يمتلك نواتين حديثتين (AMD EPYC)، فإن استهلاك7.8%من نسخة أساسية واحدة يمثل أقل من 3.9% من طاقة الخادم الفعلية. - سجلات الوصول الحية: أظهر تحقق السجلات تزامناً دقيقاً بين ظهور العملية وزيارات حقيقية قادمة من محركات البحث ومنصات التواصل الاجتماعي تطلب مقالات ووردبريس غير مخزنة مؤقتاً.
- عمود الوقت التراكمي (
TIME+): أظهر الفحص أن العمليات مجتمعة لم تستهلك سوى 8 ثوانٍ فقط من زمن المعالج التراكمي على مدار نصف ساعة كاملة، وأن الحمل الإجمالي للخادم (Load Average) ظل عند0.24فقط، مما يعني أن الخادم خامل وفارغ بنسبة تقارب 90%.
8.2 المجمّعات الزائدة التي كانت تأكل الذاكرة
كشف الفحص الأمني في إعدادات PHP أن النظام كان يشغل تلقائياً مجمّعات إضافية على إصدار PHP 8.5 غير المستخدم. تم تنظيف هذه الملفات وإيقاف العمليات الفائضة:
rm -f /etc/php/8.5/fpm/pool.d/siteuser.conf
systemctl reload php8.5-fpm
أدى ذلك إلى توفير استهلاك الذاكرة العشوائية وتثبيت استقرار النظام.
9. التجربة كلها في جدول إجرائي واحد
لأي مهندس نظم أو مطور يواجه حالة اختراق مشابهة، يلخص الجدول التالي الخطوات القياسية المعتمدة:
| المرحلة | الإجراء العملي | الأمر / الأداة | الغاية |
|---|---|---|---|
| 1. العزل | فصل الموقع فوراً وتغيير كلمات مرور قواعد البيانات وSSH | passwd, wp-config.php |
منع المهاجم من متابعة التحكم |
| 2. فحص ملفات الأساس | تحميل نسخة نظيفة رسمية والتخلص من النسخة الأساسية القديمة | wp core download --force |
استبعاد أي تعديل على ملفات ووردبريس الأساسية |
| 3. تنقية الملفات المرفوعة | نسخ مجلد uploads واستبعاد أي امتداد تنفيذي برمجياً |
tar --exclude='*.php' |
التخلص من الأبواب الخلفية المرفوعة كملفات صور |
| 4. عزل النظام | إنشاء مستخدم لينكس مستقل ومجمّع FPM خاص (Pool) خاص بصلاحيات 750 | useradd, chmod 750 |
منع انتقال العدوى للمواقع المجاورة على نفس الخادم |
| 5. تنظيف الحسابات | مراجعة وحذف كافة المسؤولين المشبوهين | wp user delete |
إغلاق حسابات العودة الخفية |
| 6. تنظيف المقالات | حذف مقالات التشويه والمسودات الخبيثة | wp post delete --force |
استعادة نظافة الصفحة الرئيسية وقواعد البيانات |
| 7. تنظيف التعليقات | حذف تعليقات الروابط المشبوهة والمزعجة Spam | DELETE FROM wp_comments |
حماية سمعة الموقع ونتائج محركات البحث (SEO) |
| 8. حماية الويب | حظر تنفيذ PHP بالـ uploads وإغلاق XML-RPC | Nginx security.conf |
سد ثغرات إعادة الاختراق على مستوى الخادم |
| 9. طرف الشبكة عبر Cloudflare | وضع WAF Challenge على wp-login.php وضبط النطاقات البديلة |
Cloudflare WAF & Aliases | صد هجمات التخمين وتفادي أخطاء SSL 525 |
| 10. التخزين المؤقت والمراقبة | نسخ التخزين المؤقت بالكامل ومراقبة access.log و htop |
wp cache flush, tail -f |
التحقق التام من استقرار البيئة وعودة الأداء الطبيعي |
10. ماذا تغيّر في النهاية؟
تحولت المنصة في نهاية هذه العملية من موقع معطل ومخترق تتصدره شاشات التشويه وتستهدفه شبكات البوتات، إلى منصة تعمل وفق معايير الحماية متعددة الطبقات (Defense-in-Depth):
- عزل برمجي ونظامي كامل: كل موقع مستقل في بيئة مستخدم مستقلة تماماً لا تؤثر ولا تتأثر بغيرها.
- قواعد بيانات نظيفة 100%: حذف كافة الحسابات والمقالات والتعليقات الخبيثة وتأمين جداول الموقع.
- طبقة حماية شبكية استباقية: صد هجمات التخمين عبر Cloudflare قبل وصولها للخادم، فلا تستهلك أي موارد منه.
- أداء مستقر وسريع: استهلاك معالج منخفض جداً، شهادات أمان سارية مع تجديد آلي مضمون، وعودة الموقع لخدمة زواره بكفاءة وأمان تام.
إذا كنت تمر بحالة مشابهة، فـإنقاذ المواقع المخترقة يبدأ بالعزل والتنظيف قبل أي نقل. وإن كانت المشكلة عطلاً غير أمني، فـإصلاح الموقع المتوقف يغطي التشخيص والاستعادة ومنع التكرار.