
PoC per innescare un buffer overflow tramite CVE-2020-0796
./CVE-2020-0796.py servername
Questo script si connette all'host di destinazione e comprime la richiesta di autenticazione con un campo offset errato impostato nell'intestazione di trasformazione, causando un buffer overflow nel decompressore e mandando in crash il target.
Questo contiene una modifica dell'eccellente smbprotocol con supporto aggiunto per la compressione/decompressione SMB 3.1.1 (solo LZNT1). La maggior parte delle aggiunte si trovano in smbprotocol/connection.py. È inclusa una versione di lznt1, modificata per supportare Python 3.
L'intestazione di trasformazione della compressione si trova nella classe SMB2CompressionTransformHeader lì. La funzione _compress viene chiamata per comprimere le richieste di tree. È qui che il campo offset viene impostato tutto alto per scatenare il crash.
def _compress(self, b_data, session):
header = SMB2CompressionTransformHeader()
header['original_size'] = len(b_data)
header['offset'] = 4294967295
header['data'] = smbprotocol.lznt1.compress(b_data)
CVE-2020-0796 è un bug nella nuova funzionalità di compressione SMB3 di Windows 10 1903/1909. Il protocollo SMB versione 3.1.1 introduce la capacità per un client o server di annunciare le capacità di compressione e di comprimere selettivamente i messaggi SMB3 quando vantaggioso. Per fare ciò, durante la negoziazione di una sessione SMB, il client e il server devono entrambi includere una SMB2_COMPRESSION_CAPABILITIES come documentato in MS-SMB2 2.2.3.1.3.
Una volta negoziata una sessione con questa capacità, sia il client che il server possono comprimere selettivamente alcuni messaggi SMB. Per farlo, l'intero pacchetto SMB viene compresso e un'intestazione trasformata viene preposta, come documentato in MS-SMB2 2.2.42. Questa intestazione è una piccola struttura (16 byte) con un valore magico, la dimensione dei dati non compressi, l'algoritmo di compressione utilizzato e un valore di offset.
CVE-2020-0796 è causato da una mancanza di controllo dei limiti in quella dimensione di offset, che viene passata direttamente a diverse subroutine. Passare un valore grande provocherà un buffer overflow e il crash del kernel. Con ulteriore lavoro, ciò potrebbe essere sviluppato in un exploit RCE.