Este fim de semana na 28C3 Alexander “alech” Klink and Julian “zeri” Wälde apresentaram DoS efetivo contra plataformas de aplicações web que pode fazer um server ficar com 99% de CPU ocupada usando poucos recursos.

Nos meus testes, um simples post HTTP, com cerca de 100k hashes colididos (cerca de 1,2MB) deixou uma thread do servidor por horas usando 99% de CPU, conforme a imagem abaixo:

Hash Collision

Se mais thread forem usadas, o servidor ficará facilmente sobrecarregado. No estudo, alech e zeri concluiram que com uma conexão de 30 kbits/s é suficiente para manter uma thread de um Core2 usando 99% de CPU indefinidamente, em um servidor rodando ASP .net. E uma conexão de 1 Gbit/s conseguirá ocupar cerca de ~30k thread do Core2. Um atacante por facilmente derrubar um pequeno datacenter usando uma conexão banda larga comum.

O Ataque

O problema ocorre pela forma como o ASP .net gerencia Forms, Cookies, Session e Query Strings. Todas essas coleções são armazenadas usando a NameValueCollection, que internamente usa StringComparer.OrdinalIgnoreCase para obter o hash das strings.

A função GetHashCode pode retornar valores iguais para strings diferentes e o método usado para calcular o hash é conhecido e pode ser adivinhado. O atacante pode gerar uma grande coleção de hashes colididos para postar em qualquer página ASP .net. O servidor tentará construir o objeto Request, e por causa das chaves colididas do Form, a chaves do NameValueCollection levarão muito tempo para serem criadas e o servidor utilizará muita CPU para comparar todos os valores.

Nos meus testes, usando IIS 7.5 e ASP .net 4.0, o servidor levou mais de uma hora usando 99% na thread afetada. O servidor não pode parar o processamento no tempo padrão (90s) porque a requisição foi afetada no começo do Pipeline do ASP .net.

A solução

Um módulo HTTP que verifique a requisição antes dela ser passada ao ASP .net e que pode para-lá caso um ataque seja detectado.

Eu comecei a criar este módulo, que é funcional mas não está pronto para uso em produção. Por enquanto, é para estudos, visto que a descoberta da falha ainda é recente.

O módulo HTTP e seu código fonte pode ser baixado do GitHub.

Qualquer comentário para ajudar a melhorar e garantir qualidade de produção ao módulo são bem vindos.