22

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 treated as an 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
3
  • 2
    Don't forget to your own query and comment out the rest (so append ;-- ). Dec 21, 2010 at 19:00
  • 5
    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, 2010 at 4:44
  • 2
    And for the sake of completeness - the syntax of last query is not correct. It should be [...] INTO OUTFILE 'blah' [...].
    – anonymous
    Dec 22, 2010 at 12:54

7 Answers 7

18

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.

1
11

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.

4

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).

3

I think this cartoon says it all. Little Bobby Tables

4
  • 1
    I love the Little Bobby Tables cartoon! +1!!
    – Matt
    Dec 21, 2010 at 18:48
  • 4
    +1 xkcd rocks. But I also love this - cache.gawkerassets.com/assets/images/4/2010/03/…
    – Rory Alsop
    Dec 21, 2010 at 23:07
  • awesome!!!!! - wonderful image
    – Dave
    Dec 21, 2010 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, 2010 at 4:42
2

id =

0 OR id <> 0

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

2

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.

0

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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