✅ Docker를 사용한 ModSecurity WAF 사용기

Web Application Firewall (WAF)

  • 웹 서비스를 통해서 공격을 시도하는 XSS, SQL Injection, Command Execute과 같은 공격을 효과적으로 차단하는 역할을 수행하는 보안 모듈

  • 어플리케이션 계층(L7) 방화벽

ModSecurity

  • ModSecurity는 웹 공격에 대한 침입탐지 및 침입방지 기능을 추가해 주는 아파치 웹서버의 하나의 모듈로 동작하는 WAF

  • 웹 클라이언트와 아파치 웹 서버 사이에 존재하여 클라이언트로부터 악의적인 트래픽이 발생되면 공격을 차단, 로깅 등 사전에 정의된 행위를 수행

  • 다른 아파치 모듈과 마찬가지로 ModSeucrity를 아파치의 한 부분으로 설치할 수 있으며, 정상적으로 설치되었을 경우 ModSecurity의 추가적인 처리로부터 발생되는 부하는 거의 없다고 할 수 있다.

사용해보기

🤔 간단한 실습은 Docker로 하는게 좋을것 같아 확인해본 결과 웹에서 레퍼런스를 도저히 못찾음!!!!!

혹시몰라서 docker search modsecurity 확인 결과, 뭔가 관련 있어보이는 Image 두 가지를 확인

이미지 Pull

→ 실패!

→ 발견. 컨테이너가 8080포트 리스닝 중.

다시 컨테이너 삭제 후 run 명령 수정

docker stop modsecurity-crs
docker rm modsecurity-crs
docker run -d -p 8080:8080 --name modsecurity-crs owasp/modsecurity-crs:nginx

localhost:8080 접속 결과 → 정상

SQL Injection Test

다른 터미널 띄워놓고 docker logs -f modsecurity-crs 명령으로 실시간으로 로그 확인

  • Request 1
curl "http://localhost:8080/?test='OR'1'='1"
  • Response 1
2024/07/03 16:36:38 [error] 98#98: *43 [client 172.17.0.1] ModSecurity: Access denied with code 403 (phase 2). Matched "Operator `Ge' with parameter `5' against variable `TX:BLOCKING_INBOUND_ANOMALY_SCORE' (Value: `5' ) [file "/etc/modsecurity.d/owasp-crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf"] [line "222"] [id "949110"] [rev ""] [msg "Inbound Anomaly Score Exceeded (Total Score: 5)"] [data ""] [severity "0"] [ver "OWASP_CRS/4.3.0"] [maturity "0"] [accuracy "0"] [tag "modsecurity"] [tag "anomaly-evaluation"] [tag "OWASP_CRS"] [hostname "172.17.0.2"] [uri "/"] [unique_id "172002459857.523994"] [ref ""], client: 172.17.0.1, server: localhost, request: "GET /?test='OR'1'='1 HTTP/1.1", host: "localhost:8080"
172.17.0.1 - - [03/Jul/2024:16:36:38 +0000] "GET /?test='OR'1'='1 HTTP/1.1" 403 146 "-" "curl/8.4.0" "-"
{"transaction":{"client_ip":"172.17.0.1","time_stamp":"Wed Jul  3 16:36:38 2024","server_id":"c670a1574c42004e6043ee8f3dd5301d3cdc8e0c","client_port":59482,"host_ip":"172.17.0.2","host_port":8080,"unique_id":"172002459857.523994","request":{"method":"GET","http_version":1.1,"uri":"/?test='OR'1'='1","headers":{"Host":"localhost:8080","User-Agent":"curl/8.4.0","Accept":"*/*"}},"response":{"body":"<html>\r\n<head><title>403 Forbidden</title></head>\r\n<body>\r\n<center><h1>403 Forbidden</h1></center>\r\n<hr><center>nginx</center>\r\n</body>\r\n</html>\r\n","http_code":403,"headers":{"Server":"nginx","Date":"Wed, 03 Jul 2024 16:36:38 GMT","Content-Length":"146","Content-Type":"text/html","Connection":"keep-alive"}},"producer":{"modsecurity":"ModSecurity v3.0.12 (Linux)","connector":"ModSecurity-nginx v1.0.3","secrules_engine":"Enabled","components":["OWASP_CRS/4.3.0\""]},"messages":[{"message":"SQL Injection Attack Detected via libinjection","details":{"match":"detected SQLi using libinjection.","reference":"v11,9","ruleId":"942100","file":"/etc/modsecurity.d/owasp-crs/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf","lineNumber":"46","data":"Matched Data: s&sos found within ARGS:test: 'OR'1'='1","severity":"2","ver":"OWASP_CRS/4.3.0","rev":"","tags":["application-multi","language-multi","platform-multi","attack-sqli","paranoia-level/1","OWASP_CRS","capec/1000/152/248/66","PCI/6.5.2"],"maturity":"0","accuracy":"0"}},{"message":"Inbound Anomaly Score Exceeded (Total Score: 5)","details":{"match":"Matched \"Operator `Ge' with parameter `5' against variable `TX:BLOCKING_INBOUND_ANOMALY_SCORE' (Value: `5' )","reference":"","ruleId":"949110","file":"/etc/modsecurity.d/owasp-crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf","lineNumber":"222","data":"","severity":"0","ver":"OWASP_CRS/4.3.0","rev":"","tags":["modsecurity","anomaly-evaluation","OWASP_CRS"],"maturity":"0","accuracy":"0"}}]}}
  • **Matched “Operator Ge' with parameter 5’ against variable TX:BLOCKING_INBOUND_ANOMALY_SCORE' (Value: 5’ ) **→ ModSecurity가 특정 규칙에 따라 요청을 차단했음을 나타냄

  • **SQL Injection Attack Detected via libinjection match”:“detected SQLi using libinjection.”,“reference”:“v11,9”,“ruleId”:“942100 → SQL 인젝션 공격이 감지되었음을 나타냄 **

Success!