こんにちは。コーポレート本部 サイバーセキュリティ推進部の耿です。
Web サービスへの攻撃を防ぐために WAF を使いましょうというのはよく聞きます。
ではインターネットに公開した Web サービスに送信される悪意のあるリクエストがどれぐらい WAF によって防御され得るのでしょうか?
お手軽に使える AWS WAF のマネージドルールを対象に確かめてみました。
この記事の概要
- 実験用に固定レスポンスを返すだけの HTTP エンドポイントを作成し、約半年間インターネットからアクセス可能な状態で放置した
- AWS WAF のマネージドルールをアタッチしており、それぞれのルールに一致したリクエスト数を集計し、ランキング形式にまとめた
- 一致したリクエスト数が多いマネージドルールそれぞれに対して、どのようなリクエストが多かったのか集計し、ランキング形式にまとめた
- 実験用システムの構成
- 基本的なデータの集計
- 一致した数が多い個別のマネージドルール
- 1位: AWSManagedRulesAnonymousIpList - HostingProviderIPList
- 2位: AWSManagedRulesKnownBadInputsRuleSet - ExploitablePaths_URIPATH
- 3位: AWSManagedRulesAdminProtectionRuleSet - AdminProtection_URIPATH
- 4位: AWSManagedRulesCommonRuleSet - NoUserAgent_HEADER
- 5位: AWSManagedRulesLinuxRuleSet - LFI_URIPATH
- 6位: AWSManagedRulesCommonRuleSet - UserAgent_BadBots_HEADER
- 7位: AWSManagedRulesAmazonIpReputationList - AWSManagedReconnaissanceList
- 8位: AWSManagedRulesKnownBadInputsRuleSet - ExploitablePaths_URIPATH_RC_COUNT
- 9位: AWSManagedRulesCommonRuleSet - RestrictedExtensions_URIPATH
- 10位: AWSManagedRulesAmazonIpReputationList - AWSManagedIPReputationList
- 11位: AWSManagedRulesCommonRuleSet - GenericLFI_URIPATH
- まとめ
実験用システムの構成
ALB を主体としたシンプルな構成としました。
- AWS 東京リージョンに200番の固定レスポンスを返すだけの ALB を構築した
- ALB のセキュリティグループは 80 ポートと 443 ポートのみをオープンにし、
0.0.0.0/0
からのアクセスを許可した - 独自ドメインの ACM 証明書を取得し、ALB にアタッチした。ホストゾーンのレコードも ALB を向くように構成した
- ただし ALB の IP アドレスも、独自ドメイン名も特に外部向けに公表していない
- WAF Web ACLをアタッチし、AWS マネージドルールグループを複数適用した
- ただしマネージドルールグループのアクションは全て
COUNT
にオーバーライドし、ルールに一致してもリクエストがブロックされないようにした - 適用したマネージドルールグループは次の11個である
- AWSManagedRulesCommonRuleSet
- AWSManagedRulesAdminProtectionRuleSet
- AWSManagedRulesKnownBadInputsRuleSet
- AWSManagedRulesSQLiRuleSet
- AWSManagedRulesLinuxRuleSet
- AWSManagedRulesUnixRuleSet
- AWSManagedRulesWindowsRuleSet
- AWSManagedRulesPHPRuleSet
- AWSManagedRulesWordPressRuleSet
- AWSManagedRulesAmazonIpReputationList
- AWSManagedRulesAnonymousIpList
- 全てデフォルトバージョンを適用した。期間中にバージョンがアップデートされている場合がある
- ただしマネージドルールグループのアクションは全て
- WAF のログを S3 バケットに出力するよう構成した
補足として、ルールのアクションは全て COUNT
にオーバーライドしても、特定のルールに一致した場合はリクエストに特定のラベルが付与されます。ログに出力された各リクエストのラベルを確認することで、どのルールに一致したかを判別できるようになっています。アクションは全て COUNT
なので、複数のルールに一致した場合には、一致した全てのルールのラベルが付与されます。
2023年10月中旬に稼働を開始し、2024年4月上旬までの約173日間のログを対象に集計を行いました。
基本的なデータの集計
ログ総数
稼働期間中のログ総数と、マネージドルールに一致したログエントリー数をまとめました。
説明 | 件数 | 総数に対する割合 |
---|---|---|
ログエントリー総数 | 153,220 件 | 100% |
いずれかのマネージドルールに一致したログエントリー数 | 115,844 件 | 76% |
いずれのマネージドルールにも一致しなかったログエントリー数 | 37,376 件 | 24% |
記録されていたログエントリー数(リクエスト数)は153,220件で、稼働期間の173日で割ると約886件/日となります。何も外部に公表していない HTTP エンドポイントでもこれだけのリクエストがインターネットから届いていることがわかります。
いずれかのマネージドルールに一致したログエントリー数は 115,844件で、全体の約76%にあたります。これだけの割合のリクエストが、今回利用したAWS WAF マネージドルールのブロック対象となっていたということです。
国名コード別のリクエスト数
マネージドルールに一致したかどうかに関わらず、全てのリクエストについて国名コード別の上位10件をまとめました。
順位 | 国名コード | 件数 | 総数に対する割合 |
---|---|---|---|
1 | US | 47,129 件 | 31 % |
2 | IL | 17,172 件 | 11 % |
3 | FR | 14,883 件 | 10 % |
4 | GB | 12,890 件 | 8 % |
5 | SG | 7,189 件 | 5 % |
6 | JP | 7,026 件 | 5 % |
7 | DE | 5,972 件 | 4 % |
8 | ID | 5,759 件 | 4 % |
9 | NL | 5,408 件 | 4 % |
10 | CN | 5,219 件 | 3 % |
HTTPメソッド別のリクエスト数
マネージドルールに一致したかどうかに関わらず、全てのリクエストについてHTTPメソッド別のリクエスト数をまとめました。
順位 | HTTPメソッド | 件数 | 総数に対する割合 |
---|---|---|---|
1 | GET | 129,700 件 | 85 % |
2 | POST | 19,839 件 | 13 % |
3 | HEAD | 3,113 件 | 2 % |
4 | OPTIONS | 565 件 | 0 % |
5 | PURGE | 2 件 | 0 % |
6 | PUT | 1 件 | 0 % |
GET リクエストが圧倒的に多く、全体の 85% を占めています。
それぞれのマネージドルールグループに一致したリクエスト数
適用した11個のマネージドルールグループそれぞれに一致したリクエスト数と割合をまとめました。注意点として複数のルールに一致した場合には、一致したルール全てに重複して計上されています。
マネージドルールグループ | 件数 | リクエスト総数に対する割合 |
---|---|---|
AWSManagedRulesCommonRuleSet | 18,286 件 | 12 % |
AWSManagedRulesAdminProtectionRuleSet | 10,069 件 | 7 % |
AWSManagedRulesKnownBadInputsRuleSet | 16,081 件 | 10 % |
AWSManagedRulesSQLiRuleSet | 6 件 | 0 % |
AWSManagedRulesLinuxRuleSet | 8130 件 | 5 % |
AWSManagedRulesUnixRuleSet | 23 件 | 0 % |
AWSManagedRulesWindowsRuleSet | 111 件 | 0 % |
AWSManagedRulesPHPRuleSet | 243 件 | 0 % |
AWSManagedRulesWordPressRuleSet | 226 件 | 0 % |
AWSManagedRulesAmazonIpReputationList | 6,289 件 | 4 % |
AWSManagedRulesAnonymousIpList | 100,886 件 | 66 % |
大きな差はありますが、いずれのルールグループも一致するリクエストがありました。目立って多いのは AWSManagedRulesAnonymousIpList ルールグループで、全リクエストの 66% が一致しました。
一致した数が多い個別のマネージドルール
マネージドルールグループの中でも、一致したリクエスト数が多い個別のマネージドルールを集計しました。
1000件以上のリクエストが記録された上位11種類を掲載します。
順位 | マネージドルールグループ | 個別ルール名 | 件数 | リクエスト総数に対する割合 |
---|---|---|---|---|
1 | AWSManagedRulesAnonymousIpList | HostingProviderIPList | 100,706 件 | 66 % |
2 | AWSManagedRulesKnownBadInputsRuleSet | ExploitablePaths_URIPATH | 12,499 件 | 8 % |
3 | AWSManagedRulesAdminProtectionRuleSet | AdminProtection_URIPATH | 10,069 件 | 7 % |
4 | AWSManagedRulesCommonRuleSet | NoUserAgent_HEADER | 8,154 件 | 5 % |
5 | AWSManagedRulesLinuxRuleSet | LFI_URIPATH | 7,654 件 | 5 % |
6 | AWSManagedRulesCommonRuleSet | UserAgent_BadBots_HEADER | 4,958 件 | 3 % |
7 | AWSManagedRulesAmazonIpReputationList | AWSManagedReconnaissanceList | 4,728 件 | 3 % |
8 | AWSManagedRulesKnownBadInputsRuleSet | ExploitablePaths_URIPATH_RC_COUNT | 3,525 件 | 2 % |
9 | AWSManagedRulesCommonRuleSet | RestrictedExtensions_URIPATH | 2,774 件 | 2 % |
10 | AWSManagedRulesAmazonIpReputationList | AWSManagedIPReputationList | 1,493 件 | 1 % |
11 | AWSManagedRulesCommonRuleSet | GenericLFI_URIPATH | 1,363 件 | 1 % |
最多は AWSManagedRulesAnonymousIpListルールグループの HostingProviderIPList
ルールで、全体の 66%を占めています。
2位以下は目立って多いルールはなく、ルールグループも分散している印象です。
続いてそれぞれのルールについて多かったリクエストをもう少し詳しく集計してみました。
1位: AWSManagedRulesAnonymousIpList - HostingProviderIPList
公式ドキュメントの説明:
エンドユーザートラフィックのソースになる可能性が低いウェブホスティングプロバイダーとクラウドプロバイダーの IP アドレスのリストを検査します。IP リストには AWS IP アドレスは含まれません。
このルールに一致したリクエストのうち、国名コード別にリクエスト数が多かった5件をまとめました。「割合」列はこのルールに一致したリクエストに占める割合を示しています。
順位 | 国名コード | 件数 | 割合 |
---|---|---|---|
1 | US | 28,305 件 | 28 % |
2 | IL | 17,165 件 | 17 % |
3 | FR | 14,043 件 | 14 % |
4 | GB | 9,265 件 | 9 % |
5 | JP | 6,020 件 | 6 % |
2位: AWSManagedRulesKnownBadInputsRuleSet - ExploitablePaths_URIPATH
公式ドキュメントの説明:
URI パスに、悪用可能なウェブアプリケーションパスにアクセスする試みがないかを検査します。パターンの例には、web-inf などのパスがあります。
このルールに一致したリクエストのうち、リクエストURLパス別にリクエスト数が多かった10件をまとめました。
順位 | リクエストURLパス | 件数 |
---|---|---|
1 | /.env | 3,328 件 |
2 | /.aws/config | 154 件 |
3 | /api/.env | 96 件 |
4 | /aws/credentials | 94 件 |
5 | /laravel/.env | 77 件 |
6 | /[具体的なIPアドレス]/.env | 72 件 |
7 | /.env.prod | 68 件 |
8 | /app/.env | 63 件 |
8 | /.env.production | 63 件 |
8 | /docker/.env | 63 件 |
機密情報が記録されている可能性がある .env
関係のファイル、AWS の configや機密情報が格納されているファイルを取得しようとしているリクエストが上位を占めました。
6位は具体的なIPアドレスが記録されており、リクエストが行われた当時のALBに割り当てられたIPアドレスだと思われます。
3位: AWSManagedRulesAdminProtectionRuleSet - AdminProtection_URIPATH
公式ドキュメントの説明:
一般的にウェブサーバーまたはアプリケーションの管理用に確保されている URI パスの有無を検査します。パターンの例には、sqlmanager などがあります。
このルールに一致したリクエストのうち、リクエストURLパス別にリクエスト数が多かった10件をまとめました。
順位 | リクエストURLパス | 件数 |
---|---|---|
1 | /admin-app/.env | 281 件 |
2 | /admin/phpinfo.php | 210 件 |
3 | /boaform/admin/formLogin | 182 件 |
4 | /admin.php | 172 件 |
5 | /admin/.env | 141 件 |
6 | /linusadmin-phpinfo.php | 97 件 |
7 | /admin/index.html | 88 件 |
8 | /phpmyadmin/index.php | 77 件 |
9 | /admin/info.php | 74 件 |
10 | /admin/config.php | 73 件 |
さまざまな admin
を含むパスへのリクエストが一致していることがわかります。
4位: AWSManagedRulesCommonRuleSet - NoUserAgent_HEADER
公式ドキュメントの説明:
HTTP User-Agent ヘッダーが欠落しているリクエストを検査します。
User-Agent ヘッダーがないリクエストなので、別観点での集計は割愛します。
5位: AWSManagedRulesLinuxRuleSet - LFI_URIPATH
公式ドキュメントの説明:
リクエストパスに、ウェブアプリケーションのローカルファイルインクルージョン (LFI) の脆弱性を悪用する試みがないかを検査します。パターンの例には、攻撃者にオペレーティングシステムの情報を提供できる /proc/version などのファイルがあります。
このルールに一致したリクエストのうち、リクエストURLパス別にリクエスト数が多かった10件をまとめました。
順位 | リクエストURLパス | 件数 |
---|---|---|
1 | /wp-config.php.bak | 102 件 |
1 | /.vscode/sftp.json | 102 件 |
3 | /wp-config.php.backup | 76 件 |
3 | /wp-config.txt | 76 件 |
3 | /wp-config.old | 76 件 |
6 | /admin/config.php | 73 件 |
7 | /app/config/parameters.yml | 61 件 |
8 | /phpMyAdmin/scripts/setup.php | 60 件 |
9 | /wp-config.php-backup | 59 件 |
10 | /wp-config.php.old | 53 件 |
1位の /wp-config.php.bak
は WordPress の設定ファイルのバックアップを取得しようとするリクエストだと思われます。
2位の /.vscode/sftp.json
は FTP や SFTP でファイル転送を行う VSCode の拡張の設定ファイルで、パスワード情報が記録されている可能性のあるものです。
全体として設定情報や機密情報の窃取を目的としているリクエストが多く一致しているようです。
6位: AWSManagedRulesCommonRuleSet - UserAgent_BadBots_HEADER
公式ドキュメントの説明:
リクエストが不正なボットであることを示す一般的な User-Agent ヘッダー値を検査します。パターンの例には、nessus、nmap などがあります。
このルールに一致したリクエストのうち、User-Agent
ヘッダー別にリクエスト数が多かった順にまとめました。
一部の User-Agent
ヘッダーには URL リンクが付与されていましたが、改変し削除しました。
順位 | User-Agent ヘッダー | 件数 |
---|---|---|
1 | Mozilla/5.0 zgrab/0.x | 3,207 件 |
2 | Mozilla/5.0 (compatible; Nmap Scripting Engine;) | 1,519 件 |
3 | Fuzz Faster U Fool v2.1.0-dev | 70 件 |
4 | masscan/1.3 | 65 件 |
5 | ivre-masscan/1.3 | 30 件 |
5 | masscan/1.0 | 30 件 |
7 | Fuzz Faster U Fool v2.0.0-dev | 21 件 |
8 | masscan-ng/1.3 | 14 件 |
1位の Mozilla/5.0 zgrab/0.x
は脆弱性スキャンツールによるリクエストに付与される User-Agent
ヘッダー値のようです。
他は主にポートスキャンツールによるリクエストに付与されるヘッダー値のようです。
7位: AWSManagedRulesAmazonIpReputationList - AWSManagedReconnaissanceList
公式ドキュメントの説明:
AWS リソースに対して偵察を実行している IP アドレスからの接続を検査します。
このルールに一致したリクエストのうち、国名コード別にリクエスト数が多かった5件をまとめました。「割合」列はこのルールに一致したリクエストに占める割合を示しています。
順位 | 国名コード | 件数 | 割合 |
---|---|---|---|
1 | FR | 2,853 件 | 60 % |
2 | US | 578 件 | 12 % |
3 | BR | 363 件 | 8 % |
4 | DE | 294 件 | 6 % |
5 | HK | 216 件 | 5 % |
8位: AWSManagedRulesKnownBadInputsRuleSet - ExploitablePaths_URIPATH_RC_COUNT
2位と同じ現象だと思われるので割愛します。
AWS WAFでは新しいマネージドルールのリリース候補に対し、テストの期間を設けて RC_COUNT
を名前に付加して稼働しているそうです。
9位: AWSManagedRulesCommonRuleSet - RestrictedExtensions_URIPATH
公式ドキュメントの説明:
読み取りや実行が安全でないシステムファイルの拡張子が URI パスに含まれているリクエストを検査します。パターンの例には、.log や .ini などの拡張子があります。
このルールに一致したリクエストのうち、リクエストURLパス別にリクエスト数が多かった12件をまとめました。
順位 | リクエストURLパス | 件数 |
---|---|---|
1 | /.env.bak | 148 件 |
2 | /wp-config.php.bak | 102 件 |
3 | /php.ini | 88 件 |
4 | /wp-config.php.backup | 76 件 |
5 | /.env.backup | 69 件 |
6 | /.config | 48 件 |
7 | /env.backup | 34 件 |
8 | /wp-config.bak | 32 件 |
9 | /wp-config.backup | 30 件 |
9 | /wp-config.conf | 30 件 |
9 | /wp-config-sample.php.bak | 30 件 |
9 | /wp-config.cfg | 30 件 |
他のルールにも一致しているリクエストパスも含まれていました。.env
関係のファイルやWordPress関係のファイルの取得が多く一致している印象です。
10位: AWSManagedRulesAmazonIpReputationList - AWSManagedIPReputationList
公式ドキュメントの説明:
ボットとして識別された IP アドレスを検査します。
このルールに一致したリクエストのうち、国名コード別にリクエスト数が多かった5件をまとめました。「割合」列はこのルールに一致したリクエストに占める割合を示しています。
順位 | 国名コード | 件数 | 割合 |
---|---|---|---|
1 | ID | 878 件 | 59 % |
2 | US | 144 件 | 10 % |
3 | FR | 125 件 | 8 % |
4 | GB | 98 件 | 7 % |
5 | AU | 62 件 | 4 % |
11位: AWSManagedRulesCommonRuleSet - GenericLFI_URIPATH
公式ドキュメントの説明:
URI パスに、ローカルファイルインクルージョン (LFI) を悪用する形跡がないかを検査します。例には、../../ などの手法を使用したパストラバーサルの試行があります。
このルールに一致したリクエストのうち、リクエストURLパス別にリクエスト数が多かった順にまとめました。
順位 | リクエストURLパス | 件数 |
---|---|---|
1 | /.aws/credentials | 1287 件 |
2 | /.aws/credentials.js | 19 件 |
2 | /root/.aws/credentials | 19 件 |
2 | /home/.aws/credentials | 19 件 |
5 | /api/v1/totp/user-backup-code/../../system/system-information | 11 件 |
6 | /rjdi../meme.1 | 4 件 |
7 | /static../.git/config | 3 件 |
8 | /media../.git/config | 1 件 |
AWSの機密情報が記録されているファイルを窃取しようとするリクエストが多く一致していました。
まとめ
どれぐらいの悪意があったのかは判断しませんが、全リクエストの76%が適用したいずれかの WAF マネージドルールに一致していました。
集計の上位にあたるリクエストは明確に機密情報ファイルの窃取を狙っているものが多数あり、AWS WAF のマネージドルールを利用するだけでもそのうちのかなりの割合をブロックできると考えると、インターネットからアクセスできるWebエンドポイントを公開する場合には (AWS WAFに限らず) WAF の適用をぜひ検討したほうが良いでしょう。
AWS WAFについては、過去にもいくつか記事を執筆しているのでご参照いただけますと幸いです。
- AWS WAFがリクエストをブロックした時に、自動的にIPアドレスレベルで一定期間ブロックし続ける方法
- AWS WAF について最初から知りたかったこと8選
- AWS WAF マネージドルールグループの個別ルールに条件を追加する方法
執筆:@kou.kinyo、レビュー:寺山 輝 (@terayama.akira)
(Shodoで執筆されました)