Desafio de segurança no MSSQL … Você consegue?
UPDATE 14-09-2012 a resposta para este desafio foi publicada aqui: https://blogfabiano.com/2012/09/14/soluo-desafio-de-segurana-no-sql-server/
Pessoal bora participar de um desafio de segurança no SQL Server e concorrer a uma cópia impressa do meu livro? Deixa eu explicar melhor.
Um dos muitos benefícios em relação ao uso de views no SQL Server é que com elas conseguimos “esconder” as tabelas do usuário final, podemos por exemplo definir que determinado usuário só tem acesso a view e não as tabelas que a view acessa. Ou seja, ele consegue executar um “select * from vw_funcionarios“ (vw_funcionarios é a view) mas não consegue executar um “select * from tab_funcionarios“ (tab_funcionarios é a tabela).
Utilizando a view, também conseguimos definir quais colunas serão visíveis para o usuário garantindo que ele somente veja os dados que ele realmente pode ver.
O desafio que estou propondo é o seguinte:
Vou descrever um cenário que usa views para “esconder” dados sigilosos, aparentemente o cenário é seguro e quero que você “hackeie” o SQL Server para conseguir visualizar os dados que supostamente você não deveria ver.
Vamos lá, o ambiente é o seguinte, tenho duas tabelas uma chamada TabFuncionarios que contêm os dados de todos os funcionários de uma empresa, e tenho outra tabela chamada TabEsconderFuncionarios que contêm os IDs dos funcionários que não quero que sejam retornados pela view. Desta forma dinamicamente consigo criar uma tela para configurar quais usuários são visíveis pela view.
Vejamos o schema do banco:
USE tempdb GO IF OBJECT_ID('vw_TabFuncionarios') IS NOT NULL DROP VIEW vw_TabFuncionarios GO IF OBJECT_ID('TabEsconderFuncionarios') IS NOT NULL DROP TABLE TabEsconderFuncionarios GO IF OBJECT_ID('TabFuncionarios') IS NOT NULL DROP TABLE TabFuncionarios GO CREATE TABLE TabFuncionarios(ID Int PRIMARY KEY, Nome VarChar(200), Salario Numeric(18,2)); GO CREATE TABLE TabEsconderFuncionarios(ID_Funcionario Int PRIMARY KEY REFERENCES TabFuncionarios(ID)) GO
Ou seja, tenho a TabFuncionarios que contem os dados dos funcionários, e a TabEsconderFuncionarios que contêm o ID correspondente a tabela TabFuncionarios.
Vamos inserir alguns dados de exemplo:
-- Inserir 4 funcionarios INSERT INTO TabFuncionarios(ID, Nome, Salario) VALUES(1, 'Fabiano', 1900),(2, 'Gilberto',2050),(3, 'Luciano', 25999),(4, 'Ivan', 9500) GO -- Esconder os funcionário "Luciano" e "Ivan" que ganham MUITO bem! 😉 INSERT INTO TabEsconderFuncionarios (ID_Funcionario) VALUES (3), (4) GO
Ou seja, temos 4 funcionários, e os funcionários que quero esconder estão na tabela TabEsconderFuncionarios. Agora precisamos apenas criar uma view que somente retorne os usuários que não estão na tabela TabEsconderFuncionarios:
IF OBJECT_ID('vw_TabFuncionarios') IS NOT NULL DROP VIEW vw_TabFuncionarios GO -- Criar a view para exibir somente funcionários que ganham pouco CREATE VIEW vw_TabFuncionarios WITH SCHEMABINDING AS SELECT ID, Nome, Salario FROM dbo.TabFuncionarios WHERE NOT EXISTS(SELECT 1 FROM dbo.TabEsconderFuncionarios WHERE TabEsconderFuncionarios.ID_Funcionario = TabFuncionarios.ID) GO -- Consultar os dados da view SELECT * FROM vw_TabFuncionarios GO
Temos o seguinte:
Ou seja, funciona! Agora seria apenas o caso de criar um usuário que só tem permissão de select na view e pronto.
CREATE LOGIN UsuarioQueNaoPodeNada WITH PASSWORD = '102030', CHECK_POLICY = OFF GO CREATE USER UsuarioQueNaoPodeNada FOR LOGIN UsuarioQueNaoPodeNada; GO GRANT SELECT ON vw_TabFuncionarios TO UsuarioQueNaoPodeNada GO
Portanto o desafio é, logando com o usuário “UsuarioQueNaoPodeNada” como descobrir os funcionários escondidos, e depois disso, quanto eles ganham?
As regras são: Não tem regras! Vale tudo! (contanto que você esteja logado com o UsuarioQueNaoPodeNada)
O ganhador será divulgado aqui no meu Blog e vou enviar a cópia do meu livro pelo correio (eu pago o frete é claro!), se você conseguir, me manda um e-mail no fabiano_amorim arroba(que não é do boi) bol ponto com ponto br.
O primeiro que me mandar o e-mail será o ganhador. Depois é claro, vou postar a solução, e explicar tudo com detalhes…
Boa sorte e have fun!
Abs.
Ótimo desafio!!! E não tem nenhuma permissão de INSERT ou DELETE? E sem usar permissão de showplan? Está difícil..
Grande Catae…. Olha só, a resposta precisa ser exibida utilizando o usuario sem as permissoes.
Porem como voce conhece as tabs e os objetos, voce pode fazer todos os testes via sysadmin. Entendeu?
Realmente sem ser sysadmin fica muito mais dificil pra hackear 🙂
Boa sorte :)… fico feliz de ver vc por aqui
abs
Gostei do desafio ! Vou tentar, mais pelo prazer de alcançar o objetivo do que pelo livro (que tenho certeza ser muito bom). Se eu conseguir o livro, melhor ainda !!!
Boa Angelo, boa sorte :-)…
Olá.
Se preparmos antes uma procedure que retorne os dados da referente tabela e/ou views utilizando internamente na stored procedure um usuario que tenha permissão a tudo. Sem problemas. Ao logar com o usuário que não pode nada em relação as tabelas e/ou views. Basta executar a referente stored procedure que os dados serão visualizados.
Já desenvolvi aqui na empresa tal procedimento para solução, precisava ler campos e dados de uma determinada tabela, mas o usuário não tinha permissão. Funcionou perfeitamente, até porque é um procedimento comum para criarmos processos temporarios e ganharmos tempo no sentido da admin. de banco de dados.
Abs.
Zanini.
Pois é Jefferson, realmente essa tecnica é bem interessante, valeu por compartilhar.
No caso do nosso desafio não vale criar outra proc que roda no escopo de outro usuário, você precisa executar o processo no escopo do usuárioquenaopodenada :-).
Abs e boa sorte!
essa é facil… Voce disse que vale tudo !!!!
Paga uma Puta pro cara de Ti comentar a View por 1 minuto
Antes :
WHERE NOT EXISTS(SELECT 1
FROM dbo.TabEsconderFuncionarios
WHERE TabEsconderFuncionarios.ID_Funcionario = TabFuncionarios.ID)
Depois do hacker :
/*
WHERE NOT EXISTS(SELECT 1
FROM dbo.TabEsconderFuncionarios
WHERE TabEsconderFuncionarios.ID_Funcionario = TabFuncionarios.ID)
*/
— Consultar os dados da view
SELECT *
FROM vw_TabFuncionarios
GO
kkkkk Muito boa Fábio.
Com certeza essa ideia daria certo 🙂
Abs.
Fabiano
Realmente daria certo. Bem lembrado Fábio.
Como não é de costume parametrizar com select no where por questões de desempenho (custo), acabei deixando este detalhe de lado. Porem, muito bom, bem lembrado.
Vale setar permissão via SQLCMD? Dessa forma consegui acessar os dados.
Conseguiu acessar os dados fazendo select na view?
Qual permissão via sqlcmd?
Abs.
!!sqlcmd -Q”EXEC tempdb..sp_helptext vw_TabFuncionarios”
!!sqlcmd -Q”SELECT ID, Nome, Salario FROM tempdb.dbo.TabFuncionarios”
Nope, dai não vale… na teoria você só tem acesso a view… e não a tabela TabFuncionarios… com qual usuário você logou via SQLcmd? … Tem que ser o o usuarioquenaopodenada.
Boa tentativa :-)… Daqui a alguns dias posto o resultado.
Abs.
Não citei nenhum usuário e assim o SQLCMD usa a minha conta de Windows. Estou logado com o usuário usuarioquenaopodenada no SSMS!
Outra opção é personificar a conta NT\SYSTEM usando SQLCMD e psexec -s. Esta conta é é um membro do grupo sysadmin em versões até SQL 2008R2.
Usa esse cara aqui para descriptografar a view:
http://www.devart.com/dbforge/sql/sqldecryptor/
Descriptografar quem? … A viu nem ta criptografada ;-).
Abs.
Pensei em algo usando DBCC PAGE, pra poder ver os dados… Mas sem sucesso… nao é qualquer um que pode ir lá executar esse comando DBCC… To curioso pra ver o resultado =)
:-), pois é DBCC PAGE não rola com o usuário que não pode nada…
Daqui a pouco posto o resultado, fica de olho :-).
Abs.