白”雪姫”の雑なエンジニアブログ

ダイアリーがなくなってしまったため、エンジニアブログとして再出発

とあるセキュリティ認証の要件に合わせたマネジメントWAFの設定~後編~

この記事は、前編を読んでくださった方向けの続きの記事です。
お読みになった上で、ご覧ください。

前回記事で、OWASP ZAP TOP10の1・2・5・7・9・(10)の対策のうち
2番のメイン対策・(10)番の付随対策の位置づけであるBot対策を説明しました。
残っている部分だけを前記事から引用します。

1. インジェクション対策(SQLInjection)
5. Broken Access Control(アクセス設定の不備)
7. Cross-Site Scripting(XSS)
9. Using Components with Known Vulnerabilities(既知の脆弱性対策)

についての説明記事です。

  • Admin protection

こちらは、5・7番への対策です。
5番におけるプログラム設定の不備、7番の管理画面のURIが判明した場合認証攻撃などをされるので、対策に役に立ちます。
名前だけで見たら、”管理者の保護”と読み取れますが、ルールの説明には以下です。

Contains rules that allow you to block external access to exposed admin pages. This may be useful if you are running third-party software or would like to reduce the risk of a malicious actor gaining administrative access to your application.

コンテンツ内の管理者ページへのアクセスを制御します。サードパーティソフトウェアもしくは悪意のある者の管理アクセスを制御するのに役に立つ
という事です。
つまり、管理者アクセスそのものを制限することで対策を行いましょう。というものです。
詳細はLearn Moreも確認してください。

  • Core rule set

9番及び前編で記載したTOP10ひいてはOWASPで推奨される全ての対策になりますが、ルール名に記載の通りプログラムの中心部で使われるであろう想定から作られるの対策となるので一部対策が甘いところがあるので「このルール入れればじゃあ良いじゃん」なんてことは思わないようにしてください。

中心にあるもののルールセットというのが、言い方としては正しいですが、内容は以下の様に英語で記載されてます。

Contains rules that are generally applicable to web applications. This provides protection against exploitation of a wide range of vulnerabilities, including those described in OWASP publications. 

何か、見た用語が出てきましたね。OWASPというワードとvulnerabilitiesという言葉です。
簡単に書きますと作成されたアプリケーションはフレームワークなどを使われてると思いますが、それの中心となるプログラムに対しての「脆弱性」や「OWASP」の対策が講じられているか、講じられていない場合、WAFの方で一時的に対処しましょう
というものです。

既知の脆弱性の対策方法でも有りますので、9番の対策をします。

Linuxにある固有脆弱性、攻撃者に公開されては困るファイル内容などを対策します。
プログラムで公開される可能性があるので、その対策です。
説明文は以下です。

Contains rules that block request patterns associated with exploitation of vulnerabilities specific to Linux, including LFI attacks. This can help prevent attacks that expose file contents or execute code for which the attacker should not have had access.

と、先に私が、日本語記載した物そのままでした・・・。詳細はLearnMoreを読んで頂いた方がより良い理解が出来るかとおもいます。

1番と9番の対策です。
SQLインジェクション対策のために実装します。
それ以外にもデータベース、SQLに対する脆弱性などの対策もできます。

説明は次の通りです。

Contains rules that allow you to block request patterns associated with exploitation of SQL databases, like SQL injection attacks. This can help prevent remote injection of unauthorized queries.

非認証なオペレーションも対策してくれる様です。

ここまでつらつらと書きましたが以上が対策に設定するルールです。

ルールは本執筆中はこのように並んでいます。

Free rule groups

OWASPの順番で並べてみます。

OWASP TOP10の内容 AWS WAFのルール 備考
1.インジェクション対策 SQL database
2.アクセス制御の不備(認証情報の漏洩) Bot Control
5.Broken Access Control(アクセス設定の不備) Bot Control,Admin protection
7.Cross-Site Scripting(XSS) Admin protection
9.Using Components with Known Vulnerabilities(既知の脆弱性対策) Core rule set,SQL database
Insufficient Logging and Monitoring(不十分なログと監視設定) Bot Control あくまで付随対策なのでプログラム(開発)側でしっかり対策が必要


順番について
ルールの適応に関して、ここまで記載してきましたが、WAFのルールには適用される順番があります。
AWS WAFではもう1つ気にすることがあります。
通過させるルールの順番です。

一通りルールを選択が終わり、次へとすると、ルールの適用する順番を聞かれます。

