Como os hackers dominam sites com injeção de SQL e DDoS
Mesmo que você tenha acompanhado apenas vagamente os eventos dos grupos de hackers Anonymous e LulzSec, você provavelmente já ouviu falar de sites e serviços sendo invadidos, como os famosos hacks da Sony. Você já se perguntou como eles fazem isso??
Há várias ferramentas e técnicas que esses grupos usam e, embora não tentemos fornecer um manual para você mesmo, é útil entender o que está acontecendo. Dois dos ataques que você ouviu consistentemente sobre eles usando “Negação de serviço (distribuída)” (DDoS) e “SQL Injections” (SQLI). Veja como eles funcionam.
Imagem por xkcd
Ataque de negação de serviço
O que é isso?
Um ataque de “negação de serviço” (às vezes chamado de “negação de serviço distribuída” ou DDoS) ocorre quando um sistema, neste caso um servidor web, recebe tantas solicitações de uma só vez que os recursos do servidor estão sobrecarregados que o sistema simplesmente bloqueia e desliga. A meta e o resultado de um ataque DDoS bem-sucedido é que os sites no servidor de destino não estão disponíveis para legitimar solicitações de tráfego.
Como funciona?
A logística de um ataque DDoS pode ser melhor explicada por um exemplo.
Imagine um milhão de pessoas (os atacantes) se unirem com o objetivo de prejudicar os negócios da Empresa X derrubando o seu call center. Os atacantes coordenam para que, na terça-feira, às 9 horas, todos eles liguem para o número de telefone da empresa X. Muito provavelmente, o sistema telefônico da Empresa X não será capaz de lidar com um milhão de chamadas ao mesmo tempo, então todas as linhas de entrada serão amarradas pelos atacantes. O resultado é que chamadas de clientes legítimas (ou seja, aquelas que não são os invasores) não passam porque o sistema de telefonia está preso ao tratamento das chamadas dos invasores. Então, em essência, a Empresa X está potencialmente perdendo negócios devido ao fato de as solicitações legítimas não conseguirem passar.
Um ataque DDoS em um servidor da Web funciona exatamente da mesma maneira. Como não há praticamente nenhuma maneira de saber qual tráfego é originado de solicitações legítimas vs. invasores até que o servidor da Web esteja processando a solicitação, esse tipo de ataque é normalmente muito eficaz.
Executando o ataque
Devido à natureza “força bruta” de um ataque DDoS, você precisa ter muitos computadores todos coordenados para atacar ao mesmo tempo. Revisitando o nosso exemplo de central de atendimento, isso exigiria que todos os invasores soubessem ligar às 9h e realmente ligarem naquele momento. Embora este princípio certamente funcione quando se trata de atacar um servidor web, torna-se significativamente mais fácil quando computadores zumbis, em vez de computadores tripulados, são utilizados.
Como você provavelmente sabe, existem muitas variantes de malware e trojans que, uma vez em seu sistema, ficam inativos e ocasionalmente “telefonam para casa” para obter instruções. Uma dessas instruções poderia, por exemplo, enviar solicitações repetidas para o servidor da Web da Empresa X às 9h. Assim, com uma única atualização para o local de origem do respectivo malware, um único invasor pode coordenar instantaneamente centenas de milhares de computadores comprometidos para executar um ataque DDoS em massa..
A beleza de utilizar computadores zumbis não é apenas em sua eficácia, mas também em seu anonimato, já que o invasor não precisa realmente usar seu computador para executar o ataque..
Ataque de injeção de SQL
O que é isso?
Um ataque de “injeção de SQL” (SQLI) é uma exploração que tira proveito de técnicas de desenvolvimento da Web insatisfatórias e, normalmente combinadas com a segurança de banco de dados defeituosa. O resultado de um ataque bem-sucedido pode variar de representação de uma conta de usuário a um comprometimento total do respectivo banco de dados ou servidor. Ao contrário de um ataque DDoS, um ataque SQLI é completamente e facilmente evitável se um aplicativo da Web for programado adequadamente.
Executando o ataque
Sempre que você fizer login em um site e digitar seu nome de usuário e senha, para testar suas credenciais, o aplicativo da Web poderá executar uma consulta como a seguinte:
SELECT UserID FROM Usuários WHERE UserName = "myuser" AND Password = "mypass";
Nota: valores de string em uma consulta SQL devem ser colocados entre aspas simples, e é por isso que eles aparecem em torno dos valores inseridos pelo usuário.
Portanto, a combinação do nome de usuário (myuser) e senha (mypass) deve corresponder a uma entrada na tabela Usuários para que um UserID seja retornado. Se não houver correspondência, nenhum UserID será retornado, portanto, as credenciais de login serão inválidas. Embora uma implementação específica possa ser diferente, a mecânica é bastante normal.
Então, agora vamos olhar para uma consulta de autenticação de modelo que podemos substituir os valores que o usuário digita no formulário da web:
SELECT UserID FROM Usuários WHERE UserName = "[user]" AND Password = "[pass]"
À primeira vista, isso pode parecer um passo direto e lógico para validar facilmente os usuários, no entanto, se uma substituição simples dos valores inseridos pelo usuário for realizada nesse modelo, ele será suscetível a um ataque de SQLI..
Por exemplo, suponha que “myuser'-” seja inserido no campo de nome de usuário e “wrongpass” seja inserido na senha. Usando a substituição simples em nossa consulta de modelo, obteríamos isso:
SELECT UserID FROM Usuários WHERE UserName = "myuser" - 'AND Password = "wrongpass"
Uma chave para essa afirmação é a inclusão dos dois traços (-)
. Este é o token de comentário inicial para instruções SQL, portanto, qualquer coisa que apareça após os dois traços (inclusive) será ignorada. Essencialmente, a consulta acima é executada pelo banco de dados como:
SELECT UserID FROM Usuários WHERE UserName = "myuser"
A omissão gritante aqui é a falta da verificação de senha. Ao incluir os dois traços como parte do campo do usuário, ignoramos completamente a condição de verificação de senha e conseguimos fazer o login como "myuser" sem saber a respectiva senha. Esse ato de manipular a consulta para produzir resultados não intencionais é um ataque de injeção de SQL.
Que danos podem ser causados?
Um ataque de injeção de SQL é causado por codificação de aplicativo negligente e irresponsável e é completamente evitável (o que abordaremos em breve), no entanto, a extensão do dano que pode ser feito depende da configuração do banco de dados. Para que um aplicativo da Web se comunique com o banco de dados de back-end, o aplicativo deve fornecer um login ao banco de dados (observe que isso é diferente de um login de usuário no próprio site). Dependendo das permissões que o aplicativo da Web requer, essa conta do banco de dados pode exigir qualquer coisa, desde a permissão de leitura / gravação em tabelas existentes, até o acesso total ao banco de dados. Se isso não estiver claro agora, alguns exemplos devem ajudar a fornecer alguma clareza.
Com base no exemplo acima, você pode ver isso inserindo, por exemplo, "youruser '-", "admin' -"
ou qualquer outro nome de usuário, podemos instantaneamente acessar o site como aquele usuário sem saber a senha. Uma vez que estamos no sistema, não sabemos que não somos realmente aquele usuário, então temos acesso total à respectiva conta. As permissões de banco de dados não fornecerão uma rede de segurança para isso, porque, normalmente, um site deve ter pelo menos acesso de leitura / gravação ao respectivo banco de dados.
Agora, vamos supor que o site tenha controle total de seu respectivo banco de dados, que permite excluir registros, adicionar / remover tabelas, adicionar novas contas de segurança, etc. É importante observar que alguns aplicativos da Web podem precisar desse tipo de permissão. não é automaticamente uma coisa ruim que o controle total é concedido.
Assim, para ilustrar o dano que pode ser feito nessa situação, usaremos o exemplo fornecido na história em quadrinhos acima, inserindo o seguinte no campo de nome de usuário: "Robert '; DROP TABLE Users; -".
Após a simples substituição, a consulta de autenticação se torna:
SELECT UserID FROM Usuários WHERE UserName = "Robert"; Usuários DROP TABLE; - 'AND Password = "wrongpass"
Nota: o ponto-e-vírgula está em uma consulta SQL é usado para indicar o final de uma instrução específica e o início de uma nova instrução.
Qual é executado pelo banco de dados como:
SELECT UserID FROM Usuários WHERE UserName = "Robert"
DROP TABLE Users
Então, assim, usamos um ataque SQLI para excluir toda a tabela Usuários.
Naturalmente, muito pior pode ser feito, pois, dependendo das permissões SQL permitidas, o invasor pode alterar valores, despejar tabelas (ou o próprio banco de dados inteiro) em um arquivo de texto, criar novas contas de login ou até seqüestrar toda a instalação do banco de dados..
Impedindo um ataque de injeção de SQL
Como mencionamos várias vezes anteriormente, um ataque de injeção SQL é facilmente evitável. Uma das regras principais do desenvolvimento web é que você nunca confia cegamente na entrada do usuário como fizemos quando fizemos uma simples substituição na nossa consulta de modelo acima.
Um ataque SQLI é facilmente frustrado pelo que é chamado de saneamento (ou escape) de suas entradas. O processo de higienização é realmente bastante trivial, pois tudo o que ele faz essencialmente é manipular qualquer caractere de aspas simples (') embutido apropriadamente, de tal modo que eles não possam ser usados para encerrar prematuramente uma cadeia dentro de uma instrução SQL..
Por exemplo, se você quisesse pesquisar “O'neil” em um banco de dados, não poderia usar a substituição simples porque a aspa simples após o O faria com que a cadeia terminasse prematuramente. Em vez disso, você limpa usando o caractere de escape do respectivo banco de dados. Vamos supor que o caractere de escape para uma aspa simples embutida esteja precedendo cada citação com um símbolo \. Então, "O'Neal" seria higienizado como "O \ 'neil".
Esse simples ato de saneamento praticamente impede um ataque de SQLI. Para ilustrar, vamos revisitar nossos exemplos anteriores e ver as consultas resultantes quando a entrada do usuário for higienizada.
myuser '--
/ passagem errada:
SELECT UserID FROM Usuários WHERE UserName = "myuser \" - 'AND Password = "wrongpass"
Como a aspa simples após myuser é escapada (significando que é considerada parte do valor de destino), o banco de dados literalmente procurará pelo UserName de "myuser '-".
Além disso, como os traços são incluídos no valor da string e não na própria instrução SQL, eles serão considerados parte do valor de destino, em vez de serem interpretados como um comentário SQL.
Robert '; DROP TABLE Usuários;--
/ passagem errada:
SELECT UserID FROM Usuários WHERE UserName = "Robert \"; Usuários DROP TABLE; - 'AND Password = "wrongpass"
Simplesmente escapando da aspas simples depois de Robert, tanto o ponto-e-vírgula quanto os traços estão contidos na string de pesquisa UserName para que o banco de dados procure literalmente "Robert '; DROP TABLE Users; -"
em vez de executar a tabela delete.
Em suma
Embora os ataques na Web evoluam e se tornem mais sofisticados ou se concentrem em um ponto de entrada diferente, é importante lembrar-se de proteger contra ataques testados e verdadeiros que foram a inspiração de várias “ferramentas de hackers” disponíveis para explorá-las..
Certos tipos de ataques, como o DDoS, não podem ser facilmente evitados, enquanto outros, como o SQLI, podem ser evitados. No entanto, os danos que podem ser causados por esses tipos de ataques podem variar de inconvenientes a catastróficos, dependendo das precauções tomadas..