룰 활성화
SecRuleEngine On | Off | DetectionOnly
ModSecurity 기능을 활성화(enable) 시킨다.
On : ModSecurity 기능 활성화
Off : ModSecurity 기능 비활성화
DetectionOnly : 활성화는 하지만 차단하지 않고 탐지만 한다.
감사로그
감사 로깅에 대한 설정을 구성한다.
On : 모든 트랜젝션 로깅
Off : 모든 트랜젝션 로깅하지 않음
RelevantOnly : Error 또는, Warning 의 트랜젝션, 그리고 SecAuditLogRelevantStatus 에 정의된 상태코드와 일치하는
트랜젝션만 로깅
감사로그 경로
SecAuditLog logs/modsec_audit.log
감사 로그 파일의 경로를 정의한다.
예) SecAuditLog /usr/local/apache2/logs/modsec_audit.log
이 파일은 Root로 접근했을 때만 확인할 수 있어야 하며 Root가 아닌 사용자의 접근은 불가해야
한다. 이 로그 파일에는 Serial 방식의 로깅 형태에 사용된다. 만약 Concurrent 방식의 로깅 형태라
면 이 파일은 로그의 Index로 쓰여 지게 되며 모든 감사로그에 대한 파일이 생성되면서 그 기록을
포함하게 된다. 만약 Concurrent 로깅방식을 사용하고 감사 로그를 원격 콘솔로 보내려면
modsec-auditlog-collector.pl 스크립트를 아래와 같이 사용하면 된다.
예) SecAuditLog \
“|/path/modsec-auditlog-collector.pl /path/SecAuditLogDataDir /path/SecAuditLog”
감사로그 항목 정의
SecAuditLogParts
ex) SecAuditLogParts ABCFHZ
A
audit log header (필수)
B
request header
C
request body (request body가 존재하고 modsecurity가 request body를 검사하도록 설정되어 있는 경우에만)
D
보류중, response header의 중개 (현재 지원 안 됨)
E
response body 중간 단계(현재 modsecurity가 response body를 검사하며 감사 로깅 엔진이 이를 저장하게끔 설정되어 있는 경우에만)
F
최종 response header(마지막 컨텐츠 전달 과정에서 아파치에 의해 매번 추가 되는 날짜와 서버 헤더를 제외한)
G
실제 response body(현재 지원 안됨)
H
감사 로그 트레일러
I
이 옵션은 C를 대체하는 옵션이다. multipart/form-data 인코딩이 사용되었을때를 제외한 모든 경우엔 C와 같은 데이터를 기록한다.
J
보류중, 이 옵션은 multipart/form-data 인코딩을 사용하는 파일 업로드에 대한 정보를 포함할 때 효과가 있다.
Z
로그의 끝을 의미한다. (필수)
SecAuditLogRelevantStatus REGEX
감사로깅의 목적과 관련된 response 상태코드의 값을 설정한다.
매개변수에는 정규표현식이 들어간다.
예) SecAuditLogRelevantStatus ^[45]
SecAuditLogType Serial | Concurrent
감사로깅 구조의 타입을 설정한다.
Serial – 모든 로그는 메인 로그파일에 저장된다. 일시적으로 편리할 순 있지만 하나의 파일에만 기록되기 때문에 느려질 수 있다.
Concurrent – 로그가 각 트랜잭션 별로 나누어 저장된다.
이 방식은 로그파일을 원격 ModSecurity Console host로 보낼 때 사용하는 방식이다.
기본동작
SecDefaultAction
SecDefaultAction “log, auditlog, deny, status:403, phase:2, t:lowercase”
룰이 매칭되면 기본적으로 취할 행동을 정의한다. 1.9.x 버전의 SecFilterDefaultAction을 떠올리면 이해가 쉬운데
2.1.x 버전에서는 옵션들이 더욱 다양해졌다. 룰이 특정 액션들에 대한 개별 룰을 적용하거나
다른 SecDefaultAction이 정의되어있지 않다면 최초 지정된 SecDefaultAction의 설정을 따른다.
위의 예는 룰이 매칭 되었을 때 차단하며 로그를 남기고, 403 상태코드 페이지를 보여주며 필터링 단계는 “2”이다.
기본적으로 대문자는 모두 소문자로 바뀌어 필터링 된다
추가적인 Action
Disruptive actions
ModSecurity가 데이터를 중간에서 가로챌 때 일어나는 행위이다. 하나의 체 인에 첫 번째 룰에만 나타낼 수 있다.
allow, deny, drop 등이 있다.
Non-Disruptive actions
어디에나 나타낼 수 있다. capture, ctl, exec, initcol 등이 있다.
Flow actions
하나의 체인에 첫 번째 룰에만 나타낼 수 있다. chain 이 있다.
Meta-data actions
하나의 체인에 첫 번째 룰에만 나타낼 수 있다. id, rev, severity, msg가 있다.
Data actions
전면적으로 수동적이고 다른 행위에서 사용된 데이터를 운반하는 역할뿐이다.
action
allow
룰에 매칭되면 처리를 멈추고 트랜젝션을 허가한다.
ex) SecRule REMOTE_ADDR “^192\.168\.1\.100$” “nolog, phase:1, allow”
※ allow 액션은 오직 현재 처리단계에서만 적용된다.
auditlog
감사로그에 트랜젝션을 기록한다.
ex) SecRule REMOTE_ADDR “^192\.168\.1\.100$” “auditlog, phase:1, allow”
capture
정규표현식과 함께 사용되었을 때 capture 액션은 정규표현식의 사본을 만들고
트랜잭션의 가변적인 콜렉션에 모은다. 최대 10개가 수집되면 각각 0~9까지 한자리 숫자의 이름이 매겨 진다.
ex) SecRule REQUEST_BODY “^username=(\w{25,})” “phase:2,capture,t:none,chain” SecRule TX:1 “(?:(?:a(dmin|nonymous)))”
chain
두개의 룰을 연관지어 허용하고 싶을 때 사용할 수 있다.
ex) SecRule REQUEST_METHOD ^POST$ “chain”
SecRule REQUEST_HEADER:Content-Length ^$
ctl
ctl 액션은 트랜잭션을 최신화하기 위한 설정 옵션이다.
ex) SecRule REQUEST_CONTENT_TYPE ^text/xml “nolog,pass,ctl:auditEngine=ON”
다음과 같은 옵션들이 들어갈 수 있다.
auditEngine
requestBodyProcessor
auditLogParts
responseBodyAccess
debugLogLevel
responseBodyLimit
requestBodyAccess
ruleEngine
requestBodyLimit
deny
룰이 일치할 경우 요청 처리를 차단한다. status action이 명시되어 있지 않으면 ModSecurity는 “HTTP 403 error code”를 반환한다.
ex) SecRule REQUEST_HEADERS:User-Agent \ “nikto“ ”log,deny,msg:’Nikto Scanners Identified'”
drop
FIN 패킷을 보내 TCP 연결을 끊어서 연결을 종료시킨다.
exec
필터가 일치하면 파라미터를 지원하는 외부 스크립트/바이너리를 실행시킨다.
예) SecRule REQUEST_URI “^/cgi-bin/script\.pl” \ “log, exec:/usr/local/apache/bin/test.sh, phase:1”
id
룰이나 체인에 unique ID를 할당한다.
ex) SecRule &REQUEST_HEADER:Host “@eq 0” \ “log, id:60008, severity:2, msg:’Request Missing a Host Header'”
log
필터가 일치하였을 때 로그를 남긴다.
※ 이 동작은 Apache의 error log와 ModSecurity의 audit log를 비교한다.
msg
룰이나 체인에 사용자 메시지를 지정한다.
noauditlog
필터가 일치하였을 때 해당 트랜젝션을 audit log에 기록하는 기준으로 하지 않는다.
ex) SecRule REQUEST_HEADER:User-Agent “Test” “allow, noauditlog”
※ 만약 SecAuditEngine이 On으로 설정되어 있으면 모든 트랜젝션은 로깅된다.
만약 RelevantOnly로 설정되어 있으면, noauditlog 로 제어할 수 있다.
noauditlog가 설정되고 audit event가 발생한다면 트랜젝션을 로깅할 수 있다.
확실하게 audit logging을 비활성화 하려면 “ctl:auditEngine=Off”를 쓰면 된다.
nolog
에러와 감사로그에서 나타나는 일치 현상을 방지한다.
ex) SecRule REQUEST_HEADERS:User-Agent “Test” “allow, nolog”
pass
요청에 대한 응답을 하기 전에 정의된 수 milliseconds 동안 중지시킨다.
ex) SecRule REQUEST_HEADERS:User-Agent “Test” “log,deny,pause:5000”
※ Brute Force scanner의 속도를 떨어트리거나 보호할 수 있다. DoS 유형의 공격아래에 있을 때는 pause가 완료할 때까지
child process가 무력화되는 경우가 발생할 수 있다.
phase
룰이나 체인이 속하게 되는 1~5 까지의 처리 단계
ex) SecDefaultAction “log,deny,phase:1,t:removeNulls,t:lowercase”
SecRule REQUEST_HEADERS:User-Agent “Test” “log,deny,status:403”
※ 잘못된 phase를 지정하지 않게 유의해야 한다. 대상 변수가 무의미 할 수 있다. 변수나 정규식이 false negative를
일으킨다면 올바른 작동이다. 그러나 악성 데이터를 처리하지 못하는 것은 잘못된 phase를 지정했기 때문이다.
proxy
필터가 일치하면 트랜젝션을 가로채어 프록시가 구동중인 다른 웹서버로 요청을 포워딩한다.
ex) SecRule REQUEST_HEADERS:User-Agent “Test” \
“log, proxy:http://www.honeypothost.com”
※ 이 동작은 mod_proxy가 반드시 설치되 있어야 한다.
redirect
필터가 일치하면 사용자를 주어진 URL로 리다이렉트 시킨다.
예) SecRule REQUEST_HEADERS:User-Agent “Test” \
“redirect:http://www.krcert.or.kr/failed.html”
※ 만약 status 액션이 현재 사용하고 있거나 가능한 값이 301,302,303,307 이라면 것은 redirection에 사용될 것이다.
그렇지 않다면 302 상태 코드를 사용한다.
skip
필터가 일치하면 하나 이상의 룰이나 체인을 건너뛸 수 있다.
ex) SecRule REQUEST_URI “^/$” “chain,skip:2”
SecRule REMOTE_ADDR “^127\.0\.0\1$” “log,deny,status:400”
SecRule &REQUEST_HEADERS:Accept “@eq 0” \ “log,deny,log,status:400,msg:’Request Missing an Accpet Header'”
status
deny 나 redirect 액션에서 사용될 상태코드 값을 지정한다.
ex) SecDefaultAction “log,deny,status:403,phase:1”
t
이 액션은 룰에 지정된 연산자가 실행되기 전 변수에 지정된 변형 함수에 사용될 수 있다.
ex) SecDefaultAction “log,deny,phase:1,t:removeNulls,t:lowercase”
SecRule REQUEST_COOKIES:SESSIONID “47414e81…..” \ “log, deny,status:403,t:md5”
지시자
SecRule
SecRequestBodyAccess On | Off
Request 값에서 Body 부분에 대한 처리를 어떻게 할 것인지 구성한다.
On : RequestBody 접근을 시도한다.
Off : RequestBody 접근시도를 하지 않는다.
이 지시자는 Request 값에서의 POST_PAYLOAD를 검사할 때 필요하다. POST값을 필터링하기 위 해서는 phase:2와 REQUESET_BODY변수/로케이션, 3가지가 모두 구성되어야만 처리가 가능하다.
SecRequestBodyLimit
ModSecurity가 Request Body 크기로 할당할 수 있는 메모리 최대 크기를 설정한다.
SecRequestBodyLimit 134217728 131072KB (134217728 byte)가 기본값이다.
SecResponseBodyAccess On | Off
Response 값에서 Body 부분에 대한 처리를 어떻게 할 것인지 구성한다.
On : ResponseBody 접근을 시도한다. (그러나 MIME 타입과 일치해야만 한다.)
Off : ResponseBody 접근시도를 하지 않는다.
이 지시자는 html 응답을 조사하기 위해 필요하다. “phase:4″의 처리 단계와 RESPONSE_BODY 변 수/로케이션, 3가지가 설정되어
있지않으면, response body를 검사할 수 없다.
SecResponseBodyLimit 524228
ModSecurity가 Response Body 크기로 할당할 수 있는 메모리 최대 크기를 설정한다.
SecRequestBodyLimit 524228
이 값을 넘어가면 서버는 500 내부 서버 오류 메시지만 표시할 것이다.
SecReponseBodyMimeType mime/type
Response 값에서 Body 값을 버퍼링할 MIME 타입을 설정한다.
SecResponseBodyMimeType text/plain text/html // 기본값 Mime 타입은 복수로 추가할 수 있다.
SecReponseBodyMimeTypesClear
ResponseBody의 버퍼링을 위해 Mime 타입의 목록을 지우며, 처음에 위치시킨다.
SecResponseBodyMimeType
사용자 Rule 정의
SecRule은 ModSecurity의 핵심 지시자이다. 데이터 분석과 액션 실행의 기본이 된다.
SecRule REQUEST_URI “attack”
SecRule은 다음 세가지로 구성되어 있다.
SecRule VARIABLES OPERATOR [ACTIONS]
– Operator는 어떻게 검사할 것인지를 지정하며,
– Actions는 operator을 통해 변수가 실행되어 일치하였을 때 어떤 행동을 취할 것인지를 지정
① 변수(Variables)
다음 예제는 ‘dirty’를 포함한 트랜젝션을 거부한다.
ex) SecRule REQUEST_URI dirty
중복하여 사용할 수도 있다.
ex) SecRule REQUEST_URI|QUERY_STRING dirty
② 연산자(Operator)
연산자에는 정규식을 사용할 수 있다. 첫문자는 @ 로 시작하여야 하며 정규식을 이용해 특별한
패턴으로 대상을 검사할 수 있다.
ex) SecRule REQUEST_URI “@rx dirty”
부정을 표현할땐 다음과 같이 사용할 수 있다.
ex) SecRule REQUEST_URI “!@rx ^0$”
③ 행위(Actions)
행위는 default action에서 지정되기 때문에 생략할 수 있다. 만약 생략하지 않고 추가로 지정된 다면 default action과 병합되어
action이 작용되게 된다. 액션은 위에서 설명하였다.
SecRuleInheritance On | Off
상위 문맥으로부터 룰을 상속받을지 안 받을지 설정하기 위한 지시자이다.
SecRuleInheritance On
각 가상호스트마다 별도로 룰을 설정할 수 있다.
…
ServerName app1.com
SecRuleInheritance Off
SecDefaultAction log,deny,phase1,redirect:http://www.test2.com
…
…
ServerName app2.com
SecRuleInheritance On SecRule ARGS “attack”
…
SecRuleRemoveById
상위 문맥과 룰이 일치하면 일치한 룰을 제거한다.
SecRuleRemoveById 1 2 “9000-9010” 다중 파라미터를 지원하며 쌍따옴표를 통한 범위를 지정할 수 있다.
파라미터는 RULE ID나 하나의 범위가 될 수도 있다.
SecRuleRemoveByMsg
상위 문맥과 룰이 일치하면 일치한 룰을 제거한다.
SecRuleRemoveByMsg “FAIL”
위 지시자는 RULE ID로 룰을 제거하지만 이 지시자는 action의 msg가 지정한 정규식에 따라 룰을 제거한다.
SecServerSignature “Netscape-Enterprise/6.0”
응답 헤더의 “Server:” 토큰을 바꿔 표시한다.
SecServerSignature “Microsoft-IIS/5.0”
이 지시자를 사용하려면 Apache의 설정파일에서 ServerTokens 값이 “Full”로 설정되있어야 한다.
SecDebugLog /path/to/modsec-debug.log
ModSecurity의 디버그 로그의 경로를 설정한다.
SecDebugLog /usr/local/apache2/logs/modsec-debug.log
SecDebugLogLevel |0|1|2|3|4|5|6|7|8|9
디버그 로그의 상세 수준을 결정한다.
SecDebugLogLevel 4
level 1~3은 항상 Apache의 에러로그로 보낸다. level 5가 디버깅에 가장 유용하며 그 이상은 서버 의 성능을 저하시키기 때문에 권장하지
않는다.
0 로깅하지 않는다.
1 에러만(요청값) 로깅
2 경고 수준
3 공지 수준
4 트랜젝션의 처리과정 상세
5 4와 동일하나 각 처리의 부분별 정보가 포함
9 모두 로깅, 디버깅 정보를 상세히 포함
SecDataDir /path/to/dir
영구적 데이터를 저장할 경로를 지정한다.(IP주소, Session 값 등)
SecDataDir /usr/local/apache2/logs/data
이 지시자는 initcol, setsid, setuid 가 사용될 때 필요하다. 반드시 웹서버 사용자에 의해 쓰기가 가능해야 한다.
SecTmpDir /path/to/dir
임시 파일이 생성될 디렉토리를 설정한다.
SecTmpDir /tmp
Apache 사용자 프로세스에 의해 쓰기가 가능해야 한다. 이 디렉토리는 검사가 진행되는 동안 아파치가 메모리가 부족할 때
디스크를 스왑하기 위한 영역이다. (메모리 크기는 SecRequestBodyInMemoryLimit 지시자에 의해 설정된 크기이다.)
SecUploadDir /path/to/dir
가로챈 파일을 저장하기 위한 디렉토리를 설정한다.
SecUploadDir /tmp
SecTmpDir 지시자에 의해 지정된 디렉토리와 같은 파일시스템에 위치해야 한다. 이 지시자는 SecUploadKeepFiles 와 함께 쓰인다.
SecUploadKeepFiles On | Off | RelevantOnly
트랜젝션이 처리된 후에 가로챈 파일을 유지할 것인지 아닌지를 설정한다.
On : 업로드된 파일을 유지한다.
Off : 업로드된 파일을 유지하지 않는다.
RelevantOnly : 수락된 요청과 관련된 업로드 파일만 유지한다.
트래픽 감사 예외 IP 설정
형 식 SecRule REMOTE_ADDR “허용할 IP” allow,ctl:ruleEngine=off
사 용
SecRule REMOTE_ADDR “221\.149\.161\.5” allow,ctl:ruleEngine=off
SecRule REMOTE_ADDR “211\.252\.151\.24” allow,ctl:ruleEngine=off
SecRule REMOTE_ADDR “211\.252\.151\.44” allow,ctl:ruleEngine=off
위 설정은 예외처리를 해주지만 그에 대한 로그는 동일하게 기록된다. 취약점 점검 서비스를 통해 다량의 로그 발생시에는
Action 지시자에 nolog를 추가해주면 로그가 기록되지 않는다.
Request body 접근
SecRequestBodyAccess(phase:2)
Response body 접근
SecResponseBodyAccess(phase:4)