ASP.NET Core & OWASP TOP 10 - Injection

Segundo o OWASP, Injection continua sendo o principal risco de segurança das aplicações. Se essa falha for explorado por um atacante o custo pode ser milhonário.

De acordo com o relatório de Segurança anual da CISCO, o volume de ataques cibernéticos quadruplicou entre 2016 e 2017. Além disso, o custo médio das violações de dados deverá ultrapassar US $ 150 milhões até 2020.

Dentro do segmento de ataques cibrnéticos, SQL Injection é o segundo ataque mais comum na Web, atrás apenas de ataques DDOS. No entanto no segmento de ataques a Websites, SQL Injection representa 51% do ataques.

OWASP

O OWASP, acronimo de Open Web Application Security Project, é uma organização sem fins lucrativos cuja finalidade é promover o desenvolvimento e o design de aplicativos Web seguros.

Eles realizam oficinas e eventos diferentes em todo o mundo, talvez o projeto mais famoso deles é o "OWASP Top Ten".

A cada período de tempo o OWASP publica uma lista das 10 principais falhas de segurança em aplicações Web. Proteger sua aplicação destas 10 falhas não significa um site impenetrável. Mas definitivamente dificulta quem está buscando por brechas.

Segurança

Segurança é tema pouco debatido nas comunidades de devs. Atualmente o termo LGPD está em alta. Muito conteúdo sobre segurança, mas majoritariamente voltado para infra.

Temas como proteger os documentos da empresa, planilha de dados sensiveis trafegando por e-mail ou armazenados na rede.

Empresas como Google e Microsoft oferecendo ferramentas para administradores de redes terem mais controle sobre os dados desses arquivo, por exemplo, identificar se a planilha contém um RG ou dados de cartão de crédito.

Firewall e Antivirus em dia. USB do computador bloqueado, avisar o usuario que o site usa Cookies.

Todo dia é isso, mas e a tua aplicação, como que anda a segurança dela?

Parece que a unica preocupação dos dev's é que a chave primária é o CPF do cliente.

Proteger sua aplicação é um tema que parece não despertar o interesse de muitos devs. Para partilhar dessa opinião pedi ajuda ao Daniel Donda, e ele respondeu em um video no youtube veja aqui.

Saiba que segundo a cisco, 53% dos ataques causam danos acima de $500 mil doláres.

Injection

O OWASP define Injection como falhas de injeção permitem que os invasores transmitam códigos maliciosos por meio de um aplicativo para outro sistema. Esses ataques incluem chamadas para o sistema operacional, bem como chamadas para bancos de dados SQL (por exemplo, injeção de SQL). Execução de scripts inteiros escritos em Perl, Python e outras linguagens podem ser injetados em aplicativos mal projetados.

Segundo relatório do Akamai de 2017, 51% dos ataques a Websites eram através de SQL Injection. Apesar de ser sempre um dos principais temas de segurança, muitos desenvolvedores parecem não proteger suas aplicações.

Este artigo vai criar uma aplicação frágil e tentar demonstrar de forma didática o poder de um SQL Injection.

Esta é uma demo, existem ferramentas para explorarem com mais sofisticação uma falha dessas. No entanto o intuíto é didático para devs .NET, como eu.

SQL Injection

O SQL Injection funciona tentando modificar os parâmetros de uma query através do teu Website. O atacante escreve uma query em um campo texto de pesquisa ou modificando os parametros da Querystring do teu Website.

Pense numa aplicação escolar, em uma das telas há um campo para buscar o Aluno pelo Nome. O atacante ao invés de inserir o nome do aluno, escreve uma query e o sistema retorna o resultado dele.

É dessa falha que surgiu a famosa piada do Bob Drop Table.

O Ataque

Considere a seuginte aplicação, onde há uma tela que liste todos os estudantes e possui um campo de pesquisa pelo nome:

A query por trás desse campo de pesquisa é este:

Esse código SQL busca qualquer usuário que contem parte do nome digitado pelo usuario.

Esse é o cenário ideal para um atacante explorar por falhas de segurança.

