Skip to content
KitploitKITPLOIT
أدواتالمدونة
Log in
إرسال
أدواتالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
POC-CVE-2026-65971 — إثبات المفهوم وتقرير فني لـ CVE-2026-65971 — حقن SQL عبر خاصية sortDirection في Livewire في power-components/livewire-powergrid (< 6.10.4) | Kitploit
أدوات/GitHubGitHub/biitts/poc-cve-2026-65971
تحليل الثغرات الأمنيةالاستغلالاستغلال تطبيقات الويباختبار الاختراقالأوراق والأبحاثالتعلم والتعليم
GitHubbiitts/poc-cve-2026-65971

POC-CVE-2026-65971

إثبات المفهوم وتقرير فني لـ CVE-2026-65971 — حقن SQL عبر خاصية sortDirection في Livewire في power-components/livewire-powergrid (< 6.10.4)

عرض المستودع
19منذ 2 أشهرلم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

CVE-2026-65971 — حقن SQL في Livewire PowerGrid عبر sortDirection

إثبات المفهوم وكتابة فنية كاملة لـ CVE-2026-65971 / GHSA-7fgc-3h6c-698r، ثغرة حقن SQL في power-components/livewire-powergrid يمكن الوصول إليها عبر خاصية Livewire العامة sortDirection.

CVECVE-2026-65971
GHSAGHSA-7fgc-3h6c-698r
الحزمةpower-components/livewire-powergrid (Composer / Packagist)
المتأثر>= 6.0.0, < 6.10.4
تم التصحيح6.10.4
الضعفCWE-89 — تحييد غير صحيح للعناصر الخاصة المستخدمة في أمر SQL
الخطورة7.6 عالية — CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:L
أبلغ من قبلCaio Fabrício (@BiiTts)
الإفصاحمنسق، عبر استشارة أمنية خاصة على GitHub
├── poc/exploit_powergrid_sqli.py working exploit — confirm + blind extraction
├── lab/ build the vulnerable app to reproduce it yourself
├── evidence/EVIDENCE.txt raw lab notes from confirmation
├── patch/security-fix-v6.10.4.diff the security-relevant portion of the official fix
└── detection/ Sigma rules + Nuclei template for defenders
---

## 🧠 ملخص

PowerGrid هو مكوّن datatable لإطار Laravel + Livewire (~2k نجمة، يُستخدم على نطاق واسع في
لوحات تحكم Laravel). حالة الفرز الخاصة به تعيش في **خاصيتين عامتين في Livewire**:```php
public string $sortField = 'id';
public string $sortDirection = 'asc';

في Livewire، تُعد الخاصية العامة جزءًا من تنسيق wire الخاص بالمكوّن — أي عميل يمكنه الوصول إلى المكوّن يستطيع تعيينها عبر POST /livewire/update. هذا أمر مقصود بالتصميم؛ الحدود الأمنية تكمن في ما يفعله الخادم بالقيمة.

ميزة naturalSort() في PowerGrid تُنشئ تعبير ORDER BY خامًا يحتوي على العنصر النائب الحرفي {sortDirection}، ويستبدل خط أنابيب المعالجة هذا العنصر النائب بـقيمة الخاصية الخام، غير المُتحقَّق منها قبل تمرير السلسلة إلى orderByRaw(). كلمة الاتجاه تستقر بالتالي حرفيًا داخل SQL.

يرفض orderBy() الخاص بـ Laravel أي شيء ليس asc/desc، وهذا التحقق هو ما يجعل مسار الفرز العادي آمنًا. الخلل هو وجود مسارٍ ثانٍ غير مُتحقَّق منه إلى نفس الجملة — ويستطيع المهاجم الوصول إليه متجاوزًا المسار المُتحقَّق منه بالكامل (انظر الالتفاف).

النتيجة: SQL عشوائي في جملة ORDER BY، قابل للاستغلال كأوراكل أعمى زمني/منطقي لقراءة أي بيانات يمكن لمستخدم قاعدة البيانات قراءتها.


🔥 الأثر

يمكن لأي شخص يمكنه الوصول إلى جدول PowerGrid يستخدم naturalSort قراءة بيانات عشوائية من قاعدة البيانات — جداول أخرى، تجزئات كلمات مرور، رموز جلسات، مفاتيح API، سجلات عبر المستأجرين — باستخدام أوراكل زمني/منطقي.

  • السرية: عالية. قراءة كاملة لأي شيء يمكن لمستخدم قاعدة البيانات تنفيذ SELECT عليه.
  • النزاهة: منخفضة. الاستعلامات المكدّسة محجوبة بواسطة الإعداد الافتراضي لـ PDO MySQL، لذلك ; UPDATE ... لا يتم تنفيذه. أثر الكتابة محدود بما يمكن أن تُحدثه استعلامات فرعية.
  • التوفر: منخفض. نفس الآلية تمنح المهاجم SLEEP() واستعلامات فرعية ثقيلة — يمكن إساءة استخدامها بسهولة لإشغال خيوط قاعدة البيانات.
  • الموضع النموذجي هو عامل التفاقم. جداول PowerGrid توجد في لوحات الإدارة و المكاتب الخلفية متعددة المستأجرين — أي بالضبط حيث توجد البيانات المثيرة للاهتمام. يمكن لمستخدم مستأجر منخفض الامتياز يصل إلى أحد هذه الجداول سرقة قاعدة البيانات بأكملها.

الامتيازات المطلوبة هي PR:L لأن جدول البيانات يوضع عادةً خلف مصادقة التطبيق. إذا كان الجدول المتأثر يُعرض على صفحة غير مصادق عليها، فأعد الحساب مع PR:N → 8.2 عالية.


🧩 السبب الجذري — سلسلة التلوث الكاملة

ثلاثة ملفات، ثلاث مراحل. جميع الإشارات إلى الإصدار الضعيف v6.10.3.

المرحلة 1 — المصدر: خاصية عامة يتحكم فيها المهاجم

`src/Concerns/Sorting.php````php public string $sortField = 'id'; // line 11 public string $sortDirection = 'asc'; // line 13

