Criptografia, Autenticadores e Ataques de Inferência no SQL Server

Boa Noite Pessoal,

A primeira vez que fui apresentado aos recursos de criptografia do SQL Server em meados de 2006, ficou uma certa curiosidade sobre o parâmetro authenticator dos métodos EncryptByKey e EncryptByPassPhrase. As formas mais seguras de criptografia utilizam a combinação de chaves públicas e privadas e são representadas pelos métodos EncryptByAsymKey e EncryptByCert que por sua vez dispensam em sua assinatura o uso de autenticadores. Qual será então a utilidade desse parâmetro ? Se os métodos mais fortes o dispensam e os métodos mais fracos o utilizam como argumento opcional em que situação ele é necessário ?

Passei algum tempo sem encontrar a resposta, mas depois de estudar um pouco mais sobre segurança acabei descobrindo a sua real utilidade. Algumas formas de ataque como negação de serviço, sql injection, etc sempre me foram familiares, pois, já trabalhei muito para prevení-las e eventualmente já tive que ajudar algumas vítimas de ataques nessa modalidade. Entretanto, o termo "ataque de inferência" não é um dos que costumo observar no dia a dia e tampouco vejo mencionado nas bibliografias de SQL Server e nem sequer no Books OnLine. O uso de autenticadores nos métodos EncryptByKey e EncryptByPassPhrase serve justamente para prevenir esse tipo de ataque a dados criptografados.

Ao invés de me prender a explicações mais formais desse termo, vejamos em uma situação prática, porque apenas a criptografia sozinha talvez não seja eficaz na garantia da integridade e confidencialidade dos dados. O script a seguir cria uma pequena tabela de empregados com algumas colunas cadastrais clássicas e alguns dados mais sensitivos a exemplo da coluna salário.

— Cria uma tabela de empregados
CREATE TABLE Empregados (
    EmpregadoID INT IDENTITY(1,1) NOT NULL,
    CPF CHAR(11) NOT NULL,
    Nome VARCHAR(50) NOT NULL,
    Funcao VARCHAR(50) NOT NULL,
    Salario VARBINARY(256) NULL)

— Adiciona as constraints
ALTER TABLE Empregados ADD CONSTRAINT PK_Empregado PRIMARY KEY (EmpregadoID)

— Insere três empregados
INSERT INTO Empregados (CPF, Nome, Funcao, Salario)
VALUES (‘70036543921’,‘Ademilda Souza Gonçalves’,‘Diretora de TI’, NULL)

INSERT INTO Empregados (CPF, Nome, Funcao, Salario)
VALUES (‘51034681233’,‘Alexandre Pereira Neto’,‘Analista Sênior’, NULL)

INSERT INTO Empregados (CPF, Nome, Funcao, Salario)
VALUES (‘25341677542’,‘Edmilson Alves Medeiros’,‘Desenvolvedor Júnior’, NULL)

Os dados cadastrais estão concluídos, agora resta informar os salários para cadastro. Podemos utilizar várias opções no próprio SQL Server como certificados, chaves simétricas, as funções pwdEncrypt e pwdCompare, etc. Não entrarei no mérito do método de criptografia mais forte. Para o propósito desse artigo uma criptografia simétrica baseada em frase já é suficiente.

— Declara uma string para montar a chave simétrica
DECLARE @pwd NCHAR(8)
SET @pwd = N’ds-ospc!’

— Declara strings para armazenar os salários (tem que ser texto para atender a criptografia)
DECLARE @Salario1 VARCHAR(8), @Salario2 VARCHAR(8), @Salario3 VARCHAR(8)
SET @Salario1 = ‘10256.78’ — Salário da Ademilda
SET @Salario2 = ‘5360.29’ — Salário do Alexandre
SET @Salario3 = ‘2230.55’ — Salário do Edmilson

— Declara strings para armazenar as senhas criptografadas
DECLARE @Salario1C VARBINARY(256), @Salario2C VARBINARY(256), @Salario3C VARBINARY(256)
SET @Salario1C = ENCRYPTBYPASSPHRASE(@pwd,@Salario1)
SET @Salario2C = ENCRYPTBYPASSPHRASE(@pwd,@Salario2)
SET @Salario3C = ENCRYPTBYPASSPHRASE(@pwd,@Salario3)

