LIMIT 可以进行 SQL 注入吗?

信息安全 Web应用程序 sql注入 mysql
2021-09-04 18:32:23

我的一个朋友构建了一个 Web 应用程序,我正在测试它以获得乐趣。我注意到他允许用户设置某个查询的限制,并且该限制没有被清理。

例如,我可以选择任何我喜欢的数字或字符串作为限制。我意识到这是SQL 注入,我可以很容易地注入 SQL 命令,但是真的有可能提取任何数据或对 a 造成任何损害LIMIT吗?

查询示例:

SELECT * FROM messages WHERE unread = 1 LIMIT **USER INPUT HERE**

我知道如果注入在WHERE子句中,我可以轻松地UNION SELECT提取任何信息,但如果用户输入超出限制,这真的可能吗?

有关更多信息,我的朋友正在使用MySQL DBMS,因此您无法真正执行两个查询,例如:

SELECT * FROM messages WHERE unread = 1 LIMIT 10;DROP TABLE messages-- 

这不可能。

4个回答

你可以在UNION SELECT这里做一个。唯一的问题是匹配消息中的列,但您可以通过添加列来猜测这些列,直到它适合:

SELECT * FROM messages WHERE unread = 1 LIMIT 
    1 UNION SELECT mail,password,1,1,1 FROM users

只需继续添加,1,直到获得正确的列数。此外,您需要匹配列类型。尝试null代替1.

如果您能看到 MySQL 错误,这将大有帮助。否则你有很多尝试。

有关详细信息,另请参阅owasp.org 上的 SQL 注入测试。

要么几乎没有限制,你可以按照通常的方式来做(UNION 或 '; XXX ---')

有时这是不可能的,你不得不在 LIMIT 中放置一个布尔表达式。这是一种盲目的 SQL 注入,它允许您一次转储整个数据库。

MySQL 确实支持多个语句,并且至少在十年前的 4.1 中就已经支持。例如,您可以在 Perl mysql 模块中使用mysql_multi_statements.

虽然客户端库现在可能不支持多个语句,但您只是远离安全漏洞的升级或配置更改。

设置限制1 UNION SELECT ...将允许攻击者从任何其他表中提取信息,只要列具有(或可能CAST具有)与第一个中的列相同的编号和类型SELECT将限制设置为从子生成的值SELECT将使攻击者从返回的行数中读取数据库中的任何其他信息。例如,可以通过重复执行子查询以不同的子字符串偏移量返回 0 到 15 之间的数字,然后计算每个结果中的行数,从而一次提取 4 位另一个用户的密码哈希。

但这两种攻击都可以被挫败。许多数据库驱动程序允许参数化LIMIT. 如果特定驱动程序干扰了参数化的LIMIT,您可以通过在将输入字符串替换为查询之前将输入转换为整数来清理输入。这也将帮助您确保返回的记录不会超过您的应用程序可以从一个查询(例如LIMIT 12345678)处理的记录。在 PHP 中,它可能看起来像这样:

<?php
//...
$limit = intval($_REQUEST['numresults']);
$limit = min(max($limit, 10), 100);
$stmt = $dbh->prepare("SELECT ... FROM ... WHERE ... LIMIT $limit");