Showing posts with label Wordpress. Show all posts
Showing posts with label Wordpress. Show all posts
Monday, June 18, 2012
Monday, April 23, 2012
WordPress Vulnerabilities and How to Fix Them
Category:
Wordpress
— SkyHi @ Monday, April 23, 2012
Did you know that more than 73 million web sites in the world run on the WordPress publishing platform? This makes WordPress more popular than Microsoft SharePoint, Blogger, or Drupal. It also means that WordPress is a large target for hackers.
Half of the WordPress sites out there are self-hosted, which means that the WordPress administrator carries the lion's share of responsibility for a secure installation. Out of the box, there are several ways that WordPress security can be tightened down, but only a fraction of sites actually do so. This makes WordPress an even more popular target for hackers.
The following five strategies can help any WordPress installation become significantly more secure, and raise awareness of the types of vulnerabilities to defend against.
Vulnerability # 1: SQL Injection & URL Hacking.
The problem: WordPress is a database-backed platform that executes server-side scripts in PHP. Both of these characteristic can make WordPress vulnerable to malicious URL insertion attacks. Commands are sent to WordPress via URL parameters, which can be abused by hackers who know how to construct parameters that WordPress may misinterpret or act on without authorization.
SQL injection describes a class of these attacks in which hackers embed commands in a URL that trigger behaviors from the database. (SQL is the command language used by the MySQL database.) These attacks can reveal sensitive information about the database, potentially giving hackers entrance to modifying the actual content of your site. Many of today's web site defacement attacks are accomplished by some form of SQL Injection.
Other versions of URL hacks can trigger unintended PHP commands which, again, can lead to injecting malware or revealing sensitive information.
The defense: Most WordPress installations are hosted on the popular Apache web server. Apache uses a file named.htaccess to define the access rules for your web site. A thorough set of rules can prevent many types of SQL Injection and URL hacks from being interpreted.
The code below represents a strong set of rules that you can insert into your web site's .htaccess file that will strip URL requests of many dangerous attack injections:
RewriteEngine On RewriteBase / RewriteCond %{REQUEST_METHOD} ^(HEAD|TRACE|DELETE|TRACK) [NC] RewriteRule ^(.*)$ - [F,L] RewriteCond %{QUERY_STRING} \.\.\/ [NC,OR] RewriteCond %{QUERY_STRING} boot\.ini [NC,OR] RewriteCond %{QUERY_STRING} tag\= [NC,OR] RewriteCond %{QUERY_STRING} ftp\: [NC,OR] RewriteCond %{QUERY_STRING} http\: [NC,OR] RewriteCond %{QUERY_STRING} https\: [NC,OR] RewriteCond %{QUERY_STRING} (\<|%3C).*script.*(\>|%3E) [NC,OR] RewriteCond %{QUERY_STRING} mosConfig_[a-zA-Z_]{1,21}(=|%3D) [NC,OR] RewriteCond %{QUERY_STRING} base64_encode.*\(.*\) [NC,OR] RewriteCond %{QUERY_STRING} ^.*(\[|\]|\(|\)|<|>|ê|"|;|\?|\*|=$).* [NC,OR] RewriteCond %{QUERY_STRING} ^.*("|'|<|>|\|{||).* [NC,OR] RewriteCond %{QUERY_STRING} ^.*(%24&x).* [NC,OR] RewriteCond %{QUERY_STRING} ^.*(%0|%A|%B|%C|%D|%E|%F|127\.0).* [NC,OR] RewriteCond %{QUERY_STRING} ^.*(globals|encode|localhost|loopback).* [NC,OR] RewriteCond %{QUERY_STRING} ^.*(request|select|insert|union|declare).* [NC] RewriteCond %{HTTP_COOKIE} !^.*wordpress_logged_in_.*$ RewriteRule ^(.*)$ - [F,L]
Vulnerability # 2: Access to Sensitive Files.
The problem: A typical WordPress install contains a number of files which you don’t want outsiders to access. These files, such as the WordPress configuration file, install script, and even the “readme” file should be kept private.
The defense: As with preventing URL hacking, you can add commands to the Apache .htaccess file to block access to sensitive private files. For a typical WordPress installation, the following code will block access to directory listings, plus a set of specific files related to WordPress and the Web server itself.
Options All -IndexesOrder allow,deny Deny from all Order allow,deny Deny from all Order allow,deny Deny from all Order allow,deny Deny from all Order allow,deny Deny from all Order allow,deny Deny from all Order allow,deny Deny from all Order allow,deny Deny from all
Vulnerability # 3: Default Admin User Account.
The problem: Many default WordPress installs include an administrator user account whose username is simply “admin”. Hackers may try to log into this account using guessed passwords.
The defense: Any element of predictability gives hackers an edge. Although a hacker would still need to guess or brute-force your password to access the admin account, you are even more secure without an “admin” account at all.
Instead, log into WordPress and create a new user with an unpredictable name. Assign administrator privileges to this user. Now delete the account named “admin”. A hacker would now need to guess both the username and password to gain administrator access, a significantly more challenging feat.
Vulnerability # 4: Default Prefix for Database Tables
The problem: The WordPress database consists of numerous tables. In many WordPress installs, these tables are named with a default prefix that begins with “wp_“. For hackers, the ability to predict anything can provide an extra advantage.
The defense: Changing the prefix of your WordPress tables can eliminate this predictability. Some security experts argue that this will not stop a savvy hacker who can use other means to determine the table names in your installation. While this is true when talking about a knowledgeable hacker, many amateur hackers use pre-packaged scripts to perform their dirty work and these are more likely to be successfully blocked by eliminating predictable table names.
When setting up a new WordPress install, you can specify the database table prefix yourself. This gives you the opportunity to choose something unique and unpredictable. If WordPress is already installed, you can retroactively change the table names. Although this can be done manually, the process requires directly manipulating the database in several places.
An easier way to change table prefixes for an existing WordPress installation is by using the plugin named Better WP Security. This plugin contains several defenses including some discussed elsewhere in this article, with a simple point-and-click interface to change your table names to include a randomly-generated prefix.
Vulnerability # 5: Brute-Force Login Attempts
The problem: Hackers often rely on automated scripts to do their dirty work. These scripts can make numerous attempts to log into your WordPress administration page by trying thousands and millions of combinations of usernames and passwords. Not only can being bombed with login attempts slow down your web site for legitimate users, it may also succeed—giving hackers complete control of your site.
The defense: Of course, you should start with always using strong passwords. A longer, mixed-type password will take longer for a brute-force attack to decode. These attacks typically use combinations of dictionary words and numbers. (But remember that malware can render strong passwords useless.)
An even more effective defense is to install a login limiter for WordPress. A login limiter can essentially block or quarantine an IP address or username which tries and fails to send login requests above a threshold rate. For example, a login limit of 10 attempts per 5 minutes can be backed up with a penalty timeout of 1 hour.
A successful brute-force attack against a strong password effectively becomes impossible with these limits in place, because the hacker can never try enough variations (or rather, it would take many years of continuous attempts).
Two WordPress plugins which let you enforce a login limiter are Limit Login Attempts and the aforementioned Better WP Security.
These five strategies are the beginning of effective WordPress security—not the end. Like any form of security, defending WordPress is an ongoing process that must involve awareness of new threats combined with specific details about your own install environment.
REFERENCES
Wednesday, March 14, 2012
Supercharge WordPress, Part 1
Here are a few example configuration settings for servers of different memory sizes running both MySQL and a web server on the same machine. These are not perfect, but they are good starting points.
For servers with 512MB RAM:
thread_cache_size=50 key_buffer=40M table_cache=384 sort_buffer_size=768K read_buffer_size=512K read_rnd_buffer_size=512K query_cache_limit=2M query_cache_size=16M query_cache_type=1 thread_concurrency=2*CPU skip-innodb
For servers with 1GB RAM:
thread_cache_size=80 key_buffer=150M table_cache=512 sort_buffer_size=1M read_buffer_size=1M read_rnd_buffer_size=768K query_cache_limit=4M query_cache_size=32M query_cache_type=1 thread_concurrency=2*CPU skip-innodb
For servers with 2GB RAM:
thread_cache_size=80 key_buffer=350M table_cache=1024 sort_buffer_size=2M read_buffer_size=2M read_rnd_buffer_size=768K query_cache_limit=4M query_cache_size=64M query_cache_type=1 thread_concurrency=2*CPU skip-innodb
Once WordPress has been up and running for some time you can tweak your settings by running MySQLTuner, a Perl script that analyzes your MySQL performance and, based on the statistics it gathers, gives recommendations about which variables you should adjust to increase performance. With MySQLTuner, you can tune your my.cnf file to tease out the last bit of performance from your MySQL server and make it work more efficiently.
http://linuxaria.com/?p=3293?lang=en
http://linuxaria.com/article/supercharge-wordpress-part-2?lang=en
http://linuxaria.com/article/supercharge-wordpress-part-3?lang=en
Tuesday, November 1, 2011
Supercharge WordPress
Category:
Performance Tune,
Wordpress
— SkyHi @ Tuesday, November 01, 2011
WordPress, the popular content managing system (CMS), is easy to set up and use, and well supported by both its community and professional consultants. WordPress depends upon a complete stack that comprises an operating system, database, web server, and PHP. If you can optimize this stack, you can enhance the performance of your site. Here are some tricks and best practices for a setup that will improve your throughput without forcing you to upgrade your hardware.
Let’s start with a look at the Linux operating system, MySQL database, and nginx web server. Later we’ll get to PHP, some setup and plugin work with WordPress itself, and Varnish Cache, a web application accelerator.
But for its better license, performance, and optimization capabilities, we’ll go with GNU/Linux, and in particular with CentOS 6. It’s a stable and free Linux distribution based on Red Hat Enterprise 6, so all the packages and commands work exactly the way they do on RHEL 6. If you prefer another distribution, such as Debian or Arch, you’ll have some files located in paths slightly different or packages with different names or version, but the concepts here are applicable on any GNU/Linux distribution.
Regarding CentOS 6 optimization, and in general for any GNU/Linux distribution, I have three tips:
Begin by installing the latest release of MySQL server with the command
The key buffer stores table indexes in memory, allowing for fast lookups and joins. The parameter accept a value that indicates of how much memory allocate for this operation. I’ll suggest a generic value below, but you can adjust it later with MySQLTuner.
Opening tables can be expensive. For example, with MyISAM, MySQL marks MYI header fields to indicate a table is currently in use. You do not want to open too many tables too frequently; it’s better to keep them open for performance. You can achieve this by adjusting the table cache to a size that is large enough to keep most of your tables open. Start with the number I’ve put in the profiles below and tune it with MySQLTuner over time.
MySQL has a query cache that stores results up to a certain size in memory. The cache is handy for quickly returning commonly accessed data when all other forms of caching (including reverse proxies, page cache, and WordPress caches) have not been invoked.
Here are a few example configuration settings for servers of different memory sizes running both MySQL and a web server on the same machine. These are not perfect, but they are good starting points.
For servers with 512MB RAM:
For servers with 1GB RAM:
For servers with 2GB RAM:
Once WordPress has been up and running for some time you can tweak your settings by running MySQLTuner, a Perl script that analyzes your MySQL performance and, based on the statistics it gathers, gives recommendations about which variables you should adjust to increase performance. With MySQLTuner, you can tune your my.cnf file to tease out the last bit of performance from your MySQL server and make it work more efficiently.
Now you should look at a few parameters in the /etc/nginx/nginx.conf configuration file.
worker_processes controls – surprise – the number of worker processes to spawn. A worker is similar to a child process in Apache. Nginx has the ability to put worker processes to use on SMP multiprocessor machines to decrease latency when workers are blocked by disk I/O, or to limit the number of connections per process when select() or poll() is used. The general rule of the thumb is to set the number of nginx workers to two, or the number of CPUs your server has. If you are going to serve sites with a lot of static content, add more workers – up to one per disk.
If your disk subsystem is poor or the load is too high, nginx worker processes may become locked on I/O operations and unable to serve other requests. Run
Along with worker_proceses, worker_connections allows you to calculate a max_clients value:
max_clients = worker_processes * worker_connections
I suggest not making this value too high. If your
Timeouts values specify the amount of time in seconds that nginx will wait for the client to complete the specified action.
client_body_timeout N is the read timeout for the request body from client. If after this time the client sends nothing, nginx returns the error “Request time out” (408).
client_header_timeout N is the timeout reading the title of the request of the client. If after this time the client send nothing, nginx returns the error “Request time out” (408).
keepalive_timeout N N – the first value is for keep-alive connections with the client. The second parameter assigns the value “Keep-Alive: timeout=time” in the header of answer.
Regarding these value I usually keep 30 seconds for the client timeouts and not more than 10 seconds for the keepalive. You can lower the keepalive, to 3 perhaps, if you have a busy site and you notice that you have a lot of connection open. Others suggest setting it to 0, thus making the client reopen a connection.
sendfile on|off Use sendfile when the nginx server can actually ignore the contents of the file it is sending. If set to on, it uses the kernel sendfile() support instead of its own resources on the request.
tcp_nopush on|off enables or disables the TCP_NOPUSH (FreeBSD) or TCP_CORK (Linux) socket option. Note that this option only applies if the sendfile directive is enabled. If tcp_nopush is set to on, nginx will attempt to transmit the entire HTTP response headers in a single TCP packet. Most sources suggest setting it to off.
tcp_nodelay on|off disables the Nagle buffering algorithm. You can use it when the server doesn’t require a response from the client. General web use does need a response, so this should be turned off, unless you need to send out small bursts of information, like tracking mouse movements.
multi_accept on|off tries to accept() as many connections as possible after nginx gets notification about a new connection.
You should also enable all the compression options of nginx. Insert into your nginx.conf file these options:
With the changes and additions to the configuration files above, you should have a good, basic optimization of nginx.
At this point you have Nginx up and running with an optimized database server. Next, we’ll see how to optimize php5-fpm. We’ll install and configure APC, the Alternative PHP Cache. We’ll look at plugins that can help your WordPress site respond faster. And we’ll put in front of the web server Varnish, a great application server cache that can do wonders to improve your site’s responsiveness.
REFERENCES
http://olex.openlogic.com/wazi/2011/supercharge-wordpress/
Let’s start with a look at the Linux operating system, MySQL database, and nginx web server. Later we’ll get to PHP, some setup and plugin work with WordPress itself, and Varnish Cache, a web application accelerator.
Operating System
In theory you could run WordPress on a Windows server using software like EasyPHP, a package that allow you to take advantage of all the power and flexibility that the dynamic PHP language offers with Windows. The package includes an Apache server, a MySQL database, phpMyAdmin, and development tools for websites and applications.But for its better license, performance, and optimization capabilities, we’ll go with GNU/Linux, and in particular with CentOS 6. It’s a stable and free Linux distribution based on Red Hat Enterprise 6, so all the packages and commands work exactly the way they do on RHEL 6. If you prefer another distribution, such as Debian or Arch, you’ll have some files located in paths slightly different or packages with different names or version, but the concepts here are applicable on any GNU/Linux distribution.
Regarding CentOS 6 optimization, and in general for any GNU/Linux distribution, I have three tips:
- If the server (real or virtual) where you are installing CentOS 6 has more than 3GB of RAM, install a 64-bit system; otherwise, choose the 32-bit version – this will save you some RAM.
- Usually CentOS 6 uses ext4 as its filesystem type. Ext4 is a journaled filesystem, which registers all changes, so if the system crashes it can recover the affected files. By default Linux records file access timestamps, meaning every time a process accesses a file there is a small overhead to write the timestamp. In a busy environment, removing this feature can speed up operations.
To remove file access timestamps, edit the /etc/fstab file and add, in the line that refers to your WordPress filesystem, thenoatime
option after the default options:
/dev/sda7 /srv ext4 defaults,noatime 1 2
- This last tip is true for all the software in the stack, but I’ll write it only here: Be sure to run the latest version of your software. This should be bug-free, and so save you from any known problems.
Under Linux we want to manage all our software stack with yum, so we’ll add the EPEL (Extra Packages for Enterprise Linux) repository to our system. The EPEL repository was developed by the Fedora community to provide extra add-on packages for RHEL, which means it’s compatible with CentOS.
To add EPEL on a 32-bit system, run this command as root from a terminal window:
rpm -ivh http://download.fedora.redhat.com/pub/epel/6/i386/epel-release-6-5.noarch.rpm
If you have a 64-bit system, run:
rpm -ivh http://download.fedora.redhat.com/pub/epel/6/x86_64/epel-release-6-5.noarch.rpm
When adding extra repositories, keep in mind that many include newer versions of packages that are available through the standard channels. This can cause problems, as packages may be automatically upgraded when you don’t want them to be and cease to function as expected. To mitigate this problem, use yum priority and give to the EPEL repository a lower priority than the official CentOS repository.
Finally, check and update the system with:
yum check-update yum update
Database Server
The database server is the heart of any CMS system. Because it’s where all the content and setup information is stored, it can get a lot of requests per second, so improving this layer can yield huge benefits.Begin by installing the latest release of MySQL server with the command
yum install MySQL-server
. A default installation of WordPress 3.2 installs the database tables as MyISAM, so to save some memory you can keep MySQL from loading InnoDB, MySQL’s other default storage engine, which can save up to 100MB of RAM on your server. Now take a look at some of the most important parameters:The key buffer stores table indexes in memory, allowing for fast lookups and joins. The parameter accept a value that indicates of how much memory allocate for this operation. I’ll suggest a generic value below, but you can adjust it later with MySQLTuner.
Opening tables can be expensive. For example, with MyISAM, MySQL marks MYI header fields to indicate a table is currently in use. You do not want to open too many tables too frequently; it’s better to keep them open for performance. You can achieve this by adjusting the table cache to a size that is large enough to keep most of your tables open. Start with the number I’ve put in the profiles below and tune it with MySQLTuner over time.
MySQL has a query cache that stores results up to a certain size in memory. The cache is handy for quickly returning commonly accessed data when all other forms of caching (including reverse proxies, page cache, and WordPress caches) have not been invoked.
Here are a few example configuration settings for servers of different memory sizes running both MySQL and a web server on the same machine. These are not perfect, but they are good starting points.
For servers with 512MB RAM:
thread_cache_size=50
key_buffer=40M
table_cache=384
sort_buffer_size=768K
read_buffer_size=512K
read_rnd_buffer_size=512K
query_cache_limit=2M
query_cache_size=16M
query_cache_type=1
thread_concurrency=2*CPU
skip-innodb
For servers with 1GB RAM:
thread_cache_size=80
key_buffer=150M
table_cache=512
sort_buffer_size=1M
read_buffer_size=1M
read_rnd_buffer_size=768K
query_cache_limit=4M
query_cache_size=32M
query_cache_type=1
thread_concurrency=2*CPU
skip-innodb
For servers with 2GB RAM:
thread_cache_size=80
key_buffer=350M
table_cache=1024
sort_buffer_size=2M
read_buffer_size=2M
read_rnd_buffer_size=768K
query_cache_limit=4M
query_cache_size=64M
query_cache_type=1
thread_concurrency=2*CPU
skip-innodb
Once WordPress has been up and running for some time you can tweak your settings by running MySQLTuner, a Perl script that analyzes your MySQL performance and, based on the statistics it gathers, gives recommendations about which variables you should adjust to increase performance. With MySQLTuner, you can tune your my.cnf file to tease out the last bit of performance from your MySQL server and make it work more efficiently.
HTTP Server
My HTTP server of choice is nginx; in a recent article I talked about some advantages of using this HTTP server with PHP5 in FPM mode versus Apache and mod_php module. If you’ve already added the EPEL repository, runyum install nginx
to install nginx 0.8.54-1.el6. While the latest stable release of nginx is currently 1.0.8, installing a package from an official repository gives you a more stable but older version.Now you should look at a few parameters in the /etc/nginx/nginx.conf configuration file.
worker_processes controls – surprise – the number of worker processes to spawn. A worker is similar to a child process in Apache. Nginx has the ability to put worker processes to use on SMP multiprocessor machines to decrease latency when workers are blocked by disk I/O, or to limit the number of connections per process when select() or poll() is used. The general rule of the thumb is to set the number of nginx workers to two, or the number of CPUs your server has. If you are going to serve sites with a lot of static content, add more workers – up to one per disk.
If your disk subsystem is poor or the load is too high, nginx worker processes may become locked on I/O operations and unable to serve other requests. Run
ps ax
and examine its output; workers that are in “D” state are locked. Increase the number of worker processes until ps ax
returns a number of worker processes not blocked equal to the number of CPUs on your system. You can also add some memory for disk cache to solve this problem.Along with worker_proceses, worker_connections allows you to calculate a max_clients value:
max_clients = worker_processes * worker_connections
I suggest not making this value too high. If your
ulimit -n
output is something like 1024, then your worker connections would need to be set to 1024 or less (maybe even 768), and its unlikely that you’ll have “worker_processes x 1024″ simultaneous connections.Timeouts values specify the amount of time in seconds that nginx will wait for the client to complete the specified action.
client_body_timeout N is the read timeout for the request body from client. If after this time the client sends nothing, nginx returns the error “Request time out” (408).
client_header_timeout N is the timeout reading the title of the request of the client. If after this time the client send nothing, nginx returns the error “Request time out” (408).
keepalive_timeout N N – the first value is for keep-alive connections with the client. The second parameter assigns the value “Keep-Alive: timeout=time” in the header of answer.
Regarding these value I usually keep 30 seconds for the client timeouts and not more than 10 seconds for the keepalive. You can lower the keepalive, to 3 perhaps, if you have a busy site and you notice that you have a lot of connection open. Others suggest setting it to 0, thus making the client reopen a connection.
sendfile on|off Use sendfile when the nginx server can actually ignore the contents of the file it is sending. If set to on, it uses the kernel sendfile() support instead of its own resources on the request.
tcp_nopush on|off enables or disables the TCP_NOPUSH (FreeBSD) or TCP_CORK (Linux) socket option. Note that this option only applies if the sendfile directive is enabled. If tcp_nopush is set to on, nginx will attempt to transmit the entire HTTP response headers in a single TCP packet. Most sources suggest setting it to off.
tcp_nodelay on|off disables the Nagle buffering algorithm. You can use it when the server doesn’t require a response from the client. General web use does need a response, so this should be turned off, unless you need to send out small bursts of information, like tracking mouse movements.
multi_accept on|off tries to accept() as many connections as possible after nginx gets notification about a new connection.
You should also enable all the compression options of nginx. Insert into your nginx.conf file these options:
worker_processes 2;
events {
worker_connections 768;
use epoll;
}
sendfile on;
tcp_nopush off;
client_body_timeout 30;
client_header_timeout 30;
keepalive_timeout 10 10;
tcp_nodelay off;
multi_accept on;
gzip on;
gzip_proxied any;
gzip_comp_level 2;
gzip_disable "MSIE [1-6].(?!.*SV1)";
gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;
These are the general options. You can also tune the specific WordPress site options. To do this, change the specific Virtuahost file. I usually give them the name of the site I’m setting up – for example, www.example.com – and I place them in the /etc/httpd/conf.d directory. Below are some suggested options if you are using php5-FPM......
location ~ .php$ {
fastcgi_split_path_info ^(.+.php)(.*)$;
fastcgi_pass backend;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/$fastcgi_script_name;
fastcgi_connect_timeout 60;
fastcgi_send_timeout 180;
fastcgi_read_timeout 180;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
fastcgi_intercept_errors on;
.....
With the changes and additions to the configuration files above, you should have a good, basic optimization of nginx.
At this point you have Nginx up and running with an optimized database server. Next, we’ll see how to optimize php5-fpm. We’ll install and configure APC, the Alternative PHP Cache. We’ll look at plugins that can help your WordPress site respond faster. And we’ll put in front of the web server Varnish, a great application server cache that can do wonders to improve your site’s responsiveness.
REFERENCES
http://olex.openlogic.com/wazi/2011/supercharge-wordpress/
Wednesday, October 19, 2011
How to find a backdoor in a hacked WordPress
Category:
Wordpress
— SkyHi @ Wednesday, October 19, 2011
http://ottopress.com/2009/hacked-wordpress-backdoors/
http://smackdown.blogsblogsblogs.com/2008/06/24/how-to-completely-clean-your-hacked-wordpress-installation/
http://codex.wordpress.org/Hardening_WordPress
http://codex.wordpress.org/FAQ_My_site_was_hacked
http://smackdown.blogsblogsblogs.com/2008/06/24/how-to-completely-clean-your-hacked-wordpress-installation/
http://codex.wordpress.org/Hardening_WordPress
http://codex.wordpress.org/FAQ_My_site_was_hacked
Tuesday, September 20, 2011
Multi-Site in WordPress
Category:
Wordpress
— SkyHi @ Tuesday, September 20, 2011
Wordpress is my favorite website platform .One of the really cool features that WordPress offers is Multi-sites. Mult-sites can be turned on in any recent WordPress installation (3.0 and up).Turning on multi-sites allows you to create and manage as many sites as you want from a single WordPress installation. It is not difficult to activate multi-sites and there are tons of blogs out there that will walk you through the process (like this one), but if you want to use different domains on each of your new sites, you will need to either install a plugin ( I have never used this method) or you can use the little trick I am going to write about.
This trick will let you use a different domain for each new website you create in your WordPress installation. So for example, you have your WordPress installed on jacksblog.net, and have set up multi-sites. You create a new site called jacksblog.net/bobsblog, but you really want to use your other domain “bobsblog.net.” No problem! You are at the right place. This trick will make that happen, and will work for as many new sites as you care to create (as long as you have a domain for each new site).
/*TECH NOTE*/
This method involves going into your MySQL database and creating a new record by hand, and modifying another record. If you are not comfortable with doing this, then better to use a plugin. Also, make sure you have backed up your database and website files in case something goes crazy-ape bonkers.
Ready? Here we go. For this setup, I have installed WordPress on my brother-in-laws domain space “3fc.co“, and set up a website for him. I wanted to create an additional site on the same WordPress install for my father-in-law’s website using the domain “filleywood.com“. That way I could manage both websites from a single location.
Firstly, I activated “Multi-Sites” using the basic instructions you can find on your blog of choice. Then I logged in as Network Admin and created a new site called 3fc.co/filleywood
Next, I needed to point the domain filleywood.com to 3fc.co. In DreamHost, this is done by setting filleywood.com to mirror 3fc.co (which is set as “Fully Hosted”.) In BlueHost, you have one domain that is your primary domain, and then you just “Park” your new domains. whatever your hosting company, the goal is to make your new domain point to wherever you have WordPress installed..WordPress will take care of the rest.
It should be noted that once you change settings for a domain with your hosting company, it can take a few hours or more for those changes to take effect, so make sure to wait a while before freaking out.
So I have my second site set up and I have my second domain pointing to my WordPress install. Now I need to makes some changes to the MySQL database that WordPress is using. I will use phpMyadmin for this, but you could use MySQL Workbench or even PuTTy if you want.
After having completed all of that, I found that there was one additional small change I needed to make:
After setting up the Multi-Sites, WordPress gave me some code to add to the wp-config.php file. I had to remove a few of those lines from my wp-config file because it was causing links in the new sites to go back to the original site. You will only need to do this once:
define( ‘MULTISITE’, true );
define( ‘SUBDOMAIN_INSTALL’, false );
$base = ‘/’;
define( ‘DOMAIN_CURRENT_SITE’, ’3fc.co’ ); ####remove line
define( ‘PATH_CURRENT_SITE’, ‘/’ );
define( ‘SITE_ID_CURRENT_SITE’, 1 ); ####remove line
define( ‘BLOG_ID_CURRENT_SITE’, 1 ); ####remove line
Thats it. Your new site should be using the new domain name. You can add as many sites and new domains as you want. In my next article I will write about setting up multiple FTP accounts for each of your new websites you add.
REFERENCES
http://ghettocottage.com/1041
http://wordpress.org/extend/plugins/wordpress-mu-domain-mapping/
This trick will let you use a different domain for each new website you create in your WordPress installation. So for example, you have your WordPress installed on jacksblog.net, and have set up multi-sites. You create a new site called jacksblog.net/bobsblog, but you really want to use your other domain “bobsblog.net.” No problem! You are at the right place. This trick will make that happen, and will work for as many new sites as you care to create (as long as you have a domain for each new site).
/*TECH NOTE*/
This method involves going into your MySQL database and creating a new record by hand, and modifying another record. If you are not comfortable with doing this, then better to use a plugin. Also, make sure you have backed up your database and website files in case something goes crazy-ape bonkers.
Using Different Domains on WordPress Multi-sites
So you have multi-sites turned on, and you have another domain you would like to use on a new site you will create. There are a few steps you need to do (the following has worked for me using BlueHost and DreamHost, but should work with other domains as well) :- Set your new domain to be Parked (BlueHost) or Mirrored to your original domain (DreamHost)
- Create a new site in your WordPress install. Just using a sub-domain for now.
- Go into the MySQL database your WordPress is using, and add a new record in the sites table.
Ready? Here we go. For this setup, I have installed WordPress on my brother-in-laws domain space “3fc.co“, and set up a website for him. I wanted to create an additional site on the same WordPress install for my father-in-law’s website using the domain “filleywood.com“. That way I could manage both websites from a single location.
Firstly, I activated “Multi-Sites” using the basic instructions you can find on your blog of choice. Then I logged in as Network Admin and created a new site called 3fc.co/filleywood
Next, I needed to point the domain filleywood.com to 3fc.co. In DreamHost, this is done by setting filleywood.com to mirror 3fc.co (which is set as “Fully Hosted”.) In BlueHost, you have one domain that is your primary domain, and then you just “Park” your new domains. whatever your hosting company, the goal is to make your new domain point to wherever you have WordPress installed..WordPress will take care of the rest.
It should be noted that once you change settings for a domain with your hosting company, it can take a few hours or more for those changes to take effect, so make sure to wait a while before freaking out.
So I have my second site set up and I have my second domain pointing to my WordPress install. Now I need to makes some changes to the MySQL database that WordPress is using. I will use phpMyadmin for this, but you could use MySQL Workbench or even PuTTy if you want.
- Log in to phpMysql and choose the database WordPress is using.
- From the list of tables on the left, choose wp_sites
- Click the Insert tab to insert a new record
- Type in 2 in the ID field (or higher number, depending on how many times you have done this..second site gets 2, 3rd site gets 3…)
- Type in the domain you want to use for your new site in the Domain field
- Type in / for path
- Click the Go button to add this record, now you should see the new site in the list of sites
- Now click on the wp-blogs table on the left
- Click the pencil icon next to the blog(site) that will get the new domain
- Change the domain field to your new domain (fillywood.com) and change the path to /
- Click the GO button to save changes, you should see your changes saved in the list
- You can leave phpMyadmin, and log into your WordPress site as Network Admin, and go to Network admin (upper-right hand corner drop-down)
- Go to Sites
- Choose “edit” on the site that has the new domain name..it can be hard to tell which is which now because they all have the same path /
- On the “Settings” tab, check the SiteURL, Home, and FileUploadURL. They should all have your new domain in them. FileUploadURL should have your domain and /files after it. Change them if they need it, click “Save Settings”
After having completed all of that, I found that there was one additional small change I needed to make:
After setting up the Multi-Sites, WordPress gave me some code to add to the wp-config.php file. I had to remove a few of those lines from my wp-config file because it was causing links in the new sites to go back to the original site. You will only need to do this once:
define( ‘MULTISITE’, true );
define( ‘SUBDOMAIN_INSTALL’, false );
$base = ‘/’;
define( ‘DOMAIN_CURRENT_SITE’, ’3fc.co’ ); ####remove line
define( ‘PATH_CURRENT_SITE’, ‘/’ );
define( ‘SITE_ID_CURRENT_SITE’, 1 ); ####remove line
define( ‘BLOG_ID_CURRENT_SITE’, 1 ); ####remove line
Thats it. Your new site should be using the new domain name. You can add as many sites and new domains as you want. In my next article I will write about setting up multiple FTP accounts for each of your new websites you add.
REFERENCES
http://ghettocottage.com/1041
http://wordpress.org/extend/plugins/wordpress-mu-domain-mapping/
http://jasonirwin.ca/2011/05/28/wordpress-multi-site-with-multi-domains/
http://think2loud.com/826-enable-multisite-wordpress/
http://think2loud.com/826-enable-multisite-wordpress/
Monday, August 1, 2011
zero day vulnerability in many wordpress themes
The Exec summary: An image resizing utility called timthumb.php is widely used by many WordPress themes. Google shows over 39 million results for the script name. If your WordPress theme is bundled with an unmodified timthumb.php as many commercial and free themes are, then you should immediately either remove it or edit it and set the $allowedSites array to be empty. The utility only does a partial match on hostnames allowing hackers to upload and execute arbitrary PHP code in your timthumb cache directory. I haven’t audited the rest of the code, so this may or may not fix all vulnerabilities. Also recursively grep your WordPress directory and subdirs for the base64_decode function and look out for long encoded strings to check if you’ve been compromised.
How to fix:
Update: As per several requests I’m posting hopefully easy to use instructions on how to fix this. This is for the latest version of timthumb.php version 1.33 available here. Check your version because there are many much older versions floating around.
NOTE: timthumb.php is inherently insecure because it relies on being able to write files into a directory that is accessible by people visiting your website. That’s never a good idea. So if you want to be truly secure, just delete the file using “rm timthumb.php” and make sure it didn’t break anything in the theme you’re using. If you still want to use it but want to be a bit more secure, you can follow the instructions below.
This will disable timthumb.php’s ability to load images from external sites, but most bloggers only use timthumb.php for resizing local images:
Earlier today this blog was hacked. I found out because I loaded a page on my blog and my blog spoke to me. It said “Congratulations, you’re a winner”.
After a brief WTF? I loaded up the dev tools in Chrome and checked what network requests were going out. Ad content was loading and I don’t run ads on my blog. For some reason the content was hidden, perhaps someone gets paid per impression.
I found the hostname the ads were loading from and grepped the WordPress code for the hostname and nothing turned up. Next I dumped the database - in fact all mysql databases on the server and grepped for the ad hostname and still nothing.
Eventually I found it. The hacker had done an eval(base64_decode(‘…long base64 encoded string’)) in one of WordPress PHP files. My bad for allowing that file to be writeable by the web server. Read on, because even if you set your file permissions correctly on the WordPress php files, you may still be vulnerable.
But what I really wanted to know was how the hell he wrote to a file on my machine.
I checked my nginx and apache access and error logs and eventually found a few PHP errors in the apache log that clued me in.
Turns out the theme I’m using, Memoir, which I bought for $30 from ElegantThemes.com uses a library called timthumb.php. timthumb.php uses a cache directory which lives under wp-content and it writes to that directory when it fetches an image and resizes it.
If you can figure out a way to get timthumb to fetch a php file and put it in that directory, you’re in.
The default configuration of timthumb.php which many themes use allow files to be remotely loaded and resized from the following domains:
So if you create a file on a web server like so: http://blogger.com.somebadhackersite.com/badscript.php and tell timthumb.php to fetch it, it merrily fetches the file and puts it in the cache directory ready for execution.
[Note: I'm 99% sure this will work on most webserver configurations because the cache directory that timthumb uses is a subdirectory of directories that are allowed to execute files with a .php extension. So unless you explicitly tell your server to not execute .php files in the cache directory, it'll execute them. ]
Then you just access the file in the cache directory on the target site using your web browser and whatever code came from http://blogger.com.somebadhackersite.com/badscript.php will get executed by the web server.
In my case, this is what the hacker saw when he accessed my site:

It’s called Alucar shell and it’s a php file that contains one massive base64 encoded string that gets decoded and evalled. It’s encoded in an attempt to hide itself.
When you first hit the script it presents you with a login page and once you’re signed in you see the screenshot above. It works quite well actually. Even if the rest of your filesystem is secure, whoever is using it can dump read-only files like /etc/passwd to get a list of user accounts, config files which may contain passwords, etc..etc..
The current version of timthumb has this issue. Since it’s already in the wild and I just got hacked by it, I figure it’s ok to release the vulnerability to the general public.
To check if you have been hacked do the following:
How to fix:
Update: As per several requests I’m posting hopefully easy to use instructions on how to fix this. This is for the latest version of timthumb.php version 1.33 available here. Check your version because there are many much older versions floating around.
NOTE: timthumb.php is inherently insecure because it relies on being able to write files into a directory that is accessible by people visiting your website. That’s never a good idea. So if you want to be truly secure, just delete the file using “rm timthumb.php” and make sure it didn’t break anything in the theme you’re using. If you still want to use it but want to be a bit more secure, you can follow the instructions below.
This will disable timthumb.php’s ability to load images from external sites, but most bloggers only use timthumb.php for resizing local images:
- SSH into your web server. You can use “putty” if you use windows and you’ll need to know your username and password.
- cd into your wordpress installation directory. That is going to vary according to which host you’re using or how you’ve installed it.
- You need to find every copy of timthumb.php on your system. Use the following command without double quotes: ” find . -name ‘timthumb.php’ “
- It will show you a list of where timthumb.php is located. You may want to repeat this command using “thumb.php” as some users have reported that’s what it’s called on their systems.
- Edit timthumb.php using a text editor like pico, nano or (if you know what you’re doing) vim. You would type (without double quotes) ” nano directory/that/tim/thumb/is/in/timthumb.php ” for example.
- Go down to line 27 where it starts $allowedSites = array (
- Change it to remove all the sites listed like “blogger.com” and “flickr.com”. Once you’re done the line should look like this from $allowedSites to the semi-colon:
- $allowedSites = array();
- Note the empty parentheses.
- The next line should be blank and the following line will probably say “STOP MODIFYING HERE”
- That’s it. Save the file and you’re done.
Earlier today this blog was hacked. I found out because I loaded a page on my blog and my blog spoke to me. It said “Congratulations, you’re a winner”.
After a brief WTF? I loaded up the dev tools in Chrome and checked what network requests were going out. Ad content was loading and I don’t run ads on my blog. For some reason the content was hidden, perhaps someone gets paid per impression.
I found the hostname the ads were loading from and grepped the WordPress code for the hostname and nothing turned up. Next I dumped the database - in fact all mysql databases on the server and grepped for the ad hostname and still nothing.
Eventually I found it. The hacker had done an eval(base64_decode(‘…long base64 encoded string’)) in one of WordPress PHP files. My bad for allowing that file to be writeable by the web server. Read on, because even if you set your file permissions correctly on the WordPress php files, you may still be vulnerable.
But what I really wanted to know was how the hell he wrote to a file on my machine.
I checked my nginx and apache access and error logs and eventually found a few PHP errors in the apache log that clued me in.
Turns out the theme I’m using, Memoir, which I bought for $30 from ElegantThemes.com uses a library called timthumb.php. timthumb.php uses a cache directory which lives under wp-content and it writes to that directory when it fetches an image and resizes it.
If you can figure out a way to get timthumb to fetch a php file and put it in that directory, you’re in.
The default configuration of timthumb.php which many themes use allow files to be remotely loaded and resized from the following domains:
$allowedSites = array ( 'flickr.com', 'picasa.com', 'blogger.com', 'wordpress.com', 'img.youtube.com', 'upload.wikimedia.org', 'photobucket.com', );The problem is the way the developer checks which domain he’s fetching from. He uses the PHP strpos function and if the domain string appears anywhere in the hostname, he’ll allow that file to be fetched.
So if you create a file on a web server like so: http://blogger.com.somebadhackersite.com/badscript.php and tell timthumb.php to fetch it, it merrily fetches the file and puts it in the cache directory ready for execution.
[Note: I'm 99% sure this will work on most webserver configurations because the cache directory that timthumb uses is a subdirectory of directories that are allowed to execute files with a .php extension. So unless you explicitly tell your server to not execute .php files in the cache directory, it'll execute them. ]
Then you just access the file in the cache directory on the target site using your web browser and whatever code came from http://blogger.com.somebadhackersite.com/badscript.php will get executed by the web server.
In my case, this is what the hacker saw when he accessed my site:
It’s called Alucar shell and it’s a php file that contains one massive base64 encoded string that gets decoded and evalled. It’s encoded in an attempt to hide itself.
When you first hit the script it presents you with a login page and once you’re signed in you see the screenshot above. It works quite well actually. Even if the rest of your filesystem is secure, whoever is using it can dump read-only files like /etc/passwd to get a list of user accounts, config files which may contain passwords, etc..etc..
The current version of timthumb has this issue. Since it’s already in the wild and I just got hacked by it, I figure it’s ok to release the vulnerability to the general public.
To check if you have been hacked do the following:
- Sign into your server using ssh
- cd to your wordpress installation directory
- run “grep -r base64_decode *”
- You should see a few occurences but if any of them have a long encoded string between the parentheses, then you’re probably hacked.
The hacker used base64_decode in the file uploaded to the timthumb.php cache directory as well as where he injected code in my blog.
Also check your /tmp/ directory and if you have any suspicious files there like xwf.txt or any other .txt files, look at them in a text editor.
How to (possibly) fix this:
- Go into your theme directory and figure out where timthumb.php is.
- You might try “find /your/wordpress/dir/wp-content/themes/YourTheme/ -name “timthumb.php”"
- Edit timthumb and remove the list of external websites that content is allowed to be loaded from.
- I have not audited the rest of the code, so this may or may not make it secure.
- The developer really needs to use a regular expression to check the external hostnames images can be loaded from.
I would also recommend that if you’re a theme developer using timthumb.php, you check to see how it’s configured and try to load a php file from blogger.com.yoursite.com to see if you’re vulnerable.
REFERENCES
Subscribe to:
Posts (Atom)