2000P's Blog

最初のページ

sslstripの未来——https先端ハイジャック

著者 gardner 時間 2020-04-17
all

前言

以前紹介したトラフィックハイジャックの記事では、ページ中のHTTPSハイパーリンクをすべてHTTPバージョンに置き換えて、ユーザーが常に明文で通信するようにする『HTTPSダウングレード』のプランを紹介しました。

これを見ていると、クラシックな中間者攻撃の道具であるSSLStripを思い浮かべるかもしれません。

しかし、今日説明したのは全く違った考えで、より効果的で、より先進的な解決策であるHTTPSの先端ハイジャックです。

バックエンドの欠陥

過去において、トラフィックハイジャックは基本的にバックエンドで実現され、SSLStripは典型的な例であった。

他の中間者ツールのように、純粋なバックエンドの実現は最も原始的な流量データを操作することしかできません。これはより高いレベルへの発展を阻害し、多くの解決しにくい問題に直面しています。

動態元素はどうすればいいですか?

どのようにデータのスライスを処理しますか?

性能消耗は低減できますか?

……

動態元素

Webができたばかりの時代には、SSLStripというツールは大いに活用されていました。その時のウェブページはすべて静的なことを主として、構造の簡単なレベルははっきりしています。流量の上で交替して、完全に任に堪えることができます。

しかし、現在のウェブページはますます複雑になり、脚本の比重はますます多くなりました。流量だけから着手したら、明らかに力が及ばないです。

var protocol = 'https'; document.write('<a href="' + protocol + '://www.alipay.com/">Login</a>');

非常に単純な動態要素であっても、バックエンドには打掛力がない。

スライス処理

ブロック分け伝送の道理はみんなが分かります。大きなデータに対しては、一気に伝えきれません。クライアントは各データブロックを順次受信し、最終的には完全なウェブページに統合することができます。

毎回受け取ったのは欠落した破片なので、リンクの入れ替えに大きな迷惑をかけます。多くのページを加えて標準のUTF-8コードではないので、もっと難しいです。

円滑に進めるために、中間者は通常まずデータを収集し、ページが完全に受信されるまで、交換を開始します。

データを水の流れにたとえれば、この代理店はダムのように、どんどん下に流れる水を遮断して、満タンになってから釈放します。したがって、下流の人々は長い干ばつに耐えてこそ、水源を待つことができる。

性能の消耗

HTMLは多くの歴史的なレガシー仕様に対応していますので、交換作業は楽ではありません。

各種の複雑な正規表現は,多くのCPU資源を消費している。ユーザーが最終的にクリックしたのは一つか二つのリンクだけですが、中間者はどちらになるか分かりませんので、ページ全体を分析する必要があります。これは悲しいと言わざるを得ない。

先端のメリット

もし私達の仲介者がページの先端に入ることができるならば、状況はある程度改善することができますか?

スライス処理

まず、一人のスパイをページに派遣します。これはとても簡単にできます。

ハイパーリンクがページのあちこちにあるのではなく、台本を頭に差し込むだけで実行できます。ですから、私たちはページ全体のデータを使いません。次のchunkを改造すればいいです。後続のデータはまだシステムに転送されます。

したがって、全体のエージェントの時間はほとんど変わりません!

動態元素

はい、簡単にページに浸透します。しかし、その後はどう攻撃を開始しますか?

先端に行くと、かなりの方法があります。最も簡単なのは、ハイパーリンク要素を遍歴して、httpsのをhttpバージョンに変えます。

この考えは確かにいいですが、SSLStrip思考モードにとどまっています。やはり『置き換える』という道は、後端から先端に移るだけです。

この方法は大部分の場合に適任できますが、まだ完璧ではありません。ダイナミック要素がいつ追加されるかは分かりませんので、タイマーをオンにして絶えずスキャンする必要があります。これは明らかにくじけそうなやり方だ。

パフォーマンス最適化

実は、ハイパーリンクは誰が作ったのか、いつ追加されたのかに関わらず、クリックしない限り、機能しません。私たちはいつクリックすればいいのかに関心を持っています。もし私たちのプログラムがクリックによって発生した最初の時間に現場をコントロールできるなら、その後の流れは私たちが決められます。

玄そうに聞こえますが、先のほうではおかずのことです。クリックしても、イベントだけです。事件である以上、我々は最も基本的なイベント捕獲メカニズムを使って、それを簡単に取り外すことができます。

