# both.conf # Initialize collection to track brute force attempts SecAction phase:1,nolog,pass,initcol:RESOURCE=%{SERVER_NAME}_%{SCRIPT_FILENAME},id:13050 # # BEGIN wp-login.php redirect_to arg rules # # T3 Trac #7968 (https://trac.imhtech.net/T3/ticket/7968) # If recaptcha is used in concert with wp-login.php, skip test for # redirect_to arg. # # This rule is a little naive and intentionally doesn't _strictly_ # match observed arg names in case their names change. SecRule ARGS_POST_NAMES "recaptcha" \ "id:13504,pass,log,skipAfter:END_REDIRECT_TO_ARG_REQUIRED" SecMarker BEGIN_REDIRECT_TO_ARG_REQUIRED # if referrer is cPanel, skip this rule SecRule REQUEST_HEADERS:Referer "@rx (:208[23]|https?://cpanel\.)" \ "id:13503,phase:2,pass,nolog,skipAfter:END_REDIRECT_TO_ARG_REQUIRED" # Block login requests that don't set redirect_to arg SecRule &ARGS_POST:redirect_to "@eq 0" "id:13501,pass,nolog,setvar:TX.brute" SecRule ARGS:redirect_to "@rx ^$" "id:13502,setvar:TX.brute,pass,nolog" SecRule REQUEST_URI "/wp-login\.php" \ "chain,deny,log,auditlog,status:406,\ msg:'POST to wp-login.php without redirect_to',id:'13052',\ tag:'WEB_ATTACK/SHELL ACCESS',severity:'4'" SecRule &ARGS_POST:pwd "@gt 0" "chain" SecRule &ARGS_POST:interim-login "@eq 0" "chain" SecRule &ARGS_POST:log "@gt 0" "chain" SecRule REQUEST_METHOD "POST" "chain" SecRule TX:brute "@ge 1" "log" SecMarker END_REDIRECT_TO_ARG_REQUIRED # # END wp-login.php redirect_to arg rules # # Block arbitrary file downloads via insecure versions of WordPress Slider Revolution # T3 Trac #7893 (https://trac.imhtech.net/T3/ticket/7893) SecRule ARGS:action "revslider_show_image" \ "chain,id:13507,deny,status:406,log,t:none,t:urlDecode,\ msg:'Potential arbitrary file download attempt (MS-ISAC 2014-070)'" SecRule ARGS:img "\.\./" "t:none,t:urlDecode" # Inspect post content to wp-comments-post.php for " t:lowercase,t:htmlEntityDecode,t:urlDecode # No posts to /wp-content/themes/mantra/uploads/.+\.php (was wp_mantra_theme.conf) SecRule REQUEST_METHOD "POST" \ "chain,deny,log,auditlog,status:406,severity:'4',id:'13065',\ msg:'POST request mantra WordPress theme upload folder',\ tag:'WEB_ATTACK/SHELL ACCESS'" SecRule REQUEST_URI "/wp-content/themes/mantra/uploads/.+\.php" # No requests to any theme archive/search php scripts (hacks) (was wp_archive_search.conf) SecRule REQUEST_METHOD "^POST$" \ "chain,deny,log,auditlog,status:406,id:'13064',severity:'4',\ msg:'POST request to archive or search',\ tag:'WEB_ATTACK/SHELL ACCESS'" SecRule REQUEST_URI "/wp-content/themes/[^/]+/(archives*|search)\.php" # Blocks access to w3tc dbcache directory, a vector that can be used to glean password hashes (was w3tc-dbcache.conf) SecRule REQUEST_URI "wp-content/w3tc/dbcache" \ "deny,log,auditlog,status:406,id:'13578',t:none,t:lowercase,\ t:htmlEntityDecode,t:removeWhitespace,severity:'4',\ msg:'Attempt to access w3tc dbcache',\ tag:'WEB_ATTACK/SHELL EXPLOIT'" # No requests to any .php files with an md5 name in /temp/ folders (was timthumbtemp.conf) SecRule REQUEST_METHOD "^GET|POST$" \ "chain,deny,log,auditlog,status:406,id:'13973',\ msg:'md5 request to temp folder',\ tag:'WEB_ATTACK/SHELL ACCESS',severity:'4'" SecRule REQUEST_URI "/temp/[0-9a-f]{32}\.php" # Block fake (and real) bing bots from hitting wp-login.php or wp-admin (was bingwplogin.conf) SecRule REQUEST_HEADERS:User-Agent "bingbot/2\.0;[+]http://www\.bing\.com/bingbot\.htm" \ "chain,deny,log,auditlog,status:406,id:'13381',t:none,t:lowercase,\ t:htmlEntityDecode,t:removeWhitespace,severity:'4',\ msg:'Bingbot user agent requesting wp-login.php',\ tag:'WEB_ATTACK/BRUTE FORCE'" SecRule REQUEST_URI "/wp-login\.php|/wp-admin" # Block 1-flash-gallery *.php uploads (was 1flashgallery.conf) SecRule REQUEST_URI "1-flash-gallery/upload\.php\?.*fileext\=php" \ "deny,log,auditlog,status:406,id:'13575',t:none,t:lowercase,\ t:htmlEntityDecode,t:removeWhitespace,severity:'4',\ msg:'1-flash-gallery upload exploit',\ tag:'WEB_ATTACK/SHELL EXPLOIT'" # CVE-2014-9119: Attempt to read files outside of the db-backup plugin (path ../../something) SecRule REQUEST_METHOD "^GET|POST$" \ "chain,deny,log,auditlog,status:406,id:'13057',severity:'4',\ msg:'attempt to exploit db-backup plugin',\ tag:'WEB_ATTACK/SHELL ACCESS'" SecRule REQUEST_URI "/wp-content/plugins/db-backup/download.php" "chain" SecRule ARGS "\.\.\/\.\.\/" # http://blog.sucuri.net/2014/12/revslider-vulnerability-leads-to-massive-wordpress-soaksoak-compromise.html SecRule ARGS_GET "wp-config.php" \ "t:lowercase,deny,status:406,severity:'4',log,id:13058,\ tag:'WEB_ATTACK/WP-CONFIG',\ msg:'wp-config string in query'" SecRule REQUEST_URI "\/update_extract\/revslider\/.*\.php.*" \ "t:lowercase,deny,log,auditlog,status:406,id:'13059',severity:'4',\ msg:'attempt to exploit revslider',\ tag:'WEB_ATTACK/SHELL ACCESS'" SecRule REQUEST_METHOD "POST" \ "chain,deny,log,auditlog,status:406,id:13060,\ msg:'Blocked for Wordpress MailPoet hack'" SecRule ARGS:page wysija_campaigns "chain" SecRule ARGS:action themes # Wordpress 4.2 Stored XSS SecRule ARGS:/^(.+\-)?comment/ "@gt 21844" \ "phase:2,deny,status:403,id:'13384',severity:'5',rev:'1.0.0',t:none,\ t:length,setvar:'tx.msg=%{rule.msg}',\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.policy_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-POLICY/SIZE_LIMIT-%{matched_var_name}=%{matched_var},\ msg:'Comment field too big'" # Genericons - https://blog.sucuri.net/2015/04security-disclosure-jetpack-twentyfifteen-and-other-wordpress-plugins-vulnerable-to-dom-based-xss-affects-millions-of-installs.html SecRule REQUEST_URI "genericons/example[0-9-_]*.html" \ "deny,log,auditlog,status:406,id:'13385',t:none,t:lowercase,\ t:htmlEntityDecode,t:removeWhitespace,severity:'4',\ msg:'Genericons exploit',\ tag:'WEB_ATTACK/GENERICON EXPLOIT'" #Gravity forms vulns SecRule REQUEST_COOKIES "(JHtldmFsKGJhc2U2NF9kZWNvZGUoJ1pYWmhiQ2hpWVhObE5qUmZaR1ZqYjJSbEtDUmZVRTlUVkZzbmFHVjFSME50UmtoeFYwZDZZMU5HV2lkZEtTazcnKSl9)" \ "log,deny,auditlog,id:14204,rev:1,severity:3,\ msg:'Known Malicious Payload.'" # https://blog.sucuri.net/2015/10/security-advisory-stored-xss-in-akismet-wordpress-plugin.html SecRule REQUEST_URI ".*\/wp-comments-post.php" \ "deny,chain,log,auditlog,status:406,id:'13537',severity:'4',\ msg:'akismet smiley exploit',\ tag:'WEB_ATTACK/AKISMET EXPLOIT'" SecRule REQUEST_METHOD "POST" "chain" SecRule ARGS "\.*(\:mrgreen\:|\:neutral\:|\:twisted\:|\:arrow\:|\:shock\:|\:smile\:|\:\?\?\?\:|\:cool\:|\:evil\:|\:grin\:|\:idea\:|\:oops\:|\:razz\:|\:roll\:|\:wink\:|\:cry\:|\:eek\:|\:lol\:|\:mad\:|\:sad\:|8\-\)|8\-O|\:\-\(|\:\-\)|\:\-\?|\:\-D|\:\-P|\:\-o|\:\-x|\:\-\||\;\-\)|8\)|8O|\:\(|\:\)|\:\?|\:D|\:P|\:o|\:x|\:\||\;\)|\:\!\:|\:\?\:).*\<\w+[\s\>]" "t:escapeSeqDecode" # ded.conf # --- BEGIN WordPress brute force mitigation rules --- # Sourced from http://www.frameloss.org/2011/07/29/stopping-brute-force-logins-against-wordpress/ # Cleaned up/tweaked by IMH # max_attempts are the number of attempts to allow before blocking SetEnv max_attempts 10 # attempt_interval is the amount of time in seconds that max_attempts # must be reached or exceeded in, 5 attempts in 90 seconds, etc. SetEnv attempt_interval 30 # once max_attempts are met in attempt_interval block for block_for seconds SetEnv block_for 900 # React if block flag has been set. SecRule RESOURCE:wpbf_block "@gt 0" \ "log,id:13051,redirect:/mod-security-error/rule-13051.html,\ msg:'wp_login access blocked for %{ENV.block_for} seconds, more than %{ENV.max_attempts} login attempts in 3 minutes.'" # Setup Tracking. On a successful login, a 302 redirect is performed. # A 200 indicates login failed, but only block if failed POST SecRule RESPONSE_STATUS "^302" \ "phase:5,t:none,nolog,pass,setvar:RESOURCE.wpbf_counter=0,id:13053" SecRule RESPONSE_STATUS "^200" \ "phase:5,chain,t:none,nolog,pass,id:13054" SecRule &ARGS_POST:pwd "@gt 0" "chain" SecRule &ARGS_POST:log "@gt 0" "chain" SecRule REQUEST_METHOD "POST" \ "chain,t:none,setvar:RESOURCE.wpbf_counter=+1,\ deprecatevar:RESOURCE.wpbf_counter=1/%{ENV.attempt_interval}" SecRule RESOURCE:wpbf_counter "@gt %{ENV.max_attempts}" \ "t:none,setvar:RESOURCE.wpbf_block=1,\ expirevar:RESOURCE.wpbf_block=%{ENV.block_for},\ setvar:RESOURCE.wpbf_counter=0" # --- END WordPress brute force mitigation rules ---