rule priority

ここで、考えるのは、パケットが来た時にどういった順番で動作をするのかです。

パケットを受け取ると、まずはアプリケーションを通過、その後、アプリケーションのミドルウェアを通過、OSを通過、とOSI参照モデルの下の方へいきます。
つまり、フロントで受け取る順番から対策をしてくという必要があります。

紹介したルールは

  • BotRule
  • Admin protection
  • Core rule set
  • Linux operation system
  • SQL database

対策順番はOSが一番最後になりますので

  1. BotRule
  2. Admin protection
  3. Core rule set
  4. SQL database
  5. Linux operation system

が、正解です。

悩ましいと思われるのは、
Admin protectionとCore rule setですが、
URLの様な見える物、権限を取られたら困る物から適用していくことになります。

Admin等の固有URI等が見えますし、権限上の管理権限等が付与されている場合もあります。
そのため、
Botの対策後Adminを対策、Core ruleによるプログラムの対策、SQLの対策後、OSの対策
というのが理想な対策かと言われています。

設定後は、ログの確認をして、完了です。
CloudWatch Logsを確認して見ます。

log-sample

こんな感じに出てきます。

要件に満ちているかを確認するため、以下に完全貼り付けをします(重要情報は、***にて潰しますが)

{
    "timestamp": 1706422856469, <strong>←UnixTimeによる時間</strong>
    "formatVersion": 1,
    "webaclId": "arn:aws:wafv2:us-east-1:********:global/webacl/test/133cfd57-461a-4011-bd47-eb9cfaacaaec", <strong>←どのACLか</strong>
    "terminatingRuleId": "Default_Action",
    "terminatingRuleType": "REGULAR",
    "action": "BLOCK", <strong>←許可か拒否か</strong>
    "terminatingRuleMatchDetails": [],
    "httpSourceName": "****",<strong>←Source Protocol</strong>
    "httpSourceId": "*******",
    "ruleGroupList": [
        {
            "ruleGroupId": "AWS#AWSManagedRulesAdminProtectionRuleSet",
            "terminatingRule": null,
            "nonTerminatingMatchingRules": [],
            "excludedRules": null,
            "customerConfig": null
        },
        {
            "ruleGroupId": "AWS#AWSManagedRulesCommonRuleSet",
            "terminatingRule": null,
            "nonTerminatingMatchingRules": [],
            "excludedRules": null,
            "customerConfig": null
        },
        {
            "ruleGroupId": "AWS#AWSManagedRulesSQLiRuleSet",
            "terminatingRule": null,
            "nonTerminatingMatchingRules": [],
            "excludedRules": null,
            "customerConfig": null
        },
        {
            "ruleGroupId": "AWS#AWSManagedRulesLinuxRuleSet",
            "terminatingRule": null,
            "nonTerminatingMatchingRules": [],
            "excludedRules": null,
            "customerConfig": null
        }
    ],
    "rateBasedRuleList": [],
    "nonTerminatingMatchingRules": [],
    "requestHeadersInserted": null,
    "responseCodeSent": null,
    "httpRequest": {
        "clientIp": "******",<strong>←SrcIP</strong>
        "country": "**", <strong>←SrcCountry</strong>
        "headers": [
            {
                "name": "User-Agent",
                "value": "Wget/1.17.1 (linux-gnu)"
            },
            {
                "name": "Accept",
                "value": "*/*"
            },
            {
                "name": "Accept-Encoding",
                "value": "identity"
            },
            {
                "name": "Host",
                "value": "*****" ←DstHost
            },
            {
                "name": "Connection",
                "value": "Keep-Alive"
            }
        ],
        "uri": "/******", <strong>←アクセスしたURI</strong>
        "args": "REDACTED",
        "httpVersion": "HTTP/1.1",
        "httpMethod": "REDACTED",
        "requestId": "tCwsXZBRpUZy_JHczpC6U0CL30m_C6U2FCDaluiXTJWmakHqEBUm_w=="
    },
    "ja3Fingerprint": "81bacd5d10832264bc04b9041be2a088"
}

なお、UnixTimeでしかログ上では表示されないので、CloudWatchLogsの時間を参照にするとアクセスしてきた時間を見る方が解析はしやすいかと思います。
また、見づらいですが、どのルールが拒否したのか等も記載されています。
前編で紹介したログにも準拠します。

長くなりましたが、設定は以上です。
ありがとうございました。