Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

I've found a whole lot of SQL injection exploits in some systems I maintain. I know how to prevent the injection, but I would like to demonstrate to my CEO and CTO how dangerous it is if we don't have enough focus on keeping our applications safe.

Many times we need to react instead of proact when it comes to security, mainly because when a vulnerability is found it is not prioritized to be fixed because its unlikely to be exploited.

The following query is one of these examples. The server is running with PHP_MAGIC_QUOTES ON (yes I know thats really bad) and thus prevent exploits several places because the programmers have explicitly added ' ' around everyone input value used in queries (so you cant break out of it). The query I've found vulnerable now is however threated as a integer instead of string, and contains no ' ' around it.

Here is the example:

$sql = "select * from vulnerable_table where id = " . $_GET['id'] . " limit 1"; 
$result= mysql_query($sql); 

How would you do max damage to the system considering you control the id variable.

Some examples I've come up with on my own:

id = 1;drop table mysql.user 
Only if semi colon is accepted

id = 1;SELECT '<?php exec($_get['cmd'])?>' INTO OUT_FILE('/var/www/backdoor.php')
Only if I could bypass the magic_quotes somehow
share|improve this question
2  
Don't forget to your own query and comment out the rest (so append ;-- ). –  Eugen Constantin Dinca Dec 21 '10 at 19:00
4  
Don't forget you CAN'T do multiple query with mysql_query. I see upvoted answer where people suggest thing that uses multiple query. –  HoLyVieR Dec 22 '10 at 4:44
1  
And for the sake of completeness - the syntax of last query is not correct. It should be [...] INTO OUTFILE 'blah' [...]. –  anonymous Dec 22 '10 at 12:54

7 Answers 7

up vote 17 down vote accepted

In PHP you cannot stack querys with a semicolon. However you can nest a query into another with parentheses (commonly called subqueries), e.g.:

SELECT * FROM vulnerable_table WHERE id = (SELECT number from other_table)

Using this technique (disregarding whether you output your SQL result or not) a keen attacker may extract all data from your database.

Example (with output on the web page)

SELECT * FROM vulnerable_table WHERE id = (SELECT group_concat(table_name) from information_schema.tables WHERE version = 10)

This query will result in a list (as a string) of all user-defined tables in your database. Further queries will reveal the columns and let the adversary gain full knowledge of your table structure (for example: "tbl_accounts, tbl_passwords, tbl_guestbook").

If you don't give any output on your web page an attacker might still inject a conditional (think: case-when) statement with his SQL subquery, which will result in an SQL error in one case and no error in the other case. Deriving from "no output at all" and your normal webpage you can gather 1 Bit of information and perform a binary search through your database.

Generating strings in an SQL query like the one you suggested to upload a PHP-Backdoor (depending on whether the current MySQL user has the FILE privilege, which he shouldnt ;)) is also not that hard to come by: Using the ascii(), and ord() functions you can just create your strings with integer inputs. Also a value like 0x414141 will automatically converted to 'AAA' in MySQL.

Regarding very advanced attack and filter evasion techniques I also recommend you to read Reiners' blog on SQL security: http://websec.wordpress.com/

For completeness's sake: To fix this vulnerability, you can just perform a typecast and transform $_GET['id'] to an integer.

share|improve this answer
    
Thank you for a very good answer! –  Chris Andrè Dale Dec 22 '10 at 11:47
2  
First statement is not correct - you can do stacked queries in PHP. You just need to use mysqli_multi_query(); - php.net/manual/en/mysqli.multi-query.php –  anonymous Dec 22 '10 at 12:49

Here is possible information extraction (like files reading or database user information extraction) and server resources consumption. First is achievable by using UNION statement in query. Second is done by using BENCHMARK() function. Data extraction is also possible by the use of mentioned function.

I don't want to show examples here - they are all over the internet. And I suppose, as system maintainer you're able to reproduce cases. If you really need them, comment.

By the way, you don't need semi colon to be supported to be able to write to files (access to write to file is needed, though).

share|improve this answer

I think this cartoon says it all. Little Bobby Tables

share|improve this answer
1  
I love the Little Bobby Tables cartoon! +1!! –  Matt Dec 21 '10 at 18:48
4  
+1 xkcd rocks. But I also love this - cache.gawkerassets.com/assets/images/4/2010/03/… –  Rory Alsop Dec 21 '10 at 23:07
    
awesome!!!!! - wonderful image –  Dave Dec 21 '10 at 23:12
2  
That wouldn't work at all because mysql_query doesn't allow multiple query. It would just throw a synthax error in the query. –  HoLyVieR Dec 22 '10 at 4:42

id =

0 OR id <> 0

would bypass the use of ID completely, and the hacker could then dump the whole table.

share|improve this answer

If the site is Drupal, they could alter the password for user 1 in the user table to provide them administrative access, and do some more targeted damage later on since they now have the ability to explore the site with admin privs.

share|improve this answer

If your company is in any way a part of regulations requiring security (like SOX or HIPPA in the US) or trade standards (like PCI or various ISO standards), all you have to do is tell them that:

  • you've found holes that could let anyone download the entire database and network (stretch the truth a bit if you have to sell it, and remind them of the ACS:Law leak).
  • give them hard numbers about how much time and money it cost other companies that lost data or got hacked.
  • that if you're ever audited, the company can be fined or dropped for not complying to standards.
  • that if you're ever sued or prosecuted, and there is any evidence whatsoever that you ignored a known or major potential problem, punitive damages could be enough to drive the company into bankruptcy. (See the Ford Pinto lawsuit.)

This will work better if you can talk the company lawyer into delivering the bad news. If that doesn't work, there's nothing that can save your company.

Whatever you do, forget exploiting the vuln yourself. You open yourself up to lawsuits and jail time if you do that without written permission, though a little evidence that shows it working on a test account you specifically set up for the purpose might work.

share|improve this answer

Maximum damage is relative. Discretely inserting small hard to detect data on an on-going basis can potentially be much more devastating than destroying large amounts of data in one shot.

A yet potentially worse situation may be merely reading the data over months/years. How many credit card numbers do you store in that database? Passwords?

Nobody can show you the silver bullet of SQL injection. It depends on the data you're keeping, the skill of the attacker, wether they have inside knowledge, the architecture of the schema, etc.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.