AWS WAF の SQLインジェクションルールステートメントに対して Sensitivity levels が設定出来るようになったので攻撃してみた

2022.07.27

いわさです。

AWS WAF では SQLインジェクションに対処するためのルールを設定することが可能です。
本日のアップデートで、カスタムのSQLインジェクションルールステートメントに対して、Sensitivity Level が設定出来るようになりました。

使い方と、実際にレベルごとに攻撃パターンを試してみたのでご紹介します。

AWS WAF の SQLインジェクションルールステートメントと Sensitivity Levels

何が出来るようになったかというと、カスタムルールを作成する際のルールステートメントで、Match type に Contains SQL Injection attacks を選択した際、Sencitivity level という項目で Low または High を選択出来るようになりました。 

このパラメータは、SQLインジェクション攻撃の検出に対する感度のレベルを指定する項目となっています。
High を指定すると多くの攻撃を検出出来るようになりますが、誤検知が増える可能性があります。
Low を指定すると、Highよりも攻撃検出割合が低くなりますが、誤検知を抑えることが出来る可能性があります。

アップデート情報によると、推奨は High とのことです。ただし、誤検知に対する追加の対応が必要になる場合があるので、誤検知が許容されないシステムの場合は Low を選択することが推奨されるとのこと。ふむふむ。

なお、AWS WAF では WCU というルールのキャパシティの概念がありますが、今回のレベルが LOW の場合は 20、HIGH の場合は 30 となっています。

既存ルールは LOW になるがレベルが下がったわけではない

既存ルールについて以下に記載があります。 デフォルトで LOW に設定されます。これは既存の評価ロジックが変更される(レベルが下がる)ことを示したものではないとのことなので、今までどおりの挙動が LOW であり、HIGH はこれまで以上に厳しい検出ルールである、という見方が出来そうです。

All existing SQLi rule statements will default to LOW sensitivity, which will not change your existing rule evaluation logic.

マネージドルールでカスタムは出来ない。現時点では LOW レベルで動作する

SQLインジェクションのマネージドルール AWS-AWSManagedRulesSQLiRuleSet を調べて見ました。

まず、マネージドルールについてはレベルの変更を行うことが出来ませんでした。
設定可能項目は今までのとおりです。

以下のドキュメントでマネージドルールのステートメントごとの個別の詳細情報を確認することが出来ます。

こちらには以下のように、LOW で動作する旨が追記されていました。

Uses the built-in AWS WAF SQL injection attack rule statement, with sensitivity level set to Low, to inspect the values of all query parameters for patterns that match malicious SQL code.

やってみる

仕様を把握出来ましたが、どんな感じで検出の違いが出るのでしょうか。
本日は ALB + EC2 な Webサーバーを用意し、AWS WAF WebACL をアタッチしていくつかの攻撃パターンを実際にレベルごとで試してみました。

前述の設定画面のとおり、カスタムルールで HTTP カスタムヘッダーのx-hoge-headerに対して SQL インジェクションルールを設定しています。

Webサーバーは以下のテンプレートを検証用にいつも使っています。Clone して Rain でササッとデプロイします。

% rain deploy template.yaml hoge0727alb -p hoge
Enter a value for parameter 'BaseAMI' (default value: ami-06098fd00463352b6): 
Enter a value for parameter 'KeyPairWeb' "Name of an existing EC2 KeyPair to enable SSH access to the instances for Web":
CloudFormation will make the following changes:

:

Deploying template 'template.yaml' as stack 'hoge0727alb' in ap-northeast-1.
Stack hoge0727alb: CREATE_COMPLETE
Successfully deployed hoge0727alb

作成された Application Load Balancer (ALB) を先程作成した WebACL に関連付けします。

良さそうですね。

実際の攻撃パターンですが、以下のサイトのチートシートを参考にいくつかピックアップさせて頂きました。

LOW

では、まずは LOW レベルで試してみたいと思います。

% curl -H "x-hoge-header:hoge" hoge-web-alb-883305193.ap-northeast-1.elb.amazonaws.com
hoge

% curl -H "x-hoge-header:10; DROP TABLE members /*" hoge-web-alb-883305193.ap-northeast-1.elb.amazonaws.com
403 Forbidden