document.addEventListener('click', function(e) { // ... }, true);

DOM-3-Eventは非常に興味深いイベントモデルである。以前はこれを使って「インラインXSSブロック」を実現しましたが、今では同じくハイジャックリンクにも使えます。

全体的なクリックイベントをキャプチャしましたが、httpsハイパーリンクに落ちていることを発見したら、断固としてそれをブロックします。

もし本当にそれをブロックしたら、新しいページは現れません。もちろん、自分でwindow.openを弾いてもいいです。とにかくクリックしてください。

しかし、すべてのハイパーリンクは弾戸ではなく、直接ジャンプするものも少なくないことを忘れないでください。あなたもロカモーションを修正して実現できると言います。

しかし、「弾戸」か「ジャンプ」かを識別するのは簡単ではない。ハイパーリンクのtarget属性以外に、ページ内の「base」要素も影響します。もちろん、これらはあなたが全部解決できると信じています。

target <base>

しかし、現実は必ずしもそう簡単ではない。いくつかのハイパーリンク自体は、Oclickイベントに結びつけられています。また、return falseまたはpreventDefaultでは、デフォルトの挙動を遮断しています。これらを無視してジャンプやパチンコをシミュレートすると、ページの意思に反します。

実際には、非常に簡単な方法があります。私たちのキャプチャプログラムが実行されている時、新しいページはまだ現れていません。この時もハイパーリンクのhrefを修正する機会があります。イベントの泡が発生して、デフォルトの行動を実行する時、ブラウザはhref属性を読み取り、最終的な結果とします。

したがって、私たちはイベントをキャプチャし、ハイパーリンクのアドレスを変更すればいいです。ジャンプするか、パチンコするか、それとも遮断されるかについては、私達は関心していません。

そんなに簡単です。私達はユーザーが注文した後にやっと改正するので、ブラウザーの状態の欄の中で、表示のはやはりもとのhttpsです!

もちろん、一回注文したら、ハイパーリンクにマウスを置いて、ステータスバーに表示されるのは修正後のものです。

ゆらゆらし続けるために、私たちはhrefを修正した後の次のスレッド周期で、それを元に戻します。一定の遅延があるので、新しいページは影響を受けません。

var url = link.href; // 保存原始地址 link.href = url.replace('https://', 'http://'); // 暂时换成 http 的 setTimeout(function() { link.href = url; // 新页面打开后,还原回来 }, 0);

このように、ページの中のハイパーリンクはいつも正常です。ユーザーが注文した瞬間だけ、仮装します。

もっとブロック

ハイパーリンク以外にも、他の方法でページにアクセスします。できるだけ多くの監視を行うべきです。たとえば:

フォームの送信

フォームの提出とハイパーリンクは非常に似ています。イベントは全部持っています。clickをsubmitに変えて、hrefをactionに変えただけです。

click submit href action

スクリプト

関数の呼び出しが一番簡単です。小さなフックだけで大丈夫です。

var raw_open = window.open; window.open = function(url) { // FIX: null, case insensitive arguments[0] = url.replace('https://', 'http://'); raw_open.apply(this, arguments); }

枠のページ

ホームページをhttpに下げましたが、中のフレームの住所は元のままです。プロトコルが異なるため、ドメインをまたぐ問題が発生し、ページが正常に動作しなくなる。

だから私達は更にページの中の枠組みをhttpバージョンに変えて、ホームページと一致することができることを確保します。

しかし、フレームワークは前のものとは違っています。自動的にロードされています。これからロードされるイベントもありません。フレームのロードが完了したら処理します。クロスドメインエラーが発生したかもしれません。また、負荷量を無駄に浪費します。

ですから、枠ができたら、すぐに住所を変えなければなりません。

これは過去には厄介な問題でしたが、HTML 5時代は新たな希望をもたらしてくれました。それを使ってリアルタイムにページの元素を監視し抑制することができて、前にもいくつか試験を試みたことがあります。

MutationEvent

もちろん、MuttionEventでも、たまに遅延があります。httpsフレームページの出現を徹底的に避けるために、HTML 5がもたらした新しい技術、Conttent Security Policyを使い続けます。これはブラウザのネイティブサポートですので、徹底的に実行します。

私たちのエージェントのリターンヘッドには、以下のHTTPヘッダを加えると、httpsフレームのページを完璧にブロックすることができます。

Content-Security-Policy: default-src * data: 'unsafe-inline' 'unsafe-eval'; frame-src http://*

フレームページの問題を解決したら、宝登録ページのアカウントボックスIrameをハイジャックすることができます。

バックエンドコンビネーション

先端のXSSスクリプトを通して、過去の様々な問題を簡単に解決しました。しかし、挑戦はここで終わりませんでした。私たちはまだ多くの困難に直面しています。

代理店にどうやって教えますか

フロントエンドの上にも関わらず、httpsへのアクセスはすでに避けられています。代理はどのように決定しますか?この要求はhttpsですか?http転送ですか?

従来のバックエンドハイジャックが正確に転送されたのは、ハイパーリンクを置き換える時に記録されています。記録中の要求があったらhttpsで転送します。

私たちのハイジャックは先端にあり、クリックした瞬間だけ発生します。すぐに仲介者に教えても、あるURLがhttpsなので、間に合わないです。

仲介者に教えるのは必要です。しかし、私たちは巧みな方法で、単独でメッセージを送る必要はありません。私たちは転換後のURLの中で、小さな記号を作ればいいです。

代理が要求のURLにこのマークがあることを発見したら、自然に分かります。直接httpsに行きます。

ページをhttpsからhttpに下げたので、関連したリクエストのrefererもhttp版になりました。だから、中間者はできるだけrefererも修正して、サーバーに気づかれないようにします。

referer

偽装を隠す

しかし、URLリガでマークする方法には、大きな欠陥があります。

ページのURLはアドレスバーに表示されますので、ユーザーは私たちのマークを見ます。もちろん、いくつかの困惑した文字を使ってもいいです。例えば?zhucn、?utfu 8、?from ubaiduなど、ユーザーをよりよく騙します。

?zh_cn ?utf_8 ?from_baidu

もちろん、不満を感じるなら、目障りなマークをできるだけ早く消してもらう方法もあります。

if url has symbol history.replaceState(..., clear_symbol(url) )

HTML 5は、アドレスバーを変更する能力を提供してくれて、更新する必要がありません。これらの強力な機能は、今では先端でも使えるようになりました。

リダイレクトハイジャック

もちろん、先端だけのハイジャックは、まだまだ足りません。現実にはもう一つのよくある方法があります。それは安全ページにリダイレクトすることです。

よく考えてみると、普段私たちはどうやって行きたいサイトに入りますか?例えば宝を支払って、コレクションがない限り、自分でwwww.alipad.comまたはwww.zhifubao.comに打ち込まなければなりません。車を返して入ると、ブラウザはどのようにHTTPSのウェブサイトですか?

最初の要求は依然として一般的なHTTPプロトコルであることは明らかである。もちろん、このHTTP版の支払宝は確かに存在します。その唯一の機能はユーザーをHTTPSバージョンにリダイレクトします。

私たちの中間者がHTTPSサイトにリダイレクトしていることを発見したら、もちろんユーザーは自分でコントロールされていないこの道を行きたくないです。このリダイレクトをブロックし、HTTPSとしてリダイレクトしたコンテンツを取得し、最後にHTTP平文としてユーザーに返信する。

したがって、ユーザーから見ると、常にHTTPサイトにあります。

しかし、今のWebには新しいセキュリティ基準が追加されています。HTTP Strict Transport Security。クライアントがこのヘッダを受信すると、その後しばらくの間、このサイトにアクセスし、常にHTTPS方式を通じている。

だから私たちの仲介者はこのフィールドがあると見つけたら、断固として削除しなければなりません。

もちろん、ユーザーが直接ウェブサイトを叩くのはあまり見られません。ほとんどが検索エンジンで、最初の結果から直接入ってきました。

悲劇的なのは、国内の検索エンジンはほとんどHTTPのものです。ユーザーが検索ページにアクセスする時、私達のXSSはすでにその中に潜伏しています。そのため、中点から出てきたどのような結果も公式のHTTPSの中に入ることができません。)

検索ページ以外にも、多くのhao 123のようなウェブサイトの大全書があります。ほとんどHTTPSを開いていません。したがって、このサイトからは、仲介者に乗っ取られる危険がある。

予防措置

攻撃方法を紹介して、防御措置を説明します。

スクリプトジャンプ

実際には、フロントエンドハイジャックやバックエンドのフィルタリングは、まだ多くのサイトが成功していません。例えば京東の登録:

スクリプトを通じてHTTPSアドレスにジャンプしました。ブラウザのlocationは特殊な属性です。それは遮断されますが、書き換えられません。したがって、私たちはページのジャンプ状況をコントロールするのが難しいです。

location

もし京東ページを乗っ取るなら、私達は白いリストの方式を使うしかないです。特別にこのサイトに対応します。これにより攻撃コストが大幅に増加しました。

明文を混同する

もちろん、京東の登録台本にはURLが一番白い明文で登場しています。したがって、SSLStripを使って、脚本のhttps:/のテキストを入れ替えたり、一定の役割を果たしたりするのですが、ほとんどのシナリオは無防備です。

https://

しかし、やや複雑なシナリオについては、例えば文字列を介して連結されたURLのようなものでは、実行が困難になります。

安全が必要な場合は、重要な住所を簡単に処理してもいいです。中間者は一般的な方法で攻撃することができません。サイトに対して特別扱いをしなければならないので、攻撃コストが高くなります。

できるだけ多くのHSTS

前にHSTSヘッダに言及しました。このフィールドが一度出現する限り、ブラウザは長い間HTTPSだけでサイトにアクセスします。したがって、できるだけ多くのHSTSをオープンします。

HSTS HTTP -> HTTPS

フロントエンドスクリプトのメリットのおかげで、私たちは登録ハイパーリンクにマウスを置いて、ステータスバーに表示されるのは元のURLです。

私たちがクリックした瞬間、隠れページの中のXSSフックがトリガされました。私たちを中間者の仮想HTTP登録ページに連れて行くことに成功しました。

もちろん、URLパラメータが多いので、アドレスバーのマークが見えなくなりました。

幸いなことに、タオバオの登録ページは住所の判断を行っていません。降格された後のページはまだ登録できます。

もちろん前にも言いましたが、すべてのページがハイジャックに成功したわけではありません。

今はより多くのサイトが重視されているため、先端のセキュリティチェックも生まれています。一つの道具だけで、大規模な汎用性のハイジャックを実現するのは、今後さらに困難になります。

しかし、従来の純粋なバックエンドよりも先に実現し、前後に結合されたスキームはより大きな再生空間をもたらすことができる。