在瀏覽本文前,先簡單體味下甚么是ModSecurity,ModSecurity是一個進(jìn)侵探測與禁止的引擎。它主如果用于Web利用法度所以也能夠叫做Web利用法度防火墻,相信良多商業(yè)WAF的簽名開辟同窗也參考了ModSecurity的法則吧。
布景:
上周Wordpress網(wǎng)站蒙受了大年夜范圍的暴力破解報復(fù)打擊,報復(fù)打擊者起首掃描互聯(lián)網(wǎng)上的Wordpress網(wǎng)站,然后操縱Web辦事器組建的僵尸收集不竭測驗測驗用戶名和暗碼試圖登錄治理界面。報復(fù)打擊者利用了超越9萬臺Web辦事器來進(jìn)行暴力破解。
本文借用此例,來介紹下若何操縱ModSecurity防御Wordpress的暴力破解。常規(guī)的減緩暴力破解編制以下:
1:更改admin默許賬戶名稱,或直接刪除admin,添加一個新的治理員帳戶。
2:利用雙身分認(rèn)證
3:利用插件限制登錄
4:利用.htpasswd對拜候特定頁面實現(xiàn)用戶名和暗碼驗證。
這些都有現(xiàn)成的編制往實現(xiàn)了,這里就介紹一下用ModSecurity V2.7.3來呵護(hù)Wordpress,避免暴力破解。
1:Wordpress的登錄過程闡發(fā)
下圖為Wordpress的登錄頁面:

