千家信息网

如何使用Winrm.vbs绕过应用白名单执行任意未签名代码

发表于:2025-11-16 作者:千家信息网编辑
千家信息网最后更新 2025年11月16日,这篇文章给大家分享的是有关如何使用Winrm.vbs绕过应用白名单执行任意未签名代码的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。严正声明:本文仅限于技术探讨,严禁用于其他
千家信息网最后更新 2025年11月16日如何使用Winrm.vbs绕过应用白名单执行任意未签名代码

这篇文章给大家分享的是有关如何使用Winrm.vbs绕过应用白名单执行任意未签名代码的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

严正声明:本文仅限于技术探讨,严禁用于其他用途。

绕过技术

winrm.vbs(System31中的一个Windows签名脚本)能够执行攻击者控制的XSL,它不会受到相关脚本主机的限制,并实现任意无符号代码执行。

当你向winrm.vbs提供"-format:pretty"或"-format:text"时,它会从cscript.exe所在的目录中相应地导出WsmPty.xsl或WsmTxt.xsl。这也就意味着,如果攻击者能够将cscript.exe拷贝到一个他能控制的且存储了恶意XSL的位置,他们就能够执行任意未签名的代码。实际上,这个问题跟Casey Smith的wmic.exe技术完全相同。

PoC

攻击操作机制如下:

1. 将WsmPty.xsl或WsmTxt.xsl存放到一个由攻击者控制的地方;

2. 将cscript.exe拷贝到同一个位置;

3. 通过"-format"指定"pretty"或"text"来执行winrm.vbs,具体取决于使用的是WsmPty.xsl或WsmTxt.xsl。

下面给出的是一个恶意XLS样本,我们需要将它放到攻击者控制的目录位置,这里选择的是C:\BypassDir\WsmPty.xsl:

   

其实我们还可以在WsmPty.xsl中嵌入恶意的DotNetToJScript Payload,并执行任意未签名代码。接下来,可以使用下列batch文件来执行Payload:

mkdir%SystemDrive%\BypassDircopy%windir%\System32\cscript.exe %SystemDrive%\BypassDir%SystemDrive%\BypassDir\cscript//nologo %windir%\System32\winrm.vbs get wmicimv2/Win32_Process?Handle=4-format:pretty

检测和绕过策略

在实现这项技术的过程中,必须用到的就是攻击者可控的WsmPty.xsl或WsmTxt.xsl。

winrm.vbs会对WsmPty.xsl或WsmTxt.xsl进行硬编码,并显式地将它们绑定到"pretty"和"text"参数上。就此看来,我们似乎没有办法来控制winrm.vbs去执行当前目录中的不同xls文件。从检测的角度来看,WsmPty.xsl或WsmTxt.xsl文件的哈希会跟System 32中原本的文件哈希不同,因此它们会被当作可疑文件,因为合法xls文件的哈希值很少会发生变化。

除此之外,合法WsmPty.xsl或WsmTxt.xsl文件应该是目录签名的,哈希值发生变化后将不会再对其进行签名。也就是说,磁盘中任何没有签名的WsmPty.xsl或WsmTxt.xsl文件都应该是可疑文件。需要注意的是,目录签名验证需要运行"cryptsvc"服务。

基于命令行来检测winrm.vbs是否存在的这种方案相对较弱,因为攻击者可以将winrm.vbs重命名为他们所选择的文件。

为了使用xls文件,这里必须在"format"参数中指定"pretty"或"text"。下面给出的是支持的"format"参数(大小写不敏感):

-format:pretty-format:"pretty"/format:pretty/format:"pretty"-format:text-format:"text"/format:text/format:"text"

虽然构建基于"format"是否存在的检测方案能够捕捉到所有的变化,但这种检测方案是存在问题的。"format"参数是否合法使用将取决于组织所采用的方案。不过除了System32中的cscript.exe和winrm.vbs之外,不太可能从其他任何地方合法调用了。

下面给出的是一个更新版的.bat PoC,它能够绕过cscript.exe的检测:

mkdir%SystemDrive%\BypassDir\cscript.execopy%windir%\System32\wscript.exe %SystemDrive%\BypassDir\cscript.exe\winword.exe%SystemDrive%\BypassDir\cscript.exe\winword.exe//nologo %windir%\System32\winrm.vbs get wmicimv2/Win32_Process?Handle=4-format:pretty

WSH/XSLScript脚本

毫无疑问,攻击者还会继续使用XSL和WSH来进行攻击。理想情况下,攻击者是可以知道Payload到底是从硬盘中执行的还是完全在内存中执行的。虽然Powershell具有这种使用scriptblock日志的能力,但针对WSH却没有相应的工具。随着反恶意软件扫描接口(AMSI)的引入,我们将能够捕捉到WSH内容。

这里我们可以使用logman.exe来对ETL事件进行跟踪,比如说下列命令将能够控制ETW的跟踪操作,并将跟AMSI相关的事件信息保存早AMSITrace.etl之中:

logman start AMSITrace -p Microsoft-Antimalware-Scan-Interface Event1 -o AMSITrace.etl-etslogmanstop AMSITrace -ets

接下来,我们还可以通过输出数据清单来了解更多事件信息:

                                                                                                                                                     

