SQL注入,它检索与查询中的数据不同的表中的所有数据

时间:2012-10-17 14:07:10

标签: php security sql-injection code-injection

我拥有一个可在Windows XP上运行虚拟服务器“Wamp”的PHP系统。我试图使用SQL注入技术检测我的系统中的漏洞。

我尝试了基本的注射方法,例如“'OR 1 = 1”,我发现了几个问题。但是,我坚持以下问题:

我的系统中有以下代码行:

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

在这行代码之后,我执行查询并显示如下结果:

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

请注意,变量“$ id”的值从上一页发送为_GET []参数。

我的问题是,我正在尝试注入参数id = 2? (2是一个例子)是从前一页发送的。这是一个例子:

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

我正在寻找一种方法来注入变量“$ id”的值,以使其显示不同表(table2)而不是table1的数据。我可以显示两个表,但我需要通过该注入显示table2数据。

我怎么可能这样做?

同样,我不是要攻击任何系统,它是我拥有的系统,我正在尝试检测其漏洞。

4 个答案:

答案 0 :(得分:2)

仅仅从SQL注入漏洞的概念证明,您将首先确定注入发生的上下文。虽然在大多数情况下注入在WHERE子句中,但也有其他可能的位置。 / p>

接下来,您将尝试确定所选列的数量。由于这是MySQL,您可以使用ORDER BY x并指定要对结果进行排序的列数。所以开始使用2' ORDER BY 1 --2' ORDER BY 2 --,直到失败。

然后你可以将原始结果集加入另一个注入了UNION SELECT的结果集:

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

这只是一个简单的测试,只显示注入的结果集。这些数字会给你一个提示,哪些值反映在哪里。从此处开始,您可以从其他表,视图或其他数据源中选择任何其他值。对于哪些信息值得提供的良好提示可以为您提供pentestmonkey’s MySQL SQL Injection Cheat Sheet

答案 1 :(得分:1)

通常的方法是使用UNION来合并来自两个不同查询的结果。您可能需要玩一下才能获得正确数量的列和字符集以允许查询通过。

网络上有几个用于SQL注入的好cheat sheets,您可以将其用作攻击媒介的参考。

您应该考虑使用允许您使用参数化查询(例如预准备语句)来查询数据库而不是自己构建(和转义)查询的库。 PDO和mysqli都可用于PHP,并允许使用预处理语句。

答案 2 :(得分:0)

这在技术上有效,但应用程序逻辑可能不会显示不同表的值:

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

如果你知道所有的表名和字段名,你可以这样做:

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

您可能需要对分号和空格进行urlencode以使其正常工作。

答案 3 :(得分:0)

SQL注入漏洞实际上并不难找到,恕我直言。

遵守的简单规则是:

不要将用户提供的值连接到传递给数据库执行的字符串中。

如果违反此规则,即将用户提供的值连接到查询字符串,则表明您已创建SQL注入漏洞。

解决问题的方法有两种:

  1. 使用允许您将参数值绑定到查询字符串的库。这些库使用API​​调用在执行查询时将参数值传递给数据库,而不是将值连接到数据库执行的语句中。

  2. 检查所有代码,以查看连接到查询字符串的值的来源。

  3. 我总是选择接近1,然后我知道我总是安全的。

    你可以继续进行方法2,但这就像试图拯救一个有洞的船。水将继续进入,或者,在您的情况下,必须检查代码,以便进行每次更改。