ModSecurity はオープンソースで開発されている
WAF(Web Application Firewall)で、無償で利用することができます。
WAF とは、Web アプリケーションにリクエストが送信される手前でリクエストを取得して、
内容を精査し、問題があればリクエストを拒否します。
これにより仮に Web アプリケーションに脆弱性があったとしても WAF が守ってくれます。
WAF にも偽陽性や偽陰性(正当なリクエストを攻撃判定したり、逆に攻撃を見逃したりする事)
の問題があるので、過信することはよくないですが
改修不能な Web アプリケーションの保護や、多層防御の一手法として有効です。
また、WAF には、ネットワーク型とホスト型がありますが
ModSecurity はホスト型の WAF になります。
ModSecurityのインストール
構築する環境は以下の通り。
また、脆弱性テスト用にapacheをインストール済み。
cmsのdrupalを攻撃対象のページとします。
# cat /etc/redhat-release CentOS release 6.8 (Final) # arch x86_64 # httpd -V Server version: Apache/2.2.15 (Unix)
ModSecurityをインストールするためにepelリポジトリを追加します。# yum install epel-releasemod_securityの以下をまとめてインストールします。
・mod_security(ModSecurity本体)
・mod_security_crs(Core Rule Set)
・mod_security_crs-extras(追加のCore Rule Set)Core Rule Setは、OWASPが開発した、Webサイトに対する攻撃を検知するためのルールを定義したものです。
# yum install mod_security mod_security_crs mod_security_crs-extras # rpm -qa mod_security mod_security_crs mod_security_crs-extras mod_security_crs-2.2.6-3.el6.noarch mod_security-2.7.3-3.el6.x86_64 mod_security_crs-extras-2.2.6-3.el6.noarchModSecurityの設定
デフォルトの設定だとフィルタリングが有効の状態なので
テストの為、一時的にログに吐くだけの設定にします。# cp -p /etc/httpd/conf.d/mod_security.conf /etc/httpd/conf.d/mod_security.conf.org #バックアップ # vi /etc/httpd/conf.d/mod_security.conf # Default recommended configuration # SecRuleEngine On ←コメントアウト SecRuleEngine DetectionOnly ←追記(攻撃を検知した場合、遮断せず、検知内容をログに出力する設定Apacheを再起動します。
# service httpd restartこれでModSecurityが有効になりました。
ModSecurityが動くかテスト実施
下記のようなパラメータを付与してアクセスしてみます。
http://[ホストIP]/?union+select今のままだとフィルタリングが有効になっていないので特段変わりなしですが
実際にログが出力されているか確認してみます。
※デフォルトの定義では/var/log/httpd/modsec_audit.logに出力されています。# tail -f /var/log/httpd/modsec_audit.log --77c22b4e-A-- [19/Apr/2017:16:55:29 +0900] WPcX8QoAAAYAAAUyDsMAAAAH 192.168.1.3 54452 10.0.0.6 80 --77c22b4e-B-- GET /?union+select HTTP/1.1 Host: 10.0.0.6 Connection: keep-alive Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Encoding: gzip, deflate, sdch Accept-Language: ja-JP,ja;q=0.8,en-US;q=0.6,en;q=0.4 Cookie: has_js=1 --77c22b4e-F-- HTTP/1.1 403 Forbidden Accept-Ranges: bytes Content-Length: 4961 Keep-Alive: timeout=15, max=100 Connection: Keep-Alive Content-Type: text/html; charset=UTF-8 --77c22b4e-H-- Message: Warning. Pattern match "^[\\d.:]+$" at REQUEST_HEADERS:Host. [file "/etc/httpd/modsecurity.d/activated_rules/modsecurity_crs_21_protocol_anomalies.conf"] [line "98"] [id "960017"] [rev "2"] [msg "Host header is a numeric IP address"] [data "10.0.0.6"] [severity "WARNING"] [ver "OWASP_CRS/2.2.6"] [maturity "9"] [accuracy "9"] [tag "OWASP_CRS/PROTOCOL_VIOLATION/IP_HOST"] [tag "WASCTC/WASC-21"] [tag "OWASP_TOP_10/A7"] [tag "PCI/6.5.10"] [tag "http://technet.microsoft.com/en-us/magazine/2005.01.hackerbasher.aspx"] Message: Warning. Pattern match "(?i:(?:(?:s(?:t(?:d(?:dev(_pop|_samp)?)?|r(?:_to_date|cmp))|u(?:b(?:str(?:ing(_index)?)?|(?:dat|tim)e)|m)|e(?:c(?:_to_time|ond)|ssion_user)|ys(?:tem_user|date)|ha(1|2)?|oundex|chema|ig?n|pace|qrt)|i(?:s(null|_(free_lock|ipv4_compat|ipv4_mapped|ipv4|ipv ..." at ARGS_NAMES:union select. [file "/etc/httpd/modsecurity.d/activated_rules/modsecurity_crs_41_sql_injection_attacks.conf"] [line "125"] [id "950001"] [rev "2"] [msg "SQL Injection Attack"] [data "Matched Data: union select found within ARGS_NAMES:union select: union select"] [severity "CRITICAL"] [ver "OWASP_CRS/2.2.6"] [maturity "9"] [accuracy "8"] [tag "OWASP_CRS/WEB_ATTACK/SQL_INJECTION"] [tag "WASCTC/WASC-19"] [tag "OWASP_TOP_10/A1"] [tag "OWASP_AppSensor/CIE1"] [tag "PCI/6.5.2"] Message: Warning. Pattern match "(?i:(?:(?:s(?:t(?:d(?:dev(_pop|_samp)?)?|r(?:_to_date|cmp))|u(?:b(?:str(?:ing(_index)?)?|(?:dat|tim)e)|m)|e(?:c(?:_to_time|ond)|ssion_user)|ys(?:tem_user|date)|ha(1|2)?|oundex|chema|ig?n|pace|qrt)|i(?:s(null|_(free_lock|ipv4_compat|ipv4_mapped|ipv4|ipv ..." at ARGS_NAMES:union select. [file "/etc/httpd/modsecurity.d/activated_rules/modsecurity_crs_41_sql_injection_attacks.conf"] [line "143"] [id "959073"] [rev "2"] [msg "SQL Injection Attack"] [data "Matched Data: union select found within ARGS_NAMES:union select: union select"] [severity "CRITICAL"] [ver "OWASP_CRS/2.2.6"] [maturity "9"] [accuracy "8"] [tag "OWASP_CRS/WEB_ATTACK/SQL_INJECTION"] [tag "WASCTC/WASC-19"] [tag "OWASP_TOP_10/A1"] [tag "OWASP_AppSensor/CIE1"] [tag "PCI/6.5.2"] Message: Warning. Pattern match "(?i:(?:\\sexec\\s+xp_cmdshell)|(?:[\"'`\xc2\xb4\xe2\x80\x99\xe2\x80\x98]\\s*?!\\s*?[\"'`\xc2\xb4\xe2\x80\x99\xe2\x80\x98\\w])|(?:from\\W+information_schema\\W)|(?:(?:(?:current_)?user|database|schema|connection_id)\\s*?\\([^\\)]*?)|(?:[\"'`\xc2\xb4\xe2 ..." at ARGS_NAMES:union select. [file "/etc/httpd/modsecurity.d/activated_rules/modsecurity_crs_41_sql_injection_attacks.conf"] [line "218"] [id "981255"] [msg "Detects MSSQL code execution and information gathering attempts"] [data "Matched Data: union select found within ARGS_NAMES:union select: union select"] [severity "CRITICAL"] [tag "OWASP_CRS/WEB_ATTACK/SQLI"] Message: Warning. Pattern match "(?i:(?:union\\s*?(?:all|distinct|[(!@]*?)?\\s*?[([]*?\\s*?select)|(?:\\w+\\s+like\\s+[\"'`\xc2\xb4\xe2\x80\x99\xe2\x80\x98])|(?:like\\s*?[\"'`\xc2\xb4\xe2\x80\x99\xe2\x80\x98]\\%)|(?:[\"'`\xc2\xb4\xe2\x80\x99\xe2\x80\x98]\\s*?like\\W*?[\"'`\xc2\xb4\xe2 ..." at ARGS_NAMES:union select. [file "/etc/httpd/modsecurity.d/activated_rules/modsecurity_crs_41_sql_injection_attacks.conf"] [line "234"] [id "981245"] [msg "Detects basic SQL authentication bypass attempts 2/3"] [data "Matched Data: union select found within ARGS_NAMES:union select: union select"] [severity "CRITICAL"] [tag "OWASP_CRS/WEB_ATTACK/SQLI"] Message: Warning. Operator GE matched 5 at TX:inbound_anomaly_score. [file "/etc/httpd/modsecurity.d/activated_rules/modsecurity_crs_60_correlation.conf"] [line "37"] [id "981204"] [msg "Inbound Anomaly Score Exceeded (Total Inbound Score: 23, SQLi=14, XSS=): 981245-Detects basic SQL authentication bypass attempts 2/3"] Apache-Error: [file "/builddir/build/BUILD/httpd-2.2.15/modules/generators/mod_autoindex.c"] [line 2292] [level 3] Directory index forbidden by Options directive: /var/www/html/ Stopwatch: 1492588529481677 7850 (- - -) Stopwatch2: 1492588529481677 7850; combined=5096, p1=487, p2=4396, p3=0, p4=0, p5=211, sr=136, sw=2, l=0, gc=0 Producer: ModSecurity for Apache/2.7.3 (http://www.modsecurity.org/); OWASP_CRS/2.2.6. Server: Apache Engine-Mode: "DETECTION_ONLY" --77c22b4e-Z--
ログを確認すると
modsecurity_crs_41_sql_injection_attacks.confの内容で
フィルタリングされていることがわかるので
SQLインジェクションのルールがパターンマッチしていることがわかりますね。この状態で「SecRuleEngine On」と設定した場合
SQLインジェクションのパラメータを付加してアクセスを行うと
apacheのテストページへ飛ばされるはずです。SQLインジェクション以外にもデフォルトで多数のルールセットが有効になっています。
# ll /etc/httpd/modsecurity.d/activated_rules 合計 88 lrwxrwxrwx 1 root root 64 4月 19 16:41 2017 modsecurity_35_bad_robots.data -> /usr/lib/modsecurity.d/base_rules/modsecurity_35_bad_robots.data lrwxrwxrwx 1 root root 62 4月 19 16:41 2017 modsecurity_35_scanners.data -> /usr/lib/modsecurity.d/base_rules/modsecurity_35_scanners.data lrwxrwxrwx 1 root root 69 4月 19 16:41 2017 modsecurity_40_generic_attacks.data -> /usr/lib/modsecurity.d/base_rules/modsecurity_40_generic_attacks.data lrwxrwxrwx 1 root root 75 4月 19 16:41 2017 modsecurity_41_sql_injection_attacks.data -> /usr/lib/modsecurity.d/base_rules/modsecurity_41_sql_injection_attacks.data lrwxrwxrwx 1 root root 62 4月 19 16:41 2017 modsecurity_50_outbound.data -> /usr/lib/modsecurity.d/base_rules/modsecurity_50_outbound.data lrwxrwxrwx 1 root root 70 4月 19 16:41 2017 modsecurity_50_outbound_malware.data -> /usr/lib/modsecurity.d/base_rules/modsecurity_50_outbound_malware.data lrwxrwxrwx 1 root root 77 4月 19 16:41 2017 modsecurity_crs_20_protocol_violations.conf -> /usr/lib/modsecurity.d/base_rules/modsecurity_crs_20_protocol_violations.conf lrwxrwxrwx 1 root root 76 4月 19 16:41 2017 modsecurity_crs_21_protocol_anomalies.conf -> /usr/lib/modsecurity.d/base_rules/modsecurity_crs_21_protocol_anomalies.conf lrwxrwxrwx 1 root root 72 4月 19 16:41 2017 modsecurity_crs_23_request_limits.conf -> /usr/lib/modsecurity.d/base_rules/modsecurity_crs_23_request_limits.conf lrwxrwxrwx 1 root root 69 4月 19 16:41 2017 modsecurity_crs_30_http_policy.conf -> /usr/lib/modsecurity.d/base_rules/modsecurity_crs_30_http_policy.conf lrwxrwxrwx 1 root root 68 4月 19 16:41 2017 modsecurity_crs_35_bad_robots.conf -> /usr/lib/modsecurity.d/base_rules/modsecurity_crs_35_bad_robots.conf lrwxrwxrwx 1 root root 73 4月 19 16:41 2017 modsecurity_crs_40_generic_attacks.conf -> /usr/lib/modsecurity.d/base_rules/modsecurity_crs_40_generic_attacks.conf lrwxrwxrwx 1 root root 79 4月 19 16:41 2017 modsecurity_crs_41_sql_injection_attacks.conf -> /usr/lib/modsecurity.d/base_rules/modsecurity_crs_41_sql_injection_attacks.conf lrwxrwxrwx 1 root root 69 4月 19 16:41 2017 modsecurity_crs_41_xss_attacks.conf -> /usr/lib/modsecurity.d/base_rules/modsecurity_crs_41_xss_attacks.conf lrwxrwxrwx 1 root root 72 4月 19 16:41 2017 modsecurity_crs_42_tight_security.conf -> /usr/lib/modsecurity.d/base_rules/modsecurity_crs_42_tight_security.conf lrwxrwxrwx 1 root root 65 4月 19 16:41 2017 modsecurity_crs_45_trojans.conf -> /usr/lib/modsecurity.d/base_rules/modsecurity_crs_45_trojans.conf lrwxrwxrwx 1 root root 75 4月 19 16:41 2017 modsecurity_crs_47_common_exceptions.conf -> /usr/lib/modsecurity.d/base_rules/modsecurity_crs_47_common_exceptions.conf lrwxrwxrwx 1 root root 82 4月 19 16:41 2017 modsecurity_crs_48_local_exceptions.conf.example -> /usr/lib/modsecurity.d/base_rules/modsecurity_crs_48_local_exceptions.conf.example lrwxrwxrwx 1 root root 74 4月 19 16:41 2017 modsecurity_crs_49_inbound_blocking.conf -> /usr/lib/modsecurity.d/base_rules/modsecurity_crs_49_inbound_blocking.conf lrwxrwxrwx 1 root root 66 4月 19 16:41 2017 modsecurity_crs_50_outbound.conf -> /usr/lib/modsecurity.d/base_rules/modsecurity_crs_50_outbound.conf lrwxrwxrwx 1 root root 75 4月 19 16:41 2017 modsecurity_crs_59_outbound_blocking.conf -> /usr/lib/modsecurity.d/base_rules/modsecurity_crs_59_outbound_blocking.conf lrwxrwxrwx 1 root root 69 4月 19 16:41 2017 modsecurity_crs_60_correlation.conf -> /usr/lib/modsecurity.d/base_rules/modsecurity_crs_60_correlation.confちなみに追加のルールセットもインストールすることも出来ます。
どのようなルールセットが追加されるかは今回は割愛します。# yum install mod_security_crs-extrasこんな感じに簡単に mod_securityが導入出来ました!
ただWAFの設定は非常に勘所が難しく、強化し過ぎるとアプリケーションに害を及ぼすし
緩くし過ぎると脆弱性のリスクが高まるので、設定は随時見なおしていくのがよいかと思います。