hacktricks/crypto-and-stego/padding-oracle-priv.md

8.7 KiB

Padding Oracle

{% hint style="success" %} Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks
{% endhint %}

CBC - Cipher Block Chaining

In CBC mode the previous encrypted block is used as IV to XOR with the next block:

https://defuse.ca/images/cbc_encryption.png

To decrypt CBC the opposite operations are done:

https://defuse.ca/images/cbc_decryption.png

Notice how it's needed to use an encryption key and an IV.

Message Padding

As the encryption is performed in fixed size blocks, padding is usually needed in the last block to complete its length.
Usually PKCS7 is used, which generates a padding repeating the number of bytes needed to complete the block. For example, if the last block is missing 3 bytes, the padding will be \x03\x03\x03.

Let's look at more examples with a 2 blocks of length 8bytes:

byte #0 byte #1 byte #2 byte #3 byte #4 byte #5 byte #6 byte #7 byte #0 byte #1 byte #2 byte #3 byte #4 byte #5 byte #6 byte #7
P A S S W O R D 1 2 3 4 5 6 0x02 0x02
P A S S W O R D 1 2 3 4 5 0x03 0x03 0x03
P A S S W O R D 1 2 3 0x05 0x05 0x05 0x05 0x05
P A S S W O R D 0x08 0x08 0x08 0x08 0x08 0x08 0x08 0x08

Note how in the last example the last block was full so another one was generated only with padding.

Padding Oracle

When an application decrypts encrypted data, it will first decrypt the data; then it will remove the padding. During the cleanup of the padding, if an invalid padding triggers a detectable behaviour, you have a padding oracle vulnerability. The detectable behaviour can be an error, a lack of results, or a slower response.

If you detect this behaviour, you can decrypt the encrypted data and even encrypt any cleartext.

How to exploit

You could use https://github.com/AonCyberLabs/PadBuster to exploit this kind of vulnerability or just do

sudo apt-get install padbuster

Pour tester si le cookie d'un site est vulnérable, vous pourriez essayer :

perl ./padBuster.pl http://10.10.10.10/index.php "RVJDQrwUdTRWJUVUeBKkEA==" 8 -encoding 0 -cookies "login=RVJDQrwUdTRWJUVUeBKkEA=="

L'encodage 0 signifie que base64 est utilisé (mais d'autres sont disponibles, consultez le menu d'aide).

Vous pourriez également exploiter cette vulnérabilité pour chiffrer de nouvelles données. Par exemple, imaginez que le contenu du cookie est "user=MyUsername", alors vous pourriez le changer en "_user=administrator_" et élever les privilèges à l'intérieur de l'application. Vous pourriez également le faire en utilisant paduster en spécifiant le paramètre -plaintext :

perl ./padBuster.pl http://10.10.10.10/index.php "RVJDQrwUdTRWJUVUeBKkEA==" 8 -encoding 0 -cookies "login=RVJDQrwUdTRWJUVUeBKkEA==" -plaintext "user=administrator"

Si le site est vulnérable, padbuster essaiera automatiquement de trouver quand l'erreur de remplissage se produit, mais vous pouvez également indiquer le message d'erreur en utilisant le paramètre -error.

perl ./padBuster.pl http://10.10.10.10/index.php "" 8 -encoding 0 -cookies "hcon=RVJDQrwUdTRWJUVUeBKkEA==" -error "Invalid padding"

La théorie

En résumé, vous pouvez commencer à déchiffrer les données chiffrées en devinant les valeurs correctes qui peuvent être utilisées pour créer tous les différents remplissages. Ensuite, l'attaque de l'oracle de remplissage commencera à déchiffrer les octets de la fin au début en devinant quelle sera la valeur correcte qui crée un remplissage de 1, 2, 3, etc.

Imaginez que vous avez un texte chiffré qui occupe 2 blocs formés par les octets de E0 à E15.
Pour déchiffrer le dernier bloc (E8 à E15), tout le bloc passe par le "décryptage par bloc" générant les octets intermédiaires I0 à I15.
Enfin, chaque octet intermédiaire est XORé avec les octets chiffrés précédents (E0 à E7). Donc :

  • C15 = D(E15) ^ E7 = I15 ^ E7
  • C14 = I14 ^ E6
  • C13 = I13 ^ E5
  • C12 = I12 ^ E4
  • ...

Maintenant, il est possible de modifier E7 jusqu'à ce que C15 soit 0x01, ce qui sera également un remplissage correct. Donc, dans ce cas : \x01 = I15 ^ E'7

Ainsi, en trouvant E'7, il est possible de calculer I15 : I15 = 0x01 ^ E'7

Ce qui nous permet de calculer C15 : C15 = E7 ^ I15 = E7 ^ \x01 ^ E'7

Sachant C15, il est maintenant possible de calculer C14, mais cette fois en forçant le remplissage \x02\x02.

Ce BF est aussi complexe que le précédent car il est possible de calculer le E''15 dont la valeur est 0x02 : E''7 = \x02 ^ I15 donc il suffit de trouver le E'14 qui génère un C14 égal à 0x02.
Ensuite, suivez les mêmes étapes pour déchiffrer C14 : C14 = E6 ^ I14 = E6 ^ \x02 ^ E''6

Suivez cette chaîne jusqu'à ce que vous déchiffriez tout le texte chiffré.

Détection de la vulnérabilité

Enregistrez un compte et connectez-vous avec ce compte.
Si vous vous connectez plusieurs fois et obtenez toujours le même cookie, il y a probablement quelque chose de mal dans l'application. Le cookie renvoyé devrait être unique chaque fois que vous vous connectez. Si le cookie est toujours le même, il sera probablement toujours valide et il n'y aura aucun moyen de l'invalider.

Maintenant, si vous essayez de modifier le cookie, vous pouvez voir que vous obtenez une erreur de l'application.
Mais si vous BF le remplissage (en utilisant padbuster par exemple), vous parvenez à obtenir un autre cookie valide pour un utilisateur différent. Ce scénario est très probablement vulnérable à padbuster.

Références

{% hint style="success" %} Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks
{% endhint %}