% curl -H "x-hoge-header: admin'--" hoge-web-alb-883305193.ap-northeast-1.elb.amazonaws.com
403 Forbidden

% curl -H "x-hoge-header:/*\! 32302 10*/" hoge-web-alb-883305193.ap-northeast-1.elb.amazonaws.com
403 Forbidden

% curl -H "x-hoge-header:;SELECT * FROM members; DROP members--" hoge-web-alb-883305193.ap-northeast-1.elb.amazonaws.com
hoge

% curl -H "x-hoge-header:if ((select user) = 'sa' OR (select user) = 'dbo') select 1 else select 1/0" hoge-web-alb-883305193.ap-northeast-1.elb.amazonaws.com
403 Forbidden

% curl -H "x-hoge-header:SELECT LOAD_FILE(0x633A5C626F6F742E696E69)" hoge-web-alb-883305193.ap-northeast-1.elb.amazonaws.com
403 Forbidden

% curl -H "x-hoge-header:select if( user() like 'root@%', benchmark(100000,sha1('test')), 'false' ); " hoge-web-alb-883305193.ap-northeast-1.elb.amazonaws.com
403 Forbidden

% curl -H "x-hoge-header:SELECT * FROM hoge" hoge-web-alb-883305193.ap-northeast-1.elb.amazonaws.com
hoge

概ねブロックされていますが、いくつかのパターンが検出されずに通っていることが確認できます。

HIGH

次に、HIGH レベルに変更して先程と同じリクエストパターンを送信してみます。

% curl -H "x-hoge-header:hoge" hoge-web-alb-883305193.ap-northeast-1.elb.amazonaws.com
hoge

% curl -H "x-hoge-header:10; DROP TABLE members /*" hoge-web-alb-883305193.ap-northeast-1.elb.amazonaws.com
403 Forbidden

% curl -H "x-hoge-header: admin'--" hoge-web-alb-883305193.ap-northeast-1.elb.amazonaws.com
403 Forbidden

% curl -H "x-hoge-header:/*\! 32302 10*/" hoge-web-alb-883305193.ap-northeast-1.elb.amazonaws.com
403 Forbidden

% curl -H "x-hoge-header:;SELECT * FROM members; DROP members--" hoge-web-alb-883305193.ap-northeast-1.elb.amazonaws.com
403 Forbidden

% curl -H "x-hoge-header:if ((select user) = 'sa' OR (select user) = 'dbo') select 1 else select 1/0" hoge-web-alb-883305193.ap-northeast-1.elb.amazonaws.com
403 Forbidden

% curl -H "x-hoge-header:SELECT LOAD_FILE(0x633A5C626F6F742E696E69)" hoge-web-alb-883305193.ap-northeast-1.elb.amazonaws.com
403 Forbidden

% curl -H "x-hoge-header:select if( user() like 'root@%', benchmark(100000,sha1('test')), 'false' ); " hoge-web-alb-883305193.ap-northeast-1.elb.amazonaws.com
403 Forbidden

% curl -H "x-hoge-header:SELECT * FROM hoge" hoge-web-alb-883305193.ap-northeast-1.elb.amazonaws.com
403 Forbidden

先程スルーしていたリクエストもブロックされるようになりました。
これが誤検知なのか、ブロックされるべきリクエストなのかは精査が必要ですが、HIGH のほうがより厳しいルールで検出されていることが確認出来ました。

さいごに

本日は、AWS WAF の SQLインジェクションルールステートメントに対して Sensitivity levels が設定出来るようになったので攻撃パターンを試してみました。

HIGH が推奨とのことですが、WCU オーバーしないよねってところと誤検知どう対処するというところが課題でしょうか。
触った限りでは、SQLインジェクションっぽくないものもなんでも検知されてしまうということは全くなかったですが、まずはカウントモードで評価してみてください。

一方、先程 LOW で通過したいくつかのルールは、攻撃パターンとして挙げられているものではあるので、可能であればブロックしておきたいような気もします。
アップデート記事にも記載されていたように誤検知に対する許容度に応じて判断にはなりますが、原則 HIGH のほうが良さそうかなという気はします。
マネージドルールも HIGH のもので追加が求められそうですね。