Abaixo os passos para testar a vulnerabilidade deste site demo. Nesta demo está sendo utilizado um campo de pesquisa, mas poderia ser através da URL, ou então interceptande e modificando um parametro do post / get através das próprias ferramentas de desenvolvedor do Chrome ou Firefox (Para estes casos o Firefox possui ferramentas mais interessantes).

Passo 1 - Testando a vulnerabilidade

O usuário mal intencionado, vai tentar descobrir possiveis brechas. Um campo texto que faz buscas no banco é um local ideal.

O primeiro passo, é verificar qual campo é passivel de Injection SQL, como por exemplo verificar se o servidor vai retornar erro numa tentativa de injeção SQL.

Pode fazer isso testando queries SQL. Neste exemplo pode usar  abc' OR 1=1 -- .

Dessa forma o comando final gerado será:  SELECT FirstName, LastName FROM Student WHERE FirstName Like '%abc' OR 1=1 --%' . Ou seja, um código SQL perfeitamente válido.

Entendendo a estratégia:

  1. O primeiro apóstrofe termina o primeiro comando.
  2. OR 1=1 faz com que o SQL retorne todos os registros do banco.
  3. Por fim o -- é para comentar o restante do comando

O servidor não vai emitir nenhum erro e ainda retornar dados válidos:

Vulnerabilidade encontrada com sucesso.

Essa é uma estratégia valida para este cenário, dependendo da complexidade da query o atacante vai precisar se esforçar mais

Passo 2 - Mapeando o banco

O SQL server possui a tabela   sys.Tables  , se o usuário do SQL de sua aplicação possuir privilégios suficientes, o atacante pode aproveitar mais uma brecha e consultar todas tuas tabelas:  abc' UNION SELECT [name], cast(max_column_id_used as varchar(5)) FROM sys.Tables -- .

Essa query vai retornar todas as tabelas e a quantidade de colunas em cada uma delas do teu banco.

É possivel também consultar as colunas das tabelas, o Schema.

Essa é uma estratégia valida para este cenário, a quantidade de campos certamente seria um problema no UNION. Novamente o atacante não vai conseguir de maneira tão simplória quanto este exemplo.

Passo 3 - Dados confidenciais

Uma vez localizado todas as tabelas do teu banco, o próximo passo é tentar localizar dados confidenciais ou manipular teus registros com Update, Delete ou Insert.

O usuario, através da mesma lógica empregada anteriormente, consegue buscar dados de outra tabela, por exemplo, Usuario e Senha.

 abc' UNION SELECT Username, Password FROM AspnetUsers -- 

E o resultado será

Ou famoso drop table:  abc'; DROP TABLE AspnetUsers -- 

Como se proteger

Há algumas maneiras de se proteger.

Parametrized Queries

SEMPRE utilize parametrized query. É a maneira mais efetiva de se proteger de SQL Injection.

Repare nas linhas 5 e 11. A simples parametrização desta query, evitaria este tipo de ataque.

Usuário do Banco

O usuario da aplicação não deveria ter permissões tão elevadas. Porém, fazendo isso não impede o atacante, uma vez que há brecha de Injection, mas iria dificultar sua vida.

Com usuário sa, dependendo do cenário o atacante inclusive pode ter acesso de Administrador do Windows.

ORM's

A Utilização de um ORM como EntityFramework ou Hibernate previne a injeção de SQL.

Stored Procedures

Stored procedures também é uma maneira de evitar queries concatenadas e como consequencia evita este tipo de ataque.

Considerações

Essa aplicação foi construida com o propósito de alertar. E é um cenário ideal, perfeitamente construido para esse artigo.

É uma aplicação hipotética e com brechas grotescas. Mas é valido relembrar que Injection é, a segunda maior vulnerabilidade de sistemas Web.

E é um tema pouco debatido, o perigo por código mal escrito é alto demais.

Conclusão

Espero com esse demo te ajude com um pouco de prática como funciona um ataque de SQL Injection.

Atacantes mais experientes utilizam ferramentas e softwares mais robustos. Esta demo é apenas uma introdução para ajudar aqueles que precisam se proteger.

Download

O código do projeto está disponível no meu GitHub

Referências