この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
2022/03/09 更新: WAFのアップデートもありこの情報は古くなっています。以下ブログを代わりに参照ください。
概要
構成図は下記のとおりです。
- ALB・EC2からなる Webサーバを作成します
- WAFを ALBに関連付けます
- WebACLには 以下 3ルールを適用させます
SQL injection match condition
cross-site scripting match condition
string match condition
- Kinesis Data Firehoseで WAFログを S3に保存します
- 保存形式は GZIP
- 他はデフォルトの設定
- 【今回の記事内容】Athenaで S3に対してクエリを実行、結果を確認・分析します
AthenaでS3に対してクエリを実行
テーブル作成
下記SQLを Athenaの New query
入力欄に貼り付けて Run query
を選択します。
(本記事では テーブル名は sample-waf-logs-2019-08
、
S3バケット・プレフィクスは s3://kawahara-waf-acl-log/2019/08/
としています)
CREATE EXTERNAL TABLE `sample-waf-logs-2019-08`(
`timestamp` bigint,
`formatversion` int,
`webaclid` string,
`terminatingruleid` string,
`terminatingruletype` string,
`action` string,
`httpsourcename` string,
`httpsourceid` string,
`rulegrouplist` array<string>,
`ratebasedrulelist` array<
struct<
ratebasedruleid:string,
limitkey:string,
maxrateallowed:int
>
>,
`nonterminatingmatchingrules` array<
struct<
ruleid:string,
action:string
>
>,
`httprequest` struct<
clientip:string,
country:string,
headers:array<
struct<
name:string,
value:string
>
>,
uri:string,
args:string,
httpversion:string,
httpmethod:string,
requestid:string
>
)
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
LOCATION 's3://kawahara-waf-acl-log/2019/08/'
マネジメントコンソールの 左側に作成したテーブルが表示されていることを確認します。
クエリ実行
下記SQLを Athenaの New query
入力欄に貼り付けて Run query
を選択します。
BLOCK されたリクエストのログを取得できます (SELECT した各要素の内容は後述します)。
SELECT from_unixtime(timestamp/1000, 'Asia/Tokyo') AS JST,
httpsourcename,
httpsourceid,
terminatingruleid,
httprequest.clientip,
httprequest.country,
httprequest.uri,
httprequest.args,
httprequest.httpmethod
FROM "sample-waf-logs-2019-08"
WHERE action = 'BLOCK';
成功するとマネジメントコンソール下部に クエリ実行結果が表示されます。 右側アイコンを選択すると CSV形式で結果をダウンロードできます。
結果を確認・分析
ダウンロードした CSVを Excelで見てみます。
確認
全体は以下のような構成です (1行目: 列名 を太字にしています)。
▼A〜D列
列名 | 説明 |
---|---|
JST | リクエスト発生日時。SELECT文の 「fromunixtime(timestamp/1000, 'Asia/Tokyo') AS JST」 部分 |
httpsourcename | リクエスト送信元。値は CF(CloufFront), APIGW(API Gawatey), ALB(Application Load Balancer) のいずれか |
httpsourceid | リクエスト送信元のID。 distribution(CF), REST API (APIGW), name (ALB) など |
terminatingruleid | BLOCKしたルールID。WebACLに適用させた各ルールのID |
▼E〜I列

列名 | 説明 |
---|---|
clientip | リクエストを送信するクライアントのIPアドレス |
country | リクエストの送信国 |
uri | リクエストのURI |
args | リクエストのクエリ文字列 |
httpmethod | リクエストのHTTPメソッド |
分析
Excelの データ → フィルター
を選択します。
今回は WebACLに以下 3つのルールを定めました。 それぞれのルールでどのようなリクエストが BLOCKできているのか確認します。
SQL injection match condition
cross-site scripting match condition
string match condition
terminatingruleid
とルールの対応は マネジメントコンソールの AWS WAF → Rules
から確認できます。
▼SQL injection match condition
terminatingruleid
列でフィルタします。
以下のようなリクエストが BLOCKされていました
country | uri | args (デコード版) |
---|---|---|
JP | /index.html | userID=20' or '1'='1 |
AR | /stats/index.php | sort={${die(md5(DIRECTORYSEPARATOR))}} |
- 表の1つ目は 私自身がリクエストしたものです
- 表の2つ目は WebShellに対する脆弱性のスキャンのようです
▼cross-site scripting match condition
XSSは私自身がリクエストしたもの ( クエリ文字列に alert(“Cookie”+document.cookie)
)以外見つかりませんでした。
▼string match condition
このルールは admin
, login
の文字列が入っているURLをブロックするように設定しましたが、500件以上ヒットしました。
/phpMyAdmin/index.php
など、データベースへのGUIアクセスを狙った攻撃が多いことが分かります。
さいごに
以上、Athenaを使った AWS WAFログ分析でした。 サーバ、DBなどのセットアップ不要で S3に対してクエリ実行できるのはとても便利に感じました。
この記事が少しでもどなたかのお役に立てば幸いです。