Sim*_*mon 9 mysql security select code-injection sql-delete
我有一个简单的问题:说有一个网站的查询如下:
SELECT id, name, message FROM messages WHERE id = $_GET['q'].
有没有办法在数据库(MySQL)中更新/删除某些内容?到目前为止,我从未见过能够使用SELECT查询删除/更新的注入,所以,它甚至可能吗?
如果您说使用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 //
Run Code Online (Sandbox Code Playgroud)
现在,你可以调用这个函数SELECT:
SELECT id, name, message FROM messages WHERE id = NULL OR testP()
(id = NULL-总是NULL(FALSE),所以testP()总会被执行.
在直接回答问题之前,值得注意的是,即使攻击者只能做的事情就是读取他不应该读取的数据,但这通常仍然很糟糕。考虑到通过使用JOINs和SELECT从系统表(如mysql.innodb_table_stats)中查找ing ,攻击者从SELECT注入开始就没有数据库的其他知识就可以映射您的模式,然后泄露MySQL中的全部数据。对于绝大多数数据库和应用程序而言,这已经是灾难性的安全漏洞。
但是要直接回答这个问题:我知道有几种方法SELECT可以将注入MySQL的方式用于修改数据。幸运的是,它们都需要合理的异常情况。下面的所有示例注入都是相对于问题中的示例可注入查询给出的:
SELECT id, name, message FROM messages WHERE id = $_GET['q']
Run Code Online (Sandbox Code Playgroud)
经典的注入技术是在注入一个语句之后再添加一个完整的语句。如此处另一个答案所示,您可以设置$_GET['q']为,1; DELETE FROM users; --以便查询形成两个连续执行的语句,第二个语句删除users表中的所有内容。
大多数MySQL连接器-特别是包括PHP的(不推荐使用的)mysql_*和(不推荐使用的)mysqli_*函数-根本不支持堆叠查询或批处理查询,因此这种攻击根本不起作用。但是,确实有一些功能 -特别是包括PHP的PDO连接器(尽管可以禁用该支持以提高安全性)。
可以从调用函数SELECT,并且可以更改数据。如果已在数据库中创建了数据更改功能,则可以SELECT调用它,例如,将0 OR SOME_FUNCTION_NAME()的值作为传递$_GET['q']。
大多数数据库不包含任何用户定义的功能-更不用说更改数据的功能-因此完全没有机会进行这种利用。
如Muhaimin Dzulfakar的论文(有点叫作“ 高级MySQL漏洞利用”)所述,您可以在MySQL select上使用INTO OUTFILEor INTO DUMPFILE子句将结果转储到文件中。由于使用a UNION可以SELECT编辑任意结果,因此可以在运行用户mysqld可以访问的任何位置写入具有任意内容的新文件。可以想象,这不仅可以用来修改MySQL数据库中的数据,而且还可以通过Shell访问运行它的服务器-例如,通过将PHP脚本编写到webroot,然后向它发出请求,如果MySQL服务器与PHP服务器共同托管。
许多因素降低了这种令人印象深刻的攻击的实际可利用性:
INTO OUTFILE或INTO DUMPFILE覆盖现有文件,也不会写入不存在的文件夹。这样可以防止攻击,例如.ssh在mysql用户的主目录中创建带有私钥的文件夹,然后进行SSH加密,或者mysqld使用恶意版本覆盖二进制文件本身并等待服务器重启。mysql)来运行mysqld,并仅向该用户授予非常有限的权限。因此,它不应该能够写入文件系统上的大多数位置-并且当然不应该通常能够执行诸如写入Web应用程序的webroot的操作。--secure-file-priv默认情况下,MySQL的现代安装带有默认设置,可防止MySQL写入指定数据导入/导出目录以外的任何位置,从而使这种攻击几乎完全无能为力...除非服务器所有者故意禁用了它。幸运的是,没有人会完全禁用像这样的安全功能,因为这显然是- 哦,等等。sys_exec()函数from lib_mysqludf_sys以运行任意的shell命令有一个MySQL扩展名为lib_mysqludf_sys-从GitHub上的星号和快速的Stack Overflow搜索来看-至少有数百个用户。它添加了一个称为sys_exec运行外壳命令的函数。如#2所述,可以从SELECT; 内调用函数。希望是显而易见的。引用消息来源,此功能“可能会带来安全隐患”。
大多数系统未安装此扩展程序。