这个问题突然出现在我的脑海里,我在任何地方都找不到,所以我想这是最好的提问地点。这只是为了教育目的。我使用适当的卫生设施,并没有为我的真实数据库提供删除权限。
假设一个拥有所有权限的数据库和一个具有三个值的简单insert查询
INSERT INTO test(a,b,c) VALUES('$a','$b','$c');
上述查询易受sql注入攻击。
假设用户输入为
a',(select database()),'a')--
开始2
开始3
结果查询如下:
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')
我尝试运行上面的查询,但它抛出了一个错误。这个查询有什么问题?
3条答案
按热度按时间vlju58qv1#
这个查询有什么问题?
这个查询有两个问题。
不能将drop数据库放入子查询。子查询必须是select语句并具有结果集(在您显示的示例中,它必须是一列一行的结果集)。
无论如何,也不允许在子查询中使用insert/update/delete。
drop database不接受子查询的结果作为其参数。语法drop database接受数据库标识符(名称),不能删除数据库“”。子查询的结果总是数据值(如字符串和数字),而不是标识符。
与此查询比较:
子查询返回列的值
x
. 如果x
是字符串值“d”,这不会导致外部查询返回标识为的列的值table1.d
. 它返回一个文本字符串“d”。一般来说,sql不允许您使用数据值作为标识符。在分析查询之前,必须在查询中显式写入数据库名、表名和列名。要使标识符动态化,必须运行两个查询,即在创建第二个sql语句时使用第一个查询的结果。
8ehkhllq2#
攻击者是否能够在不知道数据库名称的情况下删除数据库?
对。假设使用mysql,请参见以下php代码:
它将创建以下mysql语句:
尝试执行上述sql将删除当前数据库。
envsm3lx3#
我的问题是,攻击者是否能够在不知道数据库名称的情况下删除数据库?
答案是肯定的,这就是为什么我们应该使用参数而不是包含字符串,并尽可能避免使用动态sql。
恶意用户可以使用db\u name()函数获取数据库名称,如下所示:
下面是一个在不知道她名字的情况下删除数据库的示例: