Hacking Stoyan and the Importance of Web Security

Posted: December 22, 2009 at 2:56 pm

(I found a security vulnerability in some code that Stoyan recently released. I worked with Stoyan to resolve the issue. Nothing in this post still works. Usually stuff like this happens all the time and is never made public. Stoyan has very graciously allowed me to discuss the issue publicly so others can learn and avoid the same mistake. Thank you Stoyan. You Rock.)

Yesterday Stoyan released an alpha version of a cool tool he wrote, chuckview.php, which helps people visualize how web pages are delivered to the client. There is an excellent article to go with the tool and everyone should read it.

But this post isn’t about chunked encoding. This post is about how trivial mistakes in web applications can have serious consequences.

Under normal operation chunkview.php looks like this (click for larger view):

Now, I’m a very curious person. I want to know how things work. Nothing makes me happier than to poke and tinker with technology (not necessarily my own) and see what happens. So about 3 seconds after looking at this tool I thought “what happens if I don’t give it a URL?” So I typed “> into the textbox and clicked enter. Here is what came back (click for larger view):

Now this is getting interesting! I get some PHP errors! This starts to answer some questions about the how the application functions:

  • What: Stoyan is using PHP to fetch the URL the user supplies, parse the contents, and display the contents to the user.
  • How: Stoyan is using fopen() to fetch the contents of the URL. It also appears that PHP magic quotes is in use because while I input the string “> the application tried to open \”>.
  • Where: I have the absolute file system path of the PHP file. This tells me where the files are, as well as the username of Stoyan’s account, w3clubs.

So what can we do? Well, Stoyan has essentially created a “view this resource” application. He intended for the application to be used to view the contents of HTTP responses. However he is using fopen() to read the contents of the URL. fopen() can also access files on Stoyan’s web server. It is possible that Stoyan actually created a “view any file on this computer or any remote URL” application!

Let’s test this theory. We are going to try to use chunkview.php to view the source code of chunkview.php! I typed chunkview.php into the textbox and hit enter. Here is what I got (click for larger view):

Well that did not work. PHP gives us a nice error message telling us it could not find the file chunkview.php. Hmmm. Perhaps there is a problem resolving the path. Maybe if I input the absolute path and filename for chunkview.php we will be able to read the file. I typed /home/w3clubs/public_html/tools.w3clubs.com/chunkview/chunkview.php into the textbox and hit enter. Here is what I got (click for larger view):

Awesome! I am now looking at the source code for chunkview.php! I can also immediately see Stoyan’s mistake. It’s the line fopen($_GET['q']). He is passing input from an untrusted source (i.e. me) directly to a command that opens a file! This is known as a Local File Inclusion Vulnerability. (If this sounds familiar it should. We talked about how PHP scripts that combine multiple CSS or JavaScript files at runtime often contain Local File Inclusion vulnerabilities in The Challenge of Dynamically Generating Static Content post.)

From Vulnerability to Compromise

So what can an attacker actually do with this? So far all we have found is a toe hold. We have a way to read any file on the disk. But reading files != a hacked web server. At least not yet. I will now guide you through what an attacker would do to take this seemly small bit of unintended program behavior and leverage it into a compromised system. You should never never never do what I am about to describe. It is a crime.

The first thing I do is get a list of users that have accounts on the computer. That way an option we have would be to brute force their passwords and gain access to their account. We can see a list of users on the system by reading the contents of /etc/passwd.

Ok, we see a lot of these accounts don’t have shell access (because their login shells are set to /sbin/nologin). But we do know the name of an important account though that is probably used quite a bit: w3clubs! Let’s fetch the .bash_history file for this account, which should give us all the commands Stoyan has run on the system. We will view the source of the “web” page chunkview.php returns to see the contents of .bash_history file more clearly.

That much better. Notice the scroll bar. We have captured a list of approximately 1000 commands that Stoyan has run on this machine. I gain lots of valuable information by scrolling through the command history list:

  • He accesses several different MySQL databases. I know the database names and the user accounts to access them.
  • I see he is using WordPress on the box. I know where his wp-admin directory is and the names of all configuration files.
  • He has SSHed or SCPed into different boxes. I know the hostnames and the usernames he has used. Any passwords I find on this box I will use to try and break into more computers.

(Everything from here on I did not actually do. As soon as I confirmed the security issue existed I immediately stopped probing and contacted Stoyan to help him fix the vulnerability. Again, don’t ever ever ever do any of this!)

