21 06 2016
Hardening WordPress, tshark decrypting SSL traffic
From a security point of view, WordPress seems to be a nightmare. The default setup exposes hundrets of .php include files in wp-includes/ and wp-content/ that may be directly called. And indeed, many robots out there are scanning the whole internet for these kind of files.
Here are some ideas to improve security.
Step 1: Add password authentication to wp-login.php, block xmlrpc.php attacks, disable direct access to wp-includes.
in your-wordpress-root-directory/.htaccess add:
# Block the include-only files.RewriteEngine On RewriteBase / RewriteRule ^wp-admin/includes/ - [F,L] RewriteRule !^wp-includes/ - [S=3] RewriteRule ^wp-includes/[^/]+\.php$ - [F,L] RewriteRule ^wp-includes/js/tinymce/langs/.+\.php - [F,L] RewriteRule ^wp-includes/theme-compat/ - [F,L] AuthType Basic AuthName "Protected Area" AuthUserFile your-wordpress-root-directory/.htpasswd Require user your-username Satisfy All AuthType Basic AuthName "Protected Area" AuthUserFile your-wordpress-root-directory/.htpasswd Require user your-username Satisfy All AuthType Basic AuthName "Protected Area" AuthUserFile your-wordpress-root-directory/.htpasswd Require user your-username Satisfy All Order Deny,Allow deny from all # The following is required to hide the login names, # otherwise a call to http://yoursite/?author=1 will # show the username for user id 1, ?author=2 will expose # the login name for the second user, and so on ... RewriteCond %{REQUEST_URI} ^/$ RewriteCond %{QUERY_STRING} ^/?author=([0-9]*) RewriteRule ^(.*)$ http://www.yoursite.com/? [R,L]
To create your-wordpress-root-directory/.htpasswd, simply call “htpasswd -C <your-username>”.
—
Step 2: Add additional HTTP authentication to your-wordpress-root-directory/wp-admin/ folder. This way you have a second security level provided by Apache Web Server and external tools cannot directly call your .php files in order to use known exploits in the PHP code.
AuthType Basic AuthName "Protected Area" AuthUserFile your-wordpress-root-directory/.htpasswd Require user your-username Satisfy All
for specific wordpress themes that are loading content via ajax we have found out that we need to create an exception for admin-ajax.php
AuthType Basic AuthName "Protected Area" AuthUserFile your-wordpress-root-directory/.htpasswd Require user your-username Satisfy All Order Deny,Allow Allow from all Satisfy any
—
Step 3: Restrict PHP execution in wp-includes. This is important so the PHP files that are meant to be included by other PHP files cannot be accessed directly. Create/add your-wordpress-root-directory/wp-includes/.htaccess
# Disable access to all file types except the following Order deny,allow Deny from allAllow from all -- Step 4: Restrict PHP execution in wp-content. This is very important to disable potential direct PHP code execution (worst case: a .php file from an uploads!). -> Create/add your-wordpress-root-directory/wp-content/.htaccess# Disable access to all file types except the following Order deny,allow Deny from allAllow from all -- Step 5: Turn off the version number output for XML feeds in your-wordpress-root-directory/wp-includes/general-template.php in order to block tools that are scanning for specific wordpress versions (in order to use known exploits for that version). -- Step 6: If you don't use /feed and /news/feed you may create empty directories. This way PHP won't even be executed.mkdir -p your-wordpress-root-directory/feed mkdir -p your-wordpress-root-directory/news/feed--
Step 7: Alternatively to blocking thins with .htaccess, you might consider additional filters for your firewall, some examples here:
iptables -I INPUT -p tcp --dport 80 -m string --to 160 --algo bm --string 'GET /wp-sql.php' -j DROP iptables -I INPUT -p tcp --dport 80 -m string --to 160 --algo bm --string 'GET /xmlrpc.php' -j DROP iptables -I INPUT -p tcp --dport 80 -m string --to 250 --algo bm --string 'GET /%3Fm%3D201601&sa=U&ved=0ahUKEwi7mK69_brNAhUJEZAKHYPeASY4ZBAWCCEwAw' -j DROP iptables -I INPUT -p tcp --dport 80 -m string --to 250 --algo bm --string 'POST /%3Fm%3D201601&sa=U&ved=0ahUKEwi7mK69_brNAhUJEZAKHYPeASY4ZBAWCCEwAw' -j DROP iptables -I INPUT -p tcp --dport 80 -m string --to 250 --algo bm --string 'ved=0ahUKEwi7mK69_brNAhUJEZAKHYPeASY4ZBAWCCEwAw' -j DROPOf course these can also be done via .htaccess but it shows the idea. However, .htaccess might be the preferred solution, as it will also work for https:// connections.
--
Step 8: Learn and use wireshark (or tshark for terminal). Here is a simple tshark example that allows you to monitor the requests in real time. The first time i did is i had quite a few "ahas". Now i'm watching it from time to time. For the case i discover something i don't like, i can add rules to firewall and .htaccess files.
#!/bin/bash tshark -f "tcp port 80" -Y 'http.request || http.response' #OR (for decrypting SSL. Won't work when using Diffie-Hellman, see Google why): tshark -o "ssl.desegment_ssl_records: TRUE" -o "ssl.desegment_ssl_application_data: TRUE" -o "ssl.keys_list:78.46.156.164,443,http,/home/frank/ssl/.b-nm.at.key" -o "ssl.debug_file:ssldebug.log" -f "tcp port 443" -Y "http" -x
For reference see https://www.wireshark.org/docs/dfref/h/http.html
--
If you have read all the way down to this line and you think i forgot something important or have got feedback, ideas, improvements, please don't hesitate to contact me: frank (at) baumi.org
Effectively storing multiple text files NASA Open Source Software
Comments are currently closed.