详情

首页手游攻略 powerview.py:实践指南

powerview.py:实践指南

佚名 2026-09-11 19:00:02

工作中遇到相关需求时,powerview.py值得先读说明,因为它主要用于Powerview 增强版。在日常自动化场景里,常见问题是输入边界、依赖和失败处理如果不清楚就很难稳定复用,这正是评估时需要盯住的地方。更实际的做法是用一项范围明确的真实任务完成最小试跑,同时核对配置时间、输出质量、异常信息和维护痕迹,不要直接在关键项目上。我会把它列入愿意先做小范围验证并复查原始文档的团队的候选清单,而不是仅凭项目介绍直接纳入生产。

aniqfakhrul/powerview.py 项目截图 1

安装 | 基本用法 | 混淆 | 模块 | 日志记录 | 用户定义规则 | MCP | 插件 | 致谢

概述

PowerView.py 是很棒的原始 PowerView.ps1 脚本的替代品。 PowerView 中使用的大多数模块都可以在这里找到(一些标志已更改)。主要目标是实现交互式会话,而无需重复向 ldap 进行身份验证。

安装

https://github.com/aniqfakhrul/powerview.py/wiki/Installation-Guide

基本用法

[!NOTE] 请注意,一些 kerberos 功能仍然无法正常运行,但它仍然可以完成大部分工作。详细用法可以参见Wiki部分

  • 初始化连接
powerview range.net/lowpriv:[email protected] [-k] [--use-ldap | --使用 ldaps | --使用GC | --使用-gc-ldaps | --使用-adws]
  • 保持持久连接

[!TIP] 默认情况下禁用连接持久性。 LDAP 会话在不活动后超时。使用 --keepalive-interval 发送维护会话状态的定期查询。

  • 启动网页界面
powerview range.net/lowpriv:[email protected] --web [--web-host 0.0.0.0] [--web-port 3000] [--web-auth 用户:password1234]
  • 使用特定身份验证初始化连接。请注意,仅当您直接从此 分支 安装 ldap3 库时,--use-sign-and-seal--use-channel-binding 才可用
powerview range.net/lowpriv:[email protected] [--使用通道绑定 | --使用签名和盖章 | --使用简单身份验证]
  • 使用 schannel 进行初始化。 --pfx 标志接受 pfx 格式的证书文件。

[!NOTE]
powerview 将在第一次尝试时尝试加载没有密码的证书。如果失败,会提示输入密码。因此,不需要密码参数

powerview 10.10.10.10 --pfx administrator.pfx
  • 查询特定用户
Get-DomainUser Administrator
Get-DomainUser -Identity Administrator
  • 指定搜索属性
Get-DomainUser -Properties samaccountname,description
  • 过滤结果
Get-DomainUser -Where 'samaccountname [contains][in][eq] admins'
  • 计数结果
Get-DomainUser -Count
  • 输出结果到文件
Get-DomainUser -OutFile ~/domain_user.txt
  • 将输出格式化为表格。
Get-DomainUser -Properties samaccountname,memberof -TableView
Get-DomainUser -Properties samaccountname,memberof -TableView [csv,md,html,latex]
  • 设置模块
Set-DomainObject -Identity "adminuser" -Set 'servicePrincipalname=http/web.ws.local'
Set-DomainObject -Identity "adminuser" -Append 'servicePrincipalname=http/web.ws.local'
Set-DomainObject -Identity "adminuser" -Clear 'servicePrincipalname'

# Reading from local file
Set-DomainObject -Identity "adminuser" -Set 'servicePrincipalname=@/path/to/local/file'
Set-DomainObject -Identity "adminuser" -Append 'servicePrincipalname=@/path/to/local/file'
  • 中继方式
powerview 10.10.10.10 --relay [--relay-host] [--relay-port] [--use-ldap | --use-ldaps]

[!NOTE]
此演示显示使用 printerbug.py 进行强制身份验证。您可以使用强制 HTTP 身份验证的其他方法。

混淆

PowerView 使用 ldapx-py 来混淆 LDAP 查询和相关参数,在保留查询意图的同时改变可观察的模式。

  • 通过 CLI 启用(默认链)