The next thing I would do is start fetching important files from his system. I grab his Apache configuration file, his raw MySQL databases, his PHP configuration file, his WordPress configuration files and plug-ins, his SSH keys, etc. I download the source every PHP file I know about on the system looking for any file that allows me to either upload a file or execute arbitrary PHP code. My goal is to find a username and password, or some way of getting a file or content from me onto the system.

An easy target is WordPress. The web-based administration portal has exactly the functionality I need. Gaining access to it is not very difficult given that I can read all his configuration files and the WordPress database. Let’s assume I leverage all this information and can login to Stoyan’s WordPress admin panel. Now what? I use the Editor feature in admin panel for WordPress and add a back door. This is fair simpler than it sounds. By including a bit of PHP code like system($_GET["command"], $blah) I can run any command I want to on Stoyan’s computer by passing it to his WordPress application through a query string. I can use this back door to upload files onto Stoyan’s web server (by running a command like wget to fetch it) and also use the backdoor to unzip, or untar, or execute what I upload.

Pwn3d

At this point it’s game over.

I can upload and execute arbitrary programs onto Stoyan’s computer. I can modify his web site. What I do now depends on my goals. I might modify his website to serve malware to 1 out of every 1000 visitors . I might create a hidden directory and use his computer to serve porn or stolen software. I might do nothing and simply use his computer as a platform to launch attacks against other systems.

Conclusions

You should never take user supplied data and just blindly use it. User supplied data means anything that comes from the user: query string values, POST data, Cookies, uploaded images or other files, and even HTTP headers like User-Agent or Referer (sic). Before you use any input you must validate it using whitelist input validation! In this case Stoyan and I fixed the issue by validating that URLs must start with http:// or https://. If you want to know more about Web Security I suggest these resources:

The point of this is not to publicly beat Stoyan. (thanks again for being a good sport Stoyan!) He’s a bright guy who has done amazing work in the web performance field. The point of this post is to show how a trivial mistake can lead to a complete failure and how easy it is for even smart people like Stoyan to make trivial mistakes. Please make sure you are validating all input in your web applications! It does not matter if you application is performant or not if the application is insecure.

Performance Questions to Ask Hosting Providers: Secure Website Access

Posted: December 14, 2009 at 3:06 pm

(This is the third article in a series of articles about performance questions you should ask when choosing a hosting provider. The first article, “What control do I have over the web server?” and the second article “What access do you provide to web server logs?” are also available.)

So far in this series we have talked a lot about questions to ask hosting providers to make sure you can configure your website for performance and access the raw traffic logs of your website to spot performance problems. All of this is moot of course if you cannot get content onto your website. That’s why this post of “Questions to ask a hosting provider” is all about:

“Can I Securely Communicate With My Website?”

ethernet-locked

It has happened to everyone. You are out at a coffee shop, a client site, or at a conference and you need to make changes to your website. Perhaps you need to upload a few new PHP files or some images. Perhaps you need to update your web server configuration to set up a new email address for an event. Perhaps you simply saw something cool and want to write a WordPress post. But can you do anything of these things securely using a public network? This question is best answered with an analogy.

Imagine you are at a formal cocktail party. You drift from room to room, through a sea of lavishly dressed party goers and dine on mouth-watering morsels served on silver trays by waiters in white gloves. As you approach a side table of crystal champagne glasses you overhear bits and pieces of the conversations around you.

  • “We cannot wait. It should be a lovely vacation and it’s the perfect time for us to get away for a week.”
  • “That’s right, with the nanny! Walked right in on them! And he tried to say that she was only choking!”
  • “Chris starts there next spring, just like his father.”

Well attended cocktail parties are loud and noisy. Its almost impossible not to hear what everyone else is saying! Of course we are taught that to be polite we should ignore the conversations other people are having unless we are involved. You are on the honor system not to eavesdrop.

Public networks such as wireless networks are just like cocktail parties. Your wireless card is like a party guest. It broadcasts out to the room when it “speaks” and “listens” to everyone within range to hear a response. Like a real party guest, wireless cards are supposed to ignore any conversations that they overhear that is not meant for them. They do this by dropping the data and not bubbling it up to the computer. However nothing forces network devices to ignore data they receive that is not meant for them. In fact, all networking devices (not just wireless devices) can be placed into “Promiscuous Mode” where any data they receive, even data that is not addressed to themselves, is received and bubbled up to the computer to process. This allows any networking device to become a giant listening device that hears and records all the information on the network! Promiscuous mode is not some evil hacker trick. It’s a fully intended feature of networking devices that has many legitimate uses.

