Base64 y su vulnerable aplicación en el ofuscamiento de credenciales en la Autenticación Básica de HTTP/1.1 (+Ejemplo)

Imaginemos por un momento que tenemos el siguiente problema: queremos transmitir una fotografía, pero solo disponemos de una máquina de escribir mecánica, semejante a la que usó Hemingway para escribir El viejo y el mar. Sí, no es broma, piénsalo bien, incluso, si quieres sustituye la fotografía por un sonido.

Pudiera parecer un problema sobre el cual no tiene mucho sentido preocuparnos en la actualidad, sin embargo, si sustituimos la fotografía por un conjunto de datos binarios y la máquina de escribir por un protocolo de transmisión que solo permite él envió de caracteres imprimibles del código ASCII como SMTP, estaremos en presencia de una situación actual que por suerte se le dió solución a finales de la década de los 80.

La solución a la que me estoy refiriendo se denomina Base64 y su primera versión fue propuesta en el año 1987. La necesidad de darle soporte a sistemas y protocolos heredados y el aprovechamiento de ventajas implícitas de Base64 ha hecho posible su utilización hasta la fecha, por lo que se han emitido varios documentos normativos como la  RFC 4648 del año 2006 que abordan su estructura y situaciones de uso.

Base64 es ampliamente usado, hoy día, en las aplicaciones web para transmitir datos binarios en documentos XML, codificar datos binarios para que puedan ser incluidos en parámetros de URL, en campos de formularios HTML, en la codificación de ID de 128 bits, entre otros usos.

Base64 es un algoritmo para codificar/decodificar cualquier secuencia binaria en las letras mayúsculas y minúsculas del alfabeto latino [a..z] y [A..Z], los números[0..9] y los símbolos «+», «/». Se usa además el símbolo «=» para funciones de control en la especificación original. Existen varias versiones de Base64, pero todas se basan el principio simple que explicaré a continuación:

  1. El paquete binario que se quiere transmitir se divide en bloques de 24 bits (3 octetos).
  2. Cada bloque de 24 bits se divide en bloques de 6 bits.
  3. Para cada bloque de 6 bits se calcula su valor decimal. Dicho valor se tomará como el índice del carácter ASCII imprimible de Base64 que representará a dicho bloque en el mensaje a transmitir (Figura 1).
  4. Si el último bloque de 24 bits no puede completarse porque solo queda uno o dos octetos por codificar, entonces se rellenará con cero el bloque por los bits menos significativos (derecha) hasta completar el bloque de 24 bits.
    • El mensaje se finalizará con un carácter “=” si se rellenó con un octeto y con dos caracteres “==” si se rellenó con dos octetos.
Figura 1 - Tabla de índices Base64

Figura 1. Tabla de índices Base64. Tomado de la RFC 4648.

Apliquemos este algoritmo con un ejemplo sencillo. Para que sea más comprensible, en lugar de una secuencia binaria arbitraria tomemos la cadena .cu y encontremos su equivalente en Base64 (Figura 2).

  1. Determinemos el equivalente binario del código ASCII de cada carácter de la cadena .cu y secuenciemos dichos octetos en un bloque de 24 bits.
  2. Segmentemos en bloques de 6 bits, pueden apreciar como los bloques interiores toman bits de octetos diferentes.
  3. Calculemos el índice de cada carácter de Base64 mediante el valor decimal de cada bloque de 6 bits.
  4. Finalmente se obtiene la cadena LmN1 como resultado.
Figura 2 - Codificando la cadena .cu

Figura 2. Codificando la cadena “.cu”. Elaboración propia.

Para decodificar el mensaje se realiza la operación inversa. Puede apreciarse que es muy sencilla su implementación y actualmente muchos lenguajes de programación tiene funciones nativas de codificación y decodificación en Base64 como PHP y Python.

Por supuesto, en este ejemplo hemos visto una característica de Base64 que consiste en el aumento del tamaño de la información a transmitir. La cadena .cu solo tiene tres caracteres, sin embargo, su equivalente en Base64, LmN1, tiene cuatro caracteres. Esto resultaría solo un inconveniente si vamos a codificar caracteres imprimibles del código US-ASCII, y solo tendría sentido utilizarlo en el ofuscamiento de los datos transmitidos, como se explica en la próxima sección:

Aplicación de Base64 en el ofuscamiento de las credenciales de usuarios

