
Powerview on steroids
Установка | Базовое использование | Обфускация | Модули | Логирование | Пользовательские правила | MCP | Плагины | Благодарности
PowerView.py — это альтернатива замечательному оригинальному скрипту PowerView.ps1. Большинство модулей, используемых в PowerView, доступно здесь (некоторые флаги изменены). Основная цель — получить интерактивную сессию без необходимости многократной аутентификации в ldap.
https://github.com/aniqfakhrul/powerview.py/wiki/Installation-Guide
[!NOTE] Обратите внимание, что некоторые функции kerberos пока ещё работают не идеально, но большинство задач они всё равно выполнят. Подробное использование можно найти в разделе Wiki
* Поддерживать постоянное соединение
> [!TIP]
> Постоянное соединение отключено по умолчанию. Сеансы LDAP завершаются по тайм-ауту после бездействия. Используйте `--keepalive-interval` для отправки периодических запросов, поддерживающих состояние сеанса.
* Запустить веб-интерфейс```
powerview range.net/lowpriv:[email protected] --web [--web-host 0.0.0.0] [--web-port 3000] [--web-auth user:password1234]

--use-sign-and-seal и --use-channel-binding доступны только в том случае, если вы установите библиотеку ldap3 напрямую из этой ветки```
powerview range.net/lowpriv:[email protected] [--use-channel-binding | --use-sign-and-seal | --use-simple-auth]* Инициализация через schannel. Флаг `--pfx` принимает файл сертификата в формате pfx.
> [!NOTE]
> powerview сначала попытается загрузить сертификат без пароля. Если это не удастся, он запросит пароль. Поэтому параметр пароля не нужен.```
powerview 10.10.10.10 --pfx administrator.pfx

* Укажите атрибуты поиска```
Get-DomainUser -Properties samaccountname,description
* Подсчёт результатов```
Get-DomainUser -Count
* Форматировать вывод в виде таблицы.```
Get-DomainUser -Properties samaccountname,memberof -TableView
Get-DomainUser -Properties samaccountname,memberof -TableView [csv,md,html,latex]
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 (пользовательские chain codes)```
powerview range.net/lowpriv:[email protected] --obfuscate CZXANDR
[!TIP] Переключите
Obfuscateв настройках. Это применяется к последующим запросам в рамках активной сессии.
Что обфусцируется
Цепочки по умолчанию (при использовании --obfuscate без значения)
| Цель | Цепочка | Техники |
|---|---|---|
| Фильтр | CZNDR | Case, Zeros, aNR, De Morgan, Reorder |
| BaseDN |
Выполните ldapx codes --all, чтобы увидеть все доступные коды обфускации.
[!NOTE] Результаты в большинстве случаев функционально эквивалентны, однако развёртывание с помощью аппроксимации/подстановочных знаков может расширять совпадения. Некоторые коды (G, O, S) могут быть несовместимы с ldap3 - используйте с осторожностью.
[!WARNING] Чрезмерная обфускация может быть отклонена строгими серверами или промежуточными инструментами. Используйте только при необходимости.
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
| Модуль | Псевдоним | Описание |
| ------ | ----- | ---- |
|Get-DomainUser||Запрос всех пользователей или конкретных объектов пользователей в AD|
|Get-DomainComputer||Запрос всех компьютеров или конкретных объектов компьютеров в AD|
|Get-DomainGroup||Запрос всех групп или конкретных объектов групп в AD|
|Get-DomainGroupMember||Запрос участников конкретной группы домена|
|Get-DomainOU||Запрос всех OU или конкретных объектов OU в AD|
|Get-Domain||Запрос информации о домене|
|Get-DomainController||Запрос доступных контроллеров домена|
|Get-DomainDNSRecord||Запрос доступных записей. Если не указан параметр -ZoneName, выполняется рекурсивный обход всех DNS-зон|
|Get-DomainDNSZone||Запрос доступных DNS-зон в домене|
|Get-DomainObject|Get-ADObject|Запрос всех или указанных объектов домена в AD|
|Get-DomainObjectAcl|Get-ObjectAcl|Запрос ACL для указанного объекта AD|
|Get-DomainSCCM|Get-SCCM|Запрос SCCM|
|Get-DomainRBCD|Get-RBCD|Находит учетные записи, настроенные для ограниченного делегирования на основе ресурсов|
|Get-DomainObjectOwner|Get-ObjectOwner|Запрос владельца объекта AD|
|Get-DomainGMSA|Get-GMSA|Запрос групповых управляемых учетных записей служб (gMSA) и получение их password blobs|
|Get-DomainDMSA|Get-GDSA|Запрос делегированных управляемых учетных записей служб (dMSA)|
|Remove-DomainGMSA|Remove-GMSA|Удаление существующей групповой управляемой учетной записи служб (gMSA) из домена|
|Remove-DomainDMSA|Remove-DMSA|Удаление существующей делегированной управляемой учетной записи служб (dMSA) из домена|
|Remove-DomainDNSRecord||Удаление DNS-записи домена|
|Remove-DomainComputer|Remove-ADComputer|Удаление доменного компьютера|
|Remove-DomainGroupMember|Remove-GroupMember|Удаление участника конкретной группы домена|
|Remove-DomainOU|Remove-OU|Удаление OU или конкретных объектов OU в AD|
|Remove-DomainObjectAcl|Remove-ObjectAcl|Удаление ACL для указанного объекта AD|
|Remove-DomainObject|Remove-ADObject|Удаление указанного объекта домена|
|Remove-DomainUser|Remove-ADUser|Удаление указанного пользователя домена в AD|
|Set-DomainDNSRecord||Настройка DNS-записи домена|
|Set-DomainUserPassword||Установка пароля для указанного пользователя домена|
|Set-DomainComputerPassword||Установка пароля для указанного компьютера домена|
|Set-DomainObject|Set-ADObject|Настройка указанных объектов домена в AD|
|Set-DomainObjectDN|Set-ADObjectDN|Изменение атрибута distinguishedName объекта, а также смена OU|
|Set-DomainObjectOwner|Set-ObjectOwner|Установка владельца объекта AD|
|Set-ShadowCredential|Set-ShadowCred|Управление атрибутом msDS-KeyCredentialLink (теневые учетные данные) для объекта домена|
|Get-ShadowCredential|Get-ShadowCred|Вывод списка теневых учетных данных (msDS-KeyCredentialLink) для объекта домена или всех объектов|
|Remove-ShadowCredential|Remove-ShadowCred|Удаление теневых учетных данных по DeviceId или очистка всех у объекта домена|
|Add-DomainDNSRecord||Добавление DNS-записи домена|
|Disable-DomainDNSRecord||Отключение DNS-записи путем указания недействительного адреса|
|Add-DomainGMSA|Add-GMSA|Создание новой групповой управляемой учетной записи служб (gMSA) в домене|
|Add-DomainDMSA|Add-GMSA|Создание новой делегированной управляемой учетной записи служб (dMSA) в домене|
|Add-DomainUser|Add-ADUser|Добавление нового пользователя домена в AD|
|Add-DomainComputer|Add-ADComputer|Добавление нового компьютера домена в AD|
|Add-DomainGroupMember|Add-GroupMember|Добавление нового участника в указанную группу домена в AD|
|Add-DomainOU|Add-OU|Добавление нового объекта OU в AD|
|Add-DomainGPO|Add-GPO|Добавление нового объекта GPO в AD|
|Add-DomainObjectAcl|Add-ObjectAcl|Поддерживаемые права на данный момент: All, DCsync, RBCD, ShadowCred, WriteMembers|
|Clear-Cache||Очистка кэша|
### Функции GPO
| Модуль | Псевдоним | Описание |
| ------ | ----- | ---- |
|Get-DomainGPO|| Запрос объектов групповой политики домена |
|Get-DomainGPOLocalGroup|Get-GPOLocalGroup|Запрос всех GPO в домене, которые изменяют членство в локальных группах через `Restricted Groups` или `Group Policy preferences`|
|Add-GPLink||Создание новой ссылки GPO на OU|
|Remove-GPLink||Удаление ссылки GPO с OU|
### Функции перечисления компьютеров
| Модуль | Псевдоним | Описание |
| ------ | ----- | ---- |
|Get-NetSession||[MS-SRVS] Запрос информации о сеансах для локального или удаленного компьютера|
|Get-NetShare||Запрос открытых общих ресурсов на локальном или удаленном компьютере|
|Get-NetLoggedOn||[MS-WKST] Запрос вошедших в систему пользователей на локальном или удаленном компьютере|
|Get-EventLog||[MS-EVEN6] Запрос журналов событий Windows с удаленного компьютера через RPC|
|Get-EventLogChannel||[MS-EVEN6] Вывод списка каналов журнала событий на удаленном компьютере с обнаружением продуктов безопасности|
|Get-EventLogPublisher||[MS-EVEN6] Вывод списка издателей журнала событий на удаленном компьютере с обнаружением продуктов безопасности|
|Get-NetService||[MS-SCMR] Запрос запущенных служб на локальном или удаленном компьютере|
|Stop-NetService||[MS-SCMR] Остановка конкретной службы на локальном или удаленном компьютере|
|Get-NetProcess|tasklist|[MS-TSTS] Запрос запущенных процессов на локальном или удаленном компьютере|
|Stop-NetProcess|taskkill|[MS-TSTS] Завершение конкретного процесса на локальном или удаленном компьютере|
|Get-NetTerminalSession||[MS-TSTS] Запрос активных терминальных сеансов на локальном или удаленном компьютере|
|Remove-NetTerminalSession||[MS-TSTS] Завершение конкретного терминального сеанса на локальном или удаленном компьютере|
|Stop-Computer|Shutdown-Computer|[MS-TSTS] Выключение удаленного компьютера|
|Restart-Computer|Reboot-Computer|[MS-TSTS] Перезагрузка удаленного компьютера|
### Функции ADCS
| Модуль | Псевдоним | Описание |
| ------ | ----- | ---- |
|Get-DomainCATemplate|Get-CATemplate|Запрос доступных шаблонов ЦС. Поддерживает фильтрацию уязвимых шаблонов|
|Get-DomainCA|Get-CA|Запрос центра сертификации (CA)|
|Remove-DomainCATemplate|Remove-CATemplate|Удаление указанного шаблона ЦС домена|
|Set-DomainCATemplate|Set-CATemplate|Изменение атрибутов объекта домена для шаблона ЦС|
|Add-DomainCATemplate|Add-CATemplate|Добавление нового шаблона ЦС домена|
|Add-DomainCATemplateAcl|Add-CATemplateAcl|Добавление ACL к шаблону сертификата. Поддерживаемые права на данный момент: All, Enroll, Write|
### Функции Exchange
| Модуль | Псевдоним | Описание |
| ------ | ----- | ----------- |
|Get-ExchangeServer|Get-Exchange|Получение списка доступных серверов Exchange в домене|
### Функции доверия домена
| Модуль | Псевдоним | Описание |
| ------ | ----- | ---- |
|Get-DomainTrust||Запрос всех доверительных отношений домена|
|Get-DomainTrustMapping||Рекурсивно отображает все доверительные отношения, доступные из текущего домена. Переходит в каждого партнера доверия и выравнивает результаты по столбцам `SourceName` / `TargetName` (зеркалирует `Get-DomainTrustMapping` из PowerView.ps1). Используйте `-NoRecurse`, чтобы ограничиться исходным доменом.|
|Get-DomainForeignUser|Find-ForeignUser|Запрос пользователей, которые находятся в группе за пределами домена пользователя|
|Get-DomainForeignGroupMember|Find-ForeignGroup|Запрос групп с пользователями за пределами домена группы и поиск внешних участников|
### Прочие функции
| Модуль | Псевдоним | Описание |
| ------ | ----- | ---- |
|ConvertFrom-SID||Преобразование заданного идентификатора безопасности (SID) в имя пользователя/группы|
|ConvertFrom-UACValue||Преобразует целочисленное значение UAC в читаемый вид|
|Get-NamedPipes||Вывод списка именованных каналов (Named Pipes) для конкретного компьютера|
|Invoke-DFSCoerce||Принудительно вызывает аутентификацию учетной записи компьютера через MS-DFSNM NetrDfsRemoveStdRoot()|
|Invoke-Kerberoast||Запрашивает билет Kerberos для указанного имени участника службы (SPN)|
|Invoke-PrinterBug||Запускает функцию MS-RPRN RpcRemoteFindFirstPrinterChangeNotificationEx, чтобы принудить сервер аутентифицироваться на указанной машине|
|Unlock-ADAccount||Разблокировка учетных записей домена путем изменения атрибута lockoutTime|
|Find-LocalAdminAccess||Находит компьютеры в локальном домене, где текущий пользователь имеет доступ локального администратора|
### Журналирование
Мы никогда не пропускаем ведение журнала, чтобы отслеживать выполненные действия. По умолчанию powerview создает папку `.powerview` в домашнем каталоге текущего пользователя _(~)_. Каждый файл журнала создается на основе текущей даты.
Пример пути: `/root/.powerview/logs/bionic.local/2024-02-13.log`
### Обнаружение уязвимостей
PowerView.py включает встроенную систему обнаружения уязвимостей, которая автоматически выявляет распространенные проблемы безопасности Active Directory. При запросе объектов уязвимости будут отображаться в выводе:```
vulnerabilities: [VULN-026] Domain with high machine account quota (allows users to add computer accounts) (MEDIUM)
[VULN-029] Domain with weak minimum password length policy (less than 8 characters) (HIGH)
Вы можете определять пользовательские правила обнаружения уязвимостей, изменяя файл vulns.json, расположенный в каталоге хранилища PowerView (~/.powerview/vulns.json).
Каждое правило уязвимости имеет следующую структуру:```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" }
**Компоненты правил:**
- **rules**: Список условий, которые должны быть выполнены для обнаружения уязвимости
- **exclusions**: Список условий, которые при выполнении исключат объект из обнаружения, даже если он соответствует правилам
- **rule_operator**: Способ комбинирования нескольких правил (по умолчанию: "OR")
- "AND": Все правила должны совпасть
- "OR": Любое правило может совпасть
- **exclusion_operator**: Способ комбинирования нескольких исключений (по умолчанию: "OR")
- "OR": Любое исключение может совпасть, чтобы исключить объект
- "AND": Все исключения должны совпасть, чтобы исключить объект
- **negate**: Необязательное логическое значение (True/False), которое можно добавить к любому правилу для инвертирования его результата
**Поддерживаемые условия:**
| Condition | Description |
| --------- | ----------- |
| `exists` | Атрибут существует |
| `not_exists` | Атрибут не существует |
| `equals` | Точное совпадение (без учёта регистра) |
| `not_equals` | Не точное совпадение |
| `contains` | Совпадение подстроки (без учёта регистра) |
| `not_contains` | Нет совпадения подстроки |
| `startswith` | Начинается со строки (без учёта регистра) |
| `endswith` | Заканчивается строкой (без учёта регистра) |
| `older_than` | Дата старше указанного количества дней |
| `newer_than` | Дата новее указанного количества дней |
| `greater_than` | Числовое значение больше указанного |
| `less_than` | Числовое значение меньше указанного |
| `greater_than_or_equal` | Числовое значение больше или равно указанному |
| `less_than_or_equal` | Числовое значение меньше или равно указанному |
| `has_flag` | Битовый флаг установлен в числовом значении |
| `missing_flag` | Битовый флаг не установлен в числовом значении |
| `any_flag_set` | Установлен любой из указанных флагов |
| `all_flags_set` | Установлены все указанные флаги |
**Несколько значений:**
Вы можете указать несколько значений для условия, используя:
1. Строку, разделённую символом `|`: `"value": "value1|value2|value3"`
2. Формат списка: `"value": ["value1", "value2", "value3"]`
**Пример правила:**```json
"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"
}
[!note] Это не входит в базовую установку проекта. Вы можете выполнить
pip3 install .[mcp] or pip3 install powerview[mcp]для включения функциональности MCP.
Это активирует сервер Model Context Protocol, позволяя AI-агентам взаимодействовать с функциональностью PowerView через стандартизированный интерфейс по транспорту Streamable HTTP. Подробнее см. в документации MCP.
Сервер MCP предоставляет большую часть функциональности PowerView через стандартизированный интерфейс инструментов. Это включает возможность:
- Запрашивать и перечислять объекты Active Directory (пользователи, компьютеры, группы, подразделения)
- Получать информацию о доверительных отношениях доменов, объектах GPO и членстве в группах
- Искать уязвимости безопасности и ошибки конфигурации
- ...
#### Claude Desktop
Claude Desktop пока не поддерживает транспорт на основе HTTP [Github](https://github.com/orgs/modelcontextprotocol/discussions/16). Возможно, вам стоит использовать [mcp-proxy](https://github.com/sparfenyuk/mcp-proxy).
* Установите `mcp-proxy````bash
# Option 1: With uv (recommended)
uv tool install mcp-proxy
# Option 2: With pipx (alternative)
pipx install mcp-proxy
#### Cursor
Вы можете изменить это в настройках Cursor через кнопку параметров MCP.
>[!tip]
>Включите режим YOLO, чтобы активировать автономный режим, и вам не придётся каждый раз нажимать кнопку «Run Tool». Подробнее [здесь](https://docs.cursor.com/chat/agent#yolo-mode)```json
{
"mcpServers": {
"Powerview": {
"url": "http://127.0.0.1:5000/powerview"
}
}
}
[!warning] При использовании MCP с публичными ИИ-моделями (например, Claude, GPT и т.д.) ваши данные Active Directory могут передаваться и регистрироваться этими сервисами в соответствии с их политиками обработки данных. Помните о риске раскрытия конфиденциальной информации при использовании этих инструментов. Мы не несём ответственности за утечку данных или последствия для безопасности, возникшие в результате подключения PowerView к сторонним ИИ-сервисам. Self-hosted FTW!
PowerView поддерживает систему плагинов на основе декораторов, которая позволяет добавлять новые команды и перехватывать выполнение до/после существующих команд.
┌────────────────────────────────┐
│ 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 │
└─────────────────────────────────────────────────┘
Plugins are single `.py` files discovered automatically from two paths:
| Path | Purpose |
|------|---------|
| `powerview/plugins/builtin/` | Ships with the package |
| `~/.powerview/plugins/` | User-managed plugins |
#### Built-in Plugins
| Plugin | Commands | Hooks | Description |
|--------|----------|-------|-------------|
| Recon | `Invoke-DomainRecon` | — | Single-command domain reconnaissance summary |
| Highlight | — | `after:Get-DomainUser` | Highlights passwords found in user descriptions |
#### Plugin Management```
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
Создайте файл .py в ~/.powerview/plugins/. Плагины используют три декоратора: @command для регистрации новых команд, @before для выполнения логики перед существующей командой и @after для выполнения логики после.```python
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=None, identity=None, properties=None, searchbase=None): 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` принимают одно имя команды или список (например, `@after(["Get-DomainUser", "Get-DomainComputer"])`). Меньшие значения приоритета выполняются первыми.
**Расширенные определения аргументов:**
Аргументы плагина могут быть простыми строками (`"-Identity"`) или словарями для более точного управления:```python
@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.
CX |
| Case, heX encoding |
| Атрибуты | CR | Case, Reorder |