Diagram showing how clients in a wireless network hear each others' traffic

But wait! I use Encryption!

“The conference wireless network or the coffee shops wireless network is encrypted. They tell me they use something called WPA2 with a key of a million bits! I’m secure right?”

No, you are not secure.

Let’s go back to the cocktail party analogy. The hosts don’t want just anyone coming into their party and drinking all their fine wines. So they place a bouncer at the door of the party. Only people that know the password are allowed into the party. If you know the password you get into the party and can listen to all the other guests. If you do not know the password you remain outside the building and cannot hear anything that is going on inside.

Encrypted wireless networks are just cocktail parties with bouncers. You need the “password” to join the wireless network. Once you are connected you can listen to everyone else’s traffic just like before because on the network everyone is using the same password to transmit and receive their data. (This is the only scalable solution. Otherwise the wireless network administrator would have to create a new, unique password for each and every person that joins the network). In other words, an encrypted network uses the password solely to protect and restrict “access” to the network. It does nothing to protect the users of the network from themselves or from each other.

The Danger of Sniffing (packets)

So What! Who cares if someone can listen to my network traffic. It’s not a big deal. After all they will just see the blog content I was about to post anyway. Unfortunately this is not true. Using any system that requires a username and a password on a wireless network? You may have shouted to the entire cocktail party that username and password. And chances are you use that same username and password somewhere else on the Internet. Like your bank. Or an online store. Are you already logged into a system like Gmail or your WordPress administration panel? You are shouting your HTTP Cookies to the entire cocktail party. Someone can steal your HTTP session cookies and use session hijacking to access Gmail or WordPress as if they were you without needing your username and password. Next thing you know you are on The Wall Of Sheep!

Secure Communications With Your Website

Remember: network encryption protects networks and application encryption protects applications! You need to make sure you are using encrypted application protocols to properly protect yourself. What protocols you use and how you use them will vary with different use cases.

Uploading Content

How do you upload content to your website? If the answer is FTP you are in trouble. FTP sends usernames and passwords in the clear. You need an encrypted file transfer mechanism like SFTP or SCP. If you have shell access to your web server using SSH you also have the ability to use either SFTP or SCP as they are simply subsets of the functionality of SSH. By default most hosting companies provide an insecure file transfer system like FTP. Ask if they provide (for free) a secure file transfer system like SFTP or SCP. Make sure they understand you don’t need full SSH functionality and are only interested in secure file transfer. If this is not available you might need to upgrade your account or purchase an add-on to get SSH access for your website.

Writing Content

Do you use a web interface to write content for your blog platform or CMS system? Does it use SSL? Check the address bar. Does it start with https? If not you are not using SSL. Do you write your content using other software? Does that software directly publish the content to your blog using a web API like RSD or XMLRPC? Does that use SSL? Check the settings and see if you are using “https” to access the API interface. If you are not using SSL to communicate with these web resources then anyone can capture your username and password or cookies (which are just as good as your username and password).

Website Administration

How do you administer your website? Do you use a web interface like cPanel? These web administration interfaces are most common in shared hosting environments and typically run on a different hostname or an odd port number. Ask the hosting provider if they offer SSL access to the interface. Hosting providers often get confused and think you want to create an SSL certificate for your website. While this would secure a CMS you configure like WordPress (see previous use case) it does not help you secure the web administration interface because that is often running on a separate system. Make sure they understand you want secure access to their interface, not your website. This discussion may take several emails back and forth but most hosting providers are willing to supply SSL access to cPanel or other administration interfaces.

Summary

In conclusion, the questions about secure communications you should ask your hosting provider are:

  • “Do you provide a secure file transfer mechanism like SFTP or SCP? Is it provided for free or is it extra? If you don’t do you offer SSH access to the web server? Is it free?”
  • “If you provide a web-based website administration interface like cPanel do you provide access to it using SSL?”
  • “Do you provide an SSL certificate for my CMS? What is the cost?”

How to judge their answers will vary from person to person based on need. Personally, a secure file transfer mechanism is a requirement. Too many times have I needed to upload a presentation, PDF, or file to my website from a public network at a conference or client site. If you have a heavy blogger secure access to your content management system is going to be critical. After all, it is difficult to write a blog post about an event from the event if you cannot securely access your blog to write the post!