본문 바로가기
공부/AWS

[AWS WAF] #4 JSON으로 WAF Rule 직접 작성해보기

by haejang 2021. 2. 26.
728x90
728x90

목차

1. 기존 룰 백업 및 분석

2. 새 룰 요구사항 분석

3. 새 룰 작성 후 테스트

 

 

1. 기존 룰 백업 및 삭제

WAF Web ACLs에 들어가면 현재 ACL을 JSON으로 받을 수 있다

 

1-1) AWS managed rule의 Core rule set

{
  "Name": "AWS-AWSManagedRulesCommonRuleSet",
  "Priority": 0,
  "Statement": {
    "ManagedRuleGroupStatement": {
      "VendorName": "AWS",
      "Name": "AWSManagedRulesCommonRuleSet"
    }
  },
  "OverrideAction": {
    "None": {}
  },
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "AWS-AWSManagedRulesCommonRuleSet"
  }
}

1-2) AWS managed rule의 SQL database

{
  "Name": "AWS-AWSManagedRulesSQLiRuleSet",
  "Priority": 1,
  "Statement": {
    "ManagedRuleGroupStatement": {
      "VendorName": "AWS",
      "Name": "AWSManagedRulesSQLiRuleSet"
    }
  },
  "OverrideAction": {
    "None": {}
  },
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "AWS-AWSManagedRulesSQLiRuleSet"
  }
}

managed 룰들은 뭐 특별히 볼만한건 없다

1-3) 싱가포르 차단 룰

{
  "Name": "SG-Block",
  "Priority": 2,
  "Statement": {
    "GeoMatchStatement": {
    //나라 기반 룰을 만들 것
      "CountryCodes": [
      //어떤 나라?
        "SG"
        //싱가포르
      ]
    }
  },
  "Action": {
    "Block": {}
  },
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "SG-Block"
  }
}

1-4) 아이폰 차단 룰

{
  "Name": "iphone-Block",
  "Priority": 3,
  "Statement": {
    "ByteMatchStatement": {
    //헤더 기반
      "SearchString": "iphone",
      //iphone이란 문자열을 찾을 것임
      "FieldToMatch": {
      //어느 필드에서 찾을거냐
        "SingleHeader": {
          "Name": "user-agent"
          //user-agent 필드에서 찾을거다
        }
      },
      "TextTransformations": [
        {
          "Priority": 0,
          "Type": "LOWERCASE"
          //대소문자 구분 없이 찾겠다
        }
      ],
      "PositionalConstraint": "CONTAINS"
      //iphone이란 단어를 "포함"하는 user-agent 값을 찾겠다
    }
  },
  "Action": {
    "Block": {}
  },
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "iphone-Block"
  }
}

주석은 내가 그냥 보기 쉬우라고 적은거지 사실 JSON은 주석을 쓰면 안된다

1-5) 기존 룰 삭제

전체선택 후 delete 해주면 된다

 

2. 새 룰 요구사항 분석

 

논리 구성 : [한국에서 온 트래픽] AND ([request body > 100] OR [x-value=lowercase(bot)])

 

3. 새 룰 작성 후 테스트

3-1) 차단 전 확인 : curl로 진행

윈도우에서 진행하는 경우, curl.se/download.html 에서 최신버전을 내 컴에 맞는걸로 다운받아주자

 

압축만 풀어주면 사용 준비는 끝

 

curl은 명령행 기반 웹 요청 도구인데, 아무래도 리눅스 기반 명령어다보니 cmd에서는 뭐가 많이 다르고 오류가 난다

그래서 git bash에서 다음 명령들을 진행해봤다

export waf_url=[ALB의 DNS 주소]

curl -i -H "x-value: bot" $waf_url
# x-value 헤더 값이 bot인 경우
curl -i -X POST -d "Amazon":"30","is":"12374934237","known":"Target 3","as":null,"one":"Configuration Deneme 3","of":null,"the":"Configuration Deneme 3","most":0,"customer-centric":3,"companies":true $waf_url
# 파라미터를 많이 넣어서 request body size를 늘림

 

두 명령의 요청이 정상적으로 완료되었다

 

더보기

-i [URL] : GET요청 - 헤더와 바디까지 가져옴

-d "파라미터" [URL] : POST요청 - URL 인코딩된 파라미터를 앞에 쓴 후, POST를 처리할 주소를 넣음

-X [method] [URL] : 요청을 보내는 method를 직접 지정

 

3-2) Rule 생성

{
"Name": "TestRule",
"Priority": 0,
"Action": {
"Block": {}
},
"VisibilityConfig": {
"SampledRequestsEnabled": true,
"CloudWatchMetricsEnabled": true,
"MetricName": "TestRule"
},
"Statement": {
"AndStatement": {
  "Statements": [
    {
      "GeoMatchStatement": {
        "CountryCodes": [
          "KR"
        ]
      }
    },
    {
      "OrStatement": {
        "Statements": [
          {
            "SizeConstraintStatement": {
              "FieldToMatch": {
                "Body": {}
              },
              "ComparisonOperator": "GT",
              "Size": 100,
              "TextTransformations": [
                {
                  "Priority": 0,
                  "Type": "NONE"
                }
              ]
            }
          },
          {
            "ByteMatchStatement": {
              "SearchString": "bot",
              "FieldToMatch": {
                "SingleHeader": {
                  "Name": "x-value"
                }
              },
              "TextTransformations": [
                {
                  "Priority": 0,
                  "Type": "LOWERCASE"
                }
              ],
              "PositionalConstraint": "EXACTLY"
            }
          }
        ]
      }
    }
  ]
}
}
}

정답은 이렇다

AndStatement(한국차단, OrStatement(사이즈 100 이상, x-value값이 대소문자 구분 없이 bot))

룰 적용은 custom 룰 만들 때 처럼 Add my own rules and rule groups로 들어가 JSON editor 눌러서 작성해주면 된다

 

 

Validate로 문제없는지 확인해보고 완료해주자

3-3) 차단 확인

아까와 똑같은 명령을 다시 해보자

curl -i -H "x-value: bot" $waf_url
curl -i -X POST -d "Amazon":"30","is":"12374934237","known":"Target 3","as":null,"one":"Configuration Deneme 3","of":null,"the":"Configuration Deneme 3","most":0,"customer-centric":3,"companies":true $waf_url

 

 

 

아까완 다르게 403 Forbidden이 뜬다 (차단 성공)

 

실습은 이걸로 끝이고, 다음 글에선 로깅을 확인하고 리소스를 지우는 마무리 단계를 진행하도록 하겠다

 

실습 시리즈

#0 실습 전 준비

#1 사전 리소스들과 WAF 구성

#2 SQL Injection & XSS 공격과 방어 (AWS managed rule)

#3 특정 국가 or User-Agent 차단 (custom rule)

#5 실습 마무리 : 로깅 확인 & 리소스 삭제

728x90
728x90

댓글