下記の記事でIPアドレスでのブロックは確認できたので、
今回はSQL injectionのブロックを確認してみようと思います。
次のようなQuery Stringでパラメータを渡すパターンで簡単に試してみます。
$ curl http://d3q07yq8vdynnt.cloudfront.net/test.txt?id=1 test
まずはWAFの設定です。
Condition(SQL injection match condition) の作成
Query StringをURLデコードした結果に対してSQL Injectionのチェックを行うように設定します。
ルールの設定
上記のConditionに引っかかったらアクションするようにルールを設定します。
Web ACLの設定
ルールに対するアクションがBlockになっていることを確認します。
WAFにSQL injectionの攻撃
WAFの設定ができたら、実際にWAFに対してSQL injectionの攻撃を行うツールを
導入します。今回は下記のsqlmapを使いました。
上図のリンクよりダウンロード、展開して、展開したディレクトリに入り、
下記のコマンドを実行します。
$ python sqlmap.py -u http://d3q07yq8vdynnt.cloudfront.net/test.txt?id=1 _ ___ ___| |_____ ___ ___ {1.0-dev-nongit-20151015} |_ -| . | | | .'| . | |___|_ |_|_|_|_|__,| _| |_| |_| http://sqlmap.org [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program [*] starting at 08:46:17 [08:46:18] [INFO] testing connection to the target URL [08:46:18] [INFO] heuristics detected web page charset 'ascii' [08:46:18] [INFO] checking if the target is protected by some kind of WAF/IPS/IDS [08:46:18] [CRITICAL] heuristics detected that the target is protected by some kind of WAF/IPS/IDS do you want sqlmap to try to detect backend WAF/IPS/IDS? [y/N] [08:46:24] [WARNING] dropping timeout to 10 seconds (i.e. '--timeout=10') [08:46:24] [INFO] testing if the target URL is stable [08:46:24] [INFO] target URL is stable [08:46:24] [INFO] testing if GET parameter 'id' is dynamic [08:46:24] [WARNING] GET parameter 'id' does not appear dynamic [08:46:24] [WARNING] heuristic (basic) test shows that GET parameter 'id' might not be injectable [08:46:24] [INFO] testing for SQL injection on GET parameter 'id' [08:46:24] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause' [08:46:25] [INFO] testing 'MySQL >= 5.0 boolean-based blind - Parameter replace' [08:46:25] [INFO] testing 'MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause' [08:46:25] [INFO] testing 'PostgreSQL AND error-based - WHERE or HAVING clause' [08:46:25] [INFO] testing 'Microsoft SQL Server/Sybase AND error-based - WHERE or HAVING clause' [08:46:25] [INFO] testing 'Oracle AND error-based - WHERE or HAVING clause (XMLType)' [08:46:26] [INFO] testing 'MySQL >= 5.0 error-based - Parameter replace' [08:46:26] [INFO] testing 'MySQL inline queries' [08:46:26] [INFO] testing 'PostgreSQL inline queries' [08:46:26] [INFO] testing 'Microsoft SQL Server/Sybase inline queries' [08:46:26] [INFO] testing 'MySQL > 5.0.11 stacked queries (SELECT - comment)' [08:46:26] [INFO] testing 'PostgreSQL > 8.1 stacked queries (comment)' [08:46:26] [INFO] testing 'Microsoft SQL Server/Sybase stacked queries (comment)' [08:46:26] [INFO] testing 'Oracle stacked queries (DBMS_PIPE.RECEIVE_MESSAGE - comment)' [08:46:26] [INFO] testing 'MySQL >= 5.0.12 AND time-based blind (SELECT)' [08:46:27] [INFO] testing 'PostgreSQL > 8.1 AND time-based blind' [08:46:27] [INFO] testing 'Microsoft SQL Server/Sybase time-based blind' [08:46:27] [INFO] testing 'Oracle AND time-based blind' [08:46:27] [INFO] testing 'Generic UNION query (NULL) - 1 to 10 columns' [08:46:27] [WARNING] using unescaped version of the test because of zero knowledge of the back-end DBMS. You can try to explicitly set it using option '--dbms' [08:46:30] [INFO] testing 'MySQL UNION query (NULL) - 1 to 10 columns' [08:46:31] [WARNING] GET parameter 'id' is not injectable [08:46:31] [CRITICAL] all tested parameters appear to be not injectable. Try to increase '--level'/'--risk' values to perform more tests. Also, you can try to rerun by providing either a valid value for option '--string' (or '--regexp') If you suspect that there is some kind of protection mechanism involved (e.g. WAF) maybe you could retry with an option '--tamper' (e.g. '--tamper=space2comment') [08:46:31] [WARNING] HTTP error codes detected during run: 403 (Forbidden) - 209 times [*] shutting down at 08:46:31
すると、攻撃が始まります。最後に「403 (Forbidden) – 209 times」と出力され、
攻撃がブロック(403)されていることがわかります。
プロックされたリクエストの確認
下図のようにAWSコンソールから確認できます。
ブロックされたリクエストで実際にアクセスしてみると、ちゃんとブロックされていることがわかります。
$ curl http://d3q07yq8vdynnt.cloudfront.net/test.txt?id=1%20UNION%20ALL%20SELECT%20NULL--%20ERROR: The request could not be satisfied ERROR
The request could not be satisfied.
Request blocked.
Generated by cloudfront (CloudFront) Request ID: dqrrId9UiGO0klLIXFZq2dnJ7VQ7mbBCeY-24G5qdx_ZaGto8WGIgA==
CloudWatchとの連携
Blockの様子は次のようにCloudWatchで確認することもできます。