MySQL注入 - 使用SELECT查询来更新/删除

问题描述 投票:7回答:4

我有一个简单的问题:说有一个网站的查询如下:

SELECT id, name, message FROM messages WHERE id = $_GET['q']

有没有办法在数据库(MySQL)中更新/删除某些内容?到目前为止,我从未见过能够使用SELECT查询删除/更新的注入,所以,它甚至可能吗?

mysql security select code-injection sql-delete
4个回答
6
投票

如果你说你使用不支持多个查询的mysql_query,你不能直接添加DELETE / UPDATE / INSERT,但在某些情况下可以修改数据。例如,假设您具有以下功能

DELIMITER //
CREATE DEFINER=`root`@`localhost` FUNCTION `testP`()
RETURNS int(11)
LANGUAGE SQL
NOT DETERMINISTIC
MODIFIES SQL DATA
SQL SECURITY DEFINER
COMMENT ''  
BEGIN      
  DELETE FROM test2;
  return 1;
END //

现在你可以在SELECT中调用这个函数: SELECT id, name, message FROM messages WHERE id = NULL OR testP()id = NULL - 总是NULL(FALSE),所以testP()总是被执行。


5
投票

在直接回答这个问题之前,值得注意的是,即使攻击者所能做到的只是读取他无法做到的数据,这通常仍然非常糟糕。考虑一下,通过在系统表(如JOIN)中使用SELECTs和mysql.innodb_table_statsing,以SELECT注入开头并且没有其他数据库知识的攻击者可以映射您的模式,然后渗透您在MySQL中拥有的全部数据。对于绝大多数数据库和应用程序来说,这已经成为灾难性的安全漏洞。

但是直接回答这个问题:我知道有几种方法可以用来修改MySQL SELECT来修改数据。幸运的是,它们都需要合理的特殊情况。下面的所有示例注入都是相对于问题的示例可注入查询给出的:

SELECT id, name, message FROM messages WHERE id = $_GET['q']

1.“堆叠”或“批量”查询。

经典的注入技术,只需在注入一个语句之后放入整个其他语句。正如在another answer here中所建议的那样,你可以将$_GET['q']设置为1; DELETE FROM users; --,以便查询形成两个连续执行的语句,第二个语句删除users表中的所有内容。

In mitigation

大多数MySQL连接器 - 特别是包括PHP(已弃用)mysql_*和(非弃用)mysqli_*函数 - 根本不支持堆栈或批处理查询,所以这种攻击只是简单的不起作用。但是,有些人 - 特别是包括PHP的PDO连接器(虽然支持can be disabled to increase security)。

2.利用用户定义的功能

可以从SELECT调用函数,并可以更改数据。如果在数据库中创建了数据更改函数,则可以让SELECT调用它,例如通过将0 OR SOME_FUNCTION_NAME()作为$_GET['q']的值传递。

In mitigation

大多数数据库不包含任何用户定义的函数 - 更不用说改变数据了 - 因此根本不提供执行此类漏洞利用的机会。

3.写入文件

如Muhaimin Dzulfakar(有点擅自命名)论文Advanced MySQL Exploitation所述,您可以在MySQL select上使用INTO OUTFILEINTO DUMPFILE子句将结果转储到文件中。因为,通过使用UNION,任何任意结果都可以被SELECTed,这允许在运行mysqld的用户可以访问的任何位置写入具有任意内容的新文件。可以想象,这不仅可以被利用来修改MySQL数据库中的数据,而且可以获得对运行它的服务器的shell访问 - 例如,通过将一个PHP脚本编写到webroot然后向它发出请求,如果MySQL服务器与PHP服务器共同托管。

In mitigation

许多因素降低了这种令人印象深刻的声音攻击的实际可利用性:

  • MySQL永远不会让你使用INTO OUTFILEINTO DUMPFILE来覆盖现有文件,也不会写入不存在的文件夹。这可以防止像在.ssh用户的主目录中创建带有私钥的mysql文件夹,然后在恶意版本中使用恶意版本覆盖或覆盖mysqld二进制文件并等待服务器重新启动等攻击。
  • 任何中途不错的安装包都会设置一个特殊用户(通常命名为mysql)来运行mysqld,并且只为该用户提供非常有限的权限。因此,它不应该能够写入文件系统上的大多数位置 - 当然也不应该像写入Web应用程序的webroot那样。
  • MySQL的现代安装默认设置为--secure-file-priv,防止MySQL写入指定数据导入/导出目录以外的任何地方,从而使这种攻击几乎完全无能为力......除非服务器的所有者故意禁用它。幸运的是,没有人会完全禁用这样的安全功能,因为那显然是 - oh wait never mind

4.从sys_exec()调用lib_mysqludf_sys函数来运行任意shell命令

有一个名为lib_mysqludf_sys的MySQL扩展 - 从其明星on GitHuba quick Stack Overflow search判断 - 至少有几百个用户。它添加了一个名为sys_exec的函数,它运行shell命令。如#2中所述,可以在SELECT中调用函数;这些影响有望显而易见。引用the source,这个功能“可能存在安全隐患”。

In mitigation

大多数系统没有安装此扩展。


2
投票

这取决于您使用的DBMS连接器。大部分时间你的场景都不可能,但在某些情况下它可以工作。有关详细信息,请查看Blackhat-Paper Advanced MySQL Exploitation的第4章和第5章。


-2
投票

是的,这是可能的。

$ _GET ['q']将持有1; DELETE FROM users; --

SELECT id, name, message FROM messages WHERE id = 1; DELETE FROM users; -- whatever here');
© www.soinside.com 2019 - 2024. All rights reserved.