quinta-feira, 22 de setembro de 2016

Prolepse SQL Injection - SQL Server part 1

SQL Injection

É um ataque no qual um código mal-intencionado é inserido em cadeias de caracteres que são passadas posteriormente para uma instância do SQL Server para análise e execução. Qualquer procedimento que construa instruções SQL deve ser verificado quanto a vulnerabilidades de injeção porque o SQL Server executará todas as consultas sintaticamente válidas que receber. Mesmo dados com parâmetros podem ser manipulados por um invasor qualificado e determinado.
A forma principal de injeção SQL consiste em inserção direta de código em variáveis de entrada de usuário, concatenadas com comandos SQL. Quando as cadeias de caracteres armazenadas são concatenadas subseqüentemente em um comando SQL dinâmico, o código mal-intencionado é executado.
O processo de injeção funciona encerrando prematuramente uma cadeia de caracteres de texto e anexando um novo comando. Como o comando inserido pode ter cadeias de caracteres adicionais anexadas a ele antes de ser executado, o malfeitor encerra a cadeia de caracteres injetada com uma marca de comentário "--". O texto subseqüente é ignorado no momento da execução.
O script a seguir mostra uma injeção SQL simples. O script cria uma consulta SQL concatenando cadeias de caracteres codificadas com uma cadeia de caracteres inserida pelo usuário:
var CidadeDestino;
CidadeDestino= Request.form ("Cidade");
var sql = "select * from dbo.Vendas where cidade = '" + CidadeDestino + "'";
Neste cenario usuário é solicitado a inserir o nome de uma cidade. 
Se ele inserir Jaboticabal, a consulta criada pelo script terá a seguinte aparência:
SELECT * FROM dbo.Vendas WHERE cidade = 'Jaboticabal'
No entanto, suponha que o usuário insira: 'Jaboticabal'; DROP TABLE dbo.VENDAS --' 
Nesse caso, a seguinte consulta é gerada pelo script:
SELECT * FROM dbo.Vendas WHERE cidade = 'Jaboticabal'; DROP TABLE dbo.VENDAS --

O ponto-e-vírgula (;) denota o término de uma consulta e o início de outra. O hífen duplo (--) indica que o restante da linha atual é um comentário e deve ser ignorado. Se o código modificado estiver sintaticamente correto, será executado pelo servidor. Quando o SQL Server processar essa instrução, o SQL Server selecionará primeiro todos os registros em dbo.Vendas onde cidade é Jaboticabal. Em seguida, o SQL Server deletaria a tabela dbo.Vendas.
Contanto que o código SQL injetado esteja sintaticamente correto, a violação não poderá ser detectada programaticamente. Portanto, é necessário validar todas as entradas de usuário e verificar com cuidado o código que executa comandos SQL construídos no servidor que você está usando. Práticas recomendadas de codificação são descritas no proximo tópico.

Acompanhe:
http://scriptsemsql.blogspot.com.br/2016/09/prolepse-sql-injection-sql-server-part-2.html

Prolepse SQL Injection - SQL Server part 2

Analise todas as entradas:


Sempre valide entrada de usuário testando tipo, comprimento, formato e intervalo. Quando você estiver implementando precauções contra entrada mal-intencionada, considere os cenários de arquitetura e implantação de seu aplicativo. Lembre-se de que programas projetados para executar em um ambiente seguro podem ser copiados para um ambiente sem segurança. As sugestões seguintes devem ser consideradas práticas recomendadas:
  • Teste o tamanho e tipo de dados de entrada e imponha limites apropriados. Isso pode ajudar a impedir excesso deliberado de buffer.
  • Teste o conteúdo de variáveis de cadeia de caracteres e só aceite valores esperados. Rejeite entradas que contenham dados binários, seqüências de escape e caracteres de comentário. Isso pode ajudar a impedir injeção de script e proteger contra explorações de excesso de buffer.
  • Quando você estiver trabalhando com documentos XML, valide todos os dados em seu esquema à medida que são inseridos.
  • Nunca construa instruções Transact-SQL diretamente da entrada do usuário.
  • Use procedimentos armazenados para validar entrada de usuário.
  • Em ambientes de várias camadas, todos os dados devem ser validados antes de serem admitidos à zona de confiança. Os dados que não passam pelo processo de validação devem ser rejeitados e um erro deve ser retornado à camada anterior.
  • Implemente várias camadas de validação. Precauções tomadas contra usuários casualmente mal-intencionados podem ser ineficazes contra determinados invasores. Uma prática mais recomendada é validar a entrada na interface do usuário e em todos os pontos subseqüentes onde ele cruza um limite confiável.
    Por exemplo, a validação de dados em um aplicativo cliente pode evitar injeção de script simples. No entanto, se a próxima camada assumir que sua entrada já foi validada, qualquer usuário mal-intencionado que possa contornar um cliente poderá ter acesso irrestrito ao sistema.
  • Nunca concatene entrada de usuário que não seja validada. A concatenação de cadeia de caracteres é o ponto principal de entrada de injeção de script.
  • Não aceite as seguintes cadeias de caracteres em campos dos quais nomes de arquivos podem ser construídos: AUX, CLOCK$, COM1 a COM8, CON, CONFIG$, LPT1 a LPT8, NUL e PRN.

Sempre que puder, rejeite entrada que contenha os caracteres a seguir.

Use parâmetros SQL de tipo seguro

A coleção Parâmetros no SQL Server fornece verificação de tipo e validação de comprimento. Se você usar a coleção Parâmetros, a entrada será tratada como um valor literal e não como código executável. Um benefício adicional de usar a coleção Parâmetros é que você pode impor verificações de tipo e comprimento. Valores fora do intervalo irão disparar uma exceção. O seguinte fragmento de código mostra o uso da coleção Parâmetros:
SqlDataAdapter myCommand = new SqlDataAdapter("Usuario", conn);
myCommand.SelectCommand.CommandType = CommandType.StoredProcedure;
SqlParameter parm = myCommand.SelectCommand.Parameters.Add("@ID_Usuario",
SqlDbType.VarChar, 11);
parm.Value = Login.Text;
Nesse exemplo, o parâmetro @ID_Usuario é tratado como um valor literal e não como código executável. Esse valor é verificado quanto ao tipo e comprimento. Se o valor @ID_Usuario não estiver de acordo com o tipo especificado e as restrições de comprimento, uma exceção será gerada.

Filtrando a entrada

A filtragem de entrada também pode ser útil para proteger contra injeção de SQL, removendo caracteres de escape. Porém, por causa do número grande de caracteres que podem causar problemas, essa não é uma defesa confiável. O exemplo a seguir procura o delimitador de cadeia de caracteres.
private string SafeSqlLiteral(string inputSQL)
{
  return inputSQL.Replace("'", "''");
}

Cláusulas LIKE

Observe que se você estiver usando uma cláusula LIKE, os caracteres curinga ainda poderão escapar:
s = s.Replace("[", "[[]");
s = s.Replace("%", "[%]");
s = s.Replace("_", "[_]");

Revisando código para injeção SQL

Você deveria revisar todos os códigos que chamam EXECUTE, EXEC ou sp_executesql. Você pode usar consultas semelhantes à que segue para ajudá-lo a identificar procedimentos que contenham essas instruções.