捕捉到.etl跟踪信息之后,我们可以选择自己喜欢的工具来对其进行分析。Powershell中的Gt-WinEvent就是一个很好的内置.etl解析器。为此,我自己编写了一个简单的脚本来分析AMSI事件,这个脚本还可以捕捉到PowerShell中的内容:

#Script author: Matt Graeber (@mattifestation)#logman start AMSITrace -p Microsoft-Antimalware-Scan-Interface Event1 -oAMSITrace.etl -ets# Doyour malicious things here that would be logged by AMSI#logman stop AMSITrace -ets $OSArchProperty= Get-CimInstance -ClassName Win32_OperatingSystem -Property OSArchitecture$OSArch= $OSArchProperty.OSArchitecture $OSPointerSize= 32if($OSArch -eq '64-bit') { $OSPointerSize = 64 } $AMSIScanEvents= Get-WinEvent -Path .\AMSITrace.etl -Oldest -FilterXPath'*[System[EventID=1101]]' | ForEach-Object {    if(-not $_.Properties) {        # The AMSI provider is not supplyingthe contentname property when WSH content is logged resulting        # in Get-WinEvent or Event Viewer beingunable to parse the data based on the schema.        # If this bug were not present,retrieving WSH content would be trivial.         $PayloadString = ([Xml]$_.ToXml()).Event.ProcessingErrorData.EventPayload        [Byte[]] $PayloadBytes =($PayloadString -split '([0-9A-F]{2})' | Where-Object {$_} | ForEach-Object{[Byte] "0x$_"})         $MemoryStream = New-Object -TypeNameIO.MemoryStream -ArgumentList @(,$PayloadBytes)        $BinaryReader = New-Object -TypeNameIO.BinaryReader -ArgumentList $MemoryStream, ([Text.Encoding]::Unicode)         switch ($OSPointerSize) {            32 { $Session =$BinaryReader.ReadUInt32() }            64 { $Session =$BinaryReader.ReadUInt64() }        }         $ScanStatus = $BinaryReader.ReadByte()        $ScanResult = $BinaryReader.ReadInt32()         $StringBuilder = New-Object -TypeNameText.StringBuilder        do { $CharVal =$BinaryReader.ReadInt16(); $null = $StringBuilder.Append([Char] $CharVal) }while ($CharVal -ne 0)        $AppName = $StringBuilder.ToString()        $null = $StringBuilder.Clear()         $ContentSize =$BinaryReader.ReadInt32()        $OriginalSize =$BinaryReader.ReadInt32()        $ContentRaw =$BinaryReader.ReadBytes($ContentSize)        $Content =[Text.Encoding]::Unicode.GetString($ContentRaw)        $Hash =[BitConverter]::ToString($BinaryReader.ReadBytes(0x20)).Replace('-', '')        [Bool] $ContentFiltered =$BinaryReader.ReadInt32()         $BinaryReader.Close()         [PSCustomObject] @{            Session = $Session            ScanStatus = $ScanStatus            ScanResult = $ScanResult            AppName = $AppName            ContentName = $null            Content = $Content            Hash = $Hash            ContentFiltered = $ContentFiltered        }    } else {        $Session = $_.Properties[0].Value        $ScanStatus = $_.Properties[1].Value        $ScanResult = $_.Properties[2].Value        $AppName = $_.Properties[3].Value        $ContentName = $_.Properties[4].Value        $Content = [Text.Encoding]::Unicode.GetString($_.Properties[7].Value)        $Hash =[BitConverter]::ToString($_.Properties[8].Value).Replace('-', '')        $ContentFiltered =$_.Properties[9].Value         [PSCustomObject] @{            Session = $Session            ScanStatus = $ScanStatus            ScanResult = $ScanResult            AppName = $AppName            ContentName = $ContentName            Content = $Content            Hash = $Hash            ContentFiltered = $ContentFiltered        }    }} $AMSIScanEvents

捕捉到相关信息之后,我们将能够看到Payload的执行内容:

感谢各位的阅读!关于"如何使用Winrm.vbs绕过应用白名单执行任意未签名代码"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

文件 攻击 攻击者 控制 检测 代码 内容 目录 脚本 合法 事件 信息 参数 恶意 技术 方案 哈希 位置 更多 变化 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 2021年登封大数据库具体情况 关于软件开发过程中的需求分析 软件开发课程设计论文模板 网络安全宣传手抄报竖着画 锐志网络技术科技有限公司 达州市公安局网络安全支队 上海企业软件开发服务哪个好 软件移动软件开发 扬州节能软件开发多少钱 网络技术工程师求职 自主研发mysql数据库 盐城运营软件开发优势 北大青鸟网络安全 网络技术专业院校 网络安全安排部署情况 6种数据库对象有哪些 预付的软件开发费 网络安全措施文章 比较厉害的外文数据库有 扬州市信息网络安全协会 全国网络安全等级测评机构推荐目录 idea连接远程服务器 金山区自动化软件开发概念设计 湖北前端软件开发公司 双色球历史中奖数据库 游戏服务器问题 卡登录页面 如何远程阿里云服务器 排队机软件开发与升级 网络安全防范知识竞赛题库 网络安全自查报告幼儿园
0