PowerShell 的加载(Loading)分为两类: Local Loading 本地加载:脚本 / 模块位于本机本地磁盘(C:\ D:\ 等 NTFS/FAT 卷)。 Remote Loading 远程加载:脚本 / 模块位于 UNC SMB 网络共享路径 \\server\share\;HTTP/HTTPS 下载属于另一个 Web 下载场景,示例
PowerShell Local Loading(本地加载) & Remote Loading(远程加载)
适用:PowerShell 5.1 / PowerShell 7+;本地文件加载、UNC 远程路径、SMB 远程加载;包含脚本、模块
.ps1/.psm1/.psd1分析框架:底层原理|依赖文件|依赖关系|配套链|逻辑链路|边界
一、底层原理
PowerShell 的加载(Loading)分为两类:
- Local Loading 本地加载:脚本 / 模块位于本机本地磁盘(C:\ D:\ 等 NTFS/FAT 卷)。
- Remote Loading 远程加载:脚本 / 模块位于 UNC SMB 网络共享路径
\\server\share\;HTTP/HTTPS 下载属于另一个 Web 下载场景,不属于 Remote‑Loading (UNC)。
核心安全机制:PowerShell 执行策略 (ExecutionPolicy) + 区域标识符 Zone Identifier(Windows 附件流,Mark‑of‑the‑Web,MotW)
- 本地文件:默认无 MotW 标记;
- SMB 远程 UNC 下载得到的文件:Windows 会标记 MotW(来自互联网 / Intranet 区域);
执行策略不是安全边界,只是用户配置;真正安全判定来自文件的 MotW 备用数据流。
两个核心概念
- Zone Identifier(MotW 标记,
Zone.Identifier备用数据流 ADS) NTFS 备用数据流,记录文件来源区域:
- ZoneId=0:本地机器
- ZoneId=1:本地 Intranet(企业内网 SMB 共享)
- ZoneId=2:受信任站点
- ZoneId=3:Internet 互联网
- ZoneId=4:不受信任
- 执行策略
Get‑ExecutionPolicy:Restricted / AllSigned / RemoteSigned / Unrestricted / BypassRemoteSigned:本地脚本不要求签名;来自远程 (UNC/Web) 脚本必须数字签名,否则阻止运行,这是最容易混淆的分界点。
重点:Remote Loading 特指 UNC/SMB 共享加载;
Invoke‑WebRequest下载到本地后执行,文件带上 MotW,行为同远程加载。
二、依赖文件
| 文件 / 组件 | 作用 |
|---|---|
powershell.exe(PS5.1) / pwsh.exe(PS7+) |
PowerShell 主机进程入口 |
System.Management.Automation.dll |
PowerShell 引擎核心程序集,脚本解析、加载器、执行策略逻辑实现 |
ntfs.sys |
NTFS 备用数据流 ADS 存储,保存Zone.IdentifierMotW 标记;FAT32 不支持 ADS,无 MotW 标记 |
urlmon.dll |
来源区域判定;给从网络 / SMB 复制过来的文件附加 Zone.Identifier 流 |
kernel32.dll |
文件打开、读取内容;解析备用数据流 ADS |
powershell.config.json |
PS7 + 配置文件,存储执行策略等配置 |
注册表:HKLM:\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell |
PowerShell5.1 执行策略存储位置 |
辅助工具查看 MotW:
Get‑Item ‑Path "file.ps1" ‑Stream Zone.Identifier
Unblock‑File file.ps1 # 删除MotW备用数据流
三、依赖关系
1. Local Loading(本地加载)依赖
- 文件存放在本地卷(C:/D:/);NTFS/FAT 均可;
- NTFS:文件默认不存在 Zone.Identifier 备用数据流;
- 执行策略为
RemoteSigned条件:本地 ps1 不需要数字签名,可以直接运行。
2. Remote Loading(UNC‑SMB 远程加载)依赖
- 目标文件路径格式
\\FileServer\Share\script.ps1;访问依赖 SMB 客户端组件mrxsmb.sys、WebClient 服务不参与普通 SMB; - 网络连通、SMB 共享权限、NTFS 权限:PowerShell 进程账号需要读权限访问 UNC 路径;
- 文件复制 / 直接从 UNC 打开时,
urlmon.dll附加Zone.IdentifierADS 流,标记 ZoneId=1 (Intranet); - 关键:即使文件拷贝到本地,如果 ADS 流没有删除,依然被识别为 “远程来源”,行为等同于 Remote Loading。
执行策略生效对照表(核心)
| 执行策略 | 本地加载 (Local Loading) | UNC 远程加载 (Remote Loading,带 MotW) |
|---|---|---|
| Restricted | 阻止运行 ps1 脚本 | 阻止运行 ps1 脚本 |
| AllSigned | 所有脚本必须数字签名 | 所有脚本必须数字签名 |
| RemoteSigned | ✅允许无签名运行 | ❌阻止无签名脚本;需要数字签名或 Unblock‑File 清除 MotW |
| Unrestricted | 允许运行,弹出提示 | 允许运行,弹出安全确认提示框 |
| Bypass | 全部绕过,无检查 | 全部绕过,无检查 |
重要:执行策略分机器级别、用户级别、进程级别;进程级别优先级最高。
调用依赖链
PowerShell(pwsh/powershell.exe)
↓
System.Management.Automation.dll 加载器模块
↓
kernel32读取目标文件;读取NTFS备用数据流Zone.Identifier
↓
urlmon.dll判定来源区域;结合执行策略做安全校验
↓
校验通过:编译AST脚本,开始执行;校验失败抛出PSSecurityException安全异常
四、配套链
完整流水线
Local Loading 本地加载流水线
1. 进程访问本地磁盘文件 C:\scripts\test.ps1
2. PowerShell加载器读取文件;检查NTFS是否存在Zone.Identifier流(一般不存在)
3. 根据执行策略校验;RemoteSigned下直接放行
4. 解析脚本AST,执行脚本逻辑
Remote Loading(UNC SMB)流水线
1. PowerShell访问UNC路径 \\fs01\psscripts\test.ps1
2. SMB客户端连接文件服务器,读取ps1文件内容
3. urlmon.dll标记Zone.Identifier=1(Intranet) MotW(复制到本地或者直接UNC打开都会标记)
4. 加载器读取ADS流识别为远程来源脚本
5. 结合ExecutionPolicy执行策略校验
· RemoteSigned:无签名 → 安全阻止报错
· Bypass:直接放行
· Unrestricted:弹出确认提示
6. 校验通过才执行;失败抛出安全错误
配套工具与命令
- 清除 MotW 标记(将远程来源脚本转为等效本地加载行为)
Unblock‑File .\test.ps1
原理:直接删除 NTFS 备用数据流
Zone.Identifier。
- 查看当前生效执行策略
Get‑ExecutionPolicy‑List
- 进程级别临时设置执行策略(不修改机器 / 用户持久配置)
pwsh.exe ‑ExecutionPolicy Bypass ‑File "\\fs01\share\script.ps1"
- 测试备用数据流 MotW 标记
Get‑Item .\test.ps1 ‑Stream Zone.Identifier
- 模块加载同样受此约束:
Import‑Module \\fs01\mod\mymod.psm1同样属于 Remote Loading,受 MotW + 执行策略管控。
五、逻辑链路
通用加载逻辑链路(Local / Remote 共用加载器)
- PowerShell 接收脚本路径参数(
.ps1/.psm1);Resolve‑Path 解析路径,区分本地路径 / UNC 远程路径。 - 打开目标文件;读取主文件内容;尝试读取 NTFS 备用数据流
Zone.Identifier。- 读取不到 ADS →判定为本地来源 Local Loading
- 读取到 ZoneId 标记 →判定远程来源 Remote Loading
- 读取生效的 ExecutionPolicy(优先级:进程 > 用户 > 机器)。
- 安全校验分支:
- Local Loading 分支:RemoteSigned 策略下不校验数字签名;直接进入脚本编译执行。
- Remote Loading 分支:
- AllSigned:必须有效数字签名;
- RemoteSigned:必须有效数字签名,否则拒绝执行;
- Unrestricted:弹出交互式安全警告确认;
- Bypass:跳过全部来源校验。
- 校验通过:将脚本编译为 AST 抽象语法树,执行脚本;
- 校验失败:抛出
PSSecurityException,终止脚本,返回非 0 退出码。
⚠️关键点:
- 不是路径决定 Remote Loading,是 Zone.Identifier (MotW 备用数据流) 决定! 把 SMB 上文件复制拷贝到 C 盘本地,如果 ADS 流没有被清除,依旧被识别为 Remote Loading。
- 直接 UNC 路径执行,文件不落地本地磁盘,也会被标记为远程来源。
六、边界约束(高频坑点)
1 文件系统边界
- FAT32/exFAT 不支持 NTFS 备用数据流 ADS,文件复制过来不会生成 Zone.Identifier,MotW 标记丢失;远程来源脚本放到 FAT 盘会被当成本地脚本执行,安全约束失效。
- 只有 NTFS 卷支持 Zone.Identifier;SMB 服务器后端必须 NTFS,客户端本地磁盘必须 NTFS,ADS 标记才可以保存。
2 执行策略边界
- ExecutionPolicy不是安全防护边界,只是防护用户误操作;攻击者可以用进程级参数
‑ExecutionPolicy Bypass绕过持久化设置。 - 优先级:
‑ExecutionPolicy命令行参数 (进程级别) > 用户级别 > 机器级别。 - PowerShell7 不再读取注册表执行策略,读取
powershell.config.json配置文件;5.1 读取注册表。
3 Remote Loading(UNC‑SMB)边界
- 网络前提:PowerShell 进程账号要有 SMB 共享的读权限;如果没有访问权限,直接报文件找不到,不会进入安全校验。
- Intranet ZoneId=1:企业内网 SMB 共享标记为 Intranet;互联网下载文件标记 ZoneId=3。RemoteSigned 策略对二者均视为远程来源。
- 模块 Import‑Module UNC 路径,同样触发 Remote Loading 校验,很多人只知道 ps1 脚本不知道模块也会触发。
4 MotW 标记特殊边界
- 压缩包场景:从网络下载 zip 压缩包,zip 带 MotW;解压出来内部全部脚本会继承 MotW 标记,全部视为远程脚本。
- 复制文件:复制文件保留 ADS 流;移动文件在同一卷保留 ADS;跨卷移动 Windows 也会保留 MotW 标记。
Unblock‑File仅仅删除备用数据流,不会修改脚本文件主内容。
5 容易混淆边界
- ❌误区:
\\localhost\c$\scripts\test.ps1本机 UNC 路径;同样属于 Remote Loading,触发远程来源校验;虽然访问本机,但使用 UNC SMB 路径访问,会打上 MotW 标记。
✅正确:
C:\scripts\test.ps1才是 Local Loading 本地加载。
Invoke‑Command远程会话执行脚本:脚本在远程机器本地磁盘,属于远程机器的 Local Loading,不受本机 MotW 约束。- ISE、pwsh、powershell 各个主机程序,加载器逻辑完全一致。
6 权限边界
- MotW 标记读取删除,普通用户权限即可,不需要管理员;
- 修改机器级执行策略需要管理员权限;进程级别参数不需要管理员。
7 返回码
| 退出码 | 含义 |
|---|---|
| 0 | 脚本加载执行成功 |
| ‑196608 | PSSecurityException,远程脚本被执行策略阻止 |
| 1 | 文件不存在、路径访问失败 |
8 安全边界研判
风险场景:内网 SMB 共享无签名脚本;RemoteSigned 策略下直接阻止;攻击者可以:
- 使用
‑ExecutionPolicy Bypass进程参数绕过校验- 执行
Unblock‑File清除 MotW 标记转为本地加载行为
补充实操示例
# 场景1:本地加载 Local Loading
powershell.exe -File C:\scripts\demo.ps1
# 场景2:UNC远程加载 Remote Loading,RemoteSigned策略会拦截无签名脚本
powershell.exe -File \\fs‑prod\ps_share\demo.ps1
# 场景3:进程级别绕过策略(生产运维经常使用)
powershell.exe -ExecutionPolicy Bypass -File \\fs‑prod\ps_share\demo.ps1
# 清除MotW,将远程来源脚本变为等效本地加载
Unblock‑File .\demo.ps1
PowerShell 本地加载、远程加载标准英文术语与完整全称
一、本地加载
标准官方术语
- Local Module Loading(本地模块加载,最常用)
- Local Script Loading(本地脚本加载)
概念释义
C:\Windows\System32\WindowsPowerShell、用户模块目录)读取 psm1/ps1 脚本、模块文件,仅访问本机存储,不通过网络传输脚本代码;受本地ExecutionPolicy执行策略管控,无网络链路依赖,不经过tcpip.sys、Realtek 网卡。二、远程加载
标准官方术语
- Remote Module Loading(远程模块加载)
- Remote Script Loading(远程脚本加载)
细分技术实现全称
- SMB Remote Loading:基于 SMB 文件共享远程加载(
\\Server\Share\script.ps1) - HTTP/HTTPS Remote Loading:基于网络 URL 远程加载(
Invoke-WebRequest/Invoke-RestMethod拉取脚本,依赖 http.sys 内核驱动) - WinRM Remote Session Loading:WinRM 远程会话加载(Enter-PSSession,TCP 5985/5986 端口)
三、官方文档标准完整描述
- 本地加载完整定义短语
Loading modules/scripts from local filesystem paths
- 远程加载完整定义短语
Loading modules/scripts from remote network locations (SMB share / HTTP endpoint / WinRM remote session)
四、配套底层链路区分
本地加载配套链
远程加载配套链
- SMB 共享路径:tcpip.sys → Realtek 网卡 → 远程文件服务器 ntds.dit 域权限校验;
- HTTP 远程脚本:http.sys 内核驱动 → tcpip.sys → Realtek 网卡,URL 匹配内核路由;
- WinRM 远程会话:TCP 5985 端口流量走 http.sys,Kerberos 认证票据由 klist 管理,身份依托域 SID。
五、术语对照表
| 中文 | 标准英文缩写术语 | 完整全称 |
|---|---|---|
| 本地加载 | Local Loading | Local Module/Script Loading |
| 远程加载 | Remote Loading | Remote Module/Script Loading |
| SMB 远程加载 | SMB Remote Load | Remote Loading via SMB File Share |
| HTTP 远程加载 | HTTP Remote Load | Remote Loading via HTTP/HTTPS URL |
| WinRM 远程会话加载 | WinRM Remote Session Load | Script Loading inside WinRM Remote PowerShell Session |
PowerShell Local Loading(本地加载)& Remote Loading(远程加载)完整概念、原理、示例
一、Local Loading 本地加载
核心概念
.ps1)或模块(.psm1),代码文件存储在当前主机磁盘,无网络传输行为。底层配套链路
- 权限校验:基于本机账户 SID、本地 SAM 库、NTFS ACL;
- 无网络组件参与:不调用
tcpip.sys、Realtek 网卡、http.sys; - 执行策略约束:受本机
Set-ExecutionPolicy本地策略管控。
典型示例
- 加载当前目录本地脚本
# 本地磁盘C盘脚本
.\deploy.ps1
- 加载系统内置本地模块
# 从本机C:\Windows\System32\WindowsPowerShell读取模块
Import-Module NetAdapter
- 加载用户目录自定义本地模块
Import-Module "$env:USERPROFILE\Documents\WindowsPowerShell\Modules\Tools"
关键特性
- 代码文件完整保存在本机,执行前无需下载;
- 执行策略默认允许本地签名脚本,限制未签名本地脚本(默认 Restricted);
- 不产生网络流量,无 Kerberos/HTTPS 认证依赖,不使用
klist票据。
二、Remote Loading 远程加载
核心概念
三类远程加载细分定义与示例
1. SMB 文件共享远程加载(文件服务器共享路径)
\\服务器IP\共享名\脚本.ps1 访问远端文件服务器磁盘,依赖 SMB 协议(TCP 445 端口)。# 从域文件服务器共享加载脚本
\\DC01\ScriptShare\ad_user_create.ps1
Import-Module \\DC01\Modules\ADTools
ntds.dit域权限校验(基于账户 SID)。2. HTTP/HTTPS URL 远程加载(网络地址拉取脚本)
http.sys内核驱动承载远端 Web 站点 URL 资源# 方式1:Invoke-WebRequest下载到本地后执行
Invoke-WebRequest -Uri "https://learn.microsoft.com/script/install.ps1" -OutFile install.ps1
.\install.ps1
# 方式2:直接管道加载执行(远程加载经典写法)
Invoke-RestMethod "https://learn.microsoft.com/script/bootstrap.ps1" | Invoke-Expression
klist Kerberos 票据、TPM 证书tpmvscmgr。3. WinRM 远程会话加载(远程主机会话内执行)
# 连接域控远程会话,在DC01本地加载脚本执行
$session = Enter-PSSession -ComputerName DC01
Invoke-Command -Session $session -ScriptBlock {
Import-Module ActiveDirectory
.\ntds_backup.ps1
}
ntds.dit存储的机器 SID、用户 SID。统一底层特性
- 代码必须通过网络传输至本机内存,存在网络 IO 开销;
- 执行策略特殊约束:默认会阻止远程未签名脚本(需开启
RemoteSigned); - 全部依赖网卡
tcpip.sys协议栈、Realtek 网卡硬件传输; - 企业域环境会结合 SID、Kerberos 票据、AD 域控
ntds.dit做访问权限校验。
三、本地加载与远程加载核心对比表
| 对比维度 | Local Loading 本地加载 | Remote Loading 远程加载 |
|---|---|---|
| 代码存储位置 | 本机 NTFS 磁盘 | 远端文件服务器 / Web / 远程主机 |
| 网络依赖 | 无,不经过网卡 /tcpip.sys | 必须通过 Realtek 网卡、tcpip.sys 传输 |
| 协议 | 无网络协议 | SMB(TCP445)/HTTP(TCP80/443)/WinRM(TCP5985) |
| 执行策略规则 | Restricted 默认阻止未签名本地脚本 | Restricted 直接阻止所有远程脚本,需 RemoteSigned |
| 身份校验载体 | 本机 SAM 账户 SID | AD 域ntds.dit全局 SID、klist Kerberos 票据 |
| 典型场景 | 本机运维、单机脚本、内置模块 | 批量域设备下发、云端脚本、远程主机运维 |
四、生产环境使用约束补充
- 安全约束:Remote Loading 存在代码篡改风险,企业域环境推荐仅允许RemoteSigned策略,远程脚本必须附带数字证书签名;
- 性能约束:远程加载受网卡带宽影响,Realtek 2.5G / 万兆光纤网卡可降低大模块加载延迟;
- 审计约束:远程加载网络流量会记入 http.sys 系统日志、SMB 服务器安全日志,可通过 wevtutil、PerfMon 监控。
PowerShell 本地 / 远程加载 非常规另类思路、实战示例
一、Local Loading(本地加载)另类思路(不依赖磁盘物理.ps1 文件)
.\xxx.ps1、Import-Module 本地路径思路 1:内存字符串本地加载(无落地磁盘纯内存执行)
# 内存定义脚本代码
$localScriptCode = @'
Write-Host "内存本地加载,无磁盘文件落地"
Get-NetAdapter -Name "Realtek PCIe 2.5G"
'@
# 本地内存加载执行(全程不写硬盘)
Invoke-Command -ScriptBlock ([scriptblock]::Create($localScriptCode))
思路 2:注册表 INI 结构存储脚本,本地读取加载
# 写入脚本到注册表
reg add "HKCU\Software\CustomScript" /v BackupCode /t REG_SZ /d 'Get-ChildItem C:\Windows\System32\drivers\http.sys' /f
# 本地读取注册表并加载执行
$script = Get-ItemProperty "HKCU:\Software\CustomScript" | Select -ExpandProperty BackupCode
[scriptblock]::Create($script).Invoke()
思路 3:内置编译模块内存预加载(绕过模块文件校验)
Import-Module 文件路径,直接加载内存编译后的二进制模块,纯本地内存模块加载# 获取本地已加载模块二进制,重新内存加载
$mod = Get-Module NetAdapter
$ms = [System.Management.Automation.Runspaces.PSModuleInfo]::new($mod.Name,$mod.Path)
# 内存重新注入加载,不读取磁盘文件
[System.Management.Automation.ModuleIntrinsics]::ImportModule($ms)
思路 4:WMI 本地对象内嵌脚本加载
# 写入本地WMI自定义类
$class = New-CimClass -ClassName CustomScriptStore -Namespace root/cimv2
$class.CimClassProperties.Add([CimProperty]::new("Code",[string]))
Set-CimInstance -ClassName CustomScriptStore -Property @{Code='whoami /all'}
# 本地读取WMI并加载执行
$code = Get-CimInstance CustomScriptStore | Select -ExpandProperty Code
Invoke-Command -ScriptBlock ([scriptblock]::Create($code))
二、Remote Loading(远程加载)另类非常规思路(跳出 SMB / 标准 Invoke-WebRequest)
Invoke-RestMethod、WinRM 会话思路 1:AD 域 ntds.dit LDAP 远程加载(LDAP 协议拉取脚本代码)
# 读取AD计算机对象自定义扩展属性内的脚本代码
$adObj = Get-ADComputer DC01 -Properties ScriptPayload
$remoteCode = $adObj.ScriptPayload
# 远程拉取代码本地加载执行
[scriptblock]::Create($remoteCode).Invoke()
思路 2:TPM 虚拟智能卡 tpmvscmgr 证书站点隐蔽远程加载
.url快捷方式内核缓存拉取脚本,依托 http.sys 内核 SSL 卸载远程加载# 不使用Invoke-WebRequest,直接调用系统url.dll读取远程页面代码
$url = "https://dc01-intra/script/bootstrap.ps1"
$winUrl = New-Object -ComObject InternetShortcut
$winUrl.URL = $url
# 调用WinINet通过http.sys内核获取远程脚本
$req = Invoke-WinInetRequest -Uri $url
[scriptblock]::Create($req.ResponseText).Invoke()
思路 3:DNS TXT 记录远程加载(UDP 53 端口无 Web 服务依赖)
# 读取域名TXT记录存储的远程脚本
$txtRecord = (Resolve-DnsName -Name script.corp.com -Type TXT).Strings
$remoteScript = $txtRecord -join "`n"
# 执行远程DNS下发的脚本
Invoke-Command -ScriptBlock ([scriptblock]::Create($remoteScript))
思路 4:WinRM 反向会话远程加载(反向远程,客户端作为服务端)
# 本机开启WinRM监听,等待远端主动接入
Enable-PSRemoting -SkipNetworkProfileCheck
# 远端服务器主动发起反向会话,推送脚本至本机内存执行
# 远端执行:Enter-PSSession -ComputerName 本机IP
# 本机接收远端推送的脚本代码,内存加载执行
思路 5:SMB NamedPipe 管道远程加载(绕过文件共享直接 IPC 管道)
\\server\share文件共享,直接连接远端 IPC$ 命名管道读取内存脚本,非常规 SMB 文件加载# 建立远端IPC管道连接
$pipe = "\\DC01\pipe\CustomScriptPipe"
$stream = [System.IO.Pipes.NamedPipeClientStream]::new(".",$pipe,[System.IO.Pipes.PipeDirection]::InOut)
$stream.Connect(5000)
# 从管道读取远端下发的脚本代码
$reader = New-Object System.IO.StreamReader($stream)
$remoteCode = $reader.ReadToEnd()
[scriptblock]::Create($remoteCode).Invoke()
思路 6:TPM vsc 虚拟智能卡密钥导出承载脚本(硬件加密远程加载)
tpmvscmgr创建虚拟智能卡,将脚本加密存入证书扩展字段,远程拉取证书解密得到代码执行# 读取TPM虚拟智能卡证书扩展字段内加密脚本
$cert = Get-ChildItem Cert:\CurrentUser\My | Where Subject -Match "VSC-ScriptStore"
# 提取证书扩展二进制,解密还原PowerShell代码
$extData = $cert.Extensions | Where Oid -Match "1.3.6.1.4.1.9999"
$rawCode = [System.Text.Encoding]::UTF8.GetString($extData.RawData)
[scriptblock]::Create($rawCode).Invoke()
三、混合加载另类思路(本地 + 远程组合复合加载)
思路:远程拉取加密载荷,本地内存密钥解密后加载
- 远程 HTTP 站点拉取加密后的脚本密文(http.sys 缓存传输)
- 本地注册表 / TPM 存储解密密钥(本地加载密钥)
- 本地内存解密得到脚本,执行本地内存加载
# 1.远程拉取加密脚本
$cipherText = Invoke-RestMethod https://dc01-intra/cipher/script.enc
# 2.本地读取注册表密钥(本地加载)
$key = Get-ItemProperty "HKLM\Software\SecureKey" | Select -ExpandProperty AesKey
# 3.本地解密,内存执行(混合加载)
$plainCode = Decrypt-AES -Cipher $cipherText -Key $key
[scriptblock]::Create($plainCode).Invoke()
四、另类加载方案特性表
| 加载类型 | 非常规思路 | 核心特点 | 适用场景 |
|---|---|---|---|
| 本地加载 | 内存字符串 / 注册表 / WMI 存储脚本 | 无磁盘文件落地,绕过执行策略 | 隐秘运维、临时脚本、磁盘受限主机 |
| 远程加载 | DNS TXT、LDAP AD 属性、反向 WinRM | 不依赖标准 Web/SMB 共享,隐蔽传输 | 隔离内网、防火墙严格限制环境 |
| 远程加载 | TPM 证书 / 虚拟智能卡承载脚本 | 全程加密,依托硬件安全芯片 | 等保 / 高安全域环境,防脚本篡改 |
| 混合加载 | 远程密文 + 本地密钥解密 | 传输加密,解密本地完成 | 批量企业域设备下发敏感运维脚本 |
五、安全风险提醒
- 内存无文件落地加载、DNS/LDAP 隐蔽远程加载极易被恶意程序滥用,企业域环境建议通过 SID ACL、ntds.dit 组策略拦截非常规代码加载路径;
- 需配合 klist Kerberos 票据、http.sys 日志、PerfMon 性能计数器审计所有内存 / 远程脚本加载行为;
- Realtek 网卡流量日志可监控 DNS、LDAP、反向 WinRM 非常规远程加载流量,及时告警异常脚本下发。
PowerShell 本地 / 远程加载 更多另类特殊思路与完整示例
一、Local Loading 本地加载新增非常规方案(无物理 ps1 文件落地、非常规载体)
1. WMI 永久存储脚本本地加载(持久化无磁盘脚本文件)
.ps1磁盘文件,读取后内存执行# 1. 创建本地WMI存储类并写入脚本代码
New-CimClass -Namespace root\LocalScriptStore -ClassName ScriptPool -Key Name
$scriptBlockCode = @'
Get-Service | Where StartType -eq Automatic
Get-NetAdapter -Name "Realtek PCIe 2.5G"
'@
New-CimInstance -ClassName ScriptPool -Namespace root\LocalScriptStore -Property @{
Name = "AutoServiceCheck"
Payload = $scriptBlockCode
}
# 2. 本地从WMI读取代码、内存加载执行
$readCode = Get-CimInstance root\LocalScriptStore\ScriptPool | Where Name -eq AutoServiceCheck | Select -ExpandProperty Payload
[scriptblock]::Create($readCode).Invoke()
2. 事件日志隐藏脚本本地加载
# 写入代码到系统日志
Write-EventLog -LogName System -Source "CustomScriptSource" -EventId 9999 -Message 'Get-ChildItem C:\Windows\System32\drivers\http.sys'
# 读取日志提取脚本本地执行
$logCode = Get-WinEvent -FilterHashtable @{LogName='System'; Id=9999} | Select -ExpandProperty Message
[scriptblock]::Create($logCode).Invoke()
3. 进程环境变量本地内存加载
# 注入脚本到进程环境变量
$env:ScriptPayload = 'klist.exe; whoami /all'
# 从环境变量读取本地加载执行
[scriptblock]::Create($env:ScriptPayload).Invoke()
4. 二进制资源内嵌 DLL 本地加载
Add-Type编译临时 C# DLL,将 PowerShell 脚本嵌入二进制资源,加载 DLL 提取代码执行$csharpCode = @'
using System;
public class ScriptContainer {
public static string GetScript() {
return "Get-Item HKLM:\SYSTEM\CurrentControlSet\Services\HTTP\Parameters";
}
}
'@
Add-Type $csharpCode
# 从编译后的内存DLL提取脚本,本地执行
$code = [ScriptContainer]::GetScript()
[scriptblock]::Create($code).Invoke()
5. 剪贴板中转本地加载
# 写入代码到剪贴板
Set-Clipboard -Value 'ntdsutil.exe snapshot create'
# 读取剪贴板本地加载执行
$clipCode = Get-Clipboard
[scriptblock]::Create($clipCode).Invoke()
二、Remote Loading 远程加载新增隐蔽 / 非常规方案(跳出 SMB/HTTP 标准渠道)
1. AD 对象扩展属性远程加载(LDAP 389 端口,域控 ntds.dit 存储脚本)
# 远程查询域控ntds.dit中计算机对象自定义脚本字段
$adDevice = Get-ADComputer -Identity PC01 -Properties CustomScriptPayload
$remoteScript = $adDevice.CustomScriptPayload
# 远程获取代码本地内存执行
[scriptblock]::Create($remoteScript).Invoke()
2. DHCP Option 自定义字段远程加载(UDP 67/68 端口,内网无 Web 服务)
# 读取DHCP分配的自定义Option字段中的远程脚本
$dhcpOption = Get-DhcpServerv4OptionValue -ScopeId 192.168.1.0 -OptionId 240
$scriptCode = $dhcpOption.Value
[scriptblock]::Create($scriptCode).Invoke()
3. Windows 打印服务器打印队列远程加载(RPC TCP 135/445)
# 远程读取打印服务器队列注释内的脚本
$printJob = Get-PrinterJob -PrinterName "\\PRN01\OfficePrinter" -JobId 10
$remoteCode = $printJob.Comment
[scriptblock]::Create($remoteCode).Invoke()
4. WMI 远程命名空间脚本加载(DCOM RPC TCP135,无 WinRM 依赖)
# 远程连接服务器WMI,读取存储的脚本载荷
$remoteWmi = Get-CimInstance -ClassName ScriptStore -Namespace root\RemoteScript -ComputerName SRV01
$payload = $remoteWmi.Payload
[scriptblock]::Create($payload).Invoke()
5. FTP 协议远程加载(TCP21,二进制传输脚本文件)
# FTP远程下载脚本到内存,不落地磁盘直接执行
$ftpClient = New-Object System.Net.WebClient
$ftpCode = $ftpClient.DownloadString("ftp://srv-file/script/backup.ps1")
[scriptblock]::Create($ftpCode).Invoke()
6. TPM 2.0 NV 存储分区远程下发(tpmvscmgr 协同硬件加密远程脚本)
# 读取TPM NV分区中加密的远程脚本
$tpmRaw = Get-TpmNvIndex -Index 0x01000001
$decryptedCode = [System.Text.Encoding]::UTF8.GetString($tpmRaw.Data)
[scriptblock]::Create($decryptedCode).Invoke()
7. 反向 RPC 远程推送加载(远端主动推送代码至本机)
- 本机监听本地 RPC 管道;
- 远端服务器主动发起连接,推送脚本字符串;
- 本机内存接收后直接执行,无需本机主动发起网络请求。
8. IPv6 ICMPv6 数据分片远程加载(无 TCP/UDP 业务端口,隐蔽传输)
# 读取ICMP报文捕获的分片脚本数据(需配套抓包解析模块)
$icmpPayload = Read-IcmpCapture -Source 2001:db8::srv01
[scriptblock]::Create($icmpPayload).Invoke()
三、复合混合加载特殊思路(本地载体 + 远程网络双层组合)
1. 远程拉取加密脚本密文 + 本地 TPM 硬件密钥解密加载
# 远程HTTP拉取加密脚本(远程加载)
$cipher = Invoke-RestMethod https://corp-srv/cipher/script.enc
# 本地从TPM读取解密密钥(本地加载)
$aesKey = Get-TpmVscSecret -VscName "CorpAdminVSC"
# 本地内存解密后执行(混合加载)
$plainText = Unprotect-AesData -CipherText $cipher -Key $aesKey
[scriptblock]::Create($plainText).Invoke()
2. 远程 LDAP 拉取脚本 URL + 本地内存缓存加载
- LDAP 远程获取静态脚本地址(远程加载);
- http.sys 内核缓存本地读取 URL 资源(本地内核加载);
- 全程复用内核缓存,降低网络重复请求开销。
3. 远程 SMB 拉取压缩脚本包 + 内存解压本地加载
# SMB远程读取压缩zip脚本包(远程加载)
$zipStream = [System.IO.FileStream]::new("\\srv-share\script\bundle.zip", [System.IO.FileMode]::Open)
# 内存解压,不落地磁盘文件,本地执行
$memoryStream = New-Object System.IO.MemoryStream
$zip = [System.IO.Compression.ZipFile]::Open($zipStream, [System.IO.Compression.ZipFileMode]::Open)
$entry = $zip.GetEntry("deploy.ps1")
$reader = New-Object System.IO.StreamReader($entry.Open())
$scriptCode = $reader.ReadToEnd()
[scriptblock]::Create($scriptCode).Invoke()
四、特殊加载方案核心特性汇总
| 加载类型 | 另类方案 | 核心优势 | 风险提示 |
|---|---|---|---|
| 本地加载 | WMI / 事件日志 / 环境变量 / 剪贴板 | 无磁盘脚本文件,绕过执行策略拦截 | 易被恶意代码利用隐藏载荷,需审计 WMI / 日志写入行为 |
| 远程加载 | LDAP/DHCP/ICMPv6 / 打印队列 | 规避标准 80/443/445 端口防火墙限制,隐蔽传输 | 流量日志容易被运维忽略,需监控非常规协议流量 |
| 远程加载 | TPM 硬件加密脚本 | 传输全程硬件加密,防中间人篡改脚本 | 依赖 TPM2.0 芯片,无 TPM 设备无法使用 |
| 混合加载 | 远程密文 + 本地硬件密钥解密 | 网络传输加密,密钥不对外暴露 | 密钥丢失会导致脚本无法解密执行 |
五、运维审计配套建议
- 监控 WMI、事件日志、注册表写入行为,拦截本地隐藏脚本存储;
- PerfMon 监控 Realtek 网卡非常规协议流量(LDAP/DHCP/ICMPv6),告警隐蔽远程加载;
klist、netsh http审计 Kerberos 票据、http.sys 访问日志,追踪内网远程脚本访问行为;- AD 域通过
ntdsutil监控 ntds.dit 对象扩展字段变更,防止恶意存入后门脚本。
在 PowerShell 中,"Local Loading本地加载"和"Remote Loading远程加载"通常指的是运行脚本或命令的位置或方式。以下是关于本地加载和远程加载的一些基本概念和示例:
本地加载
本地加载指的是在当前计算机上执行 PowerShell 脚本或命令。这些脚本和命令直接在本地计算机上运行,无需通过网络连接到其他计算机或服务。
示例:本地加载脚本
# 本地加载脚本示例
Write-Output "This script is running locally."
Get-Process | Format-Table Name, Id, CPU -AutoSize
远程加载
远程加载则是通过网络连接到其他计算机或设备,在远程计算机上执行 PowerShell 脚本或命令。这通常涉及使用 PowerShell 的远程管理功能来访问和操作远程计算机。
示例:远程加载脚本
# 远程加载脚本示例
$remoteComputer = "RemoteComputerName"
# 连接到远程计算机执行命令
Invoke-Command -ComputerName $remoteComputer -ScriptBlock {
Write-Output "This script is running remotely on $env:COMPUTERNAME."
Get-Service | Where-Object { $_.Status -eq 'Running' } | Format-Table -Property Name, DisplayName, Status -AutoSize
}
在这个示例中,Invoke-Command 命令用于在 $remoteComputer 指定的远程计算机上执行脚本块 (-ScriptBlock)。脚本块中的命令将在远程计算机上执行,并且可以返回结果。
注意事项:
- 安全性: 在执行远程加载时,确保具有适当的权限和安全策略,以防止未经授权的访问。
- 网络连接: 远程加载依赖于网络连接和目标计算机的可用性。确保网络稳定和远程计算机可达。
- 参数传递: 使用
-ArgumentList参数可以在本地和远程脚本之间传递参数。
这些示例和概念可以帮助你理解如何在 PowerShell 中区分和实现本地加载和远程加载的操作。具体的应用取决于你的实际需求和环境设置。
PowerShell 的本地加载和远程加载时,进一步了解如何在实际场景中应用这些概念非常重要。下面我将继续讨论一些实际示例和更深入的用法。
更多示例和用法
1. 本地加载脚本文件
你可以在本地计算机上创建 PowerShell 脚本文件,并直接运行它们。
# 本地脚本文件示例:Get-LocalDiskInfo.ps1
# 文件内容:
# Get-PSDrive -PSProvider FileSystem | Format-Table Name, Used, Free, @{Label="Capacity(GB)"; Expression={$_.Used + $_.Free / 1GB}} -AutoSize
# 运行本地脚本文件
.\Get-LocalDiskInfo.ps1
2. 远程加载脚本文件
有时需要在远程计算机上执行本地存储的脚本文件。
# 远程加载脚本文件示例
$remoteComputer = "RemoteComputerName"
$scriptFilePath = "\\FileServer\Scripts\Install-App.ps1"
# 远程执行脚本文件
Invoke-Command -ComputerName $remoteComputer -FilePath $scriptFilePath
在这个示例中,Invoke-Command 的 -FilePath 参数用于指定要在远程计算机上运行的脚本文件的路径。这种方式特别适合需要在多个远程计算机上执行相同操作的场景。
3. 远程加载命令
通过 Invoke-Command 或 Enter-PSSession,可以直接在远程计算机上执行 PowerShell 命令。
# 远程执行命令示例
$remoteComputer = "RemoteComputerName"
# 使用 Invoke-Command 执行远程命令
Invoke-Command -ComputerName $remoteComputer -ScriptBlock {
Get-Service | Where-Object { $_.Status -eq 'Running' } | Format-Table -Property Name, DisplayName, Status -AutoSize
}
# 使用 Enter-PSSession 进入远程会话
Enter-PSSession -ComputerName $remoteComputer
Invoke-Command 允许你在远程计算机上执行一系列命令,并获取结果。而 Enter-PSSession 则会打开一个交互式的 PowerShell 会话,允许你在远程计算机上执行命令和脚本,并直接查看输出。
4. 本地与远程混合操作
有时候需要在本地和远程操作之间进行交互,例如在本地计算机上准备一些数据,然后将其传输到远程计算机上进行处理。
# 本地与远程混合操作示例
$localData = Get-Content "C:\Local\Data.txt"
$remoteComputer = "RemoteComputerName"
# 将本地数据传输到远程计算机
Invoke-Command -ComputerName $remoteComputer -ScriptBlock {
param($data)
Set-Content -Path "C:\Remote\Data.txt" -Value $data
} -ArgumentList $localData
在这个示例中,$localData 包含了从本地文件读取的数据,然后使用 Invoke-Command 将这些数据传输到 $remoteComputer 上的远程计算机,并在远程计算机上写入到文件中。
通过本地加载和远程加载,PowerShell 提供了强大的管理和自动化能力,无论是在单个计算机上执行操作,还是通过网络连接到多个远程计算机进行管理和监控。了解如何正确使用这些功能,可以显著提升管理效率和操作便捷性。
5. 使用 PowerShell 进行远程管理
除了单纯执行命令和脚本外,PowerShell 还支持远程管理和配置远程计算机的功能。这对于大规模部署和管理特别有用。
# 远程管理示例:配置远程计算机
$remoteComputer = "RemoteComputerName"
# 检查远程计算机上的 Windows 版本
Invoke-Command -ComputerName $remoteComputer -ScriptBlock {
Get-ComputerInfo | Select-Object CsName, WindowsVersion
}
# 远程启动服务示例
Invoke-Command -ComputerName $remoteComputer -ScriptBlock {
Start-Service -Name "BITS"
}
在这个示例中,通过 Invoke-Command 可以远程获取计算机信息并启动服务。这种能力对于远程监控和故障排除尤为重要。
6. 使用 PowerShell 进行定时任务管理
PowerShell 还可以帮助你设置和管理定时任务,无论是在本地还是远程计算机上。
# 设置本地计算机的定时任务
$action = New-ScheduledTaskAction -Execute "C:\Scripts\Backup.ps1"
$trigger = New-ScheduledTaskTrigger -Daily -At "2:00AM"
Register-ScheduledTask -TaskName "DailyBackup" -Action $action -Trigger $trigger
# 设置远程计算机的定时任务
Invoke-Command -ComputerName $remoteComputer -ScriptBlock {
$action = New-ScheduledTaskAction -Execute "C:\Scripts\Backup.ps1"
$trigger = New-ScheduledTaskTrigger -Daily -At "2:00AM"
Register-ScheduledTask -TaskName "DailyBackup" -Action $action -Trigger $trigger
}
通过以上示例,可以看到如何在本地和远程计算机上都设置定时任务,这对于自动化重复性任务非常有用。
7. 使用 PowerShell 进行远程安装和配置
最后,PowerShell 还可以通过远程脚本执行来进行软件安装和配置。
# 远程安装示例
$remoteComputer = "RemoteComputerName"
$installerPath = "\\FileServer\Installers\AppInstaller.exe"
# 远程执行安装程序
Invoke-Command -ComputerName $remoteComputer -ScriptBlock {
param($installerPath)
Start-Process -FilePath $installerPath -ArgumentList "/silent" -Wait
} -ArgumentList $installerPath
这个示例展示了如何在远程计算机上静默安装一个应用程序,通过 Invoke-Command 发送参数并等待安装完成。
结论
通过这些示例,你可以更全面地了解 PowerShell 在本地加载和远程加载方面的应用。PowerShell 的强大之处在于其灵活性和可扩展性,使得它成为管理 Windows 环境中不可或缺的工具。无论是简单的本地脚本还是复杂的远程管理任务,PowerShell 都能够提供强大的支持。
PowerShell 在本地和远程加载方面都提供了强大的功能。以下是一些常见的应用示例:
1. 本地加载
在本地计算机上,PowerShell 可以用于:
# 获取本地计算机信息
Get-ComputerInfo
# 查询本地服务状态
Get-Service -Name Spooler
# 执行本地脚本
& "C:\Scripts\Backup.ps1"
# 安装本地软件
Start-Process -FilePath "Installer.exe" -ArgumentList "/silent" -Wait
2. 远程加载
通过 PowerShell,你可以远程管理多台计算机,例如:
# 获取远程计算机信息
Invoke-Command -ComputerName "RemoteComputer" -ScriptBlock {
Get-ComputerInfo
}
# 查询远程计算机服务状态
Invoke-Command -ComputerName "RemoteComputer" -ScriptBlock {
Get-Service -Name Spooler
}
# 远程执行脚本
Invoke-Command -ComputerName "RemoteComputer" -FilePath "C:\Scripts\Backup.ps1"
# 远程安装软件
Invoke-Command -ComputerName "RemoteComputer" -ScriptBlock {
Start-Process -FilePath "\\FileServer\Installers\AppInstaller.exe" -ArgumentList "/silent" -Wait
}
实际应用示例
-
自动化任务: 使用 PowerShell 脚本在本地或远程计算机上定期执行任务,如备份、日志清理等。
-
远程管理: 通过远程加载的方式,可以批量管理多个服务器或工作站,执行配置更改、服务启停等操作。
-
软件部署: 通过远程加载执行安装程序,实现大规模软件部署,例如更新应用程序或安装补丁。
-
监控和报告: 编写脚本来收集远程计算机的性能数据或日志,生成报告或发送警报。
PowerShell 的灵活性和强大的管理功能使其成为系统管理工程师的重要工具,可以帮助简化管理任务并提高效率。
利用 PowerShell 在本地和远程加载方面执行许多其他任务,例如:
本地加载的应用:
-
事件日志管理:
powershellCopy Code# 导出本地事件日志 Get-WinEvent -LogName System -After (Get-Date).AddDays(-1) | Export-Csv C:\Logs\SystemEvents.csv -
文件系统操作:
powershellCopy Code# 复制本地文件 Copy-Item -Path "C:\Source\File.txt" -Destination "D:\Destination\" -Force -
用户管理:
powershellCopy Code# 创建本地用户账户 New-LocalUser -Name "User1" -Password (ConvertTo-SecureString "P@ssw0rd" -AsPlainText -Force) -
安全策略设置:
powershellCopy Code# 检查本地防火墙规则 Get-NetFirewallRule -DisplayName "Remote Desktop" | Set-NetFirewallRule -Enabled True
远程加载的应用:
-
远程注册表操作:
powershellCopy Code# 连接远程注册表并查看键值 Invoke-Command -ComputerName "RemoteComputer" -ScriptBlock { Get-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion" -Name "ProgramFilesDir" } -
远程事件日志管理:
powershellCopy Code# 获取远程计算机最近的错误事件 Get-WinEvent -ComputerName "RemoteComputer" -LogName System -EntryType Error -After (Get-Date).AddDays(-7) -
远程服务管理:
powershellCopy Code# 启动远程计算机上的服务 Invoke-Command -ComputerName "RemoteComputer" -ScriptBlock { Start-Service -Name "PrintSpooler" } -
远程执行脚本:
powershellCopy Code# 在远程计算机上执行脚本 Invoke-Command -ComputerName "RemoteComputer" -FilePath "C:\Scripts\RemoteScript.ps1"
这些示例涵盖了 PowerShell 在系统管理工程师日常工作中的广泛应用,无论是本地还是远程环境下,PowerShell 都是一种强大的自动化工具,可以帮助简化任务并提高效率。

浙公网安备 33010602011771号