序幕
2022 年,Pwn2Own 回到迈阿密,再次瞄准工业控制系统 (ICS) 软件。我参加了 2020 年首届 Pwn2Own 迈阿密赛,并渴望今年再次参加。我之前的工作包括针对 Iconics Genesis64 控制服务器产品的一个很好的漏洞。该漏洞允许远程攻击者使用自定义WCF客户端运行任意 SQL 命令。今年我通过运行任意 JScript.NET 代码赢得了 20,000 美元!这篇文章将描述我采取的过程以及我发现的漏洞。
不过,2022 年的规则发生了一些变化。2020 年,必须针对暴露的网络服务启动针对 Iconics Genesis64 目标的成功入口。然而,在新的 2022 规则中,打开文件现在被认为是有效的攻击场景:
此类尝试必须通过竞赛网络内参赛者的笔记本电脑或通过在竞赛笔记本电脑上打开目标内的文件来针对目标暴露的网络服务发起。可以打开的文件必须是目标应用程序默认处理的文件类型。
https://www.zerodayinitiative.com/Pwn2OwnMiami2022Rules.html
这听起来很有希望,因为在之前的事件中没有探索过这个攻击面,并且可能会有很多问题!
安装 Iconics Genesis64
下载安装 ISO 后,通过运行 ICONICS_Suite 目录中的 setup.exe 程序来安装 Iconics Genesis64。
安装程序将要求您多次重新启动,最终所有依赖项都将安装并开始配置。我在所有内容中都使用了默认配置,但也小心确保安装了演示程序。
安装是整个工作中最乏味的方面。
探索和利用新的攻击面
我首先在文件系统中搜索 Iconics Genesis64 默认处理的文件类型示例:
例如,“.awxx”文件是一个 XML 文件,并且 Iconics Genesis64 GenDemo 包中包含的“AlarmWorX64_Examples”文件夹中有许多示例文件:
<?xml version="1.0" encoding="utf-8"?>
<AwxViewControl FileVersion="10.60.063.00" Width="Auto" Height="Auto" xmlns="clr-namespace:Ico.Awx;assembly=AwxViewControl" xmlns:iws="clr-namespace:Ico.WPF.Specialized;assembly=IcoWPFSpecialized" xmlns:av="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:iwc="clr-namespace:Ico.Windows.Controls;assembly=IcoWPF" xmlns:iad="clr-namespace:Ico.Awx.DataGrid;assembly=AwxViewControl" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:iwm="clr-namespace:Ico.Windows.Media;assembly=IcoWPF">
<AwxViewControl.Items>
<iwc:MultipleTabItem IsSelected="True" Header="Tab">
<iad:AwxGridView>
<iad:AwxGridView.SavedColumns>
<iad:AwxColumn Key="AckRequiredBaseConditionType" Index="6" IsVisible="False" Text="AckRequired" />
<iad:AwxColumn Key="ActiveTimeBaseConditionType" Text="Time / Date" Width="145" />
<iad:AwxColumn Key="ConditionNameBaseConditionType" Index="7" IsVisible="False" Text="ConditionName" />
...
对于找到的每个文件,我都进行了快速的视觉扫描,以寻找有趣的数据和关键字。最初,我只是想对每个文件的用途进行高级概述。理想情况下,我会找到像存储在文件中的序列化对象之类的东西,当文件打开时会被反序列化。
一些文件是二进制文件格式。有些是压缩的。同样,在此过程中,我只是快速扫描文件以查找有趣的字符串和功能,没有真正的期望。然而,当我扫描“.gdfx”文件时,“ScriptCode”和“ScriptCodeManager”标签看起来非常有趣:
<gwx:GwxDocument.GwxDocument>
<gwx:GwxDocument FileVersion="10.85.141.00" ScanRate="500">
<gwx:GwxDocument.ScriptCodeManager>
<script:ScriptCodeManager>
<script:ScriptCodeManager.Scripts>
<script:ScriptCode Name="ThisDisplayCode" Type="JScriptNet">
<x:XData><![CDATA[
function DebugDump(sender : System.Object, cmdArgs : Ico.Gwx.CommandExecutionEventArgs)
{
var callback : Ico.Fwx.ClientWrapper.MethodCallDoneDelegate = ThisDocument.CreateDelegate(Ico.Fwx.ClientWrapper.MethodCallDoneDelegate, this, "CallDone");
ThisWindow.FwxClientWrapper.MethodCallAsync(":", "DebugDump", new Object[0], callback, null);
}
function CallDone(result : Ico.Fwx.ClientWrapper.MethodCallDoneResult)
{
message : String;
message = String.Format("Result: {0}", result.Status.ToString());
if ((result.OutputArguments != null)
&& (result.OutputArguments.Count > 0))
{
path = result.OutputArguments[0].ToString();
message += String.Format("\n\nDump file: {0}", path);
}
MessageBox.Show(message, "Debug Dump Result", MessageBoxButton.OK);
}
]]></x:XData>
</script:ScriptCode>
<script:ScriptCode Name="JScriptDotNetGlobalVariablesCode" Type="JScriptNet" EditorBrowsable="Never">
<x:XData><![CDATA[
var ThisWindow : Ico.Gwx.GwxRuntimeViewControl;
var ThisDocument : Ico.Gwx.GwxDocument;
var ThisConfiguration : Ico.Gwx.GwxConfiguration;
]]></x:XData>
</script:ScriptCode>
</script:ScriptCodeManager.Scripts>
</script:ScriptCodeManager>
</gwx:GwxDocument.ScriptCodeManager>
</gwx:GwxDocument>
</gwx:GwxDocument.GwxDocument>
这看起来像是嵌入在文件中的 JScript.NET 代码!这似乎是向项目添加脚本的功能。但是,当我尝试打开文件时,我收到“文件访问被拒绝”消息:
在打开此文件之前,似乎需要先登录 Iconics 用户。我记录了这种行为并记下检查是否可以在身份验证检查之前执行 JScript 代码,或者是否可以绕过身份验证,然后继续我对默认文件类型的调查。
当我检查 GraphWorX64 模板文件“.tdfx”时,我看到了相同的“ScriptCodeManager”标签,并且该文件无需身份验证即可打开:
将以下代码添加到模板文件中的“ScriptCode”标记中会导致在打开文件时执行 calc!
var objShell = new ActiveXObject("Shell.Application");
objShell.ShellExecute("calc.exe", "", "calc.exe", "open", 0);
提交或不提交
显然,这是一个非常浅的错误,并且是一个非常弱的错误,无法带到 Pwn2Own。其他研究人员很有可能会发现这个错误并发生碰撞。在这一点上,我只有几个小时的努力,不得不做出决定是解决这个 bug 还是立即将这个 bug 报告给 ZDI 并继续寻找更好的 bug。由于佛罗里达州的 Omicron 激增,比赛被推迟了几个月,这个决定变得更加复杂。
最终,我的懒惰和生活的忙碌占了上风。我决定冒险解决这个弱错误。最后,尽管是针对 Iconics Genesis64 的第五位(总共 7 位)研究人员,但该错误并未与之前的尝试发生冲突并且成功了!
结论
在这篇文章中,我介绍了 ICONICS Genesis64 控制服务器处理 TDFX 文件的漏洞。我还展示了在代码中找到“新”攻击面的简单过程。不幸的是,识别没有经过严格审查的攻击面通常是发现和利用关键漏洞所必需的。
ZDI 将CVE-2022-33317分配给此漏洞,ICONICS在版本 10.97.2 中修复了它。感谢供应商及时修复,感谢 ZDI 组织了另一个伟大的 Pwn2Own!
参考:
https://www.zerodayinitiative.com/Pwn2OwnMiami2022Rules.html
https://portswigger.net/web-security/deserialization
https://docs.iconics.com/V10.96/GENESIS64/Help/Apps/GWX/Scripting_Basics.htm
https://www.zerodayinitiative.com/advisories/ZDI-22-1039/
https://trenchant.io/two-lines-of-jscript-for-20000-pwn2own-miami-2022/