如何利用“PHP_MAGIC_QUOTES ON”漏洞造成最大伤害?

信息安全 php 开发 应用安全 sql注入 mysql
2021-08-15 12:31:33

我在我维护的一些系统中发现了大量的 SQL 注入漏洞。我知道如何防止注入,但我想向我的 CEO 和 CTO 证明,如果我们没有足够的注意力来保证我们的应用程序的安全,这是多么危险。

很多时候,当涉及到安全性时,我们需要做出反应而不是主动行动,主要是因为当发现漏洞时,不会优先修复它,因为它不太可能被利用。

以下查询是这些示例之一。服务器在 PHP_MAGIC_QUOTES ON 的情况下运行(是的,我知道那真的很糟糕),因此可以防止几个地方的漏洞利用,因为程序员已经在查询中使用的每个输入值周围显式添加了 ''(所以你无法摆脱它)。然而,我现在发现易受攻击的查询被视为整数而不是字符串,并且它周围不包含''。

这是示例:

$sql = "select * from vulnerable_table where id = " . $_GET['id'] . " limit 1"; 
$result= mysql_query($sql); 

考虑到您控制 id 变量,您将如何对系统造成最大损害。

我自己想出了一些例子:

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
4个回答

在 PHP 中,您不能使用分号堆叠查询。但是,您可以使用括号(通常称为子查询)将查询嵌套到另一个查询中,例如:

SELECT * FROM vulnerable_table WHERE id = (SELECT number from other_table)

使用这种技术(不管您是否输出 SQL 结果),敏锐的攻击者可能会从您的数据库中提取所有数据。

示例(网页上有输出)

SELECT * FROM vulnerable_table WHERE id = (SELECT group_concat(table_name) from information_schema.tables WHERE version = 10)

此查询将生成数据库中所有用户定义表的列表(作为字符串)。进一步的查询将显示列并让攻击者全面了解您的表结构(例如:“tbl_accounts、tbl_passwords、tbl_guestbook”)。

如果您不在网页上提供任何输出,攻击者可能仍会在其 SQL 子查询中注入条件(想想:case-when)语句,这在一种情况下会导致 SQL 错误,而在另一种情况下不会出错。从“根本没有输出”和您的正常网页派生,您可以收集 1 位信息并通过您的数据库执行二进制搜索。

在 SQL 查询中生成字符串,例如您建议上传 PHP-Backdoor 的字符串(取决于当前 MySQL 用户是否具有 FILE 权限,他不应该这样做;))也不是那么难:使用 ascii() , 和 ord() 函数,您可以使用整数输入创建字符串。此外,像 0x414141 这样的值将在 MySQL 中自动转换为“AAA”。

关于非常高级的攻击和过滤规避技术,我还建议您阅读 Reiners 的 SQL 安全博客:http ://websec.wordpress.com/

为了完整起见:要修复此漏洞,您只需执行类型转换并将 $_GET['id'] 转换为整数。

如果您的公司在任何方面都符合要求安全的法规(例如美国的 SOX 或 HIPPA)或贸易标准(例如 PCI 或各种 ISO 标准),您所要做的就是告诉他们:

  • 您发现了可以让任何人下载整个数据库和网络的漏洞(如果您必须出售它,请稍微扩大真相,并提醒他们 ACS:Law 泄漏)。
  • 向他们提供有关丢失数据或被黑客攻击的其他公司花费了多少时间和金钱的确切数字。
  • 如果你被审计过,公司可能会因不遵守标准而被罚款或撤销。
  • 如果您曾经被起诉或起诉,并且有任何证据表明您忽略了已知或重大的潜在问题,那么惩罚性赔偿可能足以使公司破产。(见福特平托诉讼。)

如果你能说服公司律师传达坏消息,这会更好。如果这不起作用,那么没有什么可以拯救您的公司。

不管你做什么,忘记自己利用漏洞。如果您在未经书面许可的情况下这样做,您将面临诉讼和入狱,尽管有一点证据表明它可以在您专门为此目的设置的测试帐户上工作。

这是可能的信息提取(如文件读取或数据库用户信息提取)和服务器资源消耗。首先可以通过在查询中使用 UNION 语句来实现。其次是通过使用 BENCHMARK() 函数完成的。通过使用上述功能也可以提取数据。

我不想在这里展示示例 - 它们遍布互联网。我想,作为系统维护者,您可以重现案例。如果您真的需要它们,请发表评论。

顺便说一句,您不需要支持分号来写入文件(尽管需要访问写入文件)。

我想这幅漫画说明了一切。小鲍比桌