Modsecurity 로그분석및 고급룰설정 오늘과내일홍석범 antihong@tt.co.kr
적용여부확인방법 차단은되는것같은데, 로그가남지않는다? error_log : [Fri Oct 19 11:24:04 2007] [error] ModSecurity: ModSecurity requires mod_unique_id to be installed. modsec_audit.log 에는남지않음이러한경우 httpd.conf 에서 LoadModule unique_id_module modules/mod_unique_id.so 확인 SecServerSignature 를 IIS 로변경하여설정했는데, 질의를하면헤더가변경되지않는다? # lynx -head -source http://127.0.0.1/ # wget -S --spider http://127.0.0.1/ # curl --head http://127.0.0.1/ httpd.conf 에서 ServerTokens Prod 를 Full 로설정하여야함 2
제로보드관련룰 (1.9) 기존KISA 제공룰 SecFilterSelective REQUEST_URI "/include/write.php?dir=(ftp http):" SecFilterSelective REQUEST_URI "/include/print_category.php?setup=1&dir=(ftp http):" SecFilterSelective REQUEST_URI "/zero_vote/error.php?dir=(ftp http):" SecFilterSelective REQUEST_URI "/outlogin.php?_zb_path=(ftp http):" SecFilterSelective S l ti REQUEST_URI URI "filename= " SecFilterSelective REQUEST_URI "check_user_id.php?user_id=<script>alert(document.cookie)" 추가룰 SecFilterSelective REQUEST_URI URI "/zero_vote/login.php?dir=(ftp http): php?dir=(ftp http): SecFilterSelective REQUEST_URI "/zero_vote/setup.php?dir=(ftp http): SecFilterSelective REQUEST_URI "/zero_vote/ask_password.php?dir=(ftp http): 또는 #Generic PHP remote file inclusion attack signature with command SecFilterSelective REQUEST_URI ".php?" chain SecFilterSelective REQUEST_URI "(http https ftp) :/" chain SecFilterSelective REQUEST_URI REQUEST_BODY "(cd ; perl lynx links mkdir cmd pwd wget lwp- (download request mirror rget) d t) id uname net(stat cat) t t t) curl telnet t gcc cc rm -[a-z A-Z])" 2.x 에서는 SecFilterSelective Secrule 3
disable 해야할룰 (1.9.x) SecFilterSelective ARGS "-->" "msg:'xss attack'" SecRule ARGS "-->" "msg:'xss attack'" 전송데이터에 --> 만들어가도공격으로판단 mod_security-message: Access denied with code 403. Error processing request body: Multipart: final boundary missing [severity "EMERGENCY"] 파일업로드시일부발생, 1.9.x에만발생, SecFilterScanPOST On =>Off mod_security-message: Access denied with code 403. Pattern match ";[[:space:]]*(ls id pwd wget cd)" at ARGS_VALUES( VALUES("content") [msg "Command execution attack"] [severity "EMERGENCY"] ttp://www.example.com/example.php?board=public&id=1225 정상임 SecFilterSelective ARGS "alert[[:space:]]*\( <SCRIPT LANGUAGE="JAVASCRIPT"> function openertr() { alert(" 팝업이차단되었습니다!"); } </SCRIPT> 4
disable or 커스터마이징 (1.9.x) SecFilterSelective ARGS "http-equiv <meta http-equiv="content-type SecFilterSelective ARGS "style[[:space:]]*= <style type="text/css"> SecFilter "\.\./\.\." SecFilter "\.\./\.\./" SecFilter "/\.\./\.\./\.\./\.\./" 고도몰등특정프로그램이작동안됨 # WEB-CGI technote main.cgi file directory traversal attempt SecFilterSelective THE_REQUEST "/technote/main\.cgi" chain SecFilter "\.\./\.\./" # WEB-CGI technote print.cgi directory traversal attempt SecFilterSelective THE_REQUEST "/technote/print\.cgi" chain SecFilter "\x00" 5
Host 나 User-Agent 가없는경우 Message: Warning. Operator EQ match: 0. [id "960008"] [msg "Request Missing a Host Header"] [severity "WARNING"] HEAD / HTTP/1.0 Accept: */* User-Agent: WhatsUp Professional/1.0 modsecurity_crs_21_protocol_anomalies.conf SecRule &REQUEST_HEADERS:Host "@eq 0" \ "skip:1,log,auditlog,msg:'request Missing a Host Header',,id:'960008',severity:'4'" SecRule REQUEST_HEADERS:Host "^$" \ "log,auditlog,msg:'request Missing a Host Header',,id:'960008',severity:'4'" SecRule &REQUEST_HEADERS:User-Agent "@eq 0" \ "skip:1,log,auditlog,msg:'request Missing a User Agent Header',,id:'960009',severity:'4'" SecRule REQUEST_HEADERS:User HEADERS:User-Agent Agent "^$" \ "log,auditlog,msg:'request Missing a User Agent Header',,id:'960009',severity:'4'" SecFilterSelective HTTP_Host "^$" (1.9.x) & : counting the number of variables (1) 아예헤더에 User-Agent가없는경우 (2) 헤더에 User-Agent는있지만데이터가없는경우 6
커스터마이징 Message: Access denied with code 400 (phase 2). Pattern match "^[\\d\\.]+$" at REQUEST_HEADERS:Host. [id "960017"] [msg "Host header is a numeric IP address"] [severity "CRITICAL"] 도메인이아닌 IP 로접속시발생 modsecurity_crs_21_protocol_anomalies.conf SecRule REQUEST_HEADERS:Host H "^[\d\.]+$" "deny,log,auditlog,status:400,msg:'host di l header is a numeric IP address', severity:'2',,id:'960017'," 7
파일에특수문자포함시 Message: Warning. Match of "rx ^[a-z]{3,10} s*(?: w{3,7}? : / /[ w -. /]*)?? /[ w -. /~%:@&=+$,;]*(?:?[ S]*)?? s*http / d. d$" against "REQUEST_LINE" required. [id "960911"] [msg "Invalid HTTP Request Line"] [severity "CRITICAL"] SecRule REQUEST_LINE "!^[a-z]{3,10} s*(?: w{3,7}? : / /[ w -. /]*)?? /[ w -. /~%:@&=+$,;]*(?:?[ S]*)?? s*http / d. d$" "t:none,t:lowercase,deny,log,auditlog,status:400,msg:'invalid HTTP Request Line',,id: id:'960911',severity: severity:'2'" ==> GET /1181633664worldhistory(McGrawHill)cover.jpg HTTP/1.1 와같이파일이나디렉토리이름에 () 가포함된경우또는공란 (space) 이있는경우등 8
특정 IP/ 도메인을제외할때 특정한 IP 에대해서는모니터링하지않을때 SecRule REMOTE_ADDR "^192.168.1 100$" phase:1,nolog,allow,ctl:ruleengine=off,ctl:auditengine=off * 특정도메인 ( 디렉토리 ) 에대해서는 modsecurity 설정을해제하고자할때.htaccess SecFilterEngine Off # 기본엔진동작정지 SecFilterScanPOST Off # POST 스캔중지 SecFilterCheckURLEncoding Off # URL 인코딩체크중지.htaccess 에 # 이있을경우 500 error가발생하므로그대로복사할경우서비스가되지않을수있으므로주석 (#) 부분은명기하지않아야함 주의 : modsecurity 2.x 에서는.htaccess 를지원하지않음 9
Phpmyadmin 등예외사항 phpmyadmin 사용시, 제외하고자할때 SecRule REQUEST_URI R ^/phpmyadmin phase:1,allow,ctl:ruleengine=off l l 또는 <LocationMatch "^/phpmyadmin/"> SecRuleEngine Off </LocationMatch> 특정룰을주석처리하지않고 disable하고자할때 Message: Warning. Pattern match "(?:\\b(?:\\.(?:ht(?:access passwd group) www_?acl) global\\.asa httpd\\.conf boot\\.ini)\\b \\/etc\\/)(?:ht(?:access passwd group) www?acl) global\\ asa httpd\\ conf boot\\ ini)\\b \\/etc\\/)" at REQUEST_FILENAME. [id "950005"] [msg "Remote File Access Attempt. Matched signature </etc/>"] [severity "CRITICAL"] SecRuleRemoveById R 950005 룰의선언위치가중요, 기선언된룰의뒤 ( 예 :modsecurity_crs_80.conf) 에선언해야함 <VirtualHost 192.168.1.4> ServerAdmin webmaster@example.com DocumentRoot /home/example/public_html ServerName example.com SecRuleRemoveById 950005 </VirtualHost> 10
404 는로그에남지않도록설정 apache-error: [level 3] File does not exist: /var/www/html/favicon.ico 주로사용하는설정 ) SecAuditLogRelevantStatus "^[45]" 권장설정 ) SecAuditLogRelevantStatus "^(?:5 4 d[^4]) 404는포함하지않음 파일명또는파라미터에한글이포함된경우예 :/list.php?page=&addr1= 강남구 &grade= 중학교 Message: Access denied with code 400 (phase 2). Invalid Unicode encoding: invalid byte value in character. [id "950801"] [msg "UTF8 Encoding Abuse Attack Attempt"] [severity "WARNING"] SecFilterCheckUnicodeEncoding Off SecFilterForceByteRange 0 255( 기본값 ) @validateutf8encoding, @validatebyterange, (2.x) 11
1.9.x 에서로그만남도록했는데, 차단되는이유? SecFilterDefaultAction "pass,log 로설정해도차단되는이유? SecFilterSignatureAction "msg:'command execution attack'" SecFilterSelective ARGS_VALUES ";[[:space:]]*(pwd wget curl) 와같이설정시발생. 옳은설정 ) SecFilterSelective ARGS_VALUES ";[[:space:]]*(ls id pwd wget cd)" "msg:'command execution attack'" SecFilterSignatureAction 의기본값이 log,deny,status:403 이므로 (1) SecFilterSignatureAction을사용하지않거나 (2) SecFilterSignatureAction "log,pass,msg: 'Command execution attack '' 와같이변경 12
modsecurity console -. 웹을통해실시간통합로그관리가가능한패키지프로그램 (web+db) -. 1개의콘솔에서 3개의센서까지무료로제공 -. 상용버전 (Enterprise Manager Console) 은 breach를통해제공 -. JDK / JRE 1.4 이상에서작동함 -. 메일등으로알람 (notify) 기능 -. pdf로보고서작성기능제공 13
console 설치방법 # tar zxvfp modsecurity-console_1_0_2_unix.tar.gz # cd modsecurity-console #./modsecurity-console No suitable Java Virtual Machine could be found on your system. The version of the JVM must be at least 1.4. Please define INSTALL4J_JAVA_HOME to point to a suitable JVM. You can also try to delete the JVM cache file /root/.install4j 에러메시지 http://java.sun.com/ 에서 jdk1.5 다운로드및설치 #./jdk-1_5_0_09-linux-i586.bin 엔터만입력 # export INSTALL4J_JAVA_HOME=/usr/local/src/modsecurity-console/jdk1.5.0_09 #./modsecurity-console start 8886/tcp 리슨확인 14
console 설정방법 Sensors => Add Sensor 클릭 httpd.conf 에아래설정추가 SecAuditEngine RelevantOnly SecAuditLogRelevantStatus "^(?:5 4 d[^4])" SecAuditLogType Concurrent SecAuditLogParts ABCDEFGHZ SecAuditLogStorageDir /usr/local/apache2/logs/data/ SecAuditLog /usr/local/apache2/logs/modsec-audit.log SecAuditLog " /usr/local/apache2/bin/modsec-auditlog-collector.pl /usr/local/apache2/logs/data/ /usr/local/apache2/logs/modsec-audit.log" http://xx.xx.xx.xx:8886/static/modsec-auditlog-collector 파일저장 my $CONSOLE_HOST = "218.236.xx.xxx"; my $CONSOLE_PORT = "8886"; my $CONSOLE_USERNAME = "alpha1"; my $CONSOLE_PASSWORD = "sensor1"; 15
라이센스입력 The licence key is missing, invalid, or expired. Please configure a valid licence key to unlock the full functionality https://bsn.breach.com/ 접속후 Licensing 클릭하여발급 발급된라이센스로업데이트시행 16
라이센스입력 LS0tLS1CRUdJTiBGSUxFLS0tLS0KcHJvZHVjdE5hbWUgPSBNb2RTZWN1cml0eSBDb25zb2xlCnBy b2r1y3rwzxjzaw9uid0gms4wljikchjvzhvjdfvyasa9igh0dha6ly93d3cubw9kc2vjdxjpdhku W9 ZHVjdFV SA9IGh0dHA6L 93d3 bw9k 2VjdXJ dhk b3jnl3byb2ply3rzl2nvbnnvbguvcnbyb2r1y3rwzw5kb3igpsbccmvhy2ggu2vjdxjpdhkkchjv ZHVjdFZlbmRvclVyaSA9IGh0dHA6Ly93d3cuYnJlYWNoLmNvbQoKbGljZW5jZURlc2NyaXB0aW9u ID0gTW9kU2VjdXJpdHkgQ29uc29sZSBGcmVlIENvbW11bml0eSBMaWNlbmNlCmxpY2VuY2VHZW5l cmf0zwrpbia9idiwmdcvmtavmjukbgljzw5jzvzhbglkvw50awwgpsa5otk5lzaxlzaxcgpsawnl bmnlzu5hbwugpsbub2rheqpsawnlbmnlzvvyasa9igh0dha6ly9jb2z3lnr0lmnvlmtylwpsawnl bmnlzuvtywlsid0gyw50awhvbmdadhquy28ua3ikicagicagicakywxsb3dlzfnlbnnvcnmgpsaz Ci0tLS0tQkVHSU4gU0lHTkFUVVJFLS0tLS0KTUN3Q0ZIdjduUGxPUjJmMlJEMTJGL3o0L0hhWHdT amlbafjyevlhmxf4zncvdfrrcfqytklqoxnzry81v0e9pq0kls0tls1ftkqgu0lhtkfuvvjfls0t LS0K Console 설정후에는 modsec_audit.log 가다음과같이보임 cofw.tt.co.kr 192.168.69.32 - - [26/Oct/2007:17:52:28 +0900] "GET /etc/passwd HTTP/1.1" 501 293 "-" "-" eg72fdrsk0saaebncvwaaaah AAAAH "-"" /20071026/20071026-1752/20071026-175228-eG72FdrsK0sAAEbnCVwAAAAH1752/20071026 175228 AAAAH 0 1282 md5:23776c01b2680eccc120209a4b7e2300 /var/log/httpd/data/20071026/20071026-1752/20071026-175228-eg72fdrsk0saaebncvwaaaah 17
console 로그조회 18
console 의부하가높을경우? -. SecAuditEngine On RelevantOnly -. SecAuditLogRelevantStatus "^[45] "^(?:5 4 d[^4])" -. modsecurity-auditlog-collector mlogc -. modsecurity-console 스크립트에 -INSTALL4J_ADD_VM_PARAMS="-Xms128M -Xmx512M 사용가능한메모리를시작시 128M, 최대 512M 로제한 19
오탐에대한대응방법 -. 어떤 application 이든오탐은있을수있다. -. 초기에는 DetectionOnly 모드로사용해야한다. -. 특정룰에오탐이있다고룰자체를삭제하면또다른오탐 (false negative) 의원인이될수있으므로상황에맞는커스터마이징이필요하다. -. 로그 (log) 에원인과해결방법이있다. ( 만약특정한로그만자세히보고자할경우 ) 특정조건만상세로그를볼수있음 SecRule REMOTE_ADDR "^192 192.168.10.69$ 168 10 69$ phase:1,log,pass,ctl:debugloglevel=9 pass SecRule REQUEST_URI "^/path/to/script.pl$" phase:1,log,pass,ctl:debugloglevel=9 -. Whitelist에대해서는 10번과 20번룰사이에생성 ( 예 :modsecurity_crs_10_white.conf) blacklist(negative) 에대해서는제일마지막 ( 예 : modsecurity_crs_60_black.conf) crs conf) -. 상세한로그설정은 performance impact 유발가능예 )-. snort등의룰 (rule) 설정 X -. 정규식을이용룰최소화 SecRule REQUEST_URI file1.cgi SecRule REQUEST_URI file2.cgi SecRule REQUEST_URI (file1 file2)\.cgi 20
부가기능활용 #Specify the local directory for collection storage SecDataDir /path/to/apache/logs/state # Initiate a collection based on the source IP address SecAction initcol:ip=%{remote_addr},nolog,pass # Increase the IP collection score based on filter hits SecRule REQUEST_FILENAME /cgi-bin/phf" pass,setvar:ip.score=+10 SecRule REQUEST_FILENAME cmd.exe pass,setvar:ip.score=+10 SecRule REQUEST_METHOD TRACE pass,setvar:ip.score=+5setvar:ip score=+5 # Evaluate the overall IP collection score SecRule IP:SCORE "@ge 30 SecRule ARGS REQUEST_BODY REQUEST_URI "Subject\:" chain SecRule ARGS REQUEST_BODY REQUEST_URI URI "\s*bcc\:" 21
Modsecurity 1.x / 2.x 차이 Modsecurity 1.x Modsecurity 2.x Processing phase Inbound(Request body) / Outbound(Response body) 지원 Request header(phase:1) Request body(phase:2) Response header(phase:3) Response body(phase:4) logging(phase:5) 설정방법 apache 1.x 의경우 <IfModule mod_security.c> apache 2.x의경우 <IfModule security_module> <IfModule security2_module> Turn on/off Rule engine SecFilterEngine SecRuleEngine Default rule action SecFilterDefaultAction SecDefaultAction Rule directive SecFilter, SecFilterSelective Secrule Accessing reuqest bodies SecFilterScanPost SecRequestBodyAccess Accessing response bodies SecFilterScanOutput SecResponseBodyAccess 22
Modsecurity 상용솔루션및작동모드 Modsecurity M1100 -. 브리지 (Transparent) 모드로동작 -. 100Mbps 처리가능, bypass 제공. -. 약 1500 만원 구현방식라우팅브리지 Reverse proxy Embeded 설치공간동일네트워크동일네트워크관계없음자체 네트워크 변경필요 불필요 불필요 불필요 설정변경 DNS 변경불필요불필요필요함불필요 서버 IP 노출노출됨노출됨노출안됨노출됨 기타대부분의상용장비방식 modsecurity 23
결론 -. 불필요한룰을삭제하고, custommizing 한다면성능저하없이이용가능함예 ) sql injection 차단룰만설정시 95% 내외 -. 초기에는오탐에대비, DetectionOnly로설정후로그를보며 Customizing 하여야함 -. DoS 공격등에는 iptables 이용이보다효과적 2.2 이상버전에는국가별설정이가능한 geoip 기능제공 SecGeoLookupsDb /usr/local/geo/data/geolitecity.dat SecRule REMOTE_ADDR "@geolookup" chain,drop,msg:'non-kr IP address' SecRule GEO:COUNTRY_CODE CODE "!@streq KR /sbin/iptables -A INPUT -m geoip! --src-cc KR -j DROP /sbin/iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 30 -j DROP -. 메일링리스트를통해최신정보습득및정보공유필요 -. Modsecurity 3.0에서는 apache 1.3.x 도지원예정 24
Q & A 질문 : antihong@tt.co.kr 25