Há algum tempo um banco passou a utilizar um sistema de verificação do computador do qual é realizado o acesso a seu sistema de internet banking, oferecendo suporte a diferentes sistemas operacionais incluindo Linux. O funcionamento desse sistema pode ser facilmente inferido com base nas chamadas feitas pela biblioteca de autenticação, dos símbolos públicos disponíveis e um pouco de dedução. O método utilizado é surpreendentemente simples tanto em conceito como em implementação; a descrição a seguir, obtida de uma breve análise das chamadas e símbolos disponíveis, pode ser de interesse dos usuários do sistema que desejem saber mais sobre os dados que são coletados de seus computadores.

O sistema de autenticação de máquina gera um hash a partir de dados coletados de diferentes componentes de hardware e de uma senha recebida. Os dados coletados são características do processador, memória, disco rígido e placa de rede.

  • Processador: concatenação em ASCII de valores hexadecimais de registradores retornados por várias chamadas à instrução cpuid.
  • Memória: representação decimal em ASCII de um valor derivado da quantidade de memória física ou tamanho do /proc/kcore.
  • Disco rígido: concatenação em ASCII das strings de modelo e capacidade.
  • Rede: representação ASCII do MAC address da interface em hexadecimal.

As strings de dados coletadas são processadas através da geração de hashes MD5 (utilizando a implementação de L. Peter Deutsch, Aladdin Enterprises) e posteriormente criptografadas. Os dados são reduzidos a um vetor de 32 bytes resultantes da concatenação de dois hashes MD5: o primeiro é calculado sobre as strings de CPU, HD e rede, e o segundo sobre CPU, memória, HD e rede. O algoritmo de criptografia utilizado é um triplo DES em modo EDE (utilizando um port de porções da biblioteca de criptografia em Java publicado pelo Legion of Bouncy Castle). As chaves utilizadas são a primeira metade do hash MD5 da string de senha de sessão para a primeira invocação, a segunda metade do hash MD5 da string de senha de sessão para a segunda invocação, e os bytes ímpares do hash MD5 da string de senha de sessão para a terceira invocação.

Alguns problemas de implementação reduzem a unicidade e a não-previsibilidade do hash gerado: a leitura dos dados de HD presume a existência de /proc/ide/hda e sistemas que utilizam SATA, SCSI ou libata (quase todos) retornarão uma string vazia, há considerável perda de precisão no processamento dos dados de memória obtidos, e o sistema requer a existência de uma interface chamada “eth0″ (que é, contudo, o caso mais comum), ou a string retornada será vazia. Adicionalmente, computadores similares (de mesmo modelo e configuração) diferirão apenas no MAC address da interface ethernet. O único dado que não pode ser estimado (endereço da interface de rede) pode ser obtido através de rede local, ou a totalidade dos dados pode ser obtida através da execução de um programa simples no computador em questão. Com base no hash que identifica o computador, é trivial simulá-lo a partir de outro sistema (bastando aplicar TDES-EDE com a senha fornecida). A utilização de dados redundantes ou de domínio restrito em vários pontos do sistema também sugere implicações nos valores calculados, mas a conseqüência exata só pode ser obtida por criptoanálise do algoritmo completo.

Exemplo de dados coletados (criptografia final feita sobre a senha “Avis Durgan”):

getCpu  = 68747541444D416369746E65681020444D41706D6553286E6F7220296D74303632202B30000000
getCpu2 = 68747541444D416369746E65681
getMem  = 512
getHd   = SAMSUNG SP0802N156368016
getHd2  = SAMSUNG SP0802N156368016
getNet  = 0011D80F05B0
in      = 30fbba7e84996466d9bde8fa04a7331835ee34e07e558cbc431beafd09857037
key     = 19fd912f8298a7e3859b3c6f5c81c48b199182a7853c5cc4
out     = 7ecb212d30b9701c784fe36b2384e4ef108c7b4109d9ea307b07e9b39b1afb65

O valor final pode ser obtido da biblioteca original com o seguinte programa em Java:

