Injeção do SQL Server - quanto dano ocorre em 26 caracteres?

21

Estou testando a resiliência contra ataques de injeção em um banco de dados do SQL Server.

Todos os nomes de tabela no banco de dados são minúsculos e o agrupamento diferencia maiúsculas de minúsculas, Latin1_General_CS_AS .

A sequência que eu posso enviar é forçada a maiúscula e pode ter no máximo 26 caracteres. Portanto, não posso enviar uma DROP TABLE porque o nome da tabela estaria em maiúsculas e, portanto, a instrução falharia devido ao agrupamento.

Então - qual o dano máximo que eu poderia causar em 26 caracteres?

EDITAR

Eu sei tudo sobre consultas parametrizadas e assim por diante - vamos imaginar que a pessoa que desenvolveu o front end que cria a consulta para enviar não usava parâmetros neste caso.

Também não estou tentando fazer nada nefasto, este é um sistema construído por outra pessoa na mesma organização.

Alan B
fonte
1
Estamos imaginando ou você está realmente testando com caneta e tem requisitos que o impedem de evitar a injeção? Você está procurando uma maneira de quebrar a falta de segurança dele?
precisa saber é o seguinte
41
Por que é mesmo uma opção deixar a porta aberta? Parece que você já passou mais tempo pensando nisso do que custaria trancar a porta. Eu sinto isso como um exercício infrutífero - se você criar 10 vulnerabilidades, eles dirão: nós iremos plugar essas 10 vulnerabilidades e certamente não haverá uma 11ª. É aqui que as seqüências de "limpeza" nos levam. / facepalm
Aaron Bertrand
5
Essa é uma pergunta insana e vaga e arbitrária, e nem sequer pode ser abordada teoricamente. Existem outros recursos atenuantes nativos do SQL Injection (permissões, sandbox, firewalls etc.), e você teria que prestar contas de todas essas coisas para responder a essa pergunta.
Evan Carroll
2
O que está impondo o limite de 26 caracteres? A aplicação?
Jonathan Fite
7
Pare com isso. Apenas pare. Se as consultas parametrizadas forem remotamente uma opção, use-as . Se alguém não souber usá-los, encontre um recurso decente e peça que o leia. Se eles não ouvirem, notifique um gerente ou supervisor que eles estão produzindo vulnerabilidades críticas de segurança (uma demonstração não destrutiva não faria mal.) E se recuse a ser educado.
Jpmc26

Respostas:

38

Fácil:

GRANT EXECUTE TO LowlyDBA

Ou, acho que nesse caso seria

grant execute to lowlydba 

Faça a sua escolha de variações sobre isso.

Com toda a probabilidade, você poderá testar isso agora em relação ao seu sistema atual, mas qualquer número de pequenas alterações no banco de dados ao longo do tempo pode invalidar o teste. A cadeia de caracteres pode mudar, alguém pode criar um procedimento armazenado em minúsculas com potencial destrutivo - qualquer coisa. Você nunca pode dizer com 100% de confiança que não há um ataque destrutivo de 26 caracteres que alguém possa construir.

Sugiro que você encontre uma maneira de fazer com que o desenvolvedor siga as práticas recomendadas de segurança básicas padrão do setor, mesmo que seja por sua conta como alguém que eu presumo ser pelo menos parcialmente responsável caso ocorram violações de segurança.

Editar:

E por malícia / diversão, você pode tentar ativar todos os sinalizadores de rastreamento. Isso seria interessante de observar. Parece um post que Brent Ozar faria ...

DBCC TRACEON(xxxx, -1)
LowlyDBA
fonte
1
Além de possibilitar sinalizadores de rastreamento: mudando várias configurações aleatórias: SET LOCK_TIMEOUT 0;, SET LANGUAGE Malaysian;, SET ANSI_NULLS OFF:...
ypercubeᵀᴹ
2
@ ypercubeᵀᴹ todos eles afetariam apenas sua própria sessão.
Martin Smith
2
@MartinSmith thnx. Se SET(afecta apenas as configurações de sessão, como são configurações satabase e servidor mudou ALTER DATABASE ...;?) DROP DATABASE ..;Iria infligir mais danos, em seguida, se conseguiu;)
ypercubeᵀᴹ
1
Altere o banco de dados e sp_configure principalmente para as configurações de nível de banco de dados e servidor. Embora você possa atingir o limite de 26 caracteres com estes. Além disso, essas configurações específicas no nível do banco de dados são usadas apenas se a conexão do cliente não as definir. E por padrão a maioria ou todos fazem.
Martin Smith
7
Eu me pareço com esse comentário.
Brent Ozar
22

