如何演示二阶 SQL 注入?

Posted

技术标签:

【中文标题】如何演示二阶 SQL 注入?【英文标题】:How do I demonstrate a Second Order SQL Injection? 【发布时间】:2012-10-08 18:22:42 【问题描述】:

所以我一直在尝试复制二阶 SQL 注入。这是我准备的两个基于 php 的站点的示例模板。我们就叫它选民登记表吧。用户可以注册,然后您可以检查您是否是注册选民。

插入.php

<?php

$db_selected = mysql_select_db('canada',$conn);
if (!db_selected)
    die("can't use mysql: ". mysql_error());

$sql_statement = "INSERT into canada (UserID,FirstName,LastName,Age,State,Town)
                    values ('".mysql_real_escape_string($_REQUEST["UserID"])."',
                    '".mysql_real_escape_string($_REQUEST["FirstName"])."',
                    '".mysql_real_escape_string($_REQUEST["LastName"])."',
                    ".intval($_REQUEST["Age"]).",
                    '".mysql_real_escape_string($_REQUEST["State"])."',
                    '".mysql_real_escape_string($_REQUEST["Town"])."')";

echo "You ran the sql query=".$sql_statement."<br/>";
$qry = mysql_query($sql_statement,$conn) || die (mysql_error());
mysql_close($conn);
Echo "Data inserted successfully";

?>

select.php

<?php


$db_selected = mysql_select_db('canada', $conn);
if(!db_selected)
    die('Can\'t use mysql:' . mysql_error());
$sql = "SELECT * FROM canada WHERE UserID='".addslashes($_POST["UserID"])."'";
echo "You ran the sql query=".$sql."<br/>";
$result = mysql_query($sql,$conn);
$row=mysql_fetch_row($result);

$sql1 = "SELECT * FROM canada WHERE FirstName = '".$row[1]."'";
echo "The web application ran the sql query internally=" .$sql1. "<br/>";
$result1 = mysql_query($sql1, $conn);
$row1 = mysql_fetch_row($result1);

mysql_close($conn);
echo "<br><b><center>Database Output</center></b><br><br>";

echo "<br>$row1[1] $row1[2] , you are a voter! <br>";

echo "<b>VoterID: $row[0]</b><br>First Name: $row[1]<br>Last Name: $row[2]
    <br>Age: $row[3]<br>Town: $row[4]<br>State: $row[5]<br><hr><br>";

?>

所以我故意让这个漏洞来展示二阶 SQL 注入是如何工作的,用户可以在名字部分输入代码(我目前卡在这个部分,我尝试了很多不同的方法,但似乎我可以'不要让它做任何事情)。 那么当一个人想要激活他在名字部分插入的代码时,他只需输入用户ID,代码就会被插入。

例如: 我将在 insert.php 页面中键入: 用户 ID = 17

firstname =(我需要在这里注入一些东西)

姓氏 = ..

年龄 = ..

城镇 = ..

状态 = ..

然后当我检查我的详细信息并输入 17 时,注入的 SQL 脚本将被激活。 我可以举几个例子来说明我可以通过这个来展示什么样的漏洞?

【问题讨论】:

试试这个演示,如果您不理解或无法应用,请回复我们。 esecforte.com/blog/second-order-sql-injection 我基于该站点的示例。但这对我也不起作用,因为我无法让输出显示为该示例中的显示方式 【参考方案1】:

使用以下名字:

' OR 1 OR '

这会在第二条SQL中产生一个where子句

WHERE FirstName = '' OR 1 OR ''

因此结果将是表中的第一条记录。

通过添加 LIMIT 子句,您可以从表中提取所有行:

' OR 1 ORDER BY UserID ASC LIMIT 0, 1 --

显然它一次只会提取 1 行,因此您需要重复该操作并增加 LIMIT 中的 0。此示例使用注释 -- 来终止剩余的 SQL,否则会导致查询失败,因为它会在您的 LIMIT 之后添加一个单引号。

上面是一个简单的例子,更复杂的攻击是使用 UNION SELECT,它可以让你通过使用 information_schema 访问整个数据库。

您也在其中一个查询中使用addslashes()。这不如mysql_real_escape_string() 安全,反过来:使用任何一个转义引号不如使用准备好的语句或参数化查询安全,例如在 PDO 或 MySQLi 中。

【讨论】:

谢谢,这只是为了展示网站易受攻击的一面。我也一直在尝试删除该表,但它似乎不起作用。如何从名字部分将命令添加到“删除数据库/删除表”? 不能,因为mysql_query() 不支持多个查询,所以无法添加 DROP 查询。见:php.net/manual/en/function.mysql-query.php 好吧,因为它是一个 SELECT 查询,您只能提取数据,因为不支持多个查询,您不能 DROP、DELETE、UPDATE 或其他任何查询,除非原始查询是其中之一。 你能给我提供一个联合选择攻击如何发生的例子吗@MrCode 这更复杂,你需要了解 UNION 选择的工作原理,但这里有一个示例:***.com/questions/4600954/… Google 上也有大量示例【参考方案2】:

有什么要展示的?

二阶SQL注入无非就是SQL注入,但不安全的代码不是第一行。

所以,为了演示:

1) 创建一个 SQL 注入字符串,该字符串在执行时会执行一些不需要的操作而无需转义。

2) 将该字符串安全地存储在您的数据库中(带有转义)。

3) 让您的代码的其他部分获取该字符串,并在其他地方使用它而不转义。

编辑:添加了一些示例代码:

一张桌子:

CREATE TABLE tblUsers (
  userId serial PRIMARY KEY,
  firstName TEXT
)

假设你有一些这样的安全代码,从表单中接收名字:

$firstname = someEscapeFunction($_POST["firstname"]);

$SQL = "INSERT INTO tblUsers (firstname) VALUES ('$firstname ');";
someConnection->execute($SQL);

到目前为止,一切都很好,假设 someEscapeFunction() 做得很好。无法注入 SQL。

如果我将以下行作为 firstname 的值发送,您不会介意:

bla');从 tblUsers 中删除; //

现在,假设同一系统上的某个人想要将 firstName 从 tblUsers 传输到 tblWhatever,然后这样做:

$userid = 42;
$SQL = "SELECT firstname FROM tblUsers WHERE (userId=$userid)";
$RS = con->fetchAll($SQL);
$firstName = $RS[0]["firstName"];

然后将其插入到 tblWhatever 中而不转义:

$SQL = "INSERT INTO tblWhatever (firstName) VALUES ('$firstName');";

现在,如果 firstname 包含一些删除命令,它仍然会被执行。

【讨论】:

这就是问题所在..我不确定如何存储和获取该代码。单个示例,例如在数据库中存储重复条目或任何内容。更复杂的事情,比如通过单击命令获取数据库条目? 我添加了一个更具体的例子。

以上是关于如何演示二阶 SQL 注入?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不使用 PDO 或 PHP 应用程序绑定的情况下解决二阶 SQL 注入

二阶SQL注入理解与体会

PHP网站中的安全策略:SQL注入、XSS攻击和二阶SQL注入

第九届极客大挑战——小帅的广告(二阶sql注入)

二阶注入

sqli-labs(24)