【THM】Windows PowerShell-学习

本文相关的TryHackMe实验房间链接:https://tryhackme.com/r/room/windowspowershell

本文相关内容:发现PowerShell中的“Power”并学习相关的基础知识。

image-20250107185433029

介绍

image-20250107192912946

学习目标

这是命令行模块中的第二个实验房间,是关于PowerShell的入门知识介绍,PowerShell是第二个(仅从历史上看)专为Windows操作系统构建的命令行实用程序。

  • 了解 PowerShell 是什么以及它的功能。
  • 了解 PowerShell 语言的基本结构。
  • 学习并运行一些基本的 PowerShell 命令。
  • 了解PowerShell在网络安全行业中的众多应用情况。

前置学习条件

在学习本文内容之前,建议你先了解TryHackMe提供的Windows 和AD基础模块以及Windows 命令行实验房间中的相关概念。

什么是PowerShell

image-20250107193034400

根据Microsoft官方页面的介绍: “ PowerShell是一个跨平台任务自动化解决方案,由命令行 shell、脚本语言和配置管理框架组成。”

PowerShell 是 Microsoft 专为任务自动化和配置管理而设计的一款功能强大的工具。它结合了命令行界面和基于 .NET 框架构建的脚本语言。与旧的基于文本的命令行工具不同,PowerShell 是面向对象的(object-oriented),这意味着它可以处理复杂的数据类型并能更有效地与系统组件进行交互。PowerShell最初仅适用于Windows操作系统,但是现在已经扩展到能够支持macOS和Linux操作系统,这使其成为跨不同操作系统的 IT 专业人员的多功能选择项。

PowerShell简史

PowerShell的开发是为了克服Windows系统中现有命令行工具和脚本环境的限制。在 2000 年代初,随着 Windows 系统越来越多地在复杂的企业环境中使用, cmd.exe和批处理文件等传统工具在自动化和管理这些系统方面显得力不从心。 Microsoft需要一种能够处理更复杂的管理任务并可与Windows的现代API交互的工具。

Microsoft工程师Jeffrey Snover意识到Windows和Unix处理系统操作的方式不同——Windows使用结构化数据和API,而Unix将所有内容都视为文本文件。这种差异使得将Unix工具移植到Windows变得不切实际。 Snover的解决方案是开发一种面向对象的方法,将脚本编写的简单性与.NET框架的强大功能结合起来。 PowerShell于2006年发布,它允许管理员通过操作对象来更有效地自动化执行任务,从而提供与 Windows 系统的更深入的集成。

随着 IT 环境发展到包含各种操作系统,对多功能自动化工具的需求也在增长。 2016 年,微软发布了 PowerShell Core,这是一个可在 Windows、macOS 和Linux上运行的开源且跨平台的Powershell版本。

PowerShell的强大功能

为了充分掌握PowerShell的强大功能,我们首先需要了解在这个上下文环境中的对象(object)是什么概念。

在编程中,对象代表具有属性(特征)和方法(动作)的一个项目。例如, 一个car对象可能具有ColorModelFuelLevel等属性,以及Drive()HonkHorn()Refuel()等方法。

同样,在PowerShell中,对象是封装数据和功能的基本单元,这使得管理和操作信息变得更加容易。 PowerShell中的对象可以包含文件名、用户名或大小作为数据(属性),并能携带一些函数(方法),如复制文件或停止进程等。

传统命令Shell的基本命令是基于文本的,这意味着它们以纯文本的形式处理和输出数据。与之相反,当我们在PowerShell中运行cmdlet (发音为command-let )时,它会返回保留其属性和方法的对象。这允许更强大和灵活的数据操作,因为这些对象不需要额外的文本解析。

我们将在接下来的内容中详细探讨PowerShell的 cmdlet 及其功能。

答题

我们将用于开发 PowerShell 的高级方法称呼为?

tips:下图为本小节内容节选。

image-20250107193626862

object-oriented(面向对象的)

image-20250107193702545

PowerShell基础知识

部署实验环境

在继续我们的PowerShell 学习之旅之前,让我们先连接到我们的实验环境。在与本文相关的TryHackMe实验房间页面中,点击Start Machine按钮,然后再点击实验房间页面顶部的Start AttackBox按钮以启动AttackBox 。 AttackBox 机器将以分屏视图启动,如果此视图不可见,请继续点击实验房间页面顶部的蓝色Show Split View按钮即可。

image-20250107193736536

image-20250107193747402

你可以按照以下步骤使用 Remmina 客户端并通过SSH连接到目标虚拟机。

  1. 单击Applications(应用程序),如下面截图中数字标记1的位置所示,然后再选择Internet (数字标记 2),然后继续选择Remmina (数字标记 3)。

    image-20250107193813178

  2. 此时将出现一个弹出窗口,提示你输入密码来解锁 AttackBox 的密钥环,单击Cancel忽略该提示即可。

    image-20250107193834797

  3. 从下拉列表中选择SSH选项(下面第二张图中的标记1),然后将目标 IP(MACHINE_IP)粘贴到顶部栏中(下面第二张图中的标记2),最后单击Enter

    image-20250425220956281

    image-20250107193853539

  4. 在接下来的窗口中,输入下面给出的登录凭据,然后单击OK即可 。

    image-20250413162932414

    tips:captain/JollyR0ger#