— Atualiza as senhas dos clientes
UPDATE Empregados SET Salario = @Salario1C WHERE EmpregadoID = 1
UPDATE Empregados SET Salario = @Salario2C WHERE EmpregadoID = 2
UPDATE Empregados SET Salario = @Salario3C WHERE EmpregadoID = 3

Edmilson é um desenvolvedor que conseguiu uma credencial para acesso a tabela de empregados. Essa credencial possui permissão de SELECT e UPDATE na tabela de Empregados. Ele não sabe exatamente o salário de Ademilda, mas a julgar pela sua posição na empresa, ele sabe que trata-se de um salário muito superior ao seu. Assim sendo, ele efetua um UPDATE para igualar o seu salário ao dela.

UPDATE Empregados SET Salario = (SELECT Salario FROM Empregados WHERE EmpregadoID = 1)
WHERE EmpregadoID = 3

— Verifica as colunas de nome e salário
SELECT Nome, Salario FROM Empregados

Após a execução do comando, o salário de Ademilda e de Edmilson realmente são iguais (ainda que criptografados). Os códigos HASH podem divergir, mas o importante é que os salários da Ademilda e do Edmilson são iguais.

Nome Salário
Ademilda Souza Gonçalves 0x01000000CF13BEDF13CFC59006793E775C19BACA7605877816E31CB8D63DC548CCBDC56A
Alexandre Pereira Neto 0x010000001DCCD902BF968B61514AF6AF0DA3510D4DDD6F001A83D149
Edmilson Alves Medeiros 0x01000000CF13BEDF13CFC59006793E775C19BACA7605877816E31CB8D63DC548CCBDC56A

O que ocorreu foi uma inferência por parte do usuário Edmilson. Ele não sabe o salário da Ademilda, mas baseando-se na sua posição, ele consegue inferir que o salário é superior e portanto efetuou a atualização. No momento que ele visualizar o contracheque, ele conseguirá descobrir o salário da Ademilda. Podemos constatar que eles são iguais através da consulta abaixo:

— Declara uma string para montar a chave simétrica
DECLARE @pwd NCHAR(8)
SET @pwd = N’ds-ospc!’

SELECT Nome,
    CAST(
        CAST(DECRYPTBYPASSPHRASE(@pwd,Salario) As VARCHAR(8))
    As SMALLMONEY) As Salario
FROM Empregados

A consulta retorna os empregados e seus salários descriptografados.

Nome Salário
Ademilda Souza Gonçalves 10256,78
Alexandre Pereira Neto 5360,29
Edmilson Alves Medeiros 10256,78

De fato, a consulta confirma que Edmilson "promoveu-se" aumentando o seu salário. Vejamos agora como o uso de autenticadores pode prevenir esse problema.

— Declara uma string para montar a chave simétrica
DECLARE @pwd NCHAR(8)
SET @pwd = N’ds-ospc!’

— Declara strings para armazenar os salários (tem que ser texto para atender a criptografia)
DECLARE @Salario1 VARCHAR(8), @Salario2 VARCHAR(8), @Salario3 VARCHAR(8)
SET @Salario1 = ‘10256.78’ — Salário da Ademilda
SET @Salario2 = ‘5360.29’ — Salário do Alexandre
SET @Salario3 = ‘2230.55’ — Salário do Edmilson

— Declara strings para armazenar as senhas criptografadas com o uso de autenticadores
DECLARE @Salario1C VARBINARY(256), @Salario2C VARBINARY(256), @Salario3C VARBINARY(256)
SET @Salario1C = (SELECT ENCRYPTBYPASSPHRASE(@pwd,@Salario1,1,CAST(EmpregadoID As SYSNAME)) FROM Empregados WHERE EmpregadoID = 1)
SET @Salario2C = (SELECT ENCRYPTBYPASSPHRASE(@pwd,@Salario2,1,CAST(EmpregadoID As SYSNAME)) FROM Empregados WHERE EmpregadoID = 2)
SET @Salario3C = (SELECT ENCRYPTBYPASSPHRASE(@pwd,@Salario3,1,CAST(EmpregadoID As SYSNAME)) FROM Empregados WHERE EmpregadoID = 3)

