12 de out de 2015

Revertendo a base64

A codificação base64 é usada para transmitir dados binários por meios de transmissão que lidam somente com texto, como por exemplo o protocolo SMTP ou o próprio HTTP que foi projetado para transferir textos ASCII, assim como imagens (que são convertidas em texto ASCII).

As conexões TCP suportam transmissão de bytes com 8 bits. Os dados do protocolo SMTP são caracteres ASCII de 7 bits, onde cada caractere é transmitido como um byte de 8 bits com o bit mais significativo zerado. No entanto, o protocolo SMTP interpreta o octeto 998 ou o caractere '.' como sendo uma nova linha, podendo gerar danos aos arquivos que contenham essa sequência de octetos. Assim, a conversão de bytes para ASCII tem sido bastante útil.

Conversão:
Na conversão da base64 o arquivo é dividido em bytes de 6 bits gerando 64 (0...63) possíveis valores, que são representados pelos caracteres: [A-Z] para (0-25)[a-z] para (26-51)[0-9] para (52-61)'+' para 62, '/' para 63 e '=' para adição, dando origem ao seu nome. A codificação da base64 não deve ser confundida com criptografia pois ela não garante nenhuma segurança.

Um caractere ASCII codificado pela base64 representa 6 bits da base2 (sistema binário). Sendo 24 o múltiplo comum de 8 e 6:
3 bytes = 4 caracteres da base64 = 24 bits da base2

Por exemplo, a palavra 'Bob' ficaria 'Qm9i' na base64, 'B,o,b' armazenado como os bytes '66,111,98', ficando '010000100110111101100010' no buffer de 24 bits.

Texto B o b
ASCII 66 111 98
base2 01000010 01101111 01100010
6 bits (2) 010000 100110 111101 100010
6 bits (10) 16 38 61 34
base64 Q m 9 i

O exemplo acima nos mostra que a base64 converte 3 bytes não codificados (simples caracteres ascii) em 4 caracteres ascii codificados. Se o tamanho do array do byte não for múltiplo de 3, o algoritmo anexa o sinal '=' (um para cada byte que falta) no final da string codificada pela base64. Então podemos ter 0, 1 ou 2 sinais de igual no final. Essa conversão garante que o tamanho da string seja sempre múltiplo de 4. O tamanho da string codificada pode ser calculada assim:
base64 = ((bytes+3 - (Bytes%3))/3) x 4

Por exemplo, se temos um array contendo 7 caracteres como a string ascii 'zeldani', o tamanho da string codificada pela base64 pode ser calculada dessa forma:
>>> ((7+3-(7%3))/3)*4
12
>>> s='zeldani'
>>> s.encode('base64')
'emVsZGFuaQ==\n'

Revertendo a base64:
Em um dos desafios do ctf-2014 do ASIS foi fornecido uma chave: 
qvnju181mjziote0zge4mdk0odi4odfmnmnmnmi5zjm2yzy3mq== 
na qual o desafio seria encontrar o significado da mensagem.

Como temos dois '==' no final da string podemos deduzir que se trata de uma codificação da base64 e fora isso o tamanho da string é 52 sendo múltiplo de 4, confirmando a base64. Como sabemos que a cada 3 bytes é gerado 4 caracteres, podemos quebrar a string em grupos de 4 bytes:
s='qvnju181mjziote0zge4mdk0odi4odfmnmnmnmi5zjm2yzy3mq=='
for i in range(0,52,4):
    a=s[i:i+4]       
    print a

Depois podemos converter cada grupo com a base64 e verificar os resultados, por exemplo o primeiro grupo: 'QVNJ' resulta em 'ASIS'. Fazendo uma permutação entre letras maiúsculas e minúsculas (para excluir caracteres estranhos):
import itertools
k=map(''.join, itertools.product(*zip(chave.upper(), chave.lower())))
    for i in k:
nk=i.decode('base64')

Obtemos: ASIS_526b914da809482881f6cf6b9f36c671

* Fontes:
https://pt.wikipedia.org/wiki/Base64
http://rayan-king.blogspot.com.br/2010/07/understanding-base64-encoding.html
https://daemoniolabs.wordpress.com/2011/09/09/codificacao-base64-em-c/
http://blog.rlr-uk.com/2011/03/base64-encoding-is-not-cryptography.html
https://beagleharrier.wordpress.com/2014/10/13/asis-ctf-finals-2014caplow-writeup/#more-5

1 comentários:

Unknown disse...
Este comentário foi removido pelo autor.

Postar um comentário