powerview range.net/lowpriv:[email protected] --obfuscate
  • 通过 CLI 启用(自定义链码)
powerview range.net/lowpriv:[email protected] --obfuscate CZXANDR
  • 通过网络启用

[!TIP] 在设置中切换 Obfuscate。这适用于活动会话的后续查询。

什么被混淆了

  • 过滤器:发送前转换属性名称、运算符和值
  • DN:改变搜索库 distinguishedName
  • 属性:改变请求的属性列表

默认链(当使用没有值的 --obfuscate 时)

目标 链条 技巧
过滤器 CZNDR 案例,Zeros,aNR,德摩根,重新排序
BaseDN CX 案例,heX编码
属性 CR 案例,重新订购

运行 ldapx codes --all 查看所有可用的混淆代码。

[!NOTE] 在大多数情况下,结果在功能上是等效的,但 approximation/wildcard 扩展可以扩大匹配范围。某些代码(G、O、S)可能与 ldap3 不兼容 - 请谨慎使用。

[!WARNING] 过度的混淆可能会被严格的服务器或中介工具拒绝。仅在需要时使用。

  • ldapx-py:LDAP 查询混淆库 — https://github.com/j0hnZ3RA/ldapx-py
  • ldapx:用于参考的灵活 LDAP 代理 — https://github.com/Macmod/ldapx
  • 研究:MaLDAPtive:混淆与反混淆(DEF CON 32 讲)— https://[email protected]/watch?v=mKRS5Iyy7Qo
  • 作者:Sabajete Elezaj — https://x.com/sabi_elezi, Daniel Bohannon — https://x.com/danielhbohannon

模块可用(到目前为止?)

PV >
Add-ADComputer                 Get-ADObject                   Get-EventLogChannel            Login-As                       Set-ADObject
Add-ADUser                     Get-CA                         Get-EventLogPublisher          Logoff-Session                 Set-ADObjectDN
Add-CATemplate                 Get-CATemplate                 Get-ExchangeDatabase           Reboot-Computer                Set-CATemplate
Add-CATemplateAcl              Get-DMSA                       Get-ExchangeMailbox            Remove-ADComputer              Set-DomainCATemplate
Add-DMSA                       Get-Domain                     Get-ExchangeServer             Remove-ADObject                Set-DomainComputerPassword
Add-DomainCATemplate           Get-DomainCA                   Get-GMSA                       Remove-ADUser                  Set-DomainDNSRecord
Add-DomainCATemplateAcl        Get-DomainCATemplate           Get-GPOLocalGroup              Remove-CATemplate              Set-DomainObject
Add-DomainComputer             Get-DomainComputer             Get-GPOSettings                Remove-DMSA                    Set-DomainObjectDN
Add-DomainDMSA                 Get-DomainController           Get-LocalUser                  Remove-DomainCATemplate        Set-DomainObjectOwner
Add-DomainDNSRecord            Get-DomainDMSA                 Get-NamedPipes                 Remove-DomainComputer          Set-DomainRBCD
Add-DomainGMSA                 Get-DomainDNSRecord            Get-NetComputerInfo            Remove-DomainDMSA              Set-DomainUserPassword
Add-DomainGPO                  Get-DomainDNSZone              Get-NetLoggedOn                Remove-DomainDNSRecord         Set-NetService
Add-DomainGroup                Get-DomainForeignGroupMember   Get-NetProcess                 Remove-DomainGMSA              Set-ObjectOwner
Add-DomainGroupMember          Get-DomainForeignUser          Get-NetService                 Remove-DomainGroupMember       Set-RBCD
Add-DomainObjectAcl            Get-DomainGMSA                 Get-NetSession                 Remove-DomainObject            Set-ShadowCred
Add-DomainOU                   Get-DomainGPO                  Get-NetShare                   Remove-DomainObjectAcl         Set-ShadowCredential
Add-DomainUser                 Get-DomainGPOLocalGroup        Get-NetTerminalSession         Remove-DomainOU                Shutdown-Computer
Add-GMSA                       Get-DomainGPOSettings          Get-ObjectAcl                  Remove-DomainUser              Start-NetService
Add-GPLink                     Get-DomainGroup                Get-ObjectOwner                Remove-GMSA                    Stop-Computer
Add-GPO                        Get-DomainGroupMember          Get-RBCD                       Remove-GPLink                  Stop-NetProcess
Add-GroupMember                Get-DomainObject               Get-RegLoggedOn                Remove-GroupMember             Stop-NetService
Add-NetService                 Get-DomainObjectAcl            Get-SCCM                       Remove-NetService              Unlock-ADAccount
Add-ObjectAcl                  Get-DomainObjectOwner          Get-ShadowCred                 Remove-NetSession              clear
Add-OU                         Get-DomainOU                   Get-ShadowCredential           Remove-NetTerminalSession      exit
Clear-Cache                    Get-DomainRBCD                 Get-TrustKey                   Remove-ObjectAcl               get_pool_stats
ConvertFrom-SID                Get-DomainSCCM                 Get-WDS                        Remove-OU                      history
ConvertFrom-UACValue           Get-DomainTrust                Invoke-ASREPRoast              Remove-ShadowCred              taskkill
Disable-DomainDNSRecord        Get-DomainTrustKey             Invoke-DFSCoerce               Remove-ShadowCredential        tasklist
                               Get-DomainTrustMapping