用戶登錄以后,發(fā)送要求到WP-loing.php頁面,HTTP要求包內(nèi)容以下:
POST /wordpress/wp-login.php HTTP/1.1
Host: mywordpress.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:12.0) Gecko/20100101 Firefox/12.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*; q=0.8
Accept-Language: en-us,en;q=0.5
DNT: 1
Referer: http://freebuf.com/wordpress/wp-login.php
Content-Type: application/x-www-form-urlencoded
Via: 1.1 owaspbwa.localdomain
Connection: Keep-Alive
Content-Length: 73
log=administrator&pwd=freebuf&submit=Login+%C2%BB&redirect_to=wp-admin%2F
payload部門包含了用戶名和暗碼,和登錄成功后轉(zhuǎn)向的頁面。OK,體味數(shù)據(jù)包布局以后,我們可以成立法則,避免未經(jīng)授權(quán)的拜候。
2:查抄Rerfer
正常的用戶登錄Wordpress,在數(shù)據(jù)包頭部會包含一個Referer字段,可是經(jīng)由過程人工編寫的法度,良多不會包含Referer字段,直接發(fā)送登錄要求到wp-login.php頁面,所以,我們可以按照此成立一個ModSecurity法則來查抄Rerfer字段信息:
SecRule REQUEST_METHOD "@streq POST" "chain,id:'1',phase:2,t:none,block,log,msg:'Warning: Direct Login Missing Referer.'"
SecRule REQUEST_FILENAME "@pm /wp-login.php /wp-admin/" "chain"
ecRule &REQUEST_HEADERS:Referer "@eq 0"
當(dāng)然經(jīng)由過程腳本,很等閑實現(xiàn)Rerfer捏造,所以還需要接下來的法則一路共同。
3:限制拜候的IP
假定你不想點竄默許治理員帳號,可以添加一個法則只承諾特定的IP拜候治理頁面,以下:
SecRule REQUEST_METHOD "@streq POST" "chain,id:'1',phase:2,t:none,block,log,msg:'Warning: Direct Login Missing Referer.'"
SecRule REQUEST_FILENAME "@pm /wp-login.php /wp-admin/" "chain"
SecRule ARGS:log "@streq freebuf" "chain"
SecRule REMOTE_ADDR !@ipMatch 72.192.214.223
在這個例子里,只承諾名稱為freebuf的治理員帳戶經(jīng)由過程72.192.214.223的IP地址來拜候。
4:跟蹤治理員帳戶的登錄測驗測驗
我們可以經(jīng)由過程ModSecurity的法則來block掉落歹意IP,以下為登錄掉敗的返回包:
HTTP/1.1 200 OK
Date: Fri, 11 May 2012 03:24:53 GMT
Server: Apache
Expires: Wed, 11 Jan 1984 05:00:00 GMT
Last-Modified: Fri, 11 May 2012 03:24:54 GMT
Cache-Control: no-cache, must-revalidate, max-age=0
Pragma: no-cache
Vary: Accept-Encoding
Content-Length: 1697
Connection: close
Content-Type: text/html; charset=UTF-8
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
functionfocusit()
{
document.getElementById('log').focus();}window.onload =focusit;
"chain, phase:4,id:999323,t:none,block,msg:'Authentication Failure Violation .',
logdata:'Number of Authentication Failures: %{ip.failed_auth_ attempt}'"
SecRule REQUEST_METHOD "@streq POST" "chain"
SecRule ARGS:log "@streq admin" "chain"
SecRule RESPONSE_STATUS "200" "chain"
SecRule RESPONSE_BODY "@contains Error:Incorrect password."
"chain,setvar:ip.failed_auth_attempt=+1,expirevar:ip.failed_auth_attempt=60"
SecRule IP:FAILED_AUTH_ATTEMPT "@gt 5"
5:設(shè)置驗證要求的次數(shù)
ModSecurity可以在指定的時候內(nèi)跟蹤要求的數(shù)量,設(shè)置閥值來進(jìn)行阻斷報復(fù)打擊,在它的法則集里已個包含了該法則,modsecurity_crs_10_setup.conf
以下:
#
# -- [[ Brute Force Protection ]] ---------------------------------------------------------
#
# If you are using the Brute Force Protection rule set, then uncomment the following
# lines and set the following variables:
# - Protected URLs: resources to protect (e.g. login pages) - set to your login page
# - Burst Time Slice Interval: time interval window to monitor for bursts
# - Request Threshold: request # threshold to trigger a burst
# - Block Period: temporary block timeout
#
SecAction \
"id:'900014', \
phase:1, \
t:none, \
setvar:'tx.brute_force_protected_urls=/wp-login.php', \
setvar:'tx.brute_force_burst_time_slice=60', \
setvar:'tx.brute_force_counter_threshold=10', \
setvar:'tx.brute_force_block_timeout=300', \
nolog, \
pass"
寄望點竄 setvar:’tx.brute_force_protected_urls=/wp-login.php‘,
設(shè)置終了后,激活modsecurity_crs_11_brute_force.conf
#
# Anti-Automation Rule for specific Pages (Brute Force Protection)
# This is a rate-limiting rule set and does not directly correlate whether the
# authentication attempt was successful or not.
#
#
# Enforce an existing IP address block and log only 1-time/minute
# We don't want to get flooded by alerts during an attack or scan so
# we are only triggering an alert once/minute. You can adjust how often
# you want to receive status alerts by changing the expirevar setting below.
#
SecRule IP:BRUTE_FORCE_BLOCK "@eq 1" "chain,phase:1,id:'981036',block,msg:
'Brute Force Attack Identified from %{tx.real_ip}
(%{tx.brute_force_block_counter} hits since last alert)',
setvar:ip.brute_force_block_counter=+1"
SecRule &IP:BRUTE_FORCE_BLOCK_FLAG "@eq 0" "setvar:ip.brute_force_block_flag=1,
expirevar:ip.brute_force_block_flag=60,
setvar:tx.brute_force_block_counter=%{ip.brute_force_block_counter},
setvar:ip.brute_force_block_counter=0"
#
# Block and track # of requests but don't log
SecRule IP:BRUTE_FORCE_BLOCK "@eq 1" "phase:1,id:'981037',block,nolog,
setvar:ip.brute_force_block_counter=+1"
#
# skipAfter Checks
# There are different scenarios where we don't want to do checks -
# 1. If the user has not defined any URLs for Brute Force Protection in the 10 config file
# 2. If the current URL is not listed as a protected URL
# 3. If the current IP address has already been blocked due to high requests
# In these cases, we skip doing the request counts.
#
SecRule &TX:BRUTE_FORCE_PROTECTED_URLS "@eq 0" "phase:5,id:'981038',
t:none,nolog,pass,skipAfter:END_BRUTE_FORCE_PROTECTION_CHECKS"
SecRule REQUEST_FILENAME "!@within %{tx.brute_force_protected_urls}"
"phase:5,id:'981039',t:none,nolog,pass,skipAfter:END_BRUTE_FORCE_PROTECTION_CHECKS"
SecRule IP:BRUTE_FORCE_BLOCK "@eq 1" "phase:5,id:'981040',
t:none,nolog,pass,skipAfter:END_BRUTE_FORCE_PROTECTION_CHECKS"
#
# Brute Force Counter
# Count the number of requests to these resoures
#
SecAction "phase:5,id:'981041',t:none,nolog,pass,setvar:ip.brute_force_counter=+1"
#
# Check Brute Force Counter
# If the request count is greater than or equal to 50 within 5 mins,
# we then set the burst counter
#
SecRule IP:BRUTE_FORCE_COUNTER "@gt %{tx.brute_force_counter_threshold}"
"phase:5,id:'981042',t:none,nolog,pass,t:none,setvar:ip.brute_force_burst_counter=+1,
expirevar:ip.brute_force_burst_counter=%{tx.brute_force_burst_time_slice},
setvar:!ip.brute_force_counter"
#
# Check Brute Force Burst Counter and set Block
# Check the burst counter - if greater than or equal to 2, then we set the IP
# block variable for 5 mins and issue an alert.
#
SecRule IP:BRUTE_FORCE_BURST_COUNTER "@ge 2" "phase:5,id:'981043',
t:none,log,pass,msg:'Potential Brute Force Attack from %{tx.real_ip}
- # of Request Bursts: %{ip.brute_force_burst_counter}',
setvar:ip.brute_force_block=1,expirevar:ip.brute_force_block=%{tx.brute_force_block_timeout}"
SecMarker END_BRUTE_FORCE_PROTECTION_CHECKS
6:利用SecGuardianLog
從 1.9版本后,ModSecurity 撐持一個新的指令,SecGuardianLog,設(shè)計此指令用于把所有承諾數(shù)據(jù)經(jīng)由過程治理日記功能發(fā)送到另外一個法度。自從 apache擺設(shè)成典型的多過程編制,信息共享變得堅苦了,這一設(shè)法就是擺設(shè)一個自力的外部過程利用狀況機(jī)的編制往不雅察所有的要求,供給額外的呵護(hù)。利用編制以下:
語法: SecGuardianLog |/path/to/httpd-guardian
示例: SecGuardianLog |/usr/local/apache/bin/httpd-guardian
范圍: Main
版本: 2.0.0
并且SecGuardianLog也能夠和 SnortSam協(xié)同工作(http://www.snortsam.net)。假定已建設(shè)過 httpd-guardian(具體介紹請查看源代碼)你只需要在 apache建設(shè)中添加一行便可以擺設(shè)它:
SecGuardianLog |/path/to/httpd-guardian
法則以下:
# If defined, execute this command when a threshold is reached
# block the IP address for one hour.
# $PROTECT_EXEC = "/sbin/blacklist block %s 3600";
# $PROTECT_EXEC = "/sbin/samtool -block -ip %s -dur 3600 www.freebuf.com";
my $PROTECT_EXEC;
# For testing only:
# $PROTECT_EXEC = "/sbin/blacklist-webclient %s 3600";
# Max. speed allowed, in requests per
# second, measured over an 1-minute period
my $THRESHOLD_1MIN = 2; # 120 requests in a minute
跟蹤httpd守護(hù)過程數(shù)量,假定超越了限制,可以履行一些把持,如封鎖IP一小時。