Quizás una de las aplicaciones más conocidas sea el ofuscamiento de datos, sobre todo credenciales de usuarios e ID de sesión. Su utilización para este propósito, por desgracia, representa una vulnerabilidad para toda la aplicación web si la transmisión no se realiza sobre un canal encriptado.

Es cierto que un usuario común le será imposible interpretar una cadena en Base64 si no tiene una formación previa, sin embargo, un ciberdelincuente no tendría ninguna dificultad en decodificar la información. Para demostrarlo utilizaré una aplicación web denominada “OWASP ZAP Web Application Vulnerability Examples”. Esta aplicación web forma parte de la máquina virtual BWA de OWASP y como su nombre lo indica, contiene un conjunto de vulnerabilidades conocidas para que sean probadas con OWASP ZAP o con otras herramientas (Figura 3):

Figura 3 - Web Application Vulnerability Examples.png

Figura 3. Página de inicio de OWASP ZAP Web Application Vulnerability Examples. Elaboración propia.

Probaremos a decodificar las credenciales de un usuario enviadas en un proceso de autenticación básica. En la prueba utilizaré el usuario “henryraul” y como contraseña “miPASSWORD”(Figura 4).

Figura 4 - Autenticación Básica.png

Figura 4. Realizando la Autenticación Básica. Elaboración propia.

Luego de dar clic en el botón Aceptar,  vamos a revisar la información que fue transmitida al servidor web. Visualicémoslo con OWASP ZAP, el cual previamente lo habíamos configurado como proxy de intercepción(Figura 5):

Figura 5 - Credenciales codificadas en Base64

Figura 5. Detección de credenciales codificadas en Base64 con OWASP ZAP. Elaboración propia.

Podemos apreciar cómo se transmite la cadena aGVucnlyYXVsOm1pUEFTU1dPUkQ= como valor del campo de encabezado Authorization: Basic, la cual, si tenemos en cuenta el comportamiento de la autenticación básica, debe contener las credenciales del usuario. Para comprobarlo copiemos la cadena, ejecutemos Ctrl-E en OWASP ZAP y usemos la opción de decodificación:

Figura 6 - Credenciales decodificadas con Base64.png

Figura 6. Decodificación de credenciales en Base64 con OWASP ZAP. Elaboración propia.

Puede apreciarse con qué facilidad la cadena es decodifica, mostrando el nombre de usuario y la contraseña, separados por dos puntos.

En este ejemplo no se transmite la información como parámetro de la URL, si se hiciera fuera incluso más sencillo obtener esta información mediante la lectura de las trazas y el historial de navegación del usuario.

En mi opinión, es muy importante que los desarrolladores conozcan cómo utilizar adecuadamente la codificación Base64. En ocasiones damos por seguro determinados mecanismos cuando en realidad no lo son, por ese motivo es importante revisar la información que se transmite usando Base64 con la misma atención que si se estuviera transmitiendo en texto plano, porque, a decir verdad, para un atacante, como demostré en esta entrada, es como si fuera texto plano.

Espero que te haya gustado el post, yo por mi parte me he divertido bastante escribiéndolo.

S4lud0s y h4st4 el próx1m0 p0st!!!

4 comentarios en “Base64 y su vulnerable aplicación en el ofuscamiento de credenciales en la Autenticación Básica de HTTP/1.1 (+Ejemplo)

  1. Pingback: Por qué la Autenticación Básica de HTTP/1.1 es vulnerable (+Ejemplo) | Behique Digital

  2. Pingback: ¿Tu aplicación web es vulnerable a un Ataque de Escalada de Privilegios? Analízalo con la OTG-AUTHZ-003 para que salgas de dudas (+Ejemplo) | Behique Digital

  3. Reto: ¿Cual es el mensaje contenido en el código siguiente?

    4oCcSGFjZXIgZXMgbGEgbWVqb3IgbWFuZXJhIGRlIGRlY2ly4oCdLiBGcmFzZSBkZSBKb3PD
    qSBNYXJ0w60sIHBvbMOtdGljbywgcGVuc2Fkb3IsIGVzY3JpdG9yLCBwZXJpb2Rpc3RhLCBm
    aWzDs3NvZm8geSBwb2V0YSBjdWJhbm8gKDE4NTMtMTg5NSk=

    Le gusta a 1 persona

Deja un comentario