SELECT object_Name(id) FROM syscomments
WHERE UPPER(text) LIKE '%EXECUTE  (%' 
OR UPPER(text) LIKE '%EXECUTE  (%'
OR UPPER(text) LIKE '%EXECUTE  (%' 
OR UPPER(text) LIKE '%EXECUTE  (%'
OR UPPER(text) LIKE '%EXEC (%' 
OR UPPER(text) LIKE '%EXEC (%'
OR UPPER(text) LIKE '%EXEC (%' 
OR UPPER(text) LIKE '%EXEC (%'
OR UPPER(text) LIKE '%SP_EXECUTESQL%'
SET @temp = N'select * from dbo.vendas where cidade ='''
+ REPLACE (@cidade,'''','''''') + N'''' 


Pensando em tudo isso a Microsoft lançou um kit de ferramentas que pretende auxiliar desenvolvedores e administradores de websites a bloquear e erradicar a recente onda de ataques de SQL Injection (Injeção SQL). 

As ferramentas são:

quinta-feira, 15 de setembro de 2016

Teste De Escalabilidade: Apache x IIS Off-Topic

Este é um teste simples de escalabilidade em comparativo entre Apache 2.2.3 e o IIS 7.










Este teste foi motivado por uma observação de clientes, que mencionam ter problemas de escalabilidade com o Apache. Eu tenho certeza que o Apache pode responder as requisições que o cliente precisa, mas por este percebemos que com a configuração padrão, isto não é possível, são necessários alguns tunings.
O Apache é o padrão do CentOS 5.5, mais atual.
O IIS é o padrão do Windows Server 2008 Enterprise.
(Obs: Todas as configurações padrões de ambas as distribuições foram mantidas default.)
O teste foi feito 3 vezes, com 10000 requisições, com concorrência de 1000, para o arquivo inicial de cada Web Server: iisstart.htm para o IIS, e index.html para o Apache.
Tanto o CentOS quanto o Windows estão em VMs, com a mesma configuração: 4GB RAM, 2 CPU. apenas uma VM foi ligada de cada vez.
IIS 7:
servidor@servidor-aplicacao:~$ ab -n 10000 -c 1000 http://192.168.56.101/issstart.html
Benchmarking 192.168.56.101 (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests
Server Software:        Microsoft-IIS/7.0
Server Hostname:     192.168.56.101
Server Port:               80
Document Path:          /issstart.html
Percentage of the requests served within a certain time (ms)
50%    881
66%    901
75%    906
80%    912
90%    940
95%   1039
98%   1081
99%   1092
100%   1124 (longest request)
Total of 1124 requests completed

Apache 2.2.3:

servidor@servidor-aplicacao:~$ ab -n 10000 -c 1000 http://192.168.56.102/index.html
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 192.168.56.102 (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
apr_socket_recv: Connection reset by peer (104)
Total of 6133 requests completed

servidor@servidor-aplicacao:~$

Conclusão

O IIS 7 escala melhor, as requisições são respondidas mais rapidamente, tanto individualmente quanto no total.
O Apache, além de respostas mais lentas, não atendeu todas sendo que no último teste atender apenas 61% das requisições.
Em um próximo Post irei executar o tuning do Apache para que este problema seja um pouco minimizado.

quarta-feira, 14 de setembro de 2016

Identificando super usuários - SQL Server

Identificando logins com permissões elevadas no SQL Server.

É uma informação crítica e vital caso você administre servidores de banco de dados  conhecer quem possui permissões elevadas.
O que defino aqui como login com permissão elevada é aquele que:
• Está incluído na role de servidor sysadmin;
• Está incluído na role de servidor securityadmin
• Possui a permissão de CONTROL SERVER;
O post traz um script básico com o intuito de identificar quem são eles:
Script
O script se divide em duas partes: a primeira analisa roles de servidor com permissões importantes (nesse caso, sysadmin e securityadmin).  A segunda analisa permissões de servidor (CONTROL SERVER, leia os motivos aqui). Ambas as partes ignoram logins desativados.
Customização a gosto do administrador: filtrar certificados, outras roles que você pode considerar importante (dbcreator por exemplo), considerar também logins desabilitados…
Espero que você não tenha surpresas ao localizar algum login de modo inesperado e que o script ajude alguém. Mas se encontrar, espero que você resolva da melhor forma possível antes de ter algum problema chato por causa de falha na segurança.
[]’s