
Powerview on steroids
Installazione | Utilizzo base | Offuscamento | Moduli | Registrazione | Regole definite dall'utente | MCP | Plugin | Riconoscimenti
PowerView.py è un'alternativa al fantastico script originale PowerView.ps1. La maggior parte dei moduli usati in PowerView è disponibile qui (alcuni flag sono cambiati). L'obiettivo principale è ottenere una sessione interattiva senza dover autenticarsi ripetutamente a ldap.
https://github.com/aniqfakhrul/powerview.py/wiki/Installation-Guide
[!NOTE] Nota che alcune delle funzioni kerberos non funzionano ancora benissimo, ma farà comunque la maggior parte del lavoro. L'uso dettagliato può essere trovato nella sezione Wiki
* Mantenere la connessione persistente
> [!TIP]
> La persistenza della connessione è disabilitata per impostazione predefinita. Le sessioni LDAP scadono dopo un periodo di inattività. Usa `--keepalive-interval` per inviare query periodiche mantenendo lo stato della sessione.
* Avviare l'interfaccia web```
powerview range.net/lowpriv:[email protected] --web [--web-host 0.0.0.0] [--web-port 3000] [--web-auth user:password1234]

--use-sign-and-seal e --use-channel-binding sono disponibili solo se installi la libreria ldap3 direttamente da questo branch```
powerview range.net/lowpriv:[email protected] [--use-channel-binding | --use-sign-and-seal | --use-simple-auth]* Inizializza con schannel. Il flag `--pfx` accetta file di certificato in formato pfx.
> [!NOTE]
> powerview proverà a caricare il certificato senza password al primo tentativo. Se fallisce, chiederà la password. Quindi, non è necessario alcun parametro password```
powerview 10.10.10.10 --pfx administrator.pfx

* Specifica gli attributi di ricerca```
Get-DomainUser -Properties samaccountname,description
* Conta i risultati```
Get-DomainUser -Count
* Formatta l'output in una tabella.```
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'
* Modalità relay```
powerview 10.10.10.10 --relay [--relay-host] [--relay-port] [--use-ldap | --use-ldaps]

[!NOTE]
Questa dimostrazione mostra che l'autenticazione forzata è stata eseguita utilizzandoprinterbug.py. Puoi utilizzare altri metodi che forzano l'autenticazione HTTP.
PowerView utilizza ldapx-py per offuscare le query LDAP e i parametri correlati, variando i pattern osservabili pur preservando l'intento delle query.
* Abilita tramite CLI (codici di catena personalizzati)```
powerview range.net/lowpriv:[email protected] --obfuscate CZXANDR
[!TIP] Commuta
Obfuscatenelle Impostazioni. Questo si applica alle query successive per la sessione attiva.
Cosa viene offuscato
Catene predefinite (quando si usa --obfuscate senza valore)
| Bersaglio | Catena | Tecniche |
|---|---|---|
| Filter | CZNDR | Case, Zeros, aNR, De Morgan, Reorder |
Esegui ldapx codes --all per vedere tutti i codici di offuscamento disponibili.
[!NOTE] I risultati sono funzionalmente equivalenti nella maggior parte dei casi, ma le espansioni per approssimazione/wildcard possono ampliare le corrispondenze. Alcuni codici (G, O, S) potrebbero non essere compatibili con ldap3 - usare con cautela.
[!WARNING] Un'offuscamento eccessivo potrebbe essere rifiutato da server rigorosi o da strumenti intermedi. Usare solo quando necessario.
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
### Funzioni di dominio/LDAP
| Modulo | Alias | Descrizione |
| ------ | ----- | ---- |
|Get-DomainUser||Cerca tutti gli utenti o oggetti utente specifici in AD|
|Get-DomainComputer||Cerca tutti i computer o oggetti computer specifici in AD|
|Get-DomainGroup||Cerca tutti i gruppi o oggetti gruppo specifici in AD|
|Get-DomainGroupMember||Cerca i membri di uno specifico gruppo di dominio|
|Get-DomainOU||Cerca tutte le OU o oggetti OU specifici in AD|
|Get-Domain||Cerca informazioni sul dominio|
|Get-DomainController||Cerca i controller di dominio disponibili|
|Get-DomainDNSRecord||Cerca i record disponibili. Ricorre in tutte le zone DNS se non viene specificato -ZoneName|
|Get-DomainDNSZone||Cerca le zone DNS disponibili nel dominio|
|Get-DomainObject|Get-ADObject|Cerca tutti gli oggetti di dominio o quelli specificati in AD|
|Get-DomainObjectAcl|Get-ObjectAcl|Cerca gli ACL per l'oggetto AD specificato|
|Get-DomainSCCM|Get-SCCM|Cerca SCCM|
|Get-DomainRBCD|Get-RBCD|Trova gli account configurati per la delega vincolata basata sulle risorse|
|Get-DomainObjectOwner|Get-ObjectOwner|Cerca il proprietario dell'oggetto AD|
|Get-DomainGMSA|Get-GMSA|Cerca gli account di servizio gestiti di gruppo (gMSA) e recupera i relativi blob delle password|
|Get-DomainDMSA|Get-GDSA|Cerca gli account di servizio gestiti delegati (dMSA)|
|Remove-DomainGMSA|Remove-GMSA|Elimina un account di servizio gestito di gruppo (gMSA) esistente dal dominio|
|Remove-DomainDMSA|Remove-DMSA|Elimina un account di servizio gestito delegato (dMSA) esistente dal dominio|
|Remove-DomainDNSRecord||Rimuove un record DNS di dominio|
|Remove-DomainComputer|Remove-ADComputer|Rimuove un computer dal dominio|
|Remove-DomainGroupMember|Remove-GroupMember|Rimuove un membro da uno specifico gruppo di dominio|
|Remove-DomainOU|Remove-OU|Rimuove le OU o oggetti OU specifici in AD|
|Remove-DomainObjectAcl|Remove-ObjectAcl|Rimuove gli ACL per l'oggetto AD specificato|
|Remove-DomainObject|Remove-ADObject|Rimuove l'oggetto di dominio specificato|
|Remove-DomainUser|Remove-ADUser|Rimuove l'utente di dominio specificato in AD|
|Set-DomainDNSRecord||Imposta un record DNS di dominio|
|Set-DomainUserPassword||Imposta la password per l'utente di dominio specificato|
|Set-DomainComputerPassword||Imposta la password per il computer di dominio specificato|
|Set-DomainObject|Set-ADObject|Imposta gli oggetti di dominio specificati in AD|
|Set-DomainObjectDN|Set-ADObjectDN| Modifica l'attributo distinguishedName dell'oggetto e cambia anche l'OU|
|Set-DomainObjectOwner|Set-ObjectOwner|Imposta il proprietario dell'oggetto AD|
|Set-ShadowCredential|Set-ShadowCred|Gestisce msDS-KeyCredentialLink (Shadow Credentials) per un oggetto di dominio|
|Get-ShadowCredential|Get-ShadowCred|Elenca le shadow credentials (msDS-KeyCredentialLink) per un oggetto di dominio o per tutti gli oggetti|
|Remove-ShadowCredential|Remove-ShadowCred|Rimuove le shadow credentials tramite DeviceId o le cancella tutte da un oggetto di dominio|
|Add-DomainDNSRecord||Aggiunge un record DNS di dominio|
|Disable-DomainDNSRecord||Disattiva un record DNS facendolo puntare a un indirizzo non valido|
|Add-DomainGMSA|Add-GMSA|Crea un nuovo account di servizio gestito di gruppo (gMSA) nel dominio|
|Add-DomainDMSA|Add-GMSA|Crea un nuovo account di servizio gestito delegato (dMSA) nel dominio|
|Add-DomainUser|Add-ADUser|Aggiunge un nuovo utente di dominio in AD|
|Add-DomainComputer|Add-ADComputer|Aggiunge un nuovo computer di dominio in AD|
|Add-DomainGroupMember|Add-GroupMember|Aggiunge un nuovo membro al gruppo di dominio specificato in AD|
|Add-DomainOU|Add-OU|Aggiunge un nuovo oggetto OU in AD|
|Add-DomainGPO|Add-GPO|Aggiunge un nuovo oggetto GPO in AD|
|Add-DomainObjectAcl|Add-ObjectAcl|I diritti supportati finora sono All, DCsync, RBCD, ShadowCred, WriteMembers|
|Clear-Cache||Svuota la cache|
### Funzioni GPO
| Modulo | Alias | Descrizione |
| ------ | ----- | ---- |
|Get-DomainGPO|| Cerca gli oggetti Criteri di gruppo del dominio |
|Get-DomainGPOLocalGroup|Get-GPOLocalGroup|Cerca tutti i GPO in un dominio che modificano le appartenenze ai gruppi locali tramite `Restricted Groups` o `Group Policy preferences`|
|Add-GPLink||Crea un nuovo collegamento GPO a un'OU|
|Remove-GPLink||Rimuove il collegamento GPO da un'OU|
### Funzioni di enumerazione computer
| Modulo | Alias | Descrizione |
| ------ | ----- | ---- |
|Get-NetSession||[MS-SRVS] Cerca informazioni sulle sessioni per il computer locale o remoto|
|Get-NetShare||Cerca le condivisioni aperte sul computer locale o remoto|
|Get-NetLoggedOn||[MS-WKST] Cerca gli utenti con sessione attiva sul computer locale o remoto|
|Get-EventLog||[MS-EVEN6] Cerca i log eventi di Windows da un computer remoto tramite RPC|
|Get-EventLogChannel||[MS-EVEN6] Elenca i canali del registro eventi su un computer remoto con rilevamento dei prodotti di sicurezza|
|Get-EventLogPublisher||[MS-EVEN6] Elenca i publisher del registro eventi su un computer remoto con rilevamento dei prodotti di sicurezza|
|Get-NetService||[MS-SCMR] Cerca i servizi in esecuzione sul computer locale o remoto|
|Stop-NetService||[MS-SCMR] Arresta un servizio specifico sul computer locale o remoto|
|Get-NetProcess|tasklist|[MS-TSTS] Cerca i processi in esecuzione sul computer locale o remoto|
|Stop-NetProcess|taskkill|[MS-TSTS] Termina un processo specifico sul computer locale o remoto|
|Get-NetTerminalSession||[MS-TSTS] Cerca le sessioni terminale attive sul computer locale o remoto|
|Remove-NetTerminalSession||[MS-TSTS] Termina una sessione terminale specifica sul computer locale o remoto|
|Stop-Computer|Shutdown-Computer|[MS-TSTS] Arresta un computer remoto|
|Restart-Computer|Reboot-Computer|[MS-TSTS] Riavvia un computer remoto|
### Funzioni ADCS
| Modulo | Alias | Descrizione |
| ------ | ----- | ---- |
|Get-DomainCATemplate|Get-CATemplate|Cerca i modelli CA disponibili. Supporta il filtraggio per modelli vulnerabili|
|Get-DomainCA|Get-CA|Cerca l'Autorità di certificazione (CA)|
|Remove-DomainCATemplate|Remove-CATemplate|Rimuove il modello CA di dominio specificato|
|Set-DomainCATemplate|Set-CATemplate|Modifica gli attributi dell'oggetto di dominio di un modello CA|
|Add-DomainCATemplate|Add-CATemplate|Aggiunge un nuovo modello CA di dominio|
|Add-DomainCATemplateAcl|Add-CATemplateAcl|Aggiunge un ACL a un modello di certificato. I diritti supportati finora sono All, Enroll, Write|
### Funzioni Exchange
| Modulo | Alias | Descrizione |
| ------ | ----- | ----------- |
|Get-ExchangeServer|Get-Exchange|Recupera l'elenco dei server Exchange disponibili nel dominio|
### Funzioni di trust di dominio
| Modulo | Alias | Descrizione |
| ------ | ----- | ---- |
|Get-DomainTrust||Cerca tutti i trust di dominio|
|Get-DomainTrustMapping||Esegue la mappatura ricorsiva di tutti i trust raggiungibili dal dominio corrente. Entra in ogni partner di trust e appiattisce i risultati con le colonne `SourceName` / `TargetName` (rispecchia `Get-DomainTrustMapping` di PowerView.ps1). Usa `-NoRecurse` per limitarsi al dominio di partenza.|
|Get-DomainForeignUser|Find-ForeignUser|Cerca gli utenti che appartengono a un gruppo al di fuori del dominio dell'utente|
|Get-DomainForeignGroupMember|Find-ForeignGroup|Cerca i gruppi con utenti al di fuori del dominio del gruppo e cerca membri esterni|
### Funzioni varie
| Modulo | Alias | Descrizione |
| ------ | ----- | ---- |
|ConvertFrom-SID||Converte un dato identificatore di sicurezza (SID) nel nome di utente/gruppo|
|ConvertFrom-UACValue||Converte un valore intero UAC in forma leggibile|
|Get-NamedPipes||Elenca le named pipe per un computer specifico|
|Invoke-DFSCoerce||Forza l'autenticazione dell'account del computer tramite MS-DFSNM NetrDfsRemoveStdRoot()|
|Invoke-Kerberoast||Richiede un ticket Kerberos per un nome principale del servizio (SPN) specificato|
|Invoke-PrinterBug||Attiva la funzione MS-RPRN RpcRemoteFindFirstPrinterChangeNotificationEx per forzare un server ad autenticarsi su una macchina specificata|
|Unlock-ADAccount||Sblocca gli account di dominio modificando l'attributo lockoutTime|
|Find-LocalAdminAccess||Trova i computer nel dominio locale in cui l'utente corrente ha accesso come amministratore locale|
### Registrazione
Non tralasciamo mai la registrazione per tenere traccia delle azioni eseguite. Per impostazione predefinita, powerview crea una cartella `.powerview` nella home directory dell'utente corrente _(~)_. Ogni file di log viene generato in base alla data corrente.
Percorso di esempio: `/root/.powerview/logs/bionic.local/2024-02-13.log`
### Rilevamento vulnerabilità
PowerView.py include un sistema integrato di rilevamento delle vulnerabilità che identifica automaticamente i problemi di sicurezza comuni di Active Directory. Quando si interrogano gli oggetti, le vulnerabilità verranno visualizzate nell'output:```
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)
Puoi definire regole personalizzate di rilevamento delle vulnerabilità modificando il file vulns.json situato nella directory di archiviazione di PowerView (~/.powerview/vulns.json).
Ogni regola di vulnerabilità ha la seguente struttura:```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" }
**Componenti della regola:**
- **rules**: Elenco di condizioni che devono essere soddisfatte affinché la vulnerabilità venga rilevata
- **exclusions**: Elenco di condizioni che, se soddisfatte, escluderanno un oggetto dal rilevamento anche se corrisponde alle regole
- **rule_operator**: Come combinare più regole (predefinito: "OR")
- "AND": Tutte le regole devono corrispondere
- "OR": Qualsiasi regola può corrispondere
- **exclusion_operator**: Come combinare più esclusioni (predefinito: "OR")
- "OR": Qualsiasi esclusione può corrispondere per escludere l'oggetto
- "AND": Tutte le esclusioni devono corrispondere per escludere l'oggetto
- **negate**: Booleano opzionale (True/False) che può essere aggiunto a qualsiasi regola per invertirne il risultato
**Condizioni supportate:**
| Condition | Description |
| --------- | ----------- |
| `exists` | L'attributo esiste |
| `not_exists` | L'attributo non esiste |
| `equals` | Corrispondenza esatta (senza distinzione tra maiuscole e minuscole) |
| `not_equals` | Non è una corrispondenza esatta |
| `contains` | Corrispondenza per sottostringa (senza distinzione tra maiuscole e minuscole) |
| `not_contains` | Nessuna corrispondenza per sottostringa |
| `startswith` | Inizia con la stringa (senza distinzione tra maiuscole e minuscole) |
| `endswith` | Termina con la stringa (senza distinzione tra maiuscole e minuscole) |
| `older_than` | La data è più vecchia del numero di giorni specificato |
| `newer_than` | La data è più recente del numero di giorni specificato |
| `greater_than` | Il valore numerico è maggiore di quello specificato |
| `less_than` | Il valore numerico è minore di quello specificato |
| `greater_than_or_equal` | Il valore numerico è maggiore o uguale a quello specificato |
| `less_than_or_equal` | Il valore numerico è minore o uguale a quello specificato |
| `has_flag` | Il flag di bit è impostato in un valore numerico |
| `missing_flag` | Il flag di bit non è impostato in un valore numerico |
| `any_flag_set` | Uno qualsiasi dei flag specificati è impostato |
| `all_flags_set` | Tutti i flag specificati sono impostati |
**Valori multipli:**
Puoi specificare più valori per una condizione utilizzando:
1. Stringa separata da pipe: `"value": "value1|value2|value3"`
2. Formato elenco: `"value": ["value1", "value2", "value3"]`
**Esempio di regola:**```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] Questo non è incluso nell'installazione di base del progetto. Puoi eseguire
pip3 install .[mcp] or pip3 install powerview[mcp]per includere le funzionalità MCP.
Questo abilita il server Model Context Protocol, consentendo agli agenti AI di interagire con le funzionalità di PowerView tramite un'interfaccia standardizzata via trasporto HTTP Streamable. Consulta la documentazione MCP per maggiori dettagli.
Il server MCP espone la maggior parte delle funzionalità di PowerView tramite un'interfaccia strumento standardizzata. Ciò include la possibilità di:
- Interrogare ed enumerare gli oggetti di Active Directory (utenti, computer, gruppi, OU)
- Recuperare informazioni su trust di dominio, GPO e appartenenze ai gruppi
- Cercare vulnerabilità di sicurezza e configurazioni errate
- ...
#### Claude Desktop
Claude Desktop non supporta ancora il trasporto basato su HTTP [Github](https://github.com/orgs/modelcontextprotocol/discussions/16). Potresti voler usare [mcp-proxy](https://github.com/sparfenyuk/mcp-proxy).
* Installare `mcp-proxy````bash
# Option 1: With uv (recommended)
uv tool install mcp-proxy
# Option 2: With pipx (alternative)
pipx install mcp-proxy
#### Cursor
Puoi modificarlo nelle impostazioni di Cursor sotto il pulsante delle opzioni MCP.
>[!tip]
>Attiva la modalità YOLO per abilitare la modalità autonoma, così non devi fare clic sul pulsante "Run Tool" ogni volta. Leggi di più [qui](https://docs.cursor.com/chat/agent#yolo-mode)```json
{
"mcpServers": {
"Powerview": {
"url": "http://127.0.0.1:5000/powerview"
}
}
}
[!warning] Quando utilizzi MCP con modelli AI pubblici (come Claude, GPT, ecc.), i tuoi dati di Active Directory potrebbero essere trasmessi e registrati da questi servizi in base alle loro politiche di gestione dei dati. Fai attenzione all'esposizione di informazioni sensibili quando utilizzi questi strumenti. Non siamo responsabili per eventuali perdite di dati o implicazioni di sicurezza derivanti dalla connessione di PowerView a servizi AI di terze parti. Self-hosted FTW!
PowerView supporta un sistema di plugin basato su decoratori che ti consente di aggiungere nuovi comandi e di agganciarti prima/dopo i comandi esistenti.
┌────────────────────────────────┐
│ 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 │
└─────────────────────────────────────────────────┘
I plugin sono singoli file `.py` rilevati automaticamente da due percorsi:
| Percorso | Scopo |
|------|---------|
| `powerview/plugins/builtin/` | Incluso con il pacchetto |
| `~/.powerview/plugins/` | Plugin gestiti dall'utente |
#### Plugin Integrati
| Plugin | Comandi | Hook | Descrizione |
|--------|----------|-------|-------------|
| Recon | `Invoke-DomainRecon` | — | Riepilogo di ricognizione del dominio con un singolo comando |
| Highlight | — | `after:Get-DomainUser` | Evidenzia le password trovate nelle descrizioni degli utenti |
#### Gestione dei Plugin```
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
Crea un file .py in ~/.powerview/plugins/. I plugin usano tre decoratori: @command per registrare nuovi comandi, @before per eseguire la logica prima di un comando esistente, e @after per eseguirla dopo.```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
**Decorators:**
| Decorator | Firma | Descrizione |
|-----------|-----------|-------------|
| `@command(name, args, description)` | `func(pv, args=None, **kwargs)` | Registra un nuovo comando verbo-sostantivo |
| `@before(command_name, priority)` | `func(pv, args)` | Esegue prima di un comando. Restituisce gli args modificati o `None` |
| `@after(command_name, priority)` | `func(pv, args, results)` | Esegue dopo un comando. Restituisce i risultati modificati o `None` |
> [!NOTE]
> `@before` e `@after` accettano un singolo nome di comando o una lista (es. `@after(["Get-DomainUser", "Get-DomainComputer"])`). I valori di priorità più bassi vengono eseguiti per primi.
**Definizioni avanzate degli argomenti:**
Gli argomenti dei plugin possono essere semplici stringhe (`"-Identity"`) o dizionari per un controllo più fine:```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] Tutti i comandi dei plugin ottengono automaticamente i flag
-OutFile,-TableViewe-SortBy.
| BaseDN |
CX |
| Case, heX encoding |
| Attributes | CR | Case, Reorder |