简体   繁体   中英

SQL injection that retrieves all data in a different table that the one in the query

I own a PHP system that works on a virtual server "Wamp" on windows XP. I am trying to detect the vulnerabilities in my system using SQL injection technique.

I have tried the basic ways of injection such as " ' OR 1=1 " and I detected several problems. However, I am stuck on the following issue:

I have the following line of code in my system:

$sql2="SELECT * FROM $table1 WHERE question_id='$id'";

After this line of code, I execute the query and display the result like this:

$result2=mysql_query($sql2);

while($rows=mysql_fetch_array($result2)){
?>
<table width="400" border="0" align="center" cellpadding="0" cellspacing="1" bgcolor="#CCCCCC">
<tr>
<td><table width="100%" border="0" cellpadding="3" cellspacing="1" bgcolor="#FFFFFF">
<tr>
<td bgcolor="#F8F7F1"><strong>ID</strong></td>
<td bgcolor="#F8F7F1">:</td>
<td bgcolor="#F8F7F1"><?php echo $rows['a_id']; ?></td>
</tr>
<tr>
.......
.......

Note that the value of the variable "$id" is sent from the previous page as _GET[] parameter.

My problem is, I am trying to inject the parameter id=2? (2 is an example) that is being sent from the previous page. Here's an example:

http://localhost/PHPforum/view_topic.php?id=2

I am looking for a way to inject the value of the variable "$id" in order to make it display the data of different table (table2) instead of table1. It's fine that I display both tables but I need table2 data to be displayed by that injection.

How can I possibly do that?

Again, I am not trying to attack any system, It's a system that I own and I am trying to detect its vulnerabilities.

From the mere proof of concept of the SQL injection vulnerability, you would first identify the context the injection happens in. Although in most cases the injection is in the WHERE clause, there are also other possible positions.

Next you would try to identify the number of columns that are selected. Since this is MySQL, you can use ORDER BY x and specify the number of the column you want the results to be ordered by. So start of with 2' ORDER BY 1 -- , 2' ORDER BY 2 -- , until one fails.

Then you can join the original result set with another one that you injected with UNION SELECT like this:

' UNION SELECT 1, 2, 3, …, n --

This is just a simple test and only the injected result set should show up. The numbers give you a hint which values are reflected where. From here on you can select any other value from other tables, views, or other data sources. A good hint for what information is worthy can give you pentestmonkey's MySQL SQL Injection Cheat Sheet .

The usual way is to use UNION to combine the results from two different queries. You might have to play around a bit to get the correct number of columns and charsets to allow the query to go through.

There are several good cheat sheets on the web for SQL injection that you can use as a reference for attack vectors.

You should really consider using a library that allows you to use parameterized queries (such as prepared statements) for querying the database instead of building (and escaping) the queries yourself. PDO and mysqli are both available for PHP and will allow prepared statements.

This works technically, but the application logic will probably not show the values of a different table:

http://localhost/PHPforum/view_topic.php?id=2;select * from table2

If you know all the table names and field names, you could do:

http://localhost/PHPforum/view_topic.php?id=2;select table2id as table1id, table2value as table1value, .. from table2

You may have to urlencode the semicolon and the spaces so that it works.

SQL Injection vulnerabilities are actually not that difficult to find, IMHO.

The simple rule to obey is this:

Don't concatenate a user-supplied value into a string which is passed to the database for execution.

If you break this rule, ie concatenate a user-supplied value into a query string, you've created a SQL Injection vulnerability.

There are two ways around the problem:

  1. Use a library which allows you to bind parameter values into query strings. These libraries use API calls to pass parameter values to the database when queries are executed rather than concatenating the values into the statement that the database executes.

  2. Check all of your code to see where values concatenated into query strings are coming from.

I always choose approach 1, then I know I'm always safe.

You can continue with approach 2, but it's like trying to bail out a boat with a hole in it. The water will keep on coming in, or, in your case, the code will have to be examined for every change you make.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM