ʼ;ŚℇℒℇℂƮ *:Injeções de SQL Customizadas

Publicado por Igor Matsunaga em

Neste post observaremos como conversões implícitas de unicode podem deixar seus dados vulneráveis.

O que é um homógrafo?

Um homógrafo é um personagem que se parece com outro personagem. Por exemplo a letra l (minúscula “L”) e o número 1 são considerados homógrafos. Assim como o O (letra) e 0 (número).

Homógrafos podem existir dentro de um conjunto de caracteres (como por exemplo os conjuntos de caracteres latinos acima) ou podem existir entre conjuntos de outros caracteres. Por exemplo, você pode ter o apóstrofo unicode , que é um homógrafo para o caractere de aspas simples em latim '.

Como o SQL Server Manipula Homógrafos Unicode?

Se você passar um caractere unicode para um tipo de dados não-unicode (como char), o SQL converterá implicitamente o caractere unicode para seu homógrafo não-unicode mais próximo.

Para ver como isso funciona, podemos usar o apóstrofo unicode do exemplo acima ʼ:

SELECT
  CAST(N'ʼ' AS nchar) AS UnicodeChar,
  CAST(N'ʼ' AS char) AS NonUnicodeChar

Você pode ver na imagem abaixo, na segunda coluna o SQL converteu automaticamente o apóstrofo em uma aspa simples:

Embora essa conversão implícita de caracteres possa ser conveniente para quando você deseja exibir caracteres unicode em um conjunto de caracteres não unicode, isso pode significar um desastre para a segurança do SQL Server.

Injeção SQL Homógrafica Unicode

Se você já estiver usando sp_executesql ou QUOTENAME () ao construir suas consultas SQL dinâmicas, estará seguro deste tipo de injeção SQL.

Dificilmente alguém escreveria suas próprias funções de segurança enquanto existem diversas funções sólidas, seguras e testadas, como as acima disponíveis. No entanto, suponhamos que você acha que pode enganar um hacker escrevendo seu próprio código de delimitação de cotação.

Teste

Usando este conjunto de dados abaixo como exemplo , vamos criar um novo procedimento armazenado que retornará alguns dados do perfil de um usuário:

USE Sandbox;
GO
DROP TABLE IF EXISTS dbo.RegisteredUser
CREATE TABLE dbo.RegisteredUser
(
	Id INT IDENTITY(1,1),
	FullName varchar(100),
	UserName varchar(40),
	HashedPassword varchar(66),
	JoinDate datetime2
)

--SELECT HASHBYTES('SHA2_256','asdf')
INSERT INTO dbo.RegisteredUser (FullName,UserName,HashedPassword,JoinDate) VALUES ('Toucan Sam','TFly37','0x3FC9B689459D738F8C88A3A48AA9E33542016B7A4052E001AAA536FCA74813CB','2014-02-11')
INSERT INTO dbo.RegisteredUser (FullName,UserName,HashedPassword,JoinDate) VALUES ('Crackle','StockingCap123','0x263B5FC234296526BB5765989FEE5935C66CCC7F3E9BF1670586AA002A222B7B','2016-09-09')
INSERT INTO dbo.RegisteredUser (FullName,UserName,HashedPassword,JoinDate) VALUES ('Tony','OrangeNBlack11','0xF857D5372D2BE839D5AD05357D46A93C2C9DE1220AB0B4FFF2A0B0B8EBAB8369','2015-01-30')
INSERT INTO dbo.RegisteredUser (FullName,UserName,HashedPassword,JoinDate) VALUES ('Smacks Frog','RibbetRibbet','0x3A6A65C685EB9153885A67490A0C77FC474D2665E274121CC445F5C8EEF29E6A','2017-08-09')
INSERT INTO dbo.RegisteredUser (FullName,UserName,HashedPassword,JoinDate) VALUES ('Count Chocula','OneAhHaHa','0x301ACDDD58EB7F053B013BD0129AB1343984904040729457E9B1F3EAF5A2F14D','2016-11-24')


DROP PROCEDURE IF EXISTS dbo.GetProfile
GO
CREATE PROCEDURE dbo.GetProfile
 @Username nvarchar(100)
AS
BEGIN
 -- Add quotes to escape injection...or not?
 SET @Username = REPLACE(@Username, '''','''''')
DECLARE @Query varchar(max)
SET @Query = 'SELECT 
     FullName, 
     JoinDate
    FROM
     dbo.RegisteredUser
    WHERE
     UserName = ''' + @Username + '''
     '
EXEC(@Query)
END
GO

Em vez de usar sp_executesql ou QUOTENAME (), vamos tentar escrever nossa própria função inteligente REPLACE () que substituirá aspas simples por dois conjuntos de aspas simples. Isso deve, em teoria, impedir a injeção de SQL.

Se testarmos uma tentativa “normal” de injeção SQL, você perceberá que essa lógica funciona muito bem. 

No entanto, se passarmos em um apóstrofo unicode …:

A razão pela qual isso acontece é porque declaramos nosso parâmetro @Query como varchar em vez do nvarchar unicode. Quando construímos nossa instrução SQL dinâmica, o SQL implicitamente converte o parâmetro nvarchar @Username no varchar não unicode:

logoNSW

Se eu substituir os apóstrofos, isso me tornará seguro?

A reposta é não!

Eu sei que parece que listar em preto / substituir o apóstrofo unicode resolveria todos os nossos problemas.

E seria … apenas neste cenário. Existem mais homógrafos unicode do que apenas um apóstrofo.

Esse script irá pesquisar através do espaço de caracteres unicode para saber quantos mais homógrafos existiam:

DECLARE @FirstNumber INT=0;
-- number of possible characters in the unicode space
DECLARE @LastNumber INT=1114112;
 
WITH Numbers AS (
    SELECT @FirstNumber AS n
    UNION ALL
    SELECT n+1 FROM Numbers WHERE n+1<[email protected]
), UnicodeConversion AS (
SELECT
       n AS CharacterNumber,
       CASE CAST(NCHAR(n) as CHAR(1))
              WHEN '''' THEN NCHAR(n)
              WHEN ';' THEN NCHAR(n)
       END AS UnicodeCharacter,
       CAST(NCHAR(n) as CHAR(1)) AS ASCIICharacter
FROM Numbers
)
SELECT
       *
FROM
       UnicodeConversion
WHERE
       UnicodeCharacter IS NOT NULL
OPTION (MAXRECURSION 0)

Embora os caracteres na captura de tela acima possam parecer semelhantes, eles são na verdade homógrafos.

Decidi procurar apenas aspas simples e ponto-e-vírgula, uma vez que são frequentemente usados ​​em ataques de injeção de SQL, mas isso não significa uma lista extensa de todos os caracteres que você deseja colocar na lista negra.

Seria algo uma tarefa muito árdua listar com segurança todos os homógrafos perigosos que existem, ainda mas com diversos personagens sendo adicionados ao unicode o tempo todo, então manter uma lista negra seria um pesadelo de manutenção. Especialmente se a pessoa que mantém esse código no futuro não estiver familiarizada com esses tipos de ataques de injeção.

E não seja atrevido pensando que você pode filtrar palavras-chave SQL perigosas – mesmo se você utilizar REPLACE (@ Username, ‘SELECT’, ”), lembre-se de que alguém pode aparecer e passar um valor como ‘ŚεℒℇℂƮ’.

Não escreva suas próprias funções de segurança – elas falharão.irão te deixar na mão.

Lista com Char e Homógrafos:

CharHomógrafos
ᅟ ᅠ                     ㅤ
!! ǃ !
” ״ ″ "
$$ $
%% %
&& &
‘ '
(( ﹝ (
)) ﹞ )
** ⁎ *
++ +
,, ‚ ,
– ‐ 𐀠񴐠-
.. ٠ ۔ ܁ ܂ ․ ‧ 。 . 。
// ̸ ⁄ ∕ ╱ ⫻ ⫽ / ノ
00 O o Ο ο О о Օ 𐐠𱠠O o
11 I ا 1
22 2
33 3
44 4
55 5
66 6
77 𐐠𱰠7
88 Ց 8
99 9
:: ։ ܃ ܄ ∶ ꞉ :
;; ; ;
<< ‹ <
== 𐀠񴀠=
>> › >
?? ?
@@ @
[[ [
\\ \
]] ]
^^ ^
__ _
`` `
aA a À Á Â Ã Ä Å à á â ã ä å ɑ Α α а Ꭺ A a
bB b ß ʙ Β β В Ь Ᏼ ᛒ B b
cC c ϲ Ϲ С с Ꮯ Ⅽ ⅽ 𐐠𺀠C c
dD d Ď ď Đ đ ԁ ժ Ꭰ ḍ Ⅾ ⅾ D d
eE e È É Ê Ë é ê ë Ē ē Ĕ ĕ Ė ė Ę Ě ě Ε Е е Ꭼ E e
fF f Ϝ F f
gG g ɡ ɢ Ԍ ն Ꮐ G g
hH h ʜ Η Н һ Ꮋ H h
iI i l ɩ Ι І і ا Ꭵ ᛁ Ⅰ ⅰ 𐐠𰰠I i
jJ j ϳ Ј ј յ Ꭻ J j
kK k Κ κ К Ꮶ ᛕ K K k
lL l ʟ ι ا Ꮮ Ⅼ ⅼ L l
mM m Μ Ϻ М Ꮇ ᛖ Ⅿ ⅿ M m
nN n ɴ Ν N n
00 O o Ο ο О о Օ 𐐠𱠠O o
pP p Ρ ρ Р р Ꮲ P p
qQ q Ⴍ Ⴓ Q q
rR r ʀ Ի Ꮢ ᚱ R r
sS s Ѕ ѕ Տ Ⴝ Ꮪ 𐐠𵠠S s
tT t Τ τ Т Ꭲ T t
uU u μ υ Ա Ս ⋃ U u
vV v ν Ѵ ѵ Ꮩ Ⅴ ⅴ V v
wW w ѡ Ꮃ W w
xX x Χ χ Х х Ⅹ ⅹ X x
yY y ʏ Υ γ у Ү Y y
zZ z Ζ Ꮓ Z z
{{ {
|| ǀ ا |
}} }
~~ ⁓ ~
ßß ӧ
äÄ Ӓ
öÖ Ӧ

Dica

Você pode utilizar o Homoglyph Attack Generator do site irongeek. para realizar testes de geração de homógrafos com base em Homoglyphs.

Conclusão

Sua melhor proteção contra injeção de SQL é não usar SQL dinâmico. Se você precisar usar SQL dinâmico, use sp_executesql e QUOTENAME ().

[products limit=”16″ columns=”4″ category=”61″ orderby=”date” order=”DESC”]

Fonte: Hackernoon


Igor Matsunaga

Diretor Técnico da NSWorld, entusiasta da área hacking, desenvolvedor hacker ético, formado em Segurança da Informação.

0 comentário

Deixe um comentário

Avatar placeholder

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *