PowerShell模块与安全指南
1. PowerShell模块回顾
1.1 模块基础
在开始编写自己的模块之前,我们先回顾了模块的基础知识。标准模块位置可以通过编辑
$ENV:PSModulePath
变量来添加新位置。PowerShell利用这些位置实现自动加载,但有时我们可能不希望自动加载发生。手动导入模块也是可行的,最后我们还了解了
PowerShellGet
模块。
1.2 编写自定义模块
- 点源法 :最早的代码导入方法,但存在一些问题。
- 脚本转换模块 :通过编写脚本并将其转换为模块,创建了第一个自定义模块。
- 嵌套模块构建应用 :可以通过嵌套模块的方式构建应用程序。
- 其他类型模块 :如二进制模块等。
1.3 清单模块
清单模块是最常见的复杂模块类型。清单文件控制着模块的加载和导出内容,并且可以编写和测试清单文件。
1.4 Plaster工具
Plaster是一个可以简化模块编写的工具。
1.5 练习
以下是一些关于模块的练习:
1. 如何列出当前PowerShell会话中所有已导入的模块?
2. 导入模块时
-Global
参数的作用是什么?
3. 如何导入不在
$ENV:PSModulePath
变量指定路径中的模块?
4. 若要导入的模块中的函数与当前会话中已存在的cmdlet重名,有哪两种解决方法?
5. 默认情况下,模块的所有函数都会被导出,有哪两种方法可以控制导出的函数?
6. 模块清单中
HelpInfoURI
键的作用是什么?
7.
.ps1xml
扩展名的文件中可能包含什么内容?
8. 加载
.dll
扩展名的模块会得到什么样的命令?
9. 为什么不编写CDXML模块?
2. PowerShell安全的重要性
2.1 强大功能带来的风险
PowerShell是一个极其强大的工具,但同时也带来了安全风险。它具有PowerShell远程处理的概念,允许我们登录到远程设备并像在本地一样运行PowerShell代码,这使得它成为一个强大的管理工具,但也可能被恶意利用。
2.2 PowerShell远程处理简介
许多旧的Windows PowerShell cmdlet有
-ComputerName
参数,可用于查询远程机器信息,但该参数依赖于当前PowerShell会话的凭据具有查询远程机器的权限。而且,即使凭据正确,远程防火墙也可能阻止请求。在PowerShell 7.2及更高版本中,部分cmdlet甚至没有
-ComputerName
参数。
为了解决这些问题,Windows PowerShell 3.0开发了PowerShell远程处理功能,它使用WinRM(Windows Remote Management)协议,该协议基于HTTP/S运行在5985(HTTP)和5986(HTTPS)端口上,可以使用SSL进行加密。在企业配置中,使用Active Directory时,流量还可以使用Kerberos进行加密。Linux机器不包含WinRM,因此PowerShell 7.x支持通过SSH运行远程会话。
3. PowerShell远程处理操作
3.1 启用PowerShell远程处理
默认情况下,所有Windows服务器都启用了PowerShell远程处理,但Windows客户端是禁用的。可以使用
Enable-PSRemoting
cmdlet来启用它,该cmdlet会完成从启用端点到在Windows防火墙中创建正确规则的所有操作,需要从提升的管理员提示符下运行。以下是常用参数:
-
-Force
:避免多次询问是否确认操作。
-
-SkipNetworkProfileCheck
:绕过网络配置文件检查,但会创建一个仅允许本地子网进行远程会话的防火墙规则。不过,最好还是正确设置网络配置文件,或者避免在公共网络上运行远程会话。
3.2 创建会话
使用
New-PSSession
cmdlet创建会话,示例代码如下:
$cred = # 存储Admin用户凭据
New-PSSession -ComputerName localhost -Authentication Negotiate -Credential $cred
这将创建一个持久会话,可以根据需要进行连接和断开连接。
3.3 加入和离开会话
-
加入会话
:可以使用
Enter-PSSessioncmdlet,有两种方式: -
通过会话名称:
Enter-PSSession -Name <session name> -
通过管道传递会话对象:
Get-PSSession -Name <session name> | Enter-PSSession
进入会话后,PowerShell提示符会显示所连接客户端的计算机名和远程工作目录。
也可以通过指定计算机名和凭据创建临时会话:
Enter-PSSession -ComputerName <name> -Credential <credential>
,这种会话在退出后将不再存在。
-
离开会话
:使用
exit关键字。
3.4 删除会话
-
通过会话名称:
Remove-PSSession –Name <session name> -
通过管道传递会话对象:
Get-PSSession -Name <session name> | Remove-PSSession
如果不指定会话名称运行Get-PSSessioncmdlet,则会删除所有会话。
3.5 一对多会话
使用
Invoke-Command
cmdlet可以在多台机器上同时运行命令或脚本,示例代码如下:
Invoke-Command -ComputerName <name 1>, <name 2> -ScriptBlock {Get-Service}
该命令使用PowerShell远程处理,与之前的
PSSession
cmdlet相同。
4. 防止PowerShell意外错误
4.1 执行策略
执行策略是一个安全功能,仅在Windows环境中可用,用于控制脚本的运行方式。Don Jones将其描述为“减缓那些无意中尝试运行不可信脚本的不知情用户”。执行策略有不同的安全级别和应用范围,级别由脚本的来源以及是否使用受信任证书颁发机构的代码签名证书进行签名决定。
执行策略级别
| 级别 | 描述 |
|---|---|
| Restricted |
Windows客户端计算机的默认策略,防止运行脚本,包括格式化文件和模块(
.ps1xml
、
.psm1
或
.ps1
扩展名的文件),只能在终端运行单个命令。
|
| AllSigned | 允许运行具有受信任发布者数字签名的脚本,包括在本地计算机上编写的脚本。未签名的脚本无法运行,由不受信任的发布者签名的脚本会提示用户。 |
| RemoteSigned | 来自本地机器以外的脚本需要数字签名,而本地编写的脚本不需要。 |
| Default | 设置默认策略,Windows客户端的默认策略是Restricted,Windows服务器的默认策略是RemoteSigned。 |
| Undefined | 移除当前范围设置的任何执行策略。如果在所有范围都使用此设置,则结果策略为默认策略。 |
| Unrestricted | 非Windows计算机的默认策略,允许运行任何位置的未签名文件,运行非本地网络的脚本时可能会提示用户。 |
| Bypass |
不阻止任何内容,没有警告,忽略执行策略。可以通过调用
pwsh.exe
程序的
-ExecutionPolicy
参数来设置。
|
执行策略范围
执行策略可以应用于以下范围,按优先级从高到低排列:
1.
MachinePolicy
:通过组策略设置,适用于机器的所有用户。
2.
UserPolicy
:通过组策略设置,适用于机器的当前用户。
3.
Process
:指当前PowerShell会话,由
$env:PSExecutionPolicyPreference
变量控制,会话关闭后变量内容将被移除。
4.
CurrentUser
:仅适用于当前用户,存储在Windows注册表中。
5.
LocalMachine
:适用于机器的所有用户,也存储在注册表中。
可以使用
Get-ExecutionPolicy
和
Set-ExecutionPolicy
cmdlet来获取和设置执行策略。
4.2 其他保护功能
-
默认关联
:PowerShell扩展名(如
.ps1)默认与记事本关联,而不是作为可执行文件。这意味着如果不小心双击脚本,会在记事本中打开,而不是运行它。 - 路径要求 :PowerShell不会在当前文件夹中搜索脚本文件,因此在终端提示符下运行脚本时,必须提供相对路径或绝对路径。
mermaid流程图:
graph LR
A[开始] --> B[检查执行策略范围]
B --> C{MachinePolicy是否设置?}
C -- 是 --> D[应用MachinePolicy策略]
C -- 否 --> E{UserPolicy是否设置?}
E -- 是 --> F[应用UserPolicy策略]
E -- 否 --> G{Process是否设置?}
G -- 是 --> H[应用Process策略]
G -- 否 --> I{CurrentUser是否设置?}
I -- 是 --> J[应用CurrentUser策略]
I -- 否 --> K[应用LocalMachine策略]
D --> L[结束]
F --> L[结束]
H --> L[结束]
J --> L[结束]
K --> L[结束]
通过以上内容,我们了解了PowerShell模块的编写和使用,以及PowerShell安全的重要性和相关保护措施。在使用PowerShell时,务必注意安全问题,合理设置执行策略,以防止意外错误和恶意攻击。后续我们还将继续探讨如何安全地运行PowerShell、PowerShell日志记录以及编写安全代码等内容。
5. 安全地运行PowerShell
5.1 远程会话安全
在使用PowerShell远程处理时,要确保会话的安全性。可以使用安全的认证方式,如
Negotiate
认证,它会根据环境自动选择合适的认证协议(如Kerberos或NTLM)。在创建会话时,使用强密码的凭据,避免使用弱密码或明文存储凭据。
$cred = Get-Credential
New-PSSession -ComputerName remoteServer -Authentication Negotiate -Credential $cred
5.2 控制访问权限
限制能够进行PowerShell远程处理的用户和计算机。可以通过Windows防火墙规则、Active Directory组策略等方式来控制哪些用户和计算机可以发起和接受远程会话。例如,只允许特定IP地址范围的计算机进行远程连接。
5.3 监控和审计
定期监控PowerShell远程会话的活动,查看哪些用户在何时连接到哪些计算机,执行了哪些命令。可以使用Windows事件日志来记录和审计这些活动。通过分析日志,可以及时发现异常行为并采取相应的措施。
6. PowerShell日志记录
6.1 日志记录的重要性
PowerShell日志记录可以帮助我们了解系统中发生的操作,追踪问题的根源,以及进行安全审计。通过记录PowerShell命令的执行情况、输入输出信息等,可以在出现问题时进行回溯和分析。
6.2 启用日志记录
在Windows环境中,可以通过组策略或注册表设置来启用PowerShell日志记录。以下是通过组策略启用日志记录的步骤:
1. 打开组策略管理控制台(GPMC)。
2. 创建或编辑一个组策略对象(GPO)。
3. 导航到“计算机配置” -> “管理模板” -> “Windows组件” -> “Windows PowerShell”。
4. 启用“打开模块日志记录”和“打开脚本块日志记录”。
5. 配置日志记录的详细程度和存储位置。
6.3 日志类型
- 模块日志 :记录模块的加载和卸载操作,以及模块中的函数调用。
- 脚本块日志 :记录PowerShell脚本块的执行情况,包括脚本块的内容、执行时间等。
- 操作日志 :记录PowerShell的各种操作,如会话创建、命令执行等。
通过查看不同类型的日志,可以全面了解PowerShell的使用情况。
6.4 日志分析
可以使用Windows事件查看器或第三方日志分析工具来分析PowerShell日志。通过设置过滤条件,可以快速定位到感兴趣的事件。例如,过滤出特定用户执行的命令,或者特定时间范围内的操作。
7. 编写安全的代码
7.1 输入验证
在编写PowerShell脚本时,要对用户输入进行严格的验证。避免直接使用用户输入的值,防止注入攻击。例如,使用
ValidateSet
或
ValidateRange
等属性来限制输入的范围。
function Get-Data {
param (
[ValidateSet("Option1", "Option2", "Option3")]
[string]$Option
)
# 处理输入
}
7.2 最小权限原则
在编写脚本时,遵循最小权限原则,只赋予脚本执行所需的最小权限。避免使用具有过高权限的账户来运行脚本,减少潜在的安全风险。
7.3 代码签名
使用代码签名证书对脚本进行签名,确保脚本的完整性和来源可追溯。可以使用
Set-AuthenticodeSignature
cmdlet来对脚本进行签名。
$cert = Get-ChildItem -Path Cert:\CurrentUser\My -CodeSigningCert
Set-AuthenticodeSignature -FilePath C:\Scripts\MyScript.ps1 -Certificate $cert
7.4 错误处理
在脚本中添加适当的错误处理机制,确保脚本在遇到错误时能够优雅地处理,避免因错误导致的安全漏洞。例如,使用
try-catch
块来捕获和处理异常。
try {
# 执行可能出错的操作
}
catch {
Write-Error "An error occurred: $_"
}
8. 总结
| 方面 | 要点 |
|---|---|
| 模块编写 | 回顾了模块基础,介绍了自定义模块的编写方法,包括点源法、脚本转换模块等,还提到了清单模块和Plaster工具。 |
| 安全重要性 | 强调了PowerShell强大功能带来的安全风险,特别是PowerShell远程处理的潜在威胁。 |
| 远程处理 | 详细介绍了PowerShell远程处理的操作,包括启用、创建会话、加入和离开会话、删除会话以及一对多会话的使用。 |
| 意外错误防范 | 介绍了执行策略和其他保护功能,如默认关联和路径要求,以防止意外运行脚本。 |
| 安全运行 | 阐述了远程会话安全、访问权限控制和监控审计等方面,确保PowerShell远程处理的安全性。 |
| 日志记录 | 说明了日志记录的重要性、启用方法、日志类型和分析方式,帮助追踪和审计PowerShell操作。 |
| 安全代码编写 | 强调了输入验证、最小权限原则、代码签名和错误处理等安全编码实践。 |
mermaid流程图:
graph LR
A[开始使用PowerShell] --> B[编写模块]
B --> C[考虑安全问题]
C --> D[设置执行策略]
D --> E[启用远程处理]
E --> F[创建安全会话]
F --> G[运行脚本]
G --> H[记录日志]
H --> I[分析日志]
I --> J[改进安全措施]
J --> K[继续使用PowerShell]
通过全面了解PowerShell模块和安全相关知识,我们可以更安全、高效地使用PowerShell。在实际应用中,要根据具体的环境和需求,合理配置和使用这些功能,确保系统的安全性和稳定性。
超级会员免费看
35

被折叠的 条评论
为什么被折叠?



