ã©ãã Security Engineering ã®è¥¿å·ã§ãã好ããªãã±ã¢ã³ã¯ã¯ã¯ãã¹ã§ããã«ããã·ç¤¾å ã«éã«ãã±ã¢ã³ã«ã¼ãé¨ãã§ãã¾ãã¦ãé¨å¡å士åç£ç¢ç£¨ãå§ãã¦ãã¾ãããã¤ãä¼æ¥å¯¾æãã±ã¢ã³ã«ã¼ã大ä¼ãããã®ã夢ã§ãã
ãã¦ãã¦ãçãã㯠AWS WAFï¼Web Application Firewallãä»¥ä¸ WAFï¼ã使ã£ã¦ãã¾ããï¼ãµã¼ãã¹ã« WAF ãå°å ¥ããéã¯ä¸å®æé COUNT ã¢ã¼ãã§éç¨ãããã¨ãã»ãªãªã¼ã¨ããã¦ãã¾ããã§ã¯ãCOUNT ã¢ã¼ããã BLOCK ã¢ã¼ãã«åãæ¿ããæã«ä½ããã£ã¦ BLOCK ã¢ã¼ãã¸ã®åãæ¿ããå¤æãã¦ãã¾ããï¼
æ¬è¨äºã¯ã¤ãå æ¥ãªãªã¼ã¹ãããã«ããã·å¾æ¥å¡ã¨ãããµã¼ãã¹ãéçºãã¦ããã¡ã³ãã¼ãããWAFï¼Web Application Firewallï¼ ã COUNT ã¢ã¼ãã§åããã¦ä¸å®æéçµã£ãã®ã ãã©ãã©ã®ã«ã¼ã«ã BLOCK ã¢ã¼ãã«ãã¦ããã®ãããã¦ã¯ãããªãã®ãã©ããã£ã¦å¤æãããè¯ãã®ï¼ãã¨ãã質åãããã試è¡é¯èª¤ããå 容ãæ¸ãã¦ããã¾ãã
å®ã®ã¨ãããããã°ã§ããããããã«æã£ã¦ããã®ã§ãããç§èªèº«ããã«è¨èªåãã¦èª¬æã§ããªãã£ãã®ã§ãã¨ã³ã¸ãã¢ã®èª°ããåãããã«å¤æã§ããããã«ãªã£ã¦ãããããææ¸åãã¾ãããã¾ããã«ããã·ã§ã¯ AWS ã使ã£ã¦ãã¾ãããã«ããã·ã®ã¨ã³ã¸ãã¢ã®èª°ããã AWS ã«è©³ããããã§ã¯ããã¾ããããã®ããæ¬è¨äºã§ã¯ Amazon CloudWatch Logs ã« AWS WAF ã®ãã°ãä¿åããã¦ããå ´åã«ãã©ã®ããã«ãã°ãæ¤ç´¢ããã©ã®ããã« BLOCK ã®å¤æãè¡ãããå«ããæé ã¨ãªã£ã¦ããã¾ãããªããã«ããã·ã§ã¯ AWS WAF ã使ã£ã¦ãã¾ãããBLOCK ã¸ã®ç§»è¡ã®èãæ¹ã¯ä»ã® WAF ã«ããã¦ãåæ§ã«ä½¿ãããã®ãã¨æã£ã¦ãã¾ãã
ä»åã¯ãããã£ãåæã§ãããããWAF ã¨ã¯ï¼ãã AWS WAF ã®ããã¼ã¸ãã«ã¼ã«ã®èª¬æãã«ã¼ã«ã®è©ä¾¡é ãªã©ã®ä»æ§é¨åã«ã¤ãã¦ã¯çãã¦ãã¾ãã
COUNT ã¢ã¼ããBLOCK ã¢ã¼ãã¨ã¯
WAF ã«ã¯é常 COUNT ã¢ã¼ã㨠BLOCK ã¢ã¼ãã¨ããäºã¤ã®ã¢ã¼ããåå¨ãã¾ãããã¡ãã BLOCK ãããã° ALLOW ã¢ã¼ããããã®ã§ããããªããªã WAF ã®ããã©ã«ãã BLOCK ã¨ããç¹å®ã®ãªã¯ã¨ã¹ãã ããéãã¨ããä¾ã¯å¤ãã¯ãªãã¨æãã®ã¨ãæ¬è¨äºã®ç®çã¨ã¯ãºã¬ã¦ããã®ã§ COUNT ã¢ã¼ã㨠BLOCK ã¢ã¼ãã«ã®ã¿è¨åãã¾ãï¼åèï¼https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/waf-rule-action.htmlï¼
ãµã¼ãã¹æä¾æ㯠COUNT ã¢ã¼ãã§éç¨ããçç±ã¨ãã¦ãæåãã BLOCK ã¢ã¼ãã§éç¨ãã¦ãã¾ãã¨æ£å¸¸ãªãªã¯ã¨ã¹ãããããããã¯ãã¦ãã¾ããããªãã¨ãããã¨ãããã¾ãããã®ãããä¸å®æé㯠COUNT ã¢ã¼ãã§åããããã¨ã§ããã°ã®ç¶æ³ãã¿ã¤ã¤ãBLOCK ã¢ã¼ãã«å¤æ´ãããã©ãããå¤æãã¦ããã¾ãããã®ããã°ã®ç¶æ³ãã¿ã¤ã¤ãã¨ããã¨ãããå ·ä½çã«ä½ããããè¯ããããã¦ãã¦ã¨ãã¦å ±æããã¦ããªãã¨æããã®ã§ãæ¬è¨äºã¯ãã®å ±æãä¸ã¤ã®ç®çã¨ãã¦ãã¾ãã 話ã¯åç´ã§ãæ£è¦ã®ãªã¯ã¨ã¹ãã COUNT ã¨ãã¦è¨é²ããã¦ããªããã°ããã®ã«ã¼ã«ã¯ BLOCK ã¢ã¼ãã«å¤ãã¦ããã§ãããã¨ãããã¨ãªã®ã§ããããã®åç´ãªè©±ã«æ°ä»ãããã¨ããã®ã1ã¤ã®ãã¤ã³ãã§ããã¨åæã«ãCOUNT ã¨ãã¦è¨é²ãããä¸ãã BLOCK ãã¦ãããã®ã¨ããã§ã¯ãªããã®ãã©ãè¦åããããéè¦ãªãã¤ã³ãã§ãã
å®ã®ã¨ããããã¯èªåãã¡ãæä¾ãã¦ãããµã¼ãã¹ã«ãä¾åãã¾ãã ä¾ãã°ä¸è¨ã®ãããªè¦ç´ ã«ãã£ã¦å¤åãã¾ãã
- èªè¨¼ãä¼´ããµã¼ãã¹ã
- æµ·å¤ã«ãµã¼ãã¹ãå±éãã¦ããã
- API ãæä¾ãã¦ãã¦ç¬¬ä¸è ããããå©ããã
- toC ã toB ã
- ..etc
æ¬è¨äºã§ã¯ä¸è¬ç㪠SaaS ã§ã¯ãããªæãã§ã¿ã¦ããã°è¯ãã®ã§ã¯ï¼ã¨ããå 容ãã¾ã¨ãã¦ãã¾ãã
ã¾ããAWS WAF ãåºåãããã°ã«ã注ç®ããå¿ è¦ãããã¾ãã®ã§ã¾ãã¯ãããã¿ã¦ããã¾ãããã
AWS WAF ã®ãã°ãè¦ã
ããã§ã¯ãCloudWatch Logs Insights ã使ã£ã¦ãã°ãã¿ã¦ããã¾ããã¨ããã®ã¯æåã ãã§ãCOUNT ã®ãã°ããã¦ã³ãã¼ãããããã ãã«å©ç¨ãã¾ãããªããªã AWS WAF ã®ãã°ã¯è¤éã§æ¤ç¥å 容ãé åã§æ¸ããã¦ãããããããããã®ã¾ã¾ãããã¯ã¨ãªã§ã©ãã«ããã¦è§£æãããã¨ããã®ã¯ç§ã«ã¨ã£ã¦ã¯è³é£ã®æ¥ã§ããã°éã«ãã£ã¦ã¯è©¦è¡é¯èª¤ããã¦ããã¨ãããªãã®ãéãæãã£ã¦ãã¦ãã¾ãã¾ããããã«ãUser-Agent ãæ¤ç´¢ãããæã« User-Agent 㨠user-agent ãåæã«æ¤ç´¢ãããå ´åãæ£è¦è¡¨ç¾ãæ¸ããã¨ãã§ããªãã®ã§ç§ã¯ jq ãé¸æãã¾ããããããã¡ãããã°éã«ãã£ã¦ã¯å¤§ééãã¦ãã¼ã«ã«ã«ãã¦ã³ãã¼ãããã®ã¯ç¡çã¨ãã¬ããã³ã¹çã«ãã°ããã¦ã³ãã¼ãã¯ã§ããªãã¿ãããªæ¹ã¯ Amazon S3 ã«ãã°ãåºåã㦠Amazon Athena ã使ãã®ãå人çã«ã¯è¯ãã¨æãã¾ãã
ããã§ã¯ãã¾ãã¯ãã°ã®æ§é ãç解ããå¿ è¦ãããã¾ãã®ã§è¦ã¦ããã¾ãããã ä¸è¨ã®ããã«ãªã£ã¦ãã¾ãã
{ "timestamp":1533689070589, "formatVersion":1, "webaclId":"385cb038-3a6f-4f2f-ac64-09ab912af590", "terminatingRuleId":"Default_Action", "terminatingRuleType":"REGULAR", "action":"ALLOW", "httpSourceName":"CF", "httpSourceId":"i-123", "ruleGroupList":[ { "ruleGroupId":"41f4eb08-4e1b-2985-92b5-e8abf434fad3", "terminatingRule":null, "nonTerminatingMatchingRules":[ {"action" : "COUNT", "ruleId" : "4659b169-2083-4a91-bbd4-08851a9aaf74"} ], "excludedRules":[ {"exclusionType" : "EXCLUDED_AS_COUNT", "ruleId" : "5432a230-0113-5b83-bbb2-89375c5bfa98"} ] } ], "rateBasedRuleList":[ { "rateBasedRuleId":"7c968ef6-32ec-4fee-96cc-51198e412e7f", "limitKey":"IP", "maxRateAllowed":100 }, { "rateBasedRuleId":"462b169-2083-4a93-bbd4-08851a9aaf30", "limitKey":"IP", "maxRateAllowed":100 } ], "nonTerminatingMatchingRules":[ {"action" : "COUNT", "ruleId" : "4659b181-2011-4a91-bbd4-08851a9aaf52"} ], "httpRequest":{ "clientIp":"192.10.23.23", "country":"US", "headers":[ { "name":"Host", "value":"127.0.0.1:1989" }, { "name":"User-Agent", "value":"curl/7.51.2" }, { "name":"Accept", "value":"*/*" } ], "uri":"REDACTED", "args":"usernam=abc", "httpVersion":"HTTP/1.1", "httpMethod":"GET", "requestId":"cloud front Request id" } }
ï¼åèï¼https://docs.aws.amazon.com/waf/latest/developerguide/classic-logging.htmlï¼
AWS WAF ã®å ´å COUNT ã¢ã¼ãã§è¦ãã¹ã㯠nonTerminatingMatchingRules ã¨ãããã£ã¼ã«ãã§ããã«ã¼ã«ã ALLOW ã BLOCK ã¢ã¼ãã«è¨å®ãã¦ããå ´åã¯ãããããæç¹ã§å¦çãçµäºãã TerminatingMatchingRules ãã£ã¼ã«ããè¦ã¦ããå¿ è¦ãããã¾ãããCOUNT ã¢ã¼ãã¯éçµäºå¦çã«è©²å½ããä»ã®ã«ã¼ã«ã«ãããããã¦ããªããã©ãããæå¾ã¾ã§è©ä¾¡ãã¾ããã§ãã®ã§ notTerminatingMatchingRules ã®æ¹ãè¦ã¦ããã¾ãã
ãã°ã解æãã
ä¸è¨ã®ã¯ã¨ãªãå®è¡ãããã¨ã§ COUNT ã¨ãã¦åºåããããã°ãæ½åºãããã¨ãå¯è½ã§ãã
fields @timestamp, @message | filter @message like /"action":"COUNT"/ | sort @timestamp desc | display @timestamp, @message, httpRequest.clientIp, httpRequest.uri, httpRequest.country
ï¼åèï¼https://aws.amazon.com/jp/blogs/news/aws-waf-log-analysis-considerations/ ï¼
ä¸è¨ã®çµæã JSON ã§ãã¦ã³ãã¼ããã¾ãã対象æéã¯æä½1ã¶æç¨åº¦ãæ¨å¥¨ãã¾ãããCloudWatch Logs Insights ã§ã¯ä¸åã§10,000件ã¾ã§ãããã¼ã¿ãåå¾ã§ããªãã®ã§ããã¯æèãã¦ããå¿ è¦ãããã¾ãã
ãã¦ã³ãã¼ããã§ããããã¨ã¯ jq ã使ã£ã¦è§£æããã¦ããã¾ããã¡ãªã¿ã«ç§ã CloudWatch Logs Insightsã«è©³ãããªãã ãã§ãè²ã ã¨è§£æã¯ã§ããããã§ãã (åèï¼https://aws.amazon.com/jp/blogs/news/analyzing-aws-waf-logs-in-amazon-cloudwatch-logs/ )
æ£è¦ã®ãªã¯ã¨ã¹ããã©ããã®å¤æ
ããã¾ã§ãããããããæ£è¦ã®ãªã¯ã¨ã¹ããã©ãããå¤æãã¦ããããã§ãããèªè¨¼ï¼ãã°ã¤ã³ï¼ãããSaaS ãåæã§è©±ãé²ãã¦ããã¾ãã
ã¾ãã¯ä¸è¨ã®ã¯ã¨ãªãå®è¡ãã¾ããããå ã»ã©ã«ãè¨è¼ã®ã¨ãã nonTerminatingMatchingRules ã®ä¸ã® ruleId ãã¿ã¦ããã¾ãã
jq -r '.[] | .["@message"].nonTerminatingMatchingRules[] | .ruleId' logs-insights-results.json | sort | uniq -c | sort -nr 10 AWSManagedRulesAnonymousIpList 5 AWSManagedRulesCommonRuleSet 5 AWSManagedRulesBotControlRuleSet 1 AWSManagedRulesLinuxRuleSet 1 AWSManagedRulesKnownBadInputsRuleSet
ãã®ãããªçµæã確èªã§ãã¾ããããã§è¡¨ç¤ºããã¦ããªãã«ã¼ã«ã¯ BLOCK ã«ãã¦ãã¾ã£ã¦å¤§ä¸å¤«ã§ããé常å©ç¨ã§è¨é²ããã¦ããªãã¨ãããã¨ã¯è¨é²ãããã¿ã¤ãã³ã°ã¯æ»æãåããã¿ã¤ãã³ã°ã§ããã¨èããããããã§ãã
次ã«ã«ã¼ã«ã¨ URI ã®çµã¿åãããè¦ã¦ããã¾ãã
jq -r '.[] | .["@message"] as $msg | $msg.nonTerminatingMatchingRules[] | "\(.ruleId) \($msg.httpRequest.uri)"' logs-insights-results.json | sort AWSManagedRulesAnonymousIpList / AWSManagedRulesAnonymousIpList / AWSManagedRulesAnonymousIpList /.env AWSManagedRulesAnonymousIpList /auth/favicon.ico AWSManagedRulesAnonymousIpList /auth/login AWSManagedRulesAnonymousIpList /auth/login AWSManagedRulesAnonymousIpList /auth/login AWSManagedRulesAnonymousIpList /auth/login AWSManagedRulesAnonymousIpList /wp-login.php AWSManagedRulesAnonymousIpList /wp-login.php AWSManagedRulesBotControlRuleSet / AWSManagedRulesBotControlRuleSet / AWSManagedRulesBotControlRuleSet /auth/favicon.ico AWSManagedRulesBotControlRuleSet /auth/login AWSManagedRulesBotControlRuleSet /auth/login AWSManagedRulesCommonRuleSet / AWSManagedRulesCommonRuleSet /news/12345 AWSManagedRulesCommonRuleSet /news/files AWSManagedRulesCommonRuleSet /auth/login AWSManagedRulesCommonRuleSet /news/sources/03a0 AWSManagedRulesKnownBadInputsRuleSet /.env AWSManagedRulesLinuxRuleSet /.env
ããã§ã¯ä¸è¨ã®ã±ã¼ã¹ã§ BLOCK ã¨ãã¦å¤æãããã¨ãå¯è½ã§ãã
- ãµã¼ãã¹ã§ä½¿ç¨ãã¦ããªã URI ã«å¯¾ãã¦ã®ã¿æ¤ç¥ããã
- ä¸è¨ã®ä¾ã§ã¯ä¸è¨ã対象
- AWSManagedRulesKnownBadInputsRuleSet
- AWSManagedRulesLinuxRuleSet
- ä¸è¨ã®ä¾ã§ã¯ä¸è¨ã対象
- èªè¨¼å¾ã®ã¢ã¯ã»ã¹ã§æ¤ç¥ããã¦ããªã IP ã¢ãã¬ã¹/Bot ç³»ã®ã«ã¼ã«
- èªè¨¼å¾ã«ãæ¤ç¥ããªããã°æ£è¦ã®å©ç¨ã§ã¯ãªããã¨ãããã
- ä¸æ£ãªå©ç¨è ããã°ã¤ã³ãã¦å©ç¨ã§ããªãã£ãã¨ãããã¨
- ãããã Bot ã®ã¢ã¯ã»ã¹ã許容ããªãã¨ãããã¨ã§ããã° BLOCK ãã¦ãã¾ã£ã¦ãã
- â»ä¸è¨ã®ä¾ã§ã¯ä¸è¨ã対象
- AWSManagedRulesAnonymousIpList
- AWSManagedRulesBotControlRuleSet
- èªè¨¼å¾ã«ãæ¤ç¥ããªããã°æ£è¦ã®å©ç¨ã§ã¯ãªããã¨ãããã
ããã§å¤æã«èªä¿¡ããªãå ´å㯠User-Agent ãåºåããã¨å¤æã®å©ãã«ãªãã§ããããUser-Agent ãåºåããå ´åã¯ä¸è¨ã®ããã«æ¸ããã¨ãã§ãã¾ãï¼çµæã¯çãã¾ãï¼
jq -r '.[] | .["@message"] as $msg | $msg.nonTerminatingMatchingRules[] | "\(.ruleId) \($msg.httpRequest.uri) \($msg.httpRequest.headers[] | select(.name | test("(?i)user-agent")) | .value)"' logs-insights-results.json | sort
ãããè¦ãã¨æããã«èªåãã¡ã®ã¦ã¼ã¶ã¼ã§ã¯ãªã User-Agent ãè¦ãã¦ãããããã®ã§ãæ£è¦ã®ãªã¯ã¨ã¹ãã§ã¯ãªãã¨è¦ãªãè¦ç´ ã¨ãããã¨ãã§ãã¾ãã åºæ¬çã«ã¯ããã¾ã§ã®èª¿æ»ã§ BLOCK ã«ããã«ã¼ã«ãå¤å¥ã§ãã¾ãããã¨ã®æ®ãã¯ä½ããã£ãæã®ããã«å¼ãç¶ã COUNT ã¢ã¼ãã§éç¨ãããã¨ãæ¨å¥¨ãã¾ãã ããã¾ã§ã§ BLOCK ã«ãã¦è¯ãçç±ã¨ãã¦ã¯ããã°ã¤ã³æ¸ã¿ã§ã㤠BLOCK ã«å¤æ´ãã¦è¯ãä¾ã¯ããã»ã©å¤ããªãããã BLOCK ãã¹ãä¾ãããã¨ããã¨ãã§ã«æ»æãåãã¦ããã¨ãããã¨ãªã®ã§ã¤ã³ã·ãã³ãã¬ã¹ãã³ã¹ãå§ã¾ãå¯è½æ§ãããã¾ããã
â»Bot ãæ¤ç¥ããæã®æ³¨æ
AWS WAF ã§ã¯ãAWSManagedRulesBotControlRuleSetãã¨ããããã¼ã¸ãã«ã¼ã«ãç¨æããã¦ãã¾ããããã¯èªãã§åã®å¦ããBot ã¢ã¯ã»ã¹ãæ¤ç¥ããããã®ãã®ã§ãã
ããã¡ã®ãµã¼ãã¹ã§ã¯ Bot ã®ã¢ã¯ã»ã¹ã許容ããªãããã
ã¨ããçç±ã§ BLOCK ãã¦ãã¾ãã¨æãã¬è½ã¨ãç©´ãããããããã¾ãããããã BLOCK ã«ããæ㯠E2E ãã¹ãã®ãã¨ã念é ã«å
¥ãã¦ããã¦ãã ãããE2E ãã¹ãã Bot ããã®ã¢ã¯ã»ã¹ã¨ãã¦æ¤ç¥ããããã¹ããè½ã¡ã¦ãã¾ãããããã¤ã«å¤±æãããã¨ãèãããã¾ãããã¡ããæ¬çªã«ä¸ããåã«æ°ä»ããã®ã§å¤§ããªåé¡ã«ã¯ãªããªãã§ãããæ¥ã«ãããã¤ãè½ã¡ãããã«ãªã£ã¦ãã¾ã£ã¦ä½ãåå ãããããªãã¦æéãæ¶è²»ãã¦ãã¾ãã¿ãããªãã¨ãèããããã®ã§èªèãã¦ããã¦ããã ããã°ã¨æãã¾ãã
ãããããBot ã«é¢ãã¦ã¯ toC ã®ãµã¼ãã¹ãªã©èª°ã§ãã¢ã¯ã»ã¹ãå¯è½ãªå ´åã«ãã°ãåºåãã¦ããã¨æ»æã® Scan ã大éã«é£ãã§ãããã¨ãããã¾ããããããã¨ãã®ãã°ã大éã«åºåããã¦ãéãããã£ã¦ãã¾ããã¨ãããã¾ãããããã£ããã¨ãå«ã㦠BotControl ãæå¹åãã/ããªããèãã¦ã¿ã¦ãã ããã
çµããã«
AWS WAF ã®ãã°ãã BLOCK ãã¦è¯ãã«ã¼ã«ãå¤å¥ããæ¹æ³ãã¾ã¨ãã¾ãããããã¾ã¨ããã¨ããããªã«å¤§ãããã¨ãªãã®ã§ã¯ï¼ãã¨æãããããã¾ããããã©ãæ¤ç´¢ãããè¯ããã«ã¤ãã¦ã¯è©¦è¡é¯èª¤ãå¿ è¦ã§ãããAWS WAF ã«éãããã°ã®æ§é ãç解ããå¿ è¦ãããã¨æãã¾ãã
ã¾ãããªã BLOCK ãã¦è¯ãã¨è¨ãåããããè«ççã«èª¬æããã¦ããæç« ãä¸ã®ä¸ã«è¦å½ãããªãã£ãã®ã§ãèªåã®ä¸ã®æèãæ´çããè¯ãæ©ä¼ã«ãªãã¾ãããã¨ã¯ããããããå¿ ãããæ£è§£ã¨ãæã£ã¦ããªãã®ã§ããã£ã¨ããããæ¹ããããããããããæ¹æ³ããããããªã©æ å ±ããæã¡ã®æ¹ã¯æãã¦ããã ããã¨å¬ããã§ãã
æå¾ã¾ã§èªãã§ãã ãããããã¨ããããã¾ããã