PowerView is a tool that I’ve spoken frequently about on this blog. It debuted as part of the Veil-Framework in March of 2014, and has gone through a huge number of changes over the last year and a half. It is now a part of the PowerTools repository under the PowerShellEmpire GitHub account, and may be integrated soon into the central PowerSploit repository.
Today marks probably the biggest change to PowerView and how people use it since its inception. PowerView v2.0 is a major refactor that eliminates some code components, renames others, absorbs some functions into existing ones, and adds a chunk of new functionality. As this is a pretty substantial change that breaks backwards compatibility, we wanted to put together a guide on converting your usage of PowerView from 1.X to 2.0.
There is a tagged release of PowerView 1.9 here, and we will also keep the previous code under the “version_1.9” branch for a few months. I will also be going through past posts on this blog and making edits where appropriate at the top of each post with new function syntax, however any relevant presentation slide decks will remain in their original states. And finally, to facilitate the transition, there are a series of aliases for *most* old cmdlets at the bottom of the powerview.ps1 file (though this is far from perfect). This will remain in place for a few months, and will eventually be removed at some point down the line.
We realized that PowerView had started to become a bit bloated as we tried to integrate several interesting PowerShell network/domain scripts into its functionality. We wanted to hit the restart button and start fresh with a reduced set of cmdlets to fight code and feature bloat. Also, some of the cmdlets removed had functionality covered by other cmdlets. If specific cmdlets from v1.9 are strongly requested back into 2.0, we will consider it.
- Invoke-Ping and Test-Server were removed, and their functionality replaced with Test-Connection combined with Invoke-ThreadedFunction
- Get-NetLocalServices as it was rarely (if ever) used
- Get-NetConnections as it was rarely (if ever) used
- Get-NetFiles as it was rarely (if ever) used
- Get-NetFileSessions as it was rarely (if ever) used
- Invoke-Netview as its functionality is duplicated with Invoke-ShareFinder and Invoke-UserHunter, and shares/found users are fundamentally different object types
- Invoke-FileDownloader as we do more targeted triage/downloads
- Get-LAPSPasswords as it makes more sense for this project to be maintained and used separately
- Invoke-HostEnum was it was rarely (if ever) used
Renamed and Combined Cmdlets
We’ve also renamed and/or combined several move cmdlets. Many of the changes are simple plural to singular name changes, and others are a move to a more ‘correct’ and descriptive naming convention:
- Invoke-CopyFile was renamed to Copy-ClonedFile
- Export-CSV was revamped to be thread-safe and renamed to Export-PowerViewCSV
- Get-HostIP was renamed to Get-IPAddress
- Translate-NT4Name was renamed to Convert-NT4toCanonical
- Invoke-NetUserAdd was renamed to Add-NetUser
- Get-NetForestDomains was renamed to Get-NetForestDomain
- Get-NetDomainControllers was renamed to Get-NetDomainController
- Get-NetComputer was renamed to Get-NetComputer
- Get-NetOUs has been renamed to Get-NetOU
- Get-NetGroups was renamed to Get-NetGroup and the old Get-NetGroup was renamed to Get-NetGroupMember
- This will likely be the biggest hangup for PowerView users, but we feel that the new scheme makes for much less confusion.
- Invoke-NetGroupUserAdd was renamed to Add-NetGroupUser
- Get-NetFileServers was renamed to Get-NetFileServer
- Get-NetSessions was renamed to Get-NetSession
- Get-NetRDPSessions was renamed to Get-NetRDPSession
- Get-NetProcesses was renamed to Get-NetProcess
- Get-UserProperties was renamed to Get-UserProperty
- Invoke-UserFieldSearch was renamed to Find-UserField
- Get-ComputerProperties was renamed to Get-ComputerProperty
- Invoke-ComputerFieldSearch was renamed to Find-ComputerField
- Invoke-SearchFiles was renamed to Find-InterestingFile
- Invoke-FindLocalAdminAccess was renamed to Find-LocalAdminAccess
- Get-ExploitableSystems was renamed to Get-ExploitableSystem
- Invoke-UserEventHunter was renamed to Invoke-EventHunter
- Invoke-EnumerateLocalAdmins was renamed to Invoke-EnumerateLocalAdmin
- Get-NetDomainTrusts was renamed to Get-NetDomainTrust
- Get-NetForestTrusts was renamed to Get-NetForestTrust
- Invoke-FindUserTrustGroups was renamed to Find-ForeignUser
- Invoke-FindGroupTrustUsers was renamed to Find-ForeignGroup
- Invoke-MapDomainTrusts was renamed to Invoke-MapDomainTrust
Additionally, several cmdlets were combined into others:
- Get-NetUserSPNs has been combined into Get-NetUser -SPN
- Get-NetPrinters has been combined into Get-NetComputer -Printers
- Get-NetGUIDOUs has been combined into Get-NetOU -GUID <guid>
- Get-UserLogonEvents and Get-UserTGTEvents have been combined into to Get-UserEvent -EventType ‘logon’ and Get-UserEvent -EventType ‘logon’, respectively
- Get-NetLocalGroups has been combined into Get-NetLocalGroup -ListGroups
- Invoke-UserView has been combined into Invoke-UserHunter -ShowAll
- Invoke-UserProcessHunter has been combined into Invoke-ProcessHunter -Username X
- Get-NetDomainTrustsLDAP has been combined into Get-NetDomainTrust -LDAP
- Invoke-FindAllUserTrustGroups has been combined into Find-ForeignUser -Recurse
- Invoke-FindAllGroupTrustUsers has been combined into Find-ForeignGroup -Recurse
- Invoke-EnumerateLocalTrustGroups has been combined into Invoke-EnumerateLocalAdmin -TrustGroups
- Invoke-MapDomainTrustsLDAP has been combined into Invoke-MapDomainTrust -LDAP
New Cmdlets and Functionality
There are also a few new cmdlets and functionality that have been integrated into v2.0:
- Many components of the LDAP querying functionality have been optimized and the code streamlined.
- Most LDAP functions that accepted a -Domain flag also now accept a -DomainController flag to specify a DC to reflect queries through.
- Get-Proxy is a start at a function to enumerate local user and SYSTEM proxy settings. We will be expanding on this soon.
- Convert-SidToName now properly resolves most builtin SIDs.
- Get-DFSshare will retrieve all fault tolerant distributed file systems in the domain (thanks to @meatballs__ ). This has also been integrated into Invoke-UserHunter -Stealth (and Invoke-StealthUserHunter) as a server search source.
- Get-ObjectAcl will return the ACLs associated with specific active directory objects.
- Add-ObjectAcl allows you to add additional ACLs/ACEs to active directory objects (thanks to @PyroTek3 for the ACL cmdlet ideas)
- Get-GUIDMap is a helper that maps GUID values to their display names.
- Get-ADObject will take an object SID and return the domain object (group, user, etc.) associated with it.
- Get-NetSite will return all sites for a specified domain, filterable by GPO -GUID if desired.
- Get-NetSubnet will give you all current subnets for a given domain, filterable by -SiteName.
- Get-NetGroup now accepts a -UserName parameter, and will recurse up a user’s group memberships, yielding all groups a given user is effectively a part of. It also now accepts a -AdminCount flag as well.
- Get-NetGPO will enumerate all current Group Policy objects for a given domain.
- Get-NetGPOGroup is a cool new cmdlet that returns all GPOs in a domain that set local group memberships through Restricted Groups or groups.xml (Group Policy Preferences).
- Find-GPOLocation is my favorite new cmdlet. It’s the start of an approach to take a user or group name and map out where the user/group has local administrator or RDP rights (“-LocalGroup Administrators” and “-LocalGroup RDP”) on the domain. It does this by wrapping Get-NetGPOGroup, matching target user/group SIDs, and enumerating back to OUs/computers. We’ll have a more in depth post on this later.
- Find-GPOComputerAdmin is similar to Find-GPOLocation, but takes a computer name and determines what users/groups have administrative access to it.
- Get-DomainPolicy will enumerate the default -Domain or -DomainController policy (things like the default Kerberos policy, etc.).
- Invoke-UserHunter now has a -Stealth option that integrates the old Invoke-StealthUserHunter functionality. A basic wrapper was left for Invoke-StealthUserHunter.
- Find-InterestingFile and Invoke-FileFinder now accept a -Credential argument for a PSCredential. This allows you to data mine with alternate credential sets.
- Invoke-UserHunter now has a -SearchForest flag (useful when you’re attempting to hop up a forest trust with Mimikatz and SID histories)
All Invoke-XThreaded commands are now implemented in their ‘normal’ functions with the “-Threads X” flag implementing the old threading code. For example, Invoke-ShareFinder will execute normal share finding behavior, while Invoke-ShareFinder -Threads 10 will execute the same functionality in a threaded fashion.
Pester is a unit testing framework written in and for PowerShell. PowerShellMagazine has a great getting started guide for Pester which I highly recommend. PowerView 2.0 includes the start of a suite of Pester unit tests that attempt to cover all cmdlets and associated arguments. These tests are located in ./Tests/ if you’re interested, and can be run with Invoke-Pester once Pester is installed. As many functions for PowerView are meant for domain enumeration and abuse, these tests have ended up being tweaked for the test environment I have in my home lab. I’m hoping to move to mocking soon in order to eliminate test environment dependence. These tests cases should hopefully increase stability in the project going forward.
A big thanks to everyone who’s helped the project along the way- @obscuresec, @mattifestation, darkoperator, everyone at the Adaptive Threat Division, @meatballs__ (for a ton of great ideas, code fixes, and LDAP optimization), @gentilkiwi, @pyrotek3 (for some great ideas and direction), tomsteele (who also did a cool version of @sixdub‘s DomainTrustExplorer), @armitagehacker for being a major advocate of the project, and the rest of the offensive PowerShell community!
There have also been numerous other tweaks, modifications, and bug fixes for the code base that I’ve sure have introduced new issues. If you encounter a problem, hit us up in #psempire on Freenode or open up a GitHub issue, and we will try to be extra-responsive over the next few weeks as everyone transitions.