Find-ForeignGroup              Get-DomainUser                 Invoke-Kerberoast              Restart-Computer
Find-ForeignUser               Get-DomainWDS                  Invoke-MessageBox              Restore-ADObject
Find-LocalAdminAccess          Get-EventLog                   Invoke-PrinterBug              Restore-DomainObject

Domain/LDAP 功能

模块 别名 描述
获取-DomainUser 查询AD中所有用户或特定用户对象
获取-DomainComputer 查询AD中所有计算机或特定计算机对象
获取-DomainGroup 查询AD中所有组或特定组对象
获取-DomainGroupMember 查询特定域组的成员
获取-DomainOU 查询OUs中的所有OUs或AD中特定的OU对象
获取域名 查询域名信息
获取-DomainController 查询可用的域控制器
获取-DomainDNSRecord 查询可用记录。如果不指定-ZoneName,它将递归所有DNS区域
获取-DomainDNSZone 查询域中可用的DNS区域
获取-DomainObject 获取-ADObject 查询AD中所有或指定域对象
获取-DomainObjectAcl 获取-ObjectAcl 查询 ACLs 指定的 AD 对象
获取-DomainSCCM 获取-SCCM 查询 SCCM
获取-DomainRBCD 获取-RBCD 查找配置为基于资源的约束委派的帐户
获取-DomainObjectOwner 获取-ObjectOwner 查询AD对象的所有者
获取-DomainGMSA 获取-GMSA 查询组托管服务帐户 (gMSA) 并检索其密码 blob
获取-DomainDMSA 获取-GDSA 查询委派托管服务帐户 (dMSA)
删除-DomainGMSA 删除-GMSA 从域中删除现有的组托管服务帐户 (GMSA)
删除-DomainDMSA 删除-DMSA 从域中删除现有的委派托管服务帐户 (dMSA)
删除-DomainDNSRecord 删除域名DNS记录
删除-DomainComputer 删除-ADComputer 删除域计算机
删除-DomainGroupMember 删除-GroupMember 删除特定域组的成员
删除-DomainOU 删除-OU 删除 OUs 或 AD 中的特定 OU 对象
删除-DomainObjectAcl 删除-ObjectAcl 删除指定 AD 对象的 ACLs
删除-DomainObject 删除-ADObject 删除指定的域对象
删除-DomainUser 删除-ADUser Remove specified Domain User in AD
套装-DomainDNSRecord 设置域名DNS记录
套装-DomainUserPassword 为指定域用户设置密码
套装-DomainComputerPassword 设置指定域计算机的密码
套装-DomainObject 套装-ADObject 为AD中的指定域对象设置
套装-DomainObjectDN 套装-ADObjectDN 修改对象的 distinguishedName 属性以及更改 OU
套装-DomainObjectOwner 套装-ObjectOwner 设置 AD 对象的所有者
套装-ShadowCredential 套装-ShadowCred 管理域对象的 msDS-KeyCredentialLink(影子凭证)
获取-ShadowCredential 获取-ShadowCred 列出域对象或所有对象的影子凭据 (msDS-KeyCredentialLink)
删除-ShadowCredential 删除-ShadowCred 通过 DeviceId 删除影子凭据或从域对象中清除所有凭据
添加-DomainDNSRecord 添加域名DNS记录
禁用-DomainDNSRecord 通过指向无效地址禁用 DNS 记录
添加-DomainGMSA 添加-GMSA 在域中创建新的组托管服务帐户 (gMSA)
添加-DomainDMSA 添加-GMSA 在域中创建新的委派托管服务帐户 (dMSA)
添加-DomainUser 添加-ADUser 在 AD 中添加新的域用户
添加-DomainComputer 添加-ADComputer 在 AD 中添加新的域计算机
添加-DomainGroupMember 添加-GroupMember 在AD指定域组中添加新成员
添加-DomainOU 添加-OU 在 AD 中添加新的 OU 对象
添加-DomainGPO 添加-GPO 在 AD 中添加新的 GPO 对象
添加-DomainObjectAcl 添加-ObjectAcl 目前支持的权限有:All、DCsync、RBCD、ShadowCred、WriteMembers
清除缓存 清除缓存

