# 解析を回避しようとするWebサイトの例 改ざんされたWebサイトの調査をしていると2回目のアクセスではフィッシングサイトにリダイレクトされない事が良くあります。代表的なものとして[JPCERT/CC, JSAC2022開催レポート](https://blogs.jpcert.or.jp/ja/2022/02/jsac2022report1.html)で紹介されたLucky Visitor Scamなどがあります。 24時間程度の時間を空けたりIPアドレスを変えたりするとリダイレクトされるので、短時間で繰り返しアクセスしてくる訪問者を識別する仕組みがあるのは間違いありません。これは脅威情報を調査するセキュリティエンジニアに情報を与えないための仕組みだと考えられます。 この記事では実際に手を動かして同様の仕組みを作ることで攻撃者の手口を理解し、セキュリティエンジニアとしての対応の引き出しを広げる事を目指します。 ## 方針の検討 攻撃者の立場で考えた時、改ざんされたWebサイトに短時間で繰り返しアクセスする訪問者はWebサイトを解析しようとしている可能性が高いと考えられます。このような訪問者を識別して無害なWebサイトに誘導したり、または改ざんによって付加した機能を実行させない方法を考えます。 注意するべきはセキュリティエンジニアと一般訪問者をまとめて排除しないようにすることです。特に企業を狙ったフィッシングサイトでは、Webサイトの訪問者が企業のゲートウェイを通じてアクセスしてくるため、IPアドレスだけに着目すると多数の一般訪問者を一人のセキュリティエンジニアと間違えてしまう可能性があります。 これを踏まえると、ブラウザのCookieで訪問者を識別する方法や、ある程度の時間が空いた同一IPアドレスからのアクセスを許可する方法が考えらえます。他にも、検索エンジン経由でアクセスした訪問者だけをターゲットにしたり、特定のWebブラウザを使っている訪問者だけをターゲットにしたりする方法も考えらえます。 この演習では実際のLucky Visitor Scamの挙動を参考に以下の方針で進めます。 - 前回のアクセスから30分以内にアクセスしたIPアドレスを解析者のものと判断する - google、yahoo、bingなどの検索エンジン以外からのアクセスを解析者のものと判断する - Chrome、Firefox、Edge などのブラウザ以外からのアクセスを解析者のものと判断する - 一般訪問者にはフィッシングサイトを表示するが、解析者には無害なコンテンツを表示する ## アルゴリズムの検討 前回のアクセスから30分以内の同一IPからのアクセスを識別する方法として、以下のアルゴリズムを考えます。 1. 訪問者のIPアドレスを取得する 2. 手元に記録したリストに該当のIPアドレスが存在するか確認する 3. 存在する場合は前回のアクセスが30分以内か確認する 4. 30分以内にアクセスしている場合は該当のIPアドレスを解析者のものと判断する 5. 手元のリストにIPアドレスが記録されていなかったり、前回のアクセスから30分以上が経過している場合は該当のIPアドレスを一般訪問者のものと判断する 6. 今回取得したIPアドレスを現在時刻と共に手元のリストに記録する 検索エンジンからアクセスしてきた訪問者を識別する方法は以下の通りです。 1. 訪問者のReferrerを取得する 2. Referrerに検索エンジンのURLが含まれていない場合は解析者のものと判断する 訪問者のブラウザを識別する方法は以下の通りです。 1. 訪問者のUser-Agentを取得する 2. User-Agentに特定の文字列が含まれていない場合は解析者のものと判断する User-Agentによるブラウザの識別は難しい作業です。以下の情報源などを参考に適切な文字列を考える必要があります。 [MDN Web Docs, ユーザーエージェント文字列を用いたブラウザーの判定](https://developer.mozilla.org/ja/docs/Web/HTTP/Browser_detection_using_the_user_agent) [Microsoft Learn, Web サイトから Microsoft Edge を検出する](https://learn.microsoft.com/ja-jp/microsoft-edge/web-platform/user-agent-guidance) ## コーディング {%gist ox0xo/a953176f12ca9abdb0a6f9dc4f05e582%} ## 動作確認 上記のコードは以下のようなフォルダ構造で動作します。 server.pyと同じ階層にiplistを置くことを忘れないでください。 ``` $ tree . ├── iplist └── server.py ``` このコードはFlaskを利用しているためモジュールをインストールしておく必要があります。 そのうえでserver.pyを実行して下さい。 以下のようなログが表示されたら正常に動作しています。 ``` $ python3 server.py * Serving Flask app 'server' * Debug mode: on WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Running on all addresses (0.0.0.0) * Running on http://127.0.0.1:8080 * Running on http://10.7.0.4:8080 Press CTRL+C to quit * Restarting with stat * Debugger is active! * Debugger PIN: 341-266-266 ``` このサーバにWindowsコマンドプロンプトからアクセスする場合は以下のコマンドを参照してください。 ``` > curl -H "Referer:www.google.com" -H "User-Agent:Chrome" http://xxx.xxx.xxx.xxx:8080 ``` ## 解析回避の回避を考える すでに動作確認したように、RefererやUser-Agentを偽装することでフィッシングサイトのセキュリティ回避機構を回避する事が出来ます。IPアドレスは偽装できない(偽装できるがレスポンスを受け取れなくなる)ので、プロバイダにプールされたIPアドレスをPPPoE再接続して取り直すしかありません。企業の回線契約は固定IPの場合がありますので、その場合は調査用のIPを複数契約しておく必要があります。 IPアドレスを1つしか用意できない場合はフィッシングサイトの調査記録を残すことが重要です。2回目以降のアクセスではフィッシングサイトを確認できなくなるため、チーム内でのディスカッションには調査記録を用います。 私は[Wireshark](https://www.wireshark.org/download.html)で生パケットを取りつつ[Burp Suite](https://portswigger.net/burp)でフィッシングサイトを調査しています。Burp Suiteを使えばRefererやUser-Agentの偽装も簡単にできるため作業効率が良くなります。Burp Suiteの標準機能ではLoggerタブにリクエスト・レスポンスが記録されるため、これをSave itemsしておけば生パケットと合わせて後の調査材料にすることができます。
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up