لا تحتوي أيٌّ من الخاصيتين على قائمة سماح، أو قاعدة تحقّق، أو مُعيِّن تطبيع. `sortDirection` يتم تعيينه أو قلبه فقط:```php
public function reverseSort(): string    // line 37
{
    return $this->sortDirection === 'asc' ? 'desc' : 'asc';
}

updatedSortDirection() (السطر 103) موجودة — وهي المكان الطبيعي للتحقق — لكن في v6.10.3 تتعامل فقط مع مسك دفاتر التحميل الكسول. ولا تفحص القيمة أبدًا.

نظرًا لأن Livewire يملا الخصائص العامة مباشرة من الطلب، فإن sortDirection يخضع بالكامل لسيطرة المهاجم، كسلسلة نصية عشوائية، في هذه المرحلة.

المرحلة 2 — الجملة الخام: naturalSort() تزرع عنصرًا نائبًا

src/Providers/Macros.php، الأسطر 102–116 — ماكرو العمود naturalSort:```php Column::macro('naturalSort', function (bool $when = false, ?string $tableName = null): Column { $this->enableSort();

if ($when) {
    $this->rawQueries[] = [
        'method'   => 'orderByRaw',                          // <-- raw sink
        'sql'      => Sql::sortStringAsNumber($this->dataField),
        'bindings' => [],
    ];
}

return $this;

});

`Sql::sortStringAsNumber()` يؤول إلى تعبير خاص بكل مُحرّك يُبنى بواسطة
`getSortSqlByDriver()` في `src/DataSource/Support/Sql.php` (الأسطر 60–100). كل نسخة من نسخ المُحرّك
تنتهي بنفس العنصر النائب الحرفي:```php
$default = "$sortField+0 {sortDirection}";                                                          // line 76
'8.0.4'  => "CAST(NULLIF(REGEXP_REPLACE($sortField, '[[:alpha:]]+', ''), '') AS SIGNED INTEGER) {sortDirection}",  // MySQL, line 81
'0'      => "CAST($sortField AS INTEGER) {sortDirection}",                                          // SQLite, line 84
'0'      => "CAST(NULLIF(REGEXP_REPLACE($sortField, '\D', '', 'g'), '') AS INTEGER) {sortDirection}", // PgSQL, line 87
'0'      => "CAST(SUBSTRING(...) AS INT) {sortDirection}",                                          // SQL Server, line 90

الثغرة مستقلة عن برنامج التشغيل — كل فرع يضمّن {sortDirection}.

المرحلة 3 — Sink: يتم حل العنصر النائب باستخدام قيمة الخاصية الخام

`src/DataSource/Processors/Database/Pipelines/ColumnRawQueries.php````php private function resolvePlaceholders(?string $sql): ?string // line 56 { if (is_null($sql)) { return null; }

return preg_replace_callback('/\{(\w+)\}/', function ($matches) {
    $property = trim($matches[1]);

    return data_get($this->component, $property, '');   // line 65 — raw property, no escaping
}, $sql);

}

والتنفيذ، السطر 52:```php
$query->{$method}($resolvedSql, $resolvedBindings);   // $method === 'orderByRaw'

data_get($this->component, 'sortDirection') ترجع سلسلة المهاجم، وpreg_replace_callback تدمجها في نص SQL، وorderByRaw() — التي بموجب العقد لا تهرب وسيطتها — تمررها إلى قاعدة البيانات.

لاحظ السخرية اللاذعة في السطر التالي: resolveBindings() (السطر 69) موجودة، وnaturalSort يعلن 'bindings' => []. آلية البارامترة الآمنة موجودة هناك تمامًا. لا يمكن استخدامها لكلمة اتجاه — ORDER BY x ? ليست SQL صالحة، والاتجاه لا يمكن أبدًا أن يكون بارامترًا مربوطًا — وهذا هو بالضبط سبب أن كلمة الاتجاه يجب أن تكون مدرجة في القائمة البيضاء بدلاً من ذلك.

السلسلة في سطر واحد```

POST /livewire/update ──▶ public string $sortDirection (Sorting.php:13, no validation) ──▶ data_get($component, 'sortDirection') (ColumnRawQueries.php:65) ──▶ "CAST(...) {sortDirection}" → "CAST(...) asc, (SELECT SLEEP(3))" ──▶ orderByRaw($sql) (ColumnRawQueries.php:52) ──▶ MySQL/MariaDB/PgSQL/SQLite/MSSQL

---

## 🔓 التحايل — لماذا لا ينقذك تحقق Laravel

هذا هو الجزء الذي يحوّل "الاستيفاء الخام" إلى ثغرة قابلة للاستغلال فعلاً، وهو السبب في بقاء المشكلة في حزمة ناضجة واسعة الاستخدام.

يعالج PowerGrid استعلامًا عبر **خط أنابيب**. هناك مرحلتان من ذلك الخط تمسّان اتجاه الفرز:
تنزيل الأداة