GPO 功能

模块 别名 描述
获取-DomainGPO Query for domain group policy objects
获取-DomainGPOLocalGroup 获取-GPOLocalGroup 通过Restricted GroupsGroup Policy preferences查询域内所有修改本地组成员身份的GPOs
添加-GPLink 创建指向 OU 的新 GPO 链接
删除-GPLink 从 OU 中删除 GPO 链接

计算机枚举函数

模块 别名 描述
获取-NetSession [MS-SRVS]查询本地或远程计算机的会话信息
获取-NetShare 查询本地或远程计算机上打开的共享
获取-NetLoggedOn [MS-WKST]查询本地或远程计算机的登录用户
获取-EventLog [MS-EVEN6] 通过RPC从远程计算机查询Windows事件日志
获取-EventLogChannel [MS-EVEN6] 通过安全产品检测列出远程计算机上的事件日志通道
获取-EventLogPublisher [MS-EVEN6] 通过安全产品检测列出远程计算机上的事件日志发布者
获取-NetService [MS-SCMR] 查询本地或远程计算机上正在运行的服务
停止-NetService [MS-SCMR] 停止本地或远程计算机上的特定服务
获取-NetProcess 任务列表 [MS-TSTS] 查询本地或远程计算机正在运行的进程
停止-NetProcess 任务终止 [MS-TSTS] 终止本地或远程计算机上的特定进程
获取-NetTerminalSession [MS-TSTS] 查询本地或远程计算机上的活动终端会话
删除-NetTerminalSession [MS-TSTS] 终止本地或远程计算机上的特定终端会话
停止计算机 关机-电脑 [MS-TSTS] 关闭远程计算机
重新启动计算机 重启电脑 [MS-TSTS] 重新启动远程计算机

ADCS 功能

模块 别名 描述
获取-DomainCATemplate 获取-CATemplate 查询可用的 CA 模板。支持过滤易受攻击的模板
获取-DomainCA 获取-CA 查询证书颁发机构(CA)
删除-DomainCATemplate 删除-CATemplate 删除指定域 CA 模板
套装-DomainCATemplate 套装-CATemplate 修改 CA 模板的域对象的属性
添加-DomainCATemplate 添加-CATemplate 添加新域 CA 模板
添加-DomainCATemplateAcl 添加-CATemplateAcl 将ACL添加到证书模板中。目前支持的权限有“全部”、“注册”、“写入”

交换功能

模块 别名 描述
获取-ExchangeServer 获取交换 检索域中可用交换服务器的列表

域信任功能

模块 别名 描述
获取-DomainTrust 查询所有域信任
获取-DomainTrustMapping 递归映射当前域可访问的所有信任。跳入每个信任合作伙伴并使用 SourceName / TargetName 列(镜像 PowerView.ps1 的 Get-DomainTrustMapping)展平结果。使用 -NoRecurse 限制起始域。
获取-DomainForeignUser 查找-ForeignUser 查询位于用户域之外的组中的用户
获取-DomainForeignGroupMember 查找-ForeignGroup 查询组域之外的用户的组并查找外部成员