public class Kta
{
        static {
                System.loadLibrary("the_lib");
        }
        public native byte[] nfl(String s);
}

public class Test
{
        public static void main(String[] argv) {
                tzy.Kta fnord = new tzy.Kta();
                byte a[] = fnord.nfl(”Avis Durgan”);
        }
}

12 Responses to “Análise: autenticação Linux”

  1. tobias_felipe says:

    Qual é o seu banco para eu Não utiliza-lo?

  2. navegantes.blog says:

    Site do BB não anda e masca chiclete ao mesmo tempo…

    O site do Banco do Brasil tem uma política de cadastro de micros para a realização de tarefas pela internet. Algumas operações apenas são possíveis em máquinas previamente cadastradas, especialmente pagamentos e transferências. Metodologia cha…

  3. Rodrigo says:

    Qual banco usa isso ?

  4. rafa says:

    caro, você não comentou nada específico sobre, queria saber se você vê chances do sistema ser usado para outros métodos que não o previsto e se ele está coletando informações que podem ser usadas por pelo banco ou terceiros com má intenção. o que acha?

  5. claudio says:

    O nome do banco em questão foi intencionalmente omitido. Quanto ao destino das informações, apenas um hash é enviado à camada superior e quem tiver acesso a este hash, seja o banco ou terceiros, poderá apenas verificar se algum dos elementos cujos dados foram coletados foi modificado.

  6. Daniel Dantas says:

    Eu sei qual o banco. É o meu banco. heheheh

    Na verdade, já meio que sabia que essa informação poderia ser facilmente copiada.

    Só estou tranquilo porque existem outras proteções para a conta e que parece que o próprio banco não considera essa proteção inquebrável.

    Isso mostra que segurança não é um programa e sim uma política. Usuários que não se importam com segurança de senhas ou com pragas virtuais vão ser atacados, mais cedo ou mais tarde.

  7. Jardel Weyrich says:

    Apesar do banco em questão utilizar code-obfuscation, escolheram a tecnologia errada para o caso.
    Mas se isso assustou a todos, procurem informações sobre os métodos que os outros utilizam, e ficarão pasmos.
    Infelizmente nunca tive tempo para analisar todos, mas com certeza podemos contar nos dedos de 1 mão os que se salvam.
    Bom trabalho claudio.

  8. claudio says:

    O envio de informação criptografada por TDES pelo mesmo canal por onde trafega a chave realmente não é um exemplo de bom uso de criptografia.

  9. Mauricio says:

    Amigo, parabéns por fazer um artigo tão detalhado, é realmente raro ler coisas assim na internet. Seu blog vai para meus favoritos.

  10. Marcio says:

    Cláudio, parabéns pelo artigo, realmente bem completo.
    Estou concluindo o curso de Ciência da Computação e estou desenvolvendo uma pesquisa sob orientação de um renomado pesquisador na área de segurança.
    A pesquisa consiste em avaliar a possibilidade de comprometimento dos mecanismo de segurança implementados pelos e-bankings no brasil.
    O objetivo final é formatar um artigo que pretendo submeter a alguns eventos, entre eles o SBSEG2008.
    Já consegui comprometer alguns mecanismos implementados e estou nesse exato momento estudando esse processo de autenticação dos computadores.
    Como não tenho muita experiência na engenharia reversa de bibliotecas, estou gastando bastante tempo para concluir essa etapa.
    Caso tenha interesse em participar desse trabalho, favor entrar em contato o quanto.

  11. Ronaldo Toledo says:

    Olá Cláudio.

    Fiquei com uma dúvida e imagino que vc possa facilmente dirimi-la. Não sou programador web, entendo muito pouco de javascript e sei que ele não permite acesso a informações do sistema. Tomando isto como premissa, pergunto: Como o banco tem acesso a estas informações?

    Um abraço.

  12. claudio says:

    Ele usa uma biblioteca em C para isso, que é chamada através de JNI.

Leave a Reply