— Atualiza as senhas dos clientes
UPDATE Empregados SET Salario = @Salario1C WHERE EmpregadoID = 1
UPDATE Empregados SET Salario = @Salario2C WHERE EmpregadoID = 2
UPDATE Empregados SET Salario = @Salario3C WHERE EmpregadoID = 3

Supondo que Edmilson irá tentar novamente efetuar um ataque por inferência, vejamos a consulta abaixo:

UPDATE Empregados SET Salario = (SELECT Salario FROM Empregados WHERE EmpregadoID = 1)
WHERE EmpregadoID = 3

— Verifica as colunas de nome e salário
SELECT Nome, Salario FROM Empregados

A consulta retorna os empregados e seus salários criptografados (parte do resultado foi truncado na exibição)

Nome Salário
Ademilda Souza Gonçalves 0x010000000D436D519FF7094F209CBA414C63D48C95DBCC868919A2AECEFDEBC53EC67…
Alexandre Pereira Neto 0x0100000041A7183124B568B47C5945C168C13382DBD8577476E3BE800F060F8CE220D…
Edmilson Alves Medeiros 0x010000000D436D519FF7094F209CBA414C63D48C95DBCC868919A2AECEFDEBC53EC67…

Realmente o salário de Ademilda e Edmilson continuam iguais na sua forma criptografada, agora vejamos se é possível descriptografá-los.

— Declara uma string para montar a chave simétrica
DECLARE @pwd NCHAR(8)
SET @pwd = N’ds-ospc!’

SELECT Nome,
    CAST(
        CAST(DECRYPTBYPASSPHRASE(@pwd,Salario,1,CAST(EmpregadoID As SYSNAME)) As VARCHAR(8))
    As SMALLMONEY) As Salario
FROM Empregados

A consulta mostra o resultado abaixo:.

Nome Salário
Ademilda Souza Gonçalves 10256,78
Alexandre Pereira Neto 5360,29
Edmilson Alves Medeiros NULL

De fato embora o salário criptografado seja exatamente o mesmo no momento de efetuar o retorno, o salário de Edmilson não pode ser descriptografado. Isso ocorreu porque embora a chave de criptografia utilizada seja exatamente a mesma (ds-ospc!), houve um autenticador a mais no processo de autenticação. Esse autenticador foi o EmpregadoID. O valor de EmpregadoID para Ademilda é 1 e para Edmilson é 2. Como ele usado como autenticador, não será possível que o salário de Edmilson seja corretamente descriptografado, pois, o EmpregadoID será diferente.

Para que o ataque tivesse êxito, seria necessário que Edmilson atualizasse também o seu valor para EmpregadoID, mas nesse caso, além dele não ter as permissões necessárias, a tabela possui uma unicidade em torno do ID que impediria que ele efetuasse a troca. Mesmo que ele conseguisse fazer isso, trocar o seu ID é semelhante a trocar sua identidade. Se esse ID for utilizado em outras tabelas ou for emitido no contracheque, ou ainda, for utilizado em outras tabelas, haverá vários indícios de fraude e certamente ele seria descoberto muito rapidamente. Imagine por exemplo que o ID seja utilizado para rastrear despesas históricas de viagem, reuniões de compromissos, etc. Nesse caso Edmilson teria que literalmente se responsabilizado por todas as atividades de Ademilda e esse tipo de fraude seria descoberto muito rapidamente.

Esse tipo de ataque não é exclusivo do SQL Server e tampouco de banco de dados. O fato de um dado ser criptografado não necessariamente significa que ele está protegido contra todos os tipos de violações de integridade e confiabilidade. O uso de autenticadores pode reduzir esse tipo de ameça embora não dispense uma boa gestão de permissões e guarda das chaves de criptografia utilizadas.

[ ]s,

Gustavo

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s