前回の記事では、Tor Browser で実行される Kali Linux コンテナと、VNC クライアントを使用してそのデスクトップ環境に接続するデモを行うことができました。ブラウジング セッション中に Tor ブラウザが Tor ネットワークに接続していることを確認しました。この設定により、Web サイトをターゲットにした攻撃者からのトラフィックの種類をシミュレートできるようになります。
この実験では、Selenium を使用して Tor ブラウザを自動化し、ブラウザの WebDriver インターフェイスを通じてキーストロークとナビゲーション イベントを合成します。各クローラーには、検出を回避するために埋め込まれた Tor プロキシによって提供されるランダムな IP アドレスが割り当てられます。結果を JSON オブジェクトとしてローカル ファイル システムに保存した後、Python を使用してそれらを 1 つの CSV ファイルに処理します。最後に、ボット アクティビティの検出、レート制限、ブロックを試みるために、データ センターとクライアント側でどのような対抗措置を適用できるかについて説明します。
すべてのファイルと該当するライセンスは、このオープンソース リポジトリ: tor-driver-pythonで入手できます。
私にはテスト自動化の経験があり、テストの設計に何時間も費やしてきました。また、私は Selenium の使用に多くの時間を費やし、テスト目的で Web ブラウザを自動化するためにさまざまなプログラミング言語や設定で Selenium を使用してきました。実際のブラウザーでのみ Web アプリケーションをテストできるシナリオがあり、Selenium はそのための優れたツールです。
DevOps エンジニアとしての仕事の中で、私は自分が担当する Web アプリケーションを攻撃し、場合によっては完全に攻撃する Web クローラーをどうするかについて、少なからぬ時間を費やしてきました。この問題の裏側を一度探ってみるのは興味深い実験になるだろうと思いました。
教育目的でボットネットからの攻撃のシミュレーションにどこまで近づけるかを確認し、最新のデータセンターで不審な Tor ネットワーク トラフィックなどに対抗する方法について議論したいと考えています。ボットネットは、Credential Stuffing 攻撃を実行するためによく使用されます。同様の手法を使用して、クエリを検索し、Web から情報を収集します。
クレデンシャル スタッフィングとは、ユーザー アカウントに不正にアクセスするために、盗んだユーザー名とパスワードのペア (「クレデンシャル」) を Web サイトのログイン フォームに自動的に挿入することです。 1
倫理的な問題を回避しながら、任務に忠実であり続けるために。シナリオに次の変更を加えます。
robots.txt
ファイルを含むサイトを意図的にターゲットにしており、執筆時点ではクロールを除外しない利用規約がチェックされています。たとえば、IMDB の利用規約では、書面による同意のないクロールを明示的に禁止しています。
Robots Exclusion Protocol は、ウェブマスターがクローラーに、自分がどこにいるのか、どこから情報を収集することが許可されていないのかを伝える方法です。詳細と例は、 robotstxt.org Web サイトでご覧いただけます。検索結果ページで Web スクレイピングを許可する検索エンジンを探しているときに、「代替検索エンジンのリスト」という記事を見つけました。以下はその研究の概要です。
検索エンジン | robots.txt URL | クロールは許可されていますか? |
---|---|---|
いいえ、ただし API はあります | ||
いいえ、ただし API はあります | ||
いいえ | ||
いいえ、ただし API はあります | ||
はい、でも私が探していたものとはまったく違います | ||
はい |
このトピックの調査中に役立つことがわかったその他のリソース:
この例では、Selenium 以外のライブラリの使用を避けるつもりです。デモしたい非常に基本的なパターンがいくつかありますが、何が起こっているのかを理解するのが難しくなる可能性のある特定のドメイン固有言語 (DSL) に行き詰まってしまうのは避けたいのです。
ただし、テスト実行フレームワークを使用することは、この種のコードを整理する優れた方法だと思います。フレームワークを追加すると、一般的なコード構造、再試行ロジック、さらにはレポートに関する多くの問題を解決できます。
WebDriver セッションでページを操作する方法には基本的なパターンがあります。また、アクションを実行するたびに一時停止を追加します。ブラウザの自動化は不安定になる場合があります。タイムアウトによりクロールの安定性が大幅に向上し、レート制限やブロックが発生する可能性が大幅に制限されます。必要に応じて、他の検索エンジンや情報ソースへの API 呼び出しを使用してクロールを強化します。
私はセレクターに対して非常にシンプルなアプローチを採用しました。ブラウザで使用できるxpathセレクターとcssセレクターの両方を使用しています。主にアンカー タグと、クロール中にページ間を移動するための URL フラグメントに焦点を当てます。
期待条件を使用して、要素をクリックする前に要素が存在するのを待機します。 Selenium プロジェクトには多くのドキュメントがありますが、 Stack Overflowでの使用例を含む待機条件に関する議論も貴重なリソースであることがわかりました。
同様の機能を持つtbseleniumと呼ばれる既存の PyPi プロジェクトがあります。この実験では、Firefox プロファイル設定を参照しましたが、tbselenium に含まれる他の機能は必要ありませんでした。 root アクセス権を持たないコンテナによるさらなる複雑さは、すべてデバッグをより困難にする一因となっていました。これにより、依存関係を制限し、単純な既存のソリューションを試す動機がさらに高まりました。たとえば、純粋な Python ソリューションを直接実装する代わりに、Linux ツールやサブシェルを使用している場所がたくさんあります。
完成したクラスは約 150 行の Python です。レビューする内容が少なくなり、何が起こっているかを詳細に分析することが容易になると思います。 Tor ブラウザ ランチャーの仕組みや Firefox プロファイルの設定方法について多くのことを学びました。このプロファイルはオンラインの複数のソースから収集されており、このドキュメントだけでなくソース コードにも記載されています。
私は、起動、分解、およびナビゲーション ロジックの非常に一般的な部分をTorDriver
というクラスに抽象化しました。これは、Tor Browser Launcher を使用して Firefox プロファイルを設定する非常に単純なクラスです。これには、要素がページ上に表示されているかどうかを確認するメソッドと、プロキシ ソケットが稼働していることを確認するメソッドがあります。 Firefox プロファイルのセットアップとデバッグは、スタック オーバーフローのディスカッション「 Open Tor Browser with Selenium 」から主に情報を得ました。
完成したファイルは次の場所にあります: tor-driver-python/torDriver.py
セットアップおよび WebDriver コンポーネント用の Selenium、pprint、サブプロセス、およびソケットをインポートします。
次のメソッドは要素のチェックを抽象化し、タイムアウト内に要素が表示される場合はTrue
またはFalse
を返します。
プロキシ ポートは、信号を送信する前にアクティブにする必要があります。 Python でのソケット接続のテストに関する Stack Overflow のいくつかの例に従って、次のことを思いつきました。
モジュールの大部分は、Firefox プロファイルを制御し、geckodriver をダウンロードし、torbrowser-launcher を開始するクラスです。
ここでは、基本的な構成とオーバーライドするいくつかの方法を示しますが、ほとんどの場合、これをできるだけシンプルに保ちます。
プロキシ ポートに接続するには、Firefox プロファイルを最低限設定する必要があります。また、JavaScript も無効にしました。
これは、TorDriver のプロファイルとバイナリを使用してドライバーを初期化します。
サブプロセスに geckodriver をダウンロードして抽出するメソッドを追加します。コンテナ内で実行すると、何らかの理由でtar.gz
圧縮されなくなり、アーカイブを解除する必要があるだけであることに言及する価値があります。エラーの詳細については、 「stdin: not in gzip format」エラーを参照してください。
ソケットが応答するまで、プロキシ ポートへの接続を再試行します。
この例では、次の 2 段階のアプローチを採用しました。最初のフェーズは情報収集であり、次のフェーズは情報の処理です。こうすることで、プロセス全体でネットワーク接続に縛られることがなくなり、ソース素材に戻ることなく、必要なだけ結果の解析を再試行できます。
完全なファイルはここにあります: tor-driver-python/crawler.py
クローラーはテキスト ファイルを読み取り、その情報を使用して WebDriver セッションにクエリを設定します。クロールの状態は、クエリごとに 1 つの json ファイルのフォルダーに保存されます。情報を 1 回エクスポートするために絶対に必要な最小限の処理を実行しようとします。その後の処理は、サイトに戻らずに既存のデータ内で行うことができます。
検索結果を保存するためにテキスト ファイルを使用しています。テキスト ファイルを選択したのは、再構成が非常に簡単であるためです。テキストの編集は、新しい情報でクロールを開始したり、途中で失敗したクロールを再開したりする際の障壁が低いです。このクローラにさらに複雑なデータ要件がある場合は、代わりにデータベースの使用を検討します。これにより、レポート用にカスタム ユーザー インターフェイスでスキャンを制御するための API を実装できるようになります。
サンプル ファイルは、リポジトリの結果フォルダーにすでに存在しています: tor-driver-python/results
より堅牢なクローラーでは、実際のデータベース テクノロジーを使用することをお勧めします。これだけで、データ収集がどこで停止したかが簡単にわかり、再開が容易になります。
クローラーは、次のコマンドを使用してコンテナーから実行できます。レポート ジェネレーターには JSON ファイルが存在する必要があります。エクスポート CSV ファイルの例は次の場所にあります。
コンテナを起動します。
docker run -it --rm -p 5901:5901 -v "${HOME}/src":/src excitingtheory/kalilinux-xvfb:torbrowser
コンテナ内で VNC サーバーを起動すると、セッション パスワードの入力を求められます。
/opt/start-vnc-server-once.sh
VNC セッション内からクロールを開始します。
python3 crawler.py
クローラーは Tor ブラウザの初期化を待ちますが、残念ながらこれは手動の手順です。チェックボックスをクリックして、「接続」をクリックするだけです。例についてはビデオデモをご覧ください。
レポート スクリプトは、次のファイルからカンマ区切り値 (CSV) ファイルを生成します。
クローラーがクロール中に保存する JavaScript Object Notation (JSON) 結果ファイル。 CSV 形式を選択したのは、CSV 形式が同僚と共有するためのより一般的な形式であると同時に、さらに分析するために他のツールにインポートするのが簡単であるためです。
完全なファイルは次の場所にあります: tor-driver-python/report.py
これは、組み込みの Python ライブラリを使用して、JSON の読み取り、CSV の書き込み、および書式設定とデータ表示のための URL の解析を行います。次に、結果をループしてロードし、データ処理を開始します。
これはレポート ジェネレーターの中心となる機能です。これにより、結果オブジェクトに取り込まれたデータの最終的なプレゼンテーションと順序付けが行われます。通常、URL はサイト内をクローラーが機能的に移動する場合にのみ役立ち、最終的なデータ キャプチャとしては役に立ちませんが、さらなるデータ抽出をカスタマイズするための良い開始点となります。
クロールの結果は、 ./results
ディレクトリに JSON ファイルとして保存されます。次のスクリプトを使用して、データからレポートを生成します。
python3 report.py
出力 CSV ファイルの例は次の場所にあります: tor-driver-python/output.csv
ボットのアクティビティを検出して軽減するには、いくつかの方法があります。主にデータセンター側に焦点を当てますが、クライアント側の検出方法についてもいくつか説明します。ただし、クライアント側の信号はいつでも変更される可能性があり、なりすましの可能性があるため、クライアントを実際に信頼することはできません。検出システムを設計する際には、このことを念頭に置くことが重要だと思います。データセンターには、これから説明する 2 つの保護形式があります。レート制限とレピュテーション ブロックです。
JavaScript だけを使用して、クライアント側でアクティブな WebDriver セッションを検出する方法はいくつかあります。 Github の関連する問題でさらに詳しく説明されています。基本的に、WebDriver プロトコルはドキュメントとウィンドウ オブジェクトを変更するため、クライアント側のコードで検出できます。
私が最も経験のあるソリューション、Fastly、AWS WAF、Nginx に焦点を当てます。 CloudFlare についてはまったくの驚きだったので、そのサービスについても説明するつもりです。
AWS ウェブ アプリケーション ファイアウォール (WAF) レートベースのルールは、サービス拒否レベルのアクティビティをブロックするために使用することもできます。また、Tor ネットワーク トラフィックの検出に使用できるデフォルトのルールもあります。詳細については、 IP レピュテーション ルールのドキュメントを参照してください。もう 1 つの一般的なアプローチは、他のデータ センターからのトラフィックをすべてブロックすることです。これは、対象者が消費者であれば安全です。ただし、企業はクラウド VPN やその他のテクノロジーを使用しており、これにより正規のトラフィックに有害な影響を与える可能性があります。
Fastly の Signal Science は非常に人気のあるソリューションであり、Tor トラフィックを特に検出するために使用できます。まず、DDOS 攻撃から保護できます。詳細については、 DDOS 軽減ページを参照してください。次に、Tor トラフィックを検出してブロックできます。これについては、 システム シグナルの使用に関するドキュメントを参照してください。
Nginxについては、これについての記事もいくつかあります: Nginx または Web アプリケーション内で匿名トラフィックをブロックする方法。基本的に、API を呼び出して Tor 終了ノードに関する情報を取得することで、IP ブロック ルールを生成し、スケジュールに従って Nginx に適用できます。
上記のクラウド プロバイダーとは驚くべき対照的に、CloudFlare は Tor クライアントのサポートを提供しています。 Tor サポート ドキュメントを見つけました。ここでは、ネットワークから Tor ユーザーにコンテンツを提供する機能について説明します。これは非常に興味深いアプローチだと思うので、今後さらに研究していきたいと思っています。
WebDriver はテスト用の強力なツールであり、API にアクセスできない場所で情報を収集するためにも使用できます。たとえば、アクセスが制限されたり、検閲されたり、価格が高すぎたり、一般に反競争的な慣行の背後にロックされたりしています。さらに良いのは、Web クローリングから収集したデータと API から収集した情報を組み合わせることです。
ボットからの悪意のあるトラフィックを防ぐのはますます困難になっており、攻撃が発生するまで待ってからそれを軽減する方法を検討するのは良いセキュリティ実践ではないため、これは重要な演習です。情報をオンラインに公開する責任を負っている人は全員、自分が担当するシステムに対して侵害された情報がどのように使用されるかを知っておくべきだと私は信じています。倫理的制約を設けた簡略化されたシナリオで、次のことを実行してこれを実証しました。