Web Hacking Lesson 6 - Arbitrary Code Execution Vulnerabilities

30 November -0001

Arbitrary Code Execution Vulnerabilities

Note: If you haven't read Lesson 1 go check it out first for test application install instructions.

This type of vulnerability is extremely dangerous. Unsafely written PHP that utilizes system calls and user input could allow an attacker to run an arbitrary command on the filesystem. This attack bears many resemblances to SQL injection in that the attacker manipulates input to cause execution of unintended commands. This vulnerability shows up in many forms, so utmost care should be used whenever using one of PHP's many filesystem call functions (such as system(), exec(), passthru(), shell_exec(), etc.)

In our test application there exists a very simple function that is implemented in a completely insecure way. The functionality is designed to allow a site administrator to list the contents of the images directory. This functionality is fairly straightforward but suffers from numerous vulnerabilities. The first flaw is that the functionality is accessible via file include to an unauthorized user. The second is that the functionality utilizes GET variables to determine it's function. By design the following link code should be available whenever an administrator logs in:

echo "<p><a href='index.php?page=list_images.php&cmd=ls -lah images/'>List Images</a></p>";

As you can see this link uses the same page include that we've seen before. It includes the page 'list_images.php' that actually includes the code:

<?php
	echo "<pre>";
	system($_GET['cmd']);
	echo "<pre>";
?>

Which, in theory should run the command 'ls -lah images/' on the filesystem shell if the link is utilized. Of course we can manipulate this command to do pretty much anything we'd like. Let's start by simply listing the application directory structure by going to the URL:

/index.php?page=list_images.php&cmd=ls%20-lah

As you can see we can view the structure of the files as well as their permissions. Now lets take the attack one step further. PHP variables such as database connection strings are often included inside PHP files, so that under normal circumstances they cannot be read via the web. Let's try the following URL which should expose these connection strings:

/index.php?page=list_images.php&cmd=cat%20header.php

You'll have to view the page source in order to see the connection information, but you should be able to spot the MySQL username and password are clearly displayed.

Using this command injection we can run any command we like, with the privileges of the web server. We can browse directories, we can download new files using 'wget' or 'curl', create new application directories, delete files, and all sorts of mischief using this vulnerability.

Preventing Code Execution Vulnerabilities

It is never advisable to utilize user supplied input for system calls. In cases where it is absolutely necessary it is vital to sanitize user input whenever passing values to system calls. Any application that utilizes system calls should be suspect, as it is a good indicator that the web application is attempting to do something for which another solution is probably more appropriate. If user input is allowed to be passed to system calls it should be strictly controlled and limited to a predefined set of values.