其他功能

模块 别名 描述
ConvertFrom-SID 将给定安全标识符 (SID) 转换为 user/group 名称
ConvertFrom-UACValue 将 UAC int 值转换为人类可读的形式
获取-NamedPipes 列出特定计算机的命名管道
调用-DFSCoerce 通过 MS-DFSNM NetrDfsRemoveStdRoot() 强制机器帐户身份验证
调用 Kerberoast 请求指定服务主体名称的 kerberos 票证 (SPN)
调用-PrinterBug 触发MS-RPRN RpcRemoteFindFirstPrinterChangeNotificationEx函数强制服务器对指定机器进行身份验证
解锁-ADAccount 通过修改lockoutTime属性解锁域帐户
查找-LocalAdminAccess 查找本地域中当前具有本地管理员访问权限的计算机

记录

我们永远不会错过记录来跟踪已完成的操作。默认情况下,powerview会在当前用户主目录_(~)_中创建一个.powerview文件夹。每个日志文件都是根据当前日期生成的。 示例路径:/root/.powerview/logs/bionic.local/2024-02-13.log

漏洞检测

PowerView.py 包括一个集成的漏洞检测系统,可自动识别常见的 Active Directory 安全问题。查询对象时,漏洞将显示在输出中:

漏洞:[VULN-026]具有高计算机帐户配额的域(允许用户添加计算机帐户)(MEDIUM)
                 [VULN-029] Domain with weak minimum password length policy (less than 8 characters) (HIGH)

用户定义的规则

您可以通过修改PowerView存储目录(~/.powerview/vulns.json)中的vulns.json文件来定义自定义漏洞检测规则。

每个漏洞规则具有以下结构:

"rule_name": {
    "description": "Human-readable description of the vulnerability",
    "rules": [
        {
            "attribute": "attributeName",
            "condition": "condition_type",
            "value": "value_to_check"
        },
        {
            "attribute": "anotherAttribute",
            "condition": "another_condition",
            "value": "another_value"
        }
    ],
    "exclusions": [
        {
            "attribute": "attributeName",
            "condition": "condition_type",
            "value": "value_to_exclude"
        }
    ],
    "severity": "low|medium|high|critical",
    "id": "VULN-XXX",
    "rule_operator": "AND|OR",
    "exclusion_operator": "AND|OR",
    "details": "Optional detailed explanation of the vulnerability and remediation steps"
}

规则组件:

  • 规则:检测漏洞必须满足的条件列表
  • 排除:条件列表,如果满足这些条件,即使对象符合规则,也会将其排除在检测之外
  • rule_operator:如何组合多个规则(默认:“OR”)
    • "AND": All rules must match
    • "OR": Any rule can match
  • exclusion_operator:如何组合多个排除(默认值:“OR”)
    • “OR”:任何排除都可以匹配以排除该对象
    • “AND”:所有排除项必须匹配才能排除该对象
  • negate:可选布尔值 (True/False),可以添加到任何规则以反转其结果

Supported Conditions:

条件 描述
exists 属性存在
not_exists 属性不存在
equals Exact match (case-insensitive)
not_equals 不完全匹配
contains Substring match (case-insensitive)
not_contains 没有子串匹配
startswith 以字符串开头(不区分大小写)
endswith 以字符串结尾(不区分大小写)
older_than Date is older than specified number of days
newer_than Date is newer than specified number of days
greater_than 数值大于指定值
less_than 数值小于指定值
greater_than_or_equal 数值大于或等于指定值
less_than_or_equal 数值小于或等于指定值
has_flag 位标志设置为数值
missing_flag Bit flag is not set in a numeric value
any_flag_set 设置任何指定的标志
all_flags_set 所有指定的标志均已设置

多个值:

您可以使用以下方法为一个条件指定多个值:

  1. 竖线分隔的字符串: "value": "value1|值2|值3"
  2. 列表格式:"value": ["value1", "value2", "value3"]

规则示例:

"weak_password_policy": {
    "description": "Domain with weak minimum password length policy (less than 8 characters)",
    "rules": [
        {
            "attribute": "objectClass",
            "condition": "contains",
            "value": "domainDNS"
        },
        {
            "attribute": "minPwdLength",
            "condition": "less_than",
            "value": 8
        }
    ],
    "exclusions": [],
    "severity": "high",
    "id": "VULN-029",
    "rule_operator": "AND"
}

MCP

[!注意] 这没有捆绑在基础项目安装中。您可以运行 pip3 install .[mcp] or pip3 install powerview[mcp] 以包含 MCP 功能。

这启用了模型上下文协议服务器,允许 AI 代理通过可流 HTTP 传输的标准化接口与 PowerView 功能进行交互。有关更多详细信息,请参阅 MCP 文档。

  • 启动MCP服务器
powerview domain.local/lowpriv:[email protected] --mcp [--mcp-主机 0.0.0.0] [--mcp-端口 8888] [--mcp-路径 powerview]

MCP 服务器通过标准化工具接口公开 PowerView 的大部分功能。这包括以下能力:

  • 查询和枚举Active Directory对象(用户、计算机、组、OUs)
  • 检索有关域信任、GPOs 和组成员身份的信息
  • 搜索安全漏洞和错误配置
  • ...

克劳德桌面

Claude Desktop 尚不支持基于 HTTP 的传输 Github。您可能想要使用 mcp-proxy。

  • 安装mcp-proxy
# Option 1: With uv (recommended)
uv tool install mcp-proxy

# Option 2: With pipx (alternative)
pipx install mcp-proxy
  • 修改%APPDATA%Claudeclaude_desktop_config.json
{
  "mcpServers": {
    "Powerview": {
        "command": "mcp-proxy",
        "args": ["http://10.10.10.10:5000/powerview"]
    }
  }
}

光标

您可以在 MCP 选项按钮下的光标设置中修改此设置。

[!提示] 启用 YOLO 模式以启用自主模式,这样您就不必每次都单击“运行工具”按钮。在这里阅读更多 here

{
  "mcpServers": {
    "Powerview": {
      "url": "http://127.0.0.1:5000/powerview"
    }
  }
}

[!警告] 当 MCP 与公共 AI 模型(如 Claude、GPT 等)一起使用时,您的 Active Directory 数据可能会根据这些服务的数据处理策略传输到这些服务并由这些服务记录。使用这些工具时请注意敏感信息的暴露。对于因将 PowerView 连接到第三方 AI 服务而导致的任何数据泄露或安全影响,我们不承担任何责任。自托管FTW!

插件

PowerView 支持基于装饰器的插件系统,可让您添加新命令并挂钩 before/after 现有命令。

它是如何运作的

                         ┌────────────────────────────────┐
                         │         Plugin Loader          │
                         │  Scans directories on startup  │
                         └──────────────┬─────────────────┘
                                        │
                        ┌───────────────┴───────────────┐
                        ▼                               ▼
            ┌───────────────────┐           ┌───────────────────┐
            │ builtin/ plugins  │           │  ~/.powerview/    │
            │                   │           │  plugins/         │
            │  dehashed.py      │           │                   │
            │  highlight.py     │           │  my_plugin.py     │
            │  recon.py         │           │  ...              │
            └───────────────────┘           └───────────────────┘
                        │                               │
                        └───────────────┬───────────────┘
                                        ▼
                            ┌──────────────────────┐
                            │   Sanity Validation  │
                            │  Check signatures &  │
                            │  required decorators │
                            └──────────┬───────────┘
                                        ▼
                            ┌──────────────────────┐
                            │   Plugin Registry    │
                            │                      │
                            │  commands: {}        │
                            │  before_hooks: {}    │
                            │  after_hooks: {}     │
                            └──────────┬───────────┘
                                        │
                                        ▼
                ┌─────────────────────────────────────────────────┐
                │              Command Execution Flow             │
                │                                                 │
                │  User Input: "Get-DomainUser -Identity admin"   │
                │                       │                         │
                │                       ▼                         │
                │          ┌────────────────────────┐             │
                │          │   @before hooks        │             │
                │          │   (modify args)        │             │
                │          └───────────┬────────────┘             │
                │                      │                          │
                │                      ▼                          │
                │          ┌────────────────────────┐             │
                │          │   Core command OR      │             │
                │          │   @command plugin      │             │
                │          └───────────┬────────────┘             │
                │                      │                          │
                │                      ▼                          │
                │          ┌────────────────────────┐             │
                │          │   @after hooks         │             │
                │          │   (modify results)     │             │
                │          └───────────┬────────────┘             │
                │                      │                          │
                │                      ▼                          │
                │               Format & Display                  │
                └─────────────────────────────────────────────────┘

