渗透学习笔记(十)PowerShell基础
声明!
学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下,如涉及侵权马上删除文章,笔记只是方便各位师傅的学习和探讨,文章所提到的网站以及内容,只做学习交流,其他均与本人以及泷羽sec团队无关,切勿触碰法律底线,否则后果自负!!!!有兴趣的小伙伴可以点击下面连接进入b站主页B站泷羽sec
前言
上一章我们学习了shell编程,这一章学习powershell的内容。powershell主要是应用在windows上,但是也兼容Linux的命令,比如说ls等命令也是可以用的,对于shell和powershell这两部分内容,我们一定要多加熟悉练习,具体学习可以参考https://learn.microsoft.com/zh-cn/powershell/scripting/overview?view=powershell-7.4 这个官方文档地址。
PowerShell知识总结
一、概述
PowerShell是一种强大的命令行工具和脚本语言,可用于自动化管理任务、系统配置、软件部署等。它基于.NET框架构建,能够与Windows操作系统及其他微软技术深度集成,同时也支持跨平台操作(在Windows、Linux和macOS上运行)。
二、基础概念
(一)命令(Cmdlet)
- 命名规范:采用“动词 - 名词”结构,如
Get-Process
、Set-Item
等,便于理解和记忆。动词表示操作,名词表示操作对象。 - 获取帮助:使用
Get-Help
命令获取Cmdlet的帮助信息,例如Get-Help Get-Process
可查看Get-Process
命令的详细帮助,包括语法、参数说明、示例等。
(二)变量
- 定义与赋值:变量以
$
开头,如$var = "Hello"
,无需提前声明数据类型,PowerShell会根据赋值自动推断。变量可以存储各种数据类型,如字符串、整数、数组、对象等。 - 作用域:变量有不同的作用域,包括全局、局部、脚本、函数等。默认在函数内定义的变量是局部变量,若要定义全局变量,可使用
$global:变量名
格式。
(三)表达式与运算符
- 表达式:由变量、常量、运算符和函数等组成,用于执行计算、比较和操作数据。例如,
$a = 5 + 3
是一个简单的表达式,计算结果为8并赋值给变量$a
。 - 算术运算符:包括
+
(加)、-
(减)、*
(乘)、/
(除)、%
(取模)等,用于执行基本的数学运算。例如,$b = 10 / 2
的结果为5。 - 比较运算符:如
-eq
(等于)、-ne
(不等于)、-gt
(大于)、-lt
(小于)、-ge
(大于等于)、-le
(小于等于)等,用于比较两个值的大小关系。例如,$a -eq 8
的结果为$true
。 - 逻辑运算符:
-and
(与)、-or
(或)、-not
(非)等,用于组合多个条件判断。例如,($a -gt 5) -and ($a -lt 10)
用于判断变量$a
是否大于5且小于10。
(四)流程控制语句
- 条件语句(if - else):根据条件执行不同的代码块,例如:
$num = 10
if ($num -gt 5) {
Write-Output "数字大于5"
} else {
Write-Output "数字小于等于5"
}
- 循环语句(for、foreach、while、do - while)
- for循环:用于指定次数的循环,例如:
for ($i = 0; $i -lt 5; $i++) {
Write-Output $i
}
- **foreach循环**:用于遍历集合或数组中的元素,例如:
$arr = 1, 2, 3, 4, 5
foreach ($item in $arr) {
Write-Output $item
}
- **while循环**:在条件为真时重复执行代码块,例如:
$count = 0
while ($count -lt 3) {
Write-Output $count
$count++
}
- **do - while循环**:先执行一次代码块,然后在条件为真时继续循环,例如:
$num = 0
do {
Write-Output $num
$num++
} while ($num -lt 2)
(五)函数
- 定义函数:使用
function
关键字定义函数,例如:
function SayHello {
Write-Output "Hello, World!"
}
- 函数参数:函数可以接受参数,参数在函数定义中声明,例如:
function AddNumbers ($num1, $num2) {
return $num1 + $num2
}
- 函数返回值:使用
return
语句返回函数的值,例如上述AddNumbers
函数返回两个数的和。
(六)脚本
- 脚本文件:扩展名为
.ps1
,可包含一系列PowerShell命令和逻辑,实现更复杂的自动化任务。 - 执行脚本:在PowerShell中,通过指定脚本文件的路径来执行脚本,例如
.\script.ps1
。需要注意的是,默认情况下,PowerShell的执行策略可能限制脚本的执行,需要根据实际情况调整执行策略。
(七)管道(|)
管道用于将一个命令的输出作为另一个命令的输入,实现命令之间的数据传递和处理。例如,Get-Process | Where-Object {$_.CPU -gt 50}
先获取所有进程,然后筛选出CPU使用率大于50的进程,其中 $_
表示管道中当前传递的对象。
(八)别名
别名是命令的简短替代名称,方便用户快速输入常用命令。可以使用 Get-Alias
命令查看已定义的别名,也可以使用 New-Alias
命令创建自定义别名,例如 New-Alias -Name np -Value Notepad
创建了一个名为 np
的别名,用于启动记事本。
(九)模块
模块是扩展PowerShell功能的一种方式,它可以包含Cmdlet、函数、变量、脚本等资源。PowerShell提供了许多内置模块,同时也可以安装第三方模块。使用 Import-Module
命令导入模块,使其提供的功能在当前会话中可用,例如 Import-Module ActiveDirectory
导入Active Directory模块,以便执行与Active Directory相关的操作。
(十)对象
在PowerShell中,几乎所有的数据和操作结果都是对象。对象具有属性和方法,可以通过 .
运算符访问对象的属性和调用对象的方法。例如,$process = Get-Process -Name "chrome"
获取名为 chrome
的进程对象,然后可以访问其属性如 $process.Id
(进程ID)、$process.Name
(进程名称),或调用其方法如 $process.Kill()
(终止进程)。
(十一)帮助系统
PowerShell提供了丰富的帮助系统,帮助用户了解命令的用法、参数、示例等。可以使用 Get-Help
命令获取命令的帮助,例如 Get-Help Get-Process
。还可以使用 Get-Command
命令查找系统中安装的所有命令,以及使用 Get-Member
命令查看对象的成员(属性和方法)。
(十二)错误处理
在PowerShell中,可以使用 try - catch
语句块来捕获和处理错误。在 try
块中放置可能出错的代码,若发生错误,控制将转移到 catch
块中进行错误处理,例如:
try {
$result = 10 / 0 # 故意引发除零错误
} catch {
Write-Error "发生错误:$_"
}
(十三)远程处理
PowerShell支持远程执行命令,可对远程计算机进行管理操作。需要在远程计算机上启用PowerShell远程处理,并配置相应的权限和防火墙规则。使用 Enter-PSSession
命令建立与远程计算机的交互式会话,例如 Enter-PSSession -ComputerName "Server01" -Credential (Get-Credential)
以指定的凭据连接到远程计算机 Server01
。还可以使用 Invoke-Command
命令在远程计算机上执行命令或脚本块,例如 Invoke-Command -ComputerName "Server01", "Server02" -ScriptBlock {Get-Process}
在两台远程计算机上获取进程信息。
(十四)提供程序
提供程序是PowerShell访问不同类型数据存储的接口,如文件系统、注册表、证书存储等。通过提供程序,用户可以使用与访问文件系统类似的方式来操作其他数据存储。例如,使用 Get-PSProvider
命令查看系统中安装的提供程序,使用 Get-PSDrive
命令查看当前可用的驱动器,包括由提供程序公开的驱动器。可以像操作文件系统一样使用 Get-ChildItem
等命令来浏览和操作提供程序所管理的数据,如 Get-ChildItem -Path Cert:\LocalMachine\CA
查看本地计算机证书存储中的证书颁发机构。
(十五)配置管理(PowerShell Desired State Configuration - DSC)
DSC是PowerShell中的一个管理框架,用于以声明性的方式管理企业基础结构的配置。通过DSC,可以创建配置脚本,定义系统应处于的状态,例如安装特定软件、配置服务等。DSC会自动检查和确保系统的实际配置与定义的期望状态一致,并可报告配置偏差。支持推送(将配置主动推送到目标节点)和拉取(目标节点定期从配置服务器获取配置)模型来部署配置,便于大规模管理和维护系统配置的一致性。
三、在不同操作系统上的安装与使用
(一)Windows
- 安装方法
- Winget(推荐):适用于Windows客户端,在Windows 11和现代版本的Windows 10中默认捆绑,可通过命令行搜索和安装PowerShell,例如
winget search Microsoft.PowerShell
搜索PowerShell,winget install --id Microsoft.PowerShell --source winget
安装PowerShell。 - MSI包:适用于Windows Server和企业部署,可从GitHub下载安装包,如
PowerShell-7.4.6-win-x64.msi
等,安装过程中可选择安装位置、启用更新等选项,安装后会在 “开始” 菜单创建快捷方式。 - ZIP包:用于 “旁加载” 或安装多个版本,将下载的ZIP文件解压到指定位置,然后运行
pwsh.exe
启动PowerShell。此方法不会检查先决条件,使用WSMan远程处理时需确保满足相关条件。 - .NET全局工具:若已安装.NET Core SDK,可使用
dotnet tool install --global PowerShell
安装PowerShell作为全局工具,但当前运行的shell需重新启动才能使用新的PATH环境变量。 - Microsoft Store包:安装方便,但存在一些限制,如在应用程序沙盒中运行,可能无法修改某些系统级配置。可在Microsoft Store网站或应用程序中找到PowerShell版本进行安装。
- Winget(推荐):适用于Windows客户端,在Windows 11和现代版本的Windows 10中默认捆绑,可通过命令行搜索和安装PowerShell,例如
- 版本支持:PowerShell 7.4及更高版本可安装在Windows 10内部版本1607及更高版本、Windows 11、Windows Server 2016及更高版本上。不同版本的Windows对PowerShell的支持可能有所不同,具体取决于操作系统的生命周期和更新策略。
(二)Linux
- 支持的发行版:支持多种Linux发行版,如Debian、Ubuntu、Red Hat Enterprise Linux(RHEL)、Alpine等。不同发行版使用不同的包管理器进行安装,例如Debian和Ubuntu使用APT,RHEL使用yum或dnf。
- 安装步骤示例(以Ubuntu为例)
- 通过包存储库安装(首选)
- 更新包列表:
sudo apt-get update
。 - 安装必要的依赖项:
sudo apt-get install -y wget apt-transport-https software-properties-common
。 - 下载并注册Microsoft存储库密钥:
wget -q https://packages.microsoft.com/config/ubuntu/$VERSION_ID/packages-microsoft-prod.deb
和sudo dpkg -i packages-microsoft-prod.deb
。 - 更新包列表后安装PowerShell:
sudo apt-get update
和sudo apt-get install -y powershell
。
- 更新包列表:
- 通过直接下载安装
- 从GitHub版本页下载通用包,如
powershell_7.4.6-1.deb_amd64.deb
。 - 安装下载的包:
sudo dpkg -i powershell_7.4.6-1.deb_amd64.deb
,若有依赖问题,使用sudo apt-get install -f
解决。
- 从GitHub版本页下载通用包,如
- 通过包存储库安装(首选)
- 其他安装方法
- Snap包:适用于支持Snap的Linux发行版,可从Snap Store安装。例如,使用
sudo snap install powershell --classic
安装稳定版本,sudo snap install powershell-preview --classic
安装预览版本。Snap包会自动升级,可使用sudo snap refresh
命令触发升级。 - 二进制存档:从GitHub版本页下载
tar.gz
包,解压到指定位置并设置执行权限,然后创建符号链接指向pwsh
可执行文件。此方法可用于在不支持正式安装方法的Linux发行版上安装PowerShell,但需注意安装依赖项。例如,在Alpine Linux上安装的具体步骤如下:- 安装依赖项:
sudo apk add --no-cache ca-certificates less ncurses-terminfo-base krb5-libs libgcc libintl libssl1.1 libstdc++ tzdata userspace-rcu zlib icu-libs curl
和sudo apk -X https://dl-cdn.alpinelinux.org/alpine/edge/main add --no-cache lttng-ust
。 - 下载并解压PowerShell二进制存档:
curl -L https://github.com/PowerShell/PowerShell/releases/download/v7.4.6/powershell-7.4.6-linux-musl-x64.tar.gz -o /tmp/powershell.tar.gz
和sudo mkdir -p /opt/microsoft/powershell/7
以及sudo tar zxf /tmp/powershell.tar.gz -C /opt/microsoft/powershell/7
。 - 设置执行权限并创建符号链接:
sudo chmod +x /opt/microsoft/powershell/7/pwsh
和sudo ln -s /opt/microsoft/powershell/7/pwsh /usr/bin/pwsh
。
- 安装依赖项:
- Snap包:适用于支持Snap的Linux发行版,可从Snap Store安装。例如,使用
(三)macOS
- 安装要求:PowerShell 7或更高版本需要macOS 11或更高版本。
- 安装方法
- 使用Homebrew安装(首选)
- 若未安装Homebrew,先安装:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
。 - 安装PowerShell:
brew install powershell/tap/powershell
安装最新稳定版本,brew install powershell/tap/powershell-preview
安装预览版本。 - 更新PowerShell:
brew update
和brew upgrade powershell
或brew upgrade powershell-preview
。
- 若未安装Homebrew,先安装:
- 通过直接下载安装
- 从版本页下载安装包,如
powershell-7.4.6-osx-x64.pkg
或powershell-7.4.6-osx-arm64.pkg
。 - 双击安装包并按照提示操作,若遇到 “无法打开…因为Apple无法检查其是否有恶意软件” 的错误,可通过查找器控制单击包并选择 “打开”,或在命令行中使用
sudo xattr -rd com.apple.quarantine./Downloads/powershell-7.4.6-osx-x64.pkg
(需包含完整路径)后再安装。
- 从版本页下载安装包,如
- 作为.NET全局工具安装:若已安装.NET Core SDK,使用
dotnet tool install --global PowerShell
安装,安装后需重新启动shell或在新shell中启动PowerShell。
- 使用Homebrew安装(首选)
(四)在Docker中使用
- 查找可用映像:已发布的映像位于Microsoft工件注册表,需要Docker 17.05或更高版本。可使用
docker run -it mcr.microsoft.com/powershell
下载并启动包含最新稳定版本PowerShell的映像,使用docker run -it mcr.microsoft.com/powershell:preview
启动预览版映像。 - 使用PowerShell in Docker:在容器中运行PowerShell命令,可进行各种操作,如管理容器内的文件系统、运行脚本等。例如,在容器中执行
Get-Process
查看容器内的进程信息。
四、安全相关
(一)执行策略
- 执行策略设置:PowerShell执行策略控制脚本的执行条件,是一项安全功能,但不是绝对的安全边界。可通过
Get-ExecutionPolicy
命令查看当前执行策略,通过Set-ExecutionPolicy
命令更改执行策略,例如Set-ExecutionPolicy -ExecutionPolicy RemoteSigned
将执行策略设置为 “远程签名”,允许运行本地创建的脚本,但阻止运行未签名的下载脚本。执行策略可以在不同范围设置,包括本地计算机、当前用户、进程等,可使用Get-ExecutionPolicy -List
查看所有范围的执行策略设置。 - 常见执行策略
- Restricted(默认,受限):在Windows客户端操作系统中默认设置,不允许运行任何脚本,仅能以交互方式运行命令。
- RemoteSigned:允许运行本地创建的脚本,但对于从网络下载的脚本,要求其具有受信任的发布者签名。
(二)遥测
默认情况下,PowerShell会收集有限的遥测数据(无个人身份信息),以帮助改进产品。若要选择不发送遥测,可在启动PowerShell之前创建名为 POWERSHELL_TELEMETRY_OPTOUT
且值为 1
的环境变量。收集的遥测数据详情可在Microsoft隐私声明中查看。
(三)安全注意事项
- 避免在脚本或共享代码中使用别名,应使用完整的Cmdlet和参数名称,以提高代码的可读性和可维护性,避免潜在的命令混淆。
- 谨慎使用方法,尤其是在处理系统配置或关键操作时,确保方法的使用符合预期且不会导致意外后果。例如,某些
Get-*
命令可能看似无破坏性,但实际上可能通过方法调用产生更改,需特别注意。 - 在使用PowerShellGet从不受信任的存储库(如PowerShell库)获取模块时,应先在独立测试环境中全面评审代码,确保其安全性和适用性后再考虑用于生产环境,防止引入恶意代码。
(四)更新管理(适用于PowerShell 7.2及更高版本)
- Microsoft更新功能:使用PowerShell的Microsoft更新功能,可在传统Microsoft更新管理流中获取最新的PowerShell 7更新,包括适用于企业的Windows更新、WSUS、Microsoft Endpoint Configuration Manager或交互式MU对话框。更新发布后,最多可能需要两周时间才能通过Microsoft更新提供,且更新作为可选软件更新提供。
- 配置要求:必须在基于x64的系统上安装Windows版本1709或更高版本,才能支持Microsoft更新功能。在安装PowerShell时,可通过MSI包的相关选项(如
USE_MU
和ENABLE_MU
)选择是否启用更新功能及更新方式,但设置ENABLE_MU = 0
不会禁用Microsoft更新,只是不使用其自动更新功能。 - 故障排除:若未收到更新,可能原因包括更新尚未发布、系统管理员通过组策略阻止了更新,或者安装程序中的复选框设置不正确等。可检查相关设置,确保已选中相应复选框,或使用
msiexec.exe
命令修复安装并启用更新选项。例如,使用msiexec.exe /fmu.\PowerShell - 7.4.1 - win - x64.msi USE_MU = 1 ENABLE_MU = 1
命令进行修复安装并启用更新。
(五)模块安全性
- 在导入模块时,特别是从非官方或不可信来源获取的模块,要谨慎检查模块的来源和内容,确保其不包含恶意代码或潜在的安全风险。例如,在使用PowerShellGet模块从PowerShell库安装模块时,由于库中大多数模块并非由Microsoft编写,需要额外小心。
- 模块清单(.PSD1文件)应包含准确的元数据信息,如作者、描述等,这有助于识别模块的来源和用途,同时也有助于确保模块的完整性和安全性。对于没有清单或清单信息不完整的模块,应谨慎使用。
(六)脚本签名
脚本签名是增强脚本安全性的一种方式,通过对脚本进行数字签名,可以验证脚本的来源和完整性,防止脚本被篡改。在企业环境或需要更高安全性的场景中,可考虑对重要的PowerShell脚本进行签名,以确保只有受信任的脚本才能在系统中执行。同时,对于从外部获取的签名脚本,也应验证签名的有效性和可信度。