启动PowerShell

PowerShell可以通过多种方式启动,这具体取决于你的需求和环境,如果你通过图形界面 ( GUI ) 在Windows系统上工作,那么你可以通过以下一些方式来启动PowerShell:

  • 开始菜单(Start Menu):在 Windows 开始菜单搜索栏中键入powershell ,然后单击结果中的Windows PowerShellPowerShell
  • Run对话框(Run Dialog):按Win + R打开Run对话框,输入powershell ,然后按下Enter
  • 文件资源管理器(File Explorer):导航到任意文件夹,在地址栏中键入powershell ,然后按下Enter ,这将在该特定目录下打开PowerShell 。
  • 任务管理器(Task Manager):打开任务管理器,转到File > Run new task ,键入powershell ,然后按下Enter

或者,可以通过键入powershell并按下Enter键 来从命令提示符 ( cmd.exe ) 界面启动PowerShell 。

在我们所部署的实验环境中,我们只能访问目标虚拟机的命令提示符界面,所以下面的命令将会是我们可使用的用于启动Powershell的方法。

captain@THEBLACKPEARL C:\Users\captain>powershell
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

Install the latest PowerShell for new features and improvements! https://aka.ms/PSWindows

PS C:\Users\captain> 

在PowerShell成功启动后,我们会在当前的工作目录中看到一个PS (代表PowerShell )提示符。

基础语法:Verb-Noun(动词-名词)

如前所述, PowerShell命令可被称为cmdlets (发音为command-lets ),它们比传统的 Windows 命令更强大,并且允许更高级的数据操作。

Cmdlet 遵循一致的Verb-Noun命名约定,这种结构使你可以轻松理解每个cmdlet的作用,Verb描述动作, Noun指定执行动作的对象。例如:

  • Get-Content :检索(获取-gets)文件的内容并将其显示在控制台中。
  • Set-Location :更改(设置-sets)当前工作目录。

基础Cmdlet

要列出可以在当前PowerShell会话中执行的所有可用 cmdlet、函数、别名和脚本,我们可以使用Get-Command,它是发现当前系统可以使用哪些PS命令的一个重要工具。

PS C:\Users\captain> Get-Command

CommandType     Name                                               Version    Source 
-----------     ----                                               -------    ------ 

Alias           Add-AppPackage                                     2.0.1.0    Appx                                                                                                                                       
Alias           Add-AppPackageVolume                               2.0.1.0    Appx                                                                                                                                       
Alias           Add-AppProvisionedPackage                          3.0        Dism                                                                                                                                       
[...]
Function        A:
Function        Add-BCDataCacheExtension                           1.0.0.0    BranchCache                                                                                                                                
Function        Add-DnsClientDohServerAddress                      1.0.0.0    DnsClient
[...]
Cmdlet          Add-AppxPackage                                    2.0.1.0    Appx
Cmdlet          Add-AppxProvisionedPackage                         3.0        Dism                                                                                                                                       
Cmdlet          Add-AppxVolume                                     2.0.1.0    Appx
[...]

对于 cmdlet 检索到的每个CommandInfo对象,控制台上都会显示一些基本信息(属性),我们可以根据已经显示的属性值来过滤命令列表;例如,如果我们只想显示“function”类型的可用命令,我们可以使用-CommandType "Function" ,如下所示:

PS C:\Users\captain> Get-Command -CommandType "Function"

CommandType     Name                                               Version    Source                                                                                                                                     
-----------     ----                                               -------    ------
Function        A:
Function        Add-BCDataCacheExtension                           1.0.0.0    BranchCache
Function        Add-DnsClientDohServerAddress                      1.0.0.0    DnsClient
Function        Add-DnsClientNrptRule                              1.0.0.0    DnsClient
[...]

我们将在下文中学习其他更有效的方法来过滤 cmdlet 的输出。

另一个重要的cmdlet是Get-Help :它能提供指定cmdlet的详细信息,包括用法、参数和示例,是学习如何使用PowerShell命令的首选 cmdlet。

PS C:\Users\captain> Get-Help Get-Date

NAME
    Get-Date

SYNOPSIS
    Gets the current date and time.

SYNTAX
    Get-Date [[-Date] <System.DateTime>] [-Day <System.Int32>] [-DisplayHint {Date | Time | DateTime}] [-Format <System.String>] [-Hour <System.Int32>] [-Millisecond <System.Int32>] [-Minute <System.Int32>] [-Month <System.Int32>] [-Second <System.Int32>] [-Year <System.Int32>] [<CommonParameters>]

    Get-Date [[-Date] <System.DateTime>] [-Day <System.Int32>] [-DisplayHint {Date | Time | DateTime}] [-Hour <System.Int32>] [-Millisecond <System.Int32>] [-Minute <System.Int32>] [-Month <System.Int32>] [-Second <System.Int32>] [-UFormat <System.String>] [-Year <System.Int32>] [<CommonParameters>]