O SHUTDOWNcomando ou KILLComando (escolha um número aleatório acima de 50) ambos têm significativamente menos de 26 caracteres, embora a conta que executa as consultas do aplicativo esperançosamente não tenha permissões suficientes para executá-los.

Martin Smith
fonte
Normalmente, a conta não seria necessário remover a tabela ou ...
Greg
3
@Greg sim. Embora você possa supor que um ambiente está considerando permitir a injeção de SQL, desde que o comprimento seja curto, não siga as práticas recomendadas de segurança e as contas podem não estar configuradas com permissões mínimas.
Martin Smith
14

Você pode criar uma tabela que preenche até o final do tempo ou o espaço em disco acabar, o que ocorrer primeiro.

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
Mikael Eriksson
fonte
19
@ AlanB Bem, então você precisaria de algo que me impede de explorar a fraqueza mais de uma vez.
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
1
Você poderia usar isso para criar um comando mais longo que o limite de caracteres e depois executá-lo?
precisa saber é o seguinte
1
@ MartinSmith Eu pensei que iria sair assim, mas agora eu só tenho que tentar :). Vou deixar você saber se eu descobrir.
Mikael Eriksson
7
O @WernerCD x:insert t select 0 GOTO xtem exatamente 26 anos.
Martin Smith
4

Dependendo da sua definição de dano, você pode executar o seguinte: WAITFOR DELAY '23: 59 'Para ser realmente mau, você pode usar uma ferramenta de teste de carga para executar isso de 32.768 clientes.

user143642
fonte
1
Se a cadeia de caracteres for injetada em um lote ad-hoc que retém bloqueios, ela poderá fornecer uma negação de serviço viável como uma única chamada, sem a necessidade de causar inanição no encadeamento.
David Spillett
3

Variação baseada na resposta de @ MikaelEriksson e de @ MartinSmith no meu comentário inicial:

declare @S char(26);

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

Inicialmente, tentei fazer uma declaração WHILE, mas o melhor que pude fazer foram 27 caracteres:

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

Mas Martin apontou GOTO:

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

GOTO ... a raiz de todo mal e criador de uma instrução de inserção de loop infinito em 26 caracteres.

Com isso dito ... pode ser vantajoso ficar com CHAR (99) em vez de int, pois isso usaria mais espaço. Outras opções usam nomes mais longos e quebram o limite de 26 caracteres ... ou usam menos espaço de armazenamento por linha.

Código de teste completo:

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
WernerCD
fonte
1
set @S = 'x:insert t;select 0;GOTO x';para compatibilidade futura do seu ataque de injeção;)
ypercubeᵀᴹ
@ ypercubeᵀᴹ Você adicionou dois ;s ... o segundo está bom - substitui um espaço e funciona se não for necessário. O primeiro interrompe a consulta - separa a instrução INSERT da instrução SELECT.
WernerCD 31/01
Ah sim. É o que acontece quando não se usa separadores! Não sabemos onde cada consulta termina e quando a próxima começa!
precisa saber é o seguinte
1
@ WarnerCD eu sei. Foi mais uma piada sobre o procedimento de depreciação no SQL Server. Parece demorar para sempre. Ainda assim, é uma boa prática usar ponto-e-vírgula entre instruções e não apenas onde é necessário.
usar o seguinte comando
2
@ yper duvido que alguma vez seja aplicada. Provavelmente, há uma tonelada de código legado que precisaria de dois pontos e vírgulas adicionados sem nenhum valor comercial específico para isso. E pode ser incorporado em aplicativos difíceis ou impossíveis de atualizar.
Martin Smith
0
XP_CMDSHELL 'SHUTDOWN -PF'

Dependendo de quão prejudicial você considere um desligamento. :-)

Isso exige que o xp_cmdshell esteja ativado no servidor, algo que não é o caso da última versão do SQL Server. Também exige que a conta de serviço tenha o desligamento correto, o que pode ou não ter.

A ativação do xp_cmdshell provavelmente vai além do seu limite de 26 caracteres. Você permitiria várias injeções?

SP_CONFIGURE 'SHOW ADV',1

RECONFIGURE

SP_CONFIGURE 'XP', 1

RECONFIGURE
Andarilho de Pedra Verde
fonte
1
O EXEC é opcional apenas se esta for a primeira instrução do lote. O que provavelmente não será o caso aqui.
9308 Martin Smith1 de
@ Martin Smith, bom comentário. O EXEC adiciona 5 caracteres a cada linha de chamada de procedimento, o que empurra a maioria deles com mais de 26 caracteres. Gostaria de saber se CREATE ALIAS ajudaria aqui?
Greenstone Walker