插件是从两个路径自动发现的单个 .py 文件:

路径 目的
powerview/plugins/builtin/ 随包裹一起发货
~/.powerview/plugins/ 用户管理的插件

内置插件

插件 命令 挂钩 描述
侦察 Invoke-DomainRecon 单命令域侦察总结
亮点 after:Get-DomainUser 突出显示在用户描述中找到的密码

插件管理

Get-Plugin                          # List all plugins with status
Enable-Plugin -Name <plugin_name>   # Enable a disabled plugin
Disable-Plugin -Name <plugin_name>  # Disable a plugin at runtime

编写插件

~/.powerview/plugins/中创建一个.py文件。插件使用三个装饰器:@command 注册新命令,@before 在现有命令之前运行逻辑,@after 在现有命令之后运行逻辑。

# ~/.powerview/plugins/custom_enum.py
from powerview.plugins import command, before, after, PowerviewPlugin

plugin = PowerviewPlugin(
    name="CustomEnum",
    description="Custom enumeration helpers",
    author="yourname",
    version="1.0",
)

@command("Get-DomainAdminUser", args=["-Identity", "-Properties", "-SearchBase"],
         description="Find users with adminCount=1")
def get_domainadminuser(pv, args=无, 身份=无, 属性=无, searchbase=无):
    results = pv.get_domainuser(
        identity=identity or "*",
        properties=properties or ["sAMAccountName", "adminCount", "memberOf", "description"],
        searchbase=searchbase,
    )
    if results:
        return [r for r in results
                if str(r.get("attributes", r).get("adminCount", "")) == "1"]
    return results

@before("Get-DomainUser", priority=10)
def inject_enabled_filter(pv, args):
    """Automatically filter out disabled accounts."""
    if not hasattr(args, 'ldapfilter') or not args.ldapfilter:
        args.ldapfilter = "(!(userAccountControl:1.2.840.113556.1.4.803:=2))"
    return args

@after("Get-DomainUser", priority=20)
def add_password_age(pv, args, results):
    """Enrich results with password age."""
    from datetime import datetime, timezone
    if not results:
        return results
    for entry in results:
        attrs = entry.get("attributes", entry)
        pwdlast = attrs.get("pwdLastSet")
        if isinstance(pwdlast, datetime):
            if pwdlast.tzinfo is None:
                pwdlast = pwdlast.replace(tzinfo=timezone.utc)
            age = (datetime.now(timezone.utc) - pwdlast).days
            attrs["PasswordAge"] = f"{age} days"
    return results

装饰器:

装饰者 签名 描述
@command(name, args, description) func(pv, args=None, **kwargs) 注册一个新的动词名词命令
@before(command_name, priority) func(pv, args) 在命令之前运行。返回修改后的参数或 None
@after(command_name, priority) func(pv, args, results) 执行命令后运行。返回修改后的结果或None

[!NOTE] @before@after 接受单个命令名称或列表(e.g.、@after(["Get-DomainUser", "Get-DomainComputer"]))。优先级较低的值首先运行。

高级参数定义:

插件参数可以是简单的字符串("-Identity")或用于更精细控制的字典:

@command("Get-CustomThing", args=[
    "-Identity",
    {"name": "-Days", "type": int, "default": 90, "help": "Threshold in days"},
    {"name": "-Verbose", "action": "store_true", "help": "Show details"},
])

[!TIP] 所有插件命令都会自动获取 -OutFile-TableView-SortBy 标志。

点击查看更多
推荐专题
热门阅读