DESCRIPTION
        The `Get-Date` cmdlet gets a DateTime object that represents the current date or a date that you specify. `Get-Date` can format the date and time in several .NET and UNIX formats. You can use `Get-Date` to generate a date or time character string, and then send the string to other cmdlets or programs.
        
        `Get-Date` uses the current culture settings of the operating system to determine how the output is formatted. To view your computer's settings, use `(Get-Culture).DateTimeFormat`.

RELATED LINKS
    Online Version: https://learn.microsoft.com/powershell/module/microsoft.powershell.utility/get-date?view=powershell-5.1&WT.mc_id=ps-gethelp
    ForEach-Object
    Get-Culture
    Get-Member
    New-Item
    New-TimeSpan
    Set-Date
    Set-Culture xref:International.Set-Culture

REMARKS
    To see the examples, type: "get-help Get-Date -examples". //////
    For more information, type: "get-help Get-Date -detailed".
    For technical information, type: "get-help Get-Date -full".
    For online help, type: "get-help Get-Date -online".

如上面的输出结果所示, Get-Help将通知我们可以通过在基本语法中附加一些选项来检索指定 cmdlet 的其他有用信息,例如,通过将-examples附加到上面所显示的命令,我们将看到可以被使用的所选 cmdlet 的常见方法列表。

为了让IT专业人员更轻松地进行过渡, PowerShell还为许多传统的Windows命令提供了别名,这些别名是cmdlet的快捷方式或替代名称。对于已经熟悉了其他命令行工具的用户来说很有帮助,Get-Alias可以列出所有可用的别名,例如,dirGet-ChildItem的别名, cdSet-Location的别名等等。

PS C:\Users\captain> Get-Alias

CommandType     Name                                               Version    Source 
-----------     ----                                               -------    ------
Alias           % -> ForEach-Object
Alias           ? -> Where-Object
Alias           ac -> Add-Content
Alias           asnp -> Add-PSSnapin
Alias           cat -> Get-Content
Alias           cd -> Set-Location
Alias           CFS -> ConvertFrom-String                          3.1.0.0    Microsoft.PowerShell.Utility
Alias           chdir -> Set-Location 
Alias           clc -> Clear-Content
Alias           clear -> Clear-Host
[...]

在哪里查找和下载 Cmdlet

PowerShell的另一个强大功能是用户可以通过从在线存储库下载其他的 cmdlet 来扩展其功能。

注意:请注意,在本节中列出的 cmdlet 需要有效的 Internet 连接才能查询在线存储库。TryHackMe所提供的目标计算机无法访问互联网,因此这些命令在本文相关的实验环境中可能无法正常工作。

要在PowerShell Gallery等在线存储库中搜索模块(cmdlet 集合),我们可以使用Find-Module 。有时,如果我们不知道模块的确切名称,搜索具有相似名称的模块可能会很有用。我们可以通过使用以下的标准PowerShell语法来过滤Name属性并在模块的部分名称后附加通配符(*)来实现此目的:

Cmdlet -Property "pattern*"

PS C:\Users\captain> Find-Module -Name "PowerShell*"   

Version    Name                                Repository           Description 
-------    ----                                ----------           ----------- 
0.4.7      powershell-yaml                     PSGallery            Powershell module for serializing and deserializing YAML

2.2.5      PowerShellGet                       PSGallery            PowerShell module with commands for discovering, installing, updating and publishing the PowerShell artifacts like Modules, DSC Resources, Role Capabilities and Scripts.                                                   
1.0.80.0   PowerShell.Module.InvokeWinGet      PSGallery            Module to Invoke WinGet and parse the output in PSOjects

0.17.0     PowerShellForGitHub                 PSGallery            PowerShell wrapper for GitHub API  

成功完成模块名称识别后,我们就可以使用Install-Module从存储库下载并安装模块,从而使得模块中所包含的新 cmdlet 变得可供使用。

PS C:\Users\captain> Install-Module -Name "PowerShellGet"

Untrusted repository
You are installing the modules from an untrusted repository. If you trust this repository, change its InstallationPolicy value by running the Set-PSRepository cmdlet. Are you sure you want to install the modules from 'PSGallery'?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "N"): 

有了这些基本工具,我们现在就可以开始探索PowerShell的功能了。

答题

在与本文相关的TryHackMe实验房间中,部署好实验环境并使用SSH访问目标机器,并启动Powershell界面:

image-20250425221608429

