The Potency of SQL Injection – A Technical Perspective
16 Aug 2010 by Pingu
Most web developers know that they should sanitize their web input. However recent figures from the UK Security Breach Investigations Report 2010 indicate that 40 per cent of all website attacks are due to SQL injections.
SQL injection attacks allow perpetrators to leak data, usually by making a web application perform a query it wasn’t intended to do. However, what most fail to realize is under the right conditions SQL injection attacks can be much more potent than data exposure (which is a serious breach in itself). A well crafted attack has the potential to subvert your entire system where circumstances allow.
To begin, let’s discuss what the SQL injection attack is, and how it works.
A Basic Example
We shall take a PHP MySQL query and consider the problem with it.
mysql_query("SELECT id,username,password FROM user_table \
WHERE username="'.$_GET['username']."');
So when a user executes a query genuinely, the variable will typically be replaced and the query such, I.E:
mysql_query("SELECT id,username,password FROM user_table WHERE username='matthew'");
The problem arises however when the data input contains characters which are meaningful in an SQL statement. Consider for example logging in with the username ma’tthew (note the intentional quotes in the middle of the username). When we do the variable expansion the query ends up appearing as:
mysql_query("SELECT id,username,password FROM user_table WHERE username='ma'tthew";
When you run this, the query is invalid SQL because the entire statement is syntactically incorrect. What has happened is the attacker has altered the behaviour of the SQL statement – actually gaining control of it. This allows the attacker to continue the statement altering to fetch data that is normally not permitted by the original statement.
This kind of attack is well known by web developers. Unfortunately for system administrators and web developers alike the problem doesn’t stop here. If the privileges that have been set by the system/database administrator are too lax it’s possible to reap data right off the disk and worse still, deploy arbitrary data onto the disk.
The Worst Case Scenario
mysql> desc data; +-------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | info | varchar(32) | YES | | Nothing | | +-------+-------------+------+-----+---------+----------------+ 2 rows in set (0.00 sec)
The webpage used is PHP written as follows:
<?php
mysql_connect('localhost','root','xxxxxx') or die(mysql_error());
mysql_select_db('mywebapp') or die(mysql_error());
echo "<table>\n";
echo "<tr><td>ID</td><td>Info</td></tr>\n";
if (isset($_GET['search'])) {
$r = mysql_query("SELECT * from data where info like '".$_GET['search']."'") \
or die(mysql_error());
echo "SELECT * from data where info like '".$_GET['search']."'";
else {
$r = mysql_query("SELECT * from data") or die(mysql_error());
}
while ($row = mysql_fetch_array($r, MYSQL_NUM)) {
echo "<tr><td>$row[0]</td><td>$row[1]</td></tr>\n";
}
echo "</table>";
?>
<form name="test">
Search: <input type=text name=search value=""><br/>
<input type="submit"/>
</form>
However, the developer also has also run “chmod 777” on a directory called “images” which is used for another part of the website. This is a common work-around used to avoid permission problems when creating files, by allowing anyone to create files.
The SQL injection vulnerability occurs on line 9. Because the input is not sanitized, the user can perform a fake search and take control of the SQL. The attacker, having already tried standard SQL injection techniques has seen little data of interest remains on the databases. Rather than find the other databases, the attacker wants to spawn a shell. But, can this be done from within mysql?
The answer is, yes of course it can. This is because the db user has the FILE privilege set that means he can read files in and write files out. The attacker needs to know where the document root is for the website. It’s not outright retrievable from SQL but it is readable in the httpd.conf.
By utilizing the LOAD_FILE privilege and UNION selecting it out, the attacker can add it to the existing table to read the total contents of the file! It’s not a pretty read but thats not relevent. By exploiting the FILE privilege the attacker has obtained a means to get the sites document root.
Armed with this infomation, we can look at the design/layout/source code (again, with more LOAD_FILE tricks it’s possible to determine the most likely place that has a globally writable directory). For example an images/avatar folder for perhaps, joomla, if the site was written as such would be a great target. Because there is a tendency to make folders world-writable when they cannot be normally written to, the attacker can exploit this weakness to deploy a new file within the sites’ document root through mysql. Normally an attacker wants to deploy PHP code into the document root because it will execute. Since it contains lots of meta-characters the attacker typically translates the actual code he wants to use into hexadecimal output. Using the INTO OUTFILE syntax in MySQL he can dump the contents of said file right into his target directory. In this example I will be using simple PHP code that generates “hello world” when the page visits.
The image illustrates what’s happened here. The attacker has injected his own custom string and dumped it into an outfile that’s globally writable and present in the document root of an existing website. Now all that’s left is to visit the file you wrote. The big issue with this type of attack is that it will subvert any coding you might put in place, typically in uploads, to prevent php files being written into sensitive areas on disk.
In Conclusion
The potency of SQL injection and commonness of not sanitizing input is a real threat to system security over and above what’s contained inside of your database. A series of failures have to be reached to get to a point like the one demonstrated above. These failures may include: not enforcing least privileges on database users, not sanitizing all input that comes from a untrusted source, lax file permissions in directories and no defensive layers in sensitive directories.
The trouble is, it’s incredibly simple for a web developer to overlook the sanitization of input, especially with the tight deadlines and rapid application development process that is typical. Not only this but the general consensus to use vulnerable libraries to connect to mysql make such situations common and a concern. Most people are unaware that it’s possible to convert a data leakage vulnerability into a system compromize which can mean IT managers dont give SQL injection threats the priority they deserve in the development process.
Fixing the Situation
There are many ways to fix SQL injection:
- Sanitize your input!
- Use MySQLi or another modern SQL library that supports prepared (or pseudo prepared) SQL satements.
- Use the setfacl command to give apache only access to directories that are meant to be writable by it.
- Deploy .htaccess files into sensitive folders (like uploads) to whitelist what files should be accessible in the folder, so image folders should only allow access to jpg, png and gif for example.
- Dont give FILE privileges to DB users if they dont need it.
- Use SELinux as a last line of defense (its not possible for mysql to write to http content in SELinux).
Such exploits are the result of lax security measures and poor coding and can undermine the confidence of visitors to your site. There’s no need to be victim to the most common form of web attack.
No related posts.