你将如何检索动词“ Remove ”开头的命令列表? [就这个问题而言,请避免在答案中使用引号("或')]

Get-Command -Name Remove*

哪个 cmdlet 的别名对应的是传统的Windows命令echo

输入Get-Alias命令并查看输出结果即可。

image-20250425221710602

Write-Output

用于检索 cmdlet New-LocalUser的一些示例用法的命令是什么?

Get-Help New-LocalUser -examples

image-20250107194722569

导航文件系统并使用文件

PowerShell提供了一系列用于导航文件系统和管理文件的 cmdlet,其中的许多命令在传统 Windows CLI中都有对应项。

与命令提示符中的dir命令(或类 Unix 系统中的ls命令 )类似, Get-ChildItem可以列出由-Path参数指定的位置中的文件和目录。它可以用于探索目录并查看其内容。如果未指定Path ,那么该 cmdlet 将显示当前工作目录的内容。

PS C:\Users\captain> Get-ChildItem 

    Directory: C:\Users\captain

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-r---          5/8/2021   9:15 AM                Desktop
d-r---          9/4/2024  10:58 AM                Documents
d-r---          5/8/2021   9:15 AM                Downloads
d-r---          5/8/2021   9:15 AM                Favorites
d-r---          5/8/2021   9:15 AM                Links
d-r---          5/8/2021   9:15 AM                Music
d-r---          5/8/2021   9:15 AM                Pictures
d-----          5/8/2021   9:15 AM                Saved Games
d-r---          5/8/2021   9:15 AM                Videos

要导航到不同的目录,我们可以使用Set-Location cmdlet,它可以更改当前的工作目录,将我们带到指定的路径下,类似于命令提示符中的cd命令。

PS C:\Users\captain> Set-Location -Path ".\Documents"
PS C:\Users\captain\Documents> 

传统的 Windows CLI 使用单独的命令来创建和管理不同的项目(例如文件、目录),而PowerShell通过提供一组 cmdlet 来处理文件、目录的创建和管理,从而简化了相关过程。

要在PowerShell中创建一个项目,我们可以使用New-Item,我们需要指定项目的路径及其类型(是文件还是目录)。

PS C:\Users\captain\Documents> New-Item -Path ".\captain-cabin\captain-wardrobe" -ItemType "Directory"

    Directory: C:\Users\captain\Documents\captain-cabin

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----          9/4/2024  12:20 PM                captain-wardrobe

PS C:\Users\captain\Documents> New-Item -Path ".\captain-cabin\captain-wardrobe\captain-boots.txt" -ItemType "File"     

    Directory: C:\Users\captain\Documents\captain-cabin\captain-wardrobe

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----          9/4/2024  11:46 AM              0 captain-boots.txt  

类似地, Remove-Item cmdlet 可以用于删除目录和文件,而在 Windows CLI中,我们有单独的命令rmdirdel来完成相同的操作 。

PS C:\Users\captain\Documents> Remove-Item -Path ".\captain-cabin\captain-wardrobe\captain-boots.txt"
PS C:\Users\captain\Documents> Remove-Item -Path ".\captain-cabin\captain-wardrobe" 

我们还可以复制或移动文件、目录,只要分别使用Copy-Item (相当于copy )和Move-Item (相当于move )命令即可。

PS C:\Users\captain\Documents> Copy-Item -Path .\captain-cabin\captain-hat.txt -Destination .\captain-cabin\captain-hat2.txt
PS C:\Users\captain\Documents> Get-ChildItem -Path ".\captain-cabin\" 

    Directory: C:\Users\captain\Documents\captain-cabin

Mode                 LastWriteTime         Length Name 
----                 -------------         ------ ----
d-----          9/4/2024  12:50 PM                captain-wardrobe
-a----          9/4/2024  12:50 PM              0 captain-boots.txt
-a----          9/4/2024  12:14 PM            264 captain-hat.txt
-a----          9/4/2024  12:14 PM            264 captain-hat2.txt
-a----          9/4/2024  12:37 PM           2116 ship-flag.txt 

最后,如果想读取和显示文件的内容,我们可以使用Get-Content,它的工作方式类似于命令提示符中的type命令(或者类Unix系统中的cat命令)。

PS C:\Users\captain\Documents\captain-cabin> Get-Content -Path ".\captain-hat.txt"
 _           _   
| |         | |
| |__   __ _| |_
| '_ \ / _ | __|
| | | | (_| | |_
|_| |_|\__,_|\__|

Don't touch my hat!

答题

你可以使用什么 cmdlet 来代替传统的 Windows 命令type

输入Get-Alias命令并查看输出结果即可。

image-20250425222719629

Get-Content

你将使用什么 PowerShell 命令来显示“C:\Users”目录的内容? [就这个问题而言,请避免在答案中使用引号( " 或 ' ) ]

Get-ChildItem -Path C:\Users

上一个问题中所描述的命令 的执行结果将显示多少项?

image-20250425222806589

4

image-20250413163135828

对数据进行管道传输、过滤和排序

管道是命令行环境中使用的一种技术,它允许将一个命令的输出用作另一个命令的输入,这将创建一系列操作,其中数据从一个命令流向下一个命令。管道以|符号表示,被广泛应用于 Windows CLI中(如本模块前面所介绍的那样)以及基于 Unix 的 shell 中。

在PowerShell中,管道的功能更加强大,因为它将传递对象而不仅仅是文本,这些对象不仅携带数据,还携带描述数据并与数据交互的属性和方法。

例如,如果你想获取目录中的文件列表,然后按size(大小)对它们进行排序,你可以在PowerShell中使用以下命令:

PS C:\Users\captain\Documents\captain-cabin> Get-ChildItem | Sort-Object Length

    Directory: C:\Users\captain\Documents\captain-cabin

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----          9/4/2024  12:50 PM              0 captain-boots.txt
-a----          9/4/2024  12:14 PM            264 captain-hat2.txt
-a----          9/4/2024  12:14 PM            264 captain-hat.txt
-a----          9/4/2024  12:37 PM           2116 ship-flag.txt
d-----          9/4/2024  12:50 PM                captain-wardrobe

此处, Get-ChildItem将检索文件(以文件作为对象),并通过管道 ( | ) 将这些文件对象发送到Sort-Object ,然后按其Length(大小)属性对它们进行排序。这种基于对象的方法允许我们使用更加详细和灵活的命令序列。

在上面的示例中,我们利用了Sort-Object cmdlet 来根据指定属性对对象进行排序。除了排序之外, PowerShell还提供了一组cmdlet,当它们与管道结合使用时,就可以进行一些高级数据操作和分析。

要根据指定条件来过滤对象,从而仅返回符合条件的对象,我们可以使用Where-Object cmdlet;例如,如果想列出目录中的.txt文件,我们可以使用以下命令:

PS C:\Users\captain\Documents\captain-cabin> Get-ChildItem | Where-Object -Property "Extension" -eq ".txt" 

    Directory: C:\Users\captain\Documents\captain-cabin

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----          9/4/2024  12:50 PM              0 captain-boots.txt
-a----          9/4/2024  12:14 PM            264 captain-hat.txt
-a----          9/4/2024  12:14 PM            264 captain-hat2.txt
-a----          9/4/2024  12:37 PM           2116 ship-flag.txt

在此处, Where-Object将会按Extension属性过滤文件,确保仅列出扩展名等于 ( -eq ) .txt的文件。

运算符-eq (即“等于”)是与其他脚本语言(例如 Bash、Python)共享的一组比较运算符的一部分。为了显示 PowerShell 过滤的潜力,我们在下面给出了一些最有用的运算符:

  • -ne :“不等于(not equal)”;该运算符可用于根据指定标准从结果中排除对象。
  • -gt :“大于(greater than)”;该运算符将仅过滤超过指定值的对象。需要注意的是,这是一个严格的比较,这意味着等于指定值的对象将会从结果中排除。
  • -ge :“大于或等于(greater than or equal to)”;这是前一个运算符的非严格版本,是-gt(大于)和-eq(等于)的组合。
  • -lt :“小于(less than)”;与它的相反项“大于”运算符一样,这也是一个严格运算符,它将仅包括严格低于特定值的对象。
  • -le :“小于或等于(less than or equal to)”,与它的相反项-ge一样,它是前一个运算符的非严格版本,是 -lt(小于)和-eq(等于)的组合。

如下面的另一个示例命令所示,我们还可以通过选择与指定模式匹配( -like )的属性来过滤对象:

PS C:\Users\captain\Documents\captain-cabin> Get-ChildItem | Where-Object -Property "Name" -like "ship*"  

    Directory: C:\Users\captain\Documents\captain-cabin

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----          9/4/2024  12:37 PM           2116 ship-flag.txt

下一个用于过滤的 cmdlet Select-Object可用于从对象中选择特定属性或限制返回的对象数量,它对于优化输出以仅显示所需的详细信息非常有用。

PS C:\Users\captain\Documents\captain-cabin> Get-ChildItem | Select-Object Name,Length 

Name              Length
----              ------
captain-wardrobe
captain-boots.txt 0
captain-hat.txt   264
captain-hat2.txt  264
ship-flag.txt     2116

我们可以通过添加更多命令来扩展 cmdlet 管道,因为该功能不仅限于在两个 cmdlet 之间进行管道传输。作为练习,我们可以尝试构建一个 cmdlet 管道来对输出结果进行排序和筛选,目的是显示一些文件中最大的那个文件,这些文件在C:\Users\captain\Documents\captain-cabin 目录中。

tips:查看可能的解决方案。不要作弊!

Get-ChildItem | Sort-Object Length -Descending | Select-Object -First 1

    Directory: C:\Users\captain\Documents\captain-cabin

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----          9/4/2024  12:37 PM           2116 ship-flag.txt

我们在本小节将介绍的用于过滤的 cmdlet 中的最后一个是 Select-String 。这个 cmdlet 将会搜索文件内容中的文本模式,它的效果类似于基于 Unix 的系统中的grep命令或者 Windows 命令提示符中的findstr命令 。它通常用于查找日志文件或文档中的特定内容。

PS C:\Users\captain\Documents\captain-cabin> Select-String -Path ".\captain-hat.txt" -Pattern "hat" 

captain-hat.txt:8:Don't touch my hat!

Select-String cmdlet 完全支持使用正则表达式 ( regex )。这一高级功能允许我们针对文件内容进行复杂的模式匹配操作,使其成为搜索和分析文本数据的强大工具。

答题

如何检索当前目录中size大于 100 的项目? [就这个问题而言,请避免在答案中使用引号("或')]

Get-ChildItem | Where-Object -Property Length -gt 100

image-20250107195706769

系统和网络信息

PowerShell的创建是为了满足对强大的自动化和管理工具日益增长的需求,以帮助系统管理员和 IT 专业人员。因此,它还提供了一系列 cmdlet,来允许检索有关系统配置和网络设置的详细信息。

Get-ComputerInfo cmdlet 可检索全面的系统信息,包括操作系统信息、硬件规格、 BIOS详细信息等。它通过单个命令提供整个系统配置的快照。它的传统对应项systeminfo仅能检索一小部分相同的详细信息。

PS C:\Users\captain> Get-ComputerInfo

WindowsBuildLabEx                                       : 20348.859.amd64fre.fe_release_svc_prod2.220707-1832
WindowsCurrentVersion                                   : 6.3
WindowsEditionId                                        : ServerDatacenter
WindowsInstallationType                                 : Server Core
WindowsInstallDateFromRegistry                          : 4/23/2024 6:36:29 PM
WindowsProductId                                        : 00454-60000-00001-AA763
WindowsProductName                                      : Windows Server 2022 Datacenter
[...]

Get-LocalUser可以列出当前计算机系统上的所有本地用户帐户,这对于管理用户帐户和了解计算机的安全配置至关重要,此命令的默认输出将会显示每个本地用户的用户名、帐户状态和描述。

PS C:\Users\captain> Get-LocalUser

Name               Enabled Description 
----               ------- -----------
Administrator      True    Built-in account for administering the computer/domain
captain            True    The beloved captain of this pirate ship.
DefaultAccount     False   A user account managed by the system.
Guest              False   Built-in account for guest access to the computer/domain
WDAGUtilityAccount False   A user account managed and used by the system for Windows Defender Application Guard scenarios.

与传统的ipconfig命令类似,以下两个 cmdlet (Get-NetIPConfigurationGet-NetIPAddress)可用于检索有关系统网络配置的详细信息。

Get-NetIPConfiguration将提供有关系统上网络接口的详细信息,包括 IP 地址、 DNS服务器和网关配置。

PS C:\Users\captain> Get-NetIPConfiguration

InterfaceAlias       : Ethernet
InterfaceIndex       : 5
InterfaceDescription : Amazon Elastic Network Adapter
NetProfile.Name      : Network 3
IPv4Address          : 10.10.178.209
IPv6DefaultGateway   :
IPv4DefaultGateway   : 10.10.0.1
DNSServer            : 10.0.0.2

如果我们需要有关分配给网络接口的 IP 地址的具体详细信息,那么我们可以使用 Get-NetIPAddress cmdlet,它将会显示系统上已配置的所有IP地址的详细信息,包括当前未活动的 IP 地址。

PS C:\Users\captain> Get-NetIPAddress

IPAddress         : fe80::3fef:360c:304:64e%5
InterfaceIndex    : 5
InterfaceAlias    : Ethernet
AddressFamily     : IPv6
Type              : Unicast
PrefixLength      : 64
PrefixOrigin      : WellKnown
SuffixOrigin      : Link
AddressState      : Preferred
ValidLifetime     : Infinite ([TimeSpan]::MaxValue)
PreferredLifetime : Infinite ([TimeSpan]::MaxValue)
SkipAsSource      : False
PolicyStore       : ActiveStore

IPAddress         : ::1
InterfaceIndex    : 1
InterfaceAlias    : Loopback Pseudo-Interface 1
AddressFamily     : IPv6
[...]

IPAddress         : 10.10.178.209
InterfaceIndex    : 5
InterfaceAlias    : Ethernet
AddressFamily     : IPv4
[...]

IPAddress         : 127.0.0.1
InterfaceIndex    : 1
InterfaceAlias    : Loopback Pseudo-Interface 1
AddressFamily     : IPv4
[...]

以上这些 cmdlet 可以使得 IT 专业人员能够直接从命令行快速访问关键的系统和网络信息,从而能够更加轻松地监控和管理本地及远程计算机。

答题

除了当前用户和默认的“管理员”帐户之外,目标计算机上还启用了哪些其他用户?

tips:使用 Get-LocalUser命令。

image-20250425230131088

p1r4t3

这个小伙子把他的账户隐藏在其他人中间,完全不顾及我们敬爱的船长!他在帐户描述中如此直率地提出的座右铭是什么?

tips:使用 Get-LocalUser命令。

image-20250425230239231

A merry life and a short one.

快乐而短暂的一生。

现在有一个将上面这些问题整合在一起的小挑战,我们刚刚发现的这个隐藏在本地用户中的可疑小伙子在"C:\Users"目录中拥有自己的主文件夹。

你能浏览文件系统并找到这个海盗家中隐藏的宝藏吗?

Set-Location C:\Users\p1r4t3
Get-ChildItem
Set-Location hidden-treasure-chest
Get-ChildItem
Get-Content big-treasure.txt

image-20250425230606556

image-20250425230622965

FLAG: THM{p34rlInAsh3ll} 。

image-20250425230813875

实时系统分析

为了收集更高级的系统信息,特别是有关正在运行的进程、服务以及活动的网络连接等动态方面的信息,我们可以尝试利用一组可以获取到超越静态的计算机详细信息的 cmdlet。

使用Get-Process命令可以为我们提供所有当前正在运行的进程的详细视图,包括 CPU 和内存的使用情况,这使其成为用于监控和故障排除的强大工具之一。

PS C:\Users\captain> Get-Process

Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName 
-------  ------    -----      -----     ------     --  -- -----------
     67       5      872        500       0.06   2340   0 AggregatorHost
     55       5      712       2672       0.02   3024   0 AM_Delta_Patch_1.417.483.0
    309      13    18312       1256       0.52   1524   0 amazon-ssm-agent
     78       6     4440        944       0.02    516   0 cmd
     94       7     1224       1744       0.31    568   0 conhost
[...]

同样, Get-Service命令允许我们检索关于计算机上的服务的状态的信息,例如哪些服务正在运行、已停止或已暂停。此命令可以被系统管理员广泛应用于故障排除,也可以被取证分析师用来寻找当前系统上已安装的一些异常服务。

PS C:\Users\captain> Get-Service

Status   Name               DisplayName                           
------   ----               -----------
Stopped  Amazon EC2Launch   Amazon EC2Launch
Running  AmazonSSMAgent     Amazon SSM Agent
Stopped  AppIDSvc           Application Identity
Running  BFE                Base Filtering Engine
Running  CertPropSvc        Certificate Propagation
Stopped  ClipSVC            Client License Service (ClipSVC)
[...]

为了监控活动的网络连接,我们可以使用Get-NetTCPConnection命令来显示当前的TCP连接,从而更加深入地了解本地和远程端点。这个 cmdlet 在事件响应或恶意软件分析任务期间特别方便,因为它可以用来发现“隐藏的后门”或者“与攻击者所控制的服务器已建立的恶意连接”。

PS C:\Users\captain> Get-NetTCPConnection

LocalAddress        LocalPort RemoteAddress       RemotePort State       AppliedSetting OwningProcess 
------------        --------- -------------       ---------- -----       -------------- -------------
[...]
::                  22        ::                  0          Listen                     1444          
10.10.178.209       49695     199.232.26.172      80         TimeWait                   0
0.0.0.0             49668     0.0.0.0             0          Listen                     424
0.0.0.0             49667     0.0.0.0             0          Listen                     652
0.0.0.0             49666     0.0.0.0             0          Listen                     388
0.0.0.0             49665     0.0.0.0             0          Listen                     560
0.0.0.0             49664     0.0.0.0             0          Listen                     672           
0.0.0.0             3389      0.0.0.0             0          Listen                     980
10.10.178.209       139       0.0.0.0             0          Listen                     4
0.0.0.0             135       0.0.0.0             0          Listen                     908
10.10.178.209       22        10.14.87.60         53523      Established Internet       1444
0.0.0.0             22        0.0.0.0             0          Listen                     1444

此外,我们将提及Get-FileHash命令,它可以作为生成文件哈希的有用 cmdlet,这在事件响应、威胁搜寻和恶意软件分析中特别有价值,因为它有助于我们验证文件完整性并检测是否存在潜在的篡改行为。

PS C:\Users\captain\Documents\captain-cabin> Get-FileHash -Path .\ship-flag.txt    

Algorithm       Hash                      Path 
---------       ----                      ----
SHA256          54D2EC3C12BF3D[...]       C:\Users\captain\Documents\captain-cabin\ship-flag.txt

这些 cmdlet 共同为我们提供了一套全面的工具,可用于实时系统监控和分析,事实证明这些命令对于事件响应人员和威胁追踪人员而言特别有用。

答题

在上一个答题任务中,你发现了目标机器中精心隐藏的奇妙宝藏。请问包含它的文件的哈希值是什么?

Get-FileHash -Path big-treasure.txt

image-20250425232220389

71FC5EC11C2497A32F8F08E61399687D90ABE6E204D2964DF589543A613F3E08

Get-NetTCPConnection默认检索的哪些属性包含关于已经启动的连接的进程信息?

Get-NetTCPConnection

image-20250425232315636

OwningProcess

是时候进行另一个小挑战了。这艘海盗船上安装了一些重要的服务,以保证船长始终能够安全航行。但有些事情并没有按预期进行,船长想知道为什么。经过调查,他们终于查明了真相:服务被篡改了!之前的可疑小伙子修改了服务的DisplayName以反映他自己的座右铭,与他在用户描述中放入的座右铭相同。

有了这些信息以及你目前掌握的 PowerShell 知识,你能找到相关的服务名称吗?

#Get-Service | Where-Object { $_.DisplayName -like "*$motto*" } | Select-Object Name, DisplayName
Get-Service | Where-Object { $_.DisplayName -like "*A merry life and a short one*" } | Select-Object Name, DisplayName

image-20250425232622653

p1r4t3-s-compass

image-20250425232646570

脚本编写

脚本编写(Scripting)是编写和执行一个文本文件(在这被称为脚本)中所包含的一系列命令的过程,它可用于自动执行通常在 shell(如PowerShell)中需要去手动执行的任务。

简单来说,脚本编写就像给计算机一个待办事项列表,在脚本文件内容中的每一行都是计算机将要自动执行的任务。这样可以节省时间,减少出错的机会,并允许我们去执行过于复杂或繁琐而不方便手动完成的一些任务。随着你对 shell 和脚本的了解越来越多,你会发现脚本可以成为管理系统、处理数据的强大工具。

虽然学习如何使用PowerShell进行脚本编写超出了本文的内容范围,但是我们必须明白——Powershell脚本的强大能力使其成为了所有网络安全行业角色需要去掌握的关键技能。

  • 对于网络安全蓝队人员(例如事件响应人员、恶意软件分析师和威胁搜寻人员)而言, PowerShell脚本可以自动执行许多不同的任务,包括日志分析、检测异常和提取妥协指标 (IOCs-indicators of compromise)。Powershell脚本还可以用于对恶意代码(恶意软件)进行逆向工程或者自动扫描系统以查找入侵迹象等等。
  • 对于网络安全红队人员(包括渗透测试人员和道德黑客)而言,PowerShell脚本可以用来自动执行系统枚举、执行远程命令以及制作混淆脚本以绕过防御机制等任务。它与所有类型的系统的深度集成能力使其成为用于模拟攻击和测试系统抵御现实威胁的强大工具。
  • 在网络安全的背景下,系统管理员可以受益于PowerShell脚本来自动执行完整性检查、管理系统配置和保护网络安全,尤其是在远程或大规模环境中。 PowerShell脚本可用于执行安全策略、监控系统运行状况并自动响应安全事件,从而能够增强整体安全态势。

无论是防御性使用还是进攻性使用, PowerShell脚本都是网络安全工具包中的一项重要功能。

在结束本小节的内容之前,我们不能不提及的一个命令是Invoke-Command cmdlet。

Invoke-Command对于在远程系统上执行命令至关重要,这使其成为系统管理员、安全工程师和渗透测试人员需要掌握的一项基础技巧。Invoke-Command可以实现高效的远程管理,并能与脚本结合起来,从而实现跨多台机器的任务自动化,在渗透测试人员进行模拟攻击期间,它还可以用于在目标系统上执行有效载荷或命令。

让我们通过查阅相关的Get-Help "examples"页面来发现这个强大的 cmdlet 的一些示例用法:

PS C:\Users\captain> Get-Help Invoke-Command -examples

NAME
    Invoke-Command
    
SYNOPSIS
    Runs commands on local and remote computers.
    
    ------------- Example 1: Run a script on a server -------------
    
    Invoke-Command -FilePath c:\scripts\test.ps1 -ComputerName Server01
    
    The FilePath parameter specifies a script that is located on the local computer. The script runs on the remote computer and the results are returned to the local computer.

    --------- Example 2: Run a command on a remote server ---------

    Invoke-Command -ComputerName Server01 -Credential Domain01\User01 -ScriptBlock { Get-Culture }

    The ComputerName parameter specifies the name of the remote computer. The Credential parameter is used to run the command in the security context of Domain01\User01, a user who has permission to run commands. The ScriptBlock parameter specifies the command to be run on the remote computer.

    In response, PowerShell requests the password and an authentication method for the User01 account. It then runs the command on the Server01 computer and returns the result.
[...]

上面的Get-Help "examples" 页面提供的前两个示例以及上面报告的示例足以让我们了解Invoke-Command cmdlet 的简单用法和强大功能。

帮助页面中的第一个示例展示了如何轻松地将 cmdlet 与任何自定义脚本结合起来,以自动执行远程计算机上的任务。

帮助页面中的第二个示例演示了我们不需要知道如何编写脚本即可从Invoke-Command的强大功能中受益。事实上,通过将-ScriptBlock { ... }参数附加到cmdlet的具体语法中,我们可以在远程计算机上执行任何PS命令(或命令序列),这样做的结果与我们在远程计算机本身的本地PowerShell会话中键入命令的效果相同。

答题

在名为“RoyalFortune”的远程计算机上执行Get-Service命令的具体语法是什么?假设你不需要提供凭据来建立连接。 [就这个问题而言,请避免在答案中使用引号(" 或')]

Invoke-Command -ComputerName RoyalFortune -ScriptBlock

image-20250425234630941

本文小结

干得好!你已经成功地航行在PowerShell的险恶水域中,并且发现了 TheBlackPearl 上隐藏的宝藏和神秘服务。

有了上文提及的这些工具,你就已经准备好了探索 Windows 系统中最严密的角落。

记住,真正的海盗永远不会停止寻找宝藏——所以请不断磨练你的技能,谁知道你会在下一次冒险中发现什么珍珠呢?

为了继续提升你的命令行技能,请继续学习下一个知识点:Linux命令行

posted @ 2025-04-26 00:27  Hekeatsll  阅读(336)  评论(0)    收藏  举报