Searching User Properties with Veil-PowerView

A few months ago, @obscuresec published a post on finding and extracting custom user properties in Active Directory using PowerShell. Veil-PowerView 1.4 added some cmdlets that integrated (read: shamelessly stole :) some of this functionality, and I wanted to briefly cover how to utilize these new methods.

As Chris states in his post, “Since most administrators interact with AD with a MMC snapin, they mistakingly believe that custom fields can’t be viewed by other user“. To enumerate all custom fields from user AD objects with Veil-PowerView, use the Get-UserProperties function:

  • PS C:\> Get-UserProperties

This will dump out all the fields for user objects. If you want to extract out all users/values for a particular field, use the -Properties flag with one or more property names:

  • PS C:\> Get-UserProperties -Properties description,info

If you want to search particular fields for wildcard terms, Invoke-UserFieldSearch will take care of that for you. It defaults to searching the ‘description’ field for ‘*pass*’. If you want to search another field, say for something custom you found from Get-UserProperties, just supply the field and terms you want:

  • PS C:\> Invoke-UserFieldSearch -Field info -Term backup

You’d be surprised as to the information you can find in Active Directory, even from non-privileged/basic user accounts :)

Hunting for Sensitive Data with the Veil-Framework

Data mining available file shares for sensitive data is a staple of red teaming. We’ve found everything from password lists, to full employee directories, salary information, network diagrams and more, all due to network shares with incorrectly configured permissions. Veil-PowerView has a few functions (Invoke-Netview and Invoke-Sharefinder) that have helped us quickly find and explore shares our current user has access to. I’ve talked in the past about using Powershell to triage file servers during engagements, and realized that robust, recursive file listing would make a great addition into PowerView. Those two functions (Invoke-SearchFiles and Invoke-FileFinder) were recently added, and I wanted to demonstrate how this new functionality can help you find sensitive files on the network as quickly as possible.

Invoke-ShareFinder has had its output recently reworked so it spits out any “\\HOST\share    – COMMENT” found, instead of the status output similar to Invoke-Netview. The reason for this is to easily chain together Invoke-ShareFinder and Invoke-FileFinder, while preserving as much information we might want as possible. Here’s how I usually run sharefinder:

  • PS C:\> Invoke-ShareFinder -Ping -CheckShareAccess -Verbose | Out-File -Encoding ascii found_shares.txt

This will query AD for all machine objects, ping each one to ensure the host is up before enumeration, check each found share for read access, and output everything to found_shares.txt. The -Verbose flag gives some status output as it chews through all the retrieved servers, and the output will look something like this:

\\\MSBuild 	- test
\\\NETLOGON 	- Logon server share 
\\\SYSVOL 	- Logon server share 
\\\test 	- 
\\\Users 	- User share
\\\secret	- don't look here

I’ll save off an original copy of the file off for reference, and then will glance over the output, manually trimming out certain shares that seem like they likely won’t be interesting. I can then feed that output file straight into Invoke-FileFinder. This will recursively search given shares for sensitive files:

  • PS C:> Invoke-FileFinder -ShareList .\found_shares.txt -OutFile found_files.csv

This will take the share input list from sharefinder and recursively list each share, filtering for files with ‘*pass*’, ‘*sensitive*’, ‘*admin*’, ‘*secret*’, ‘*login*’, ‘*unattend*.xml’, ‘*.vmdk’, ‘*creds*’, or ‘*credential*’ in the file name. Anything found is then output to a CSV with the full path, owner, last access time, last write time, and length. If I want/need to search for other terms, I’ll use something like this:

  • PS C:> Invoke-FileFinder -ShareList .\found_shares.txt -OutFile found_files.csv -Terms payroll,CEO,…

This will replace the default terms with the wildcarded terms specified. If you want to run Invoke-FileFinder without enumerating shares ahead of time, the following function will query AD for active machines like the rest of PowerView’s Invoke-* cmdlets. It will then enumerate all shares it finds, excluding C$ and ADMIN$ by default (these can be included with the -IncludeC and -IncludeAdmin flags). I still advise running Invoke-ShareFinder first and pruning your results a bit for speed reasons, but kicking off the following command will find everything sensitive it can in the network:

  • PS C:> Invoke-FileFinder -OutFile all_files.csv -Verbose

There are several more flags available, including filters for office documents, last creation/write/access times, etc. Check out Invoke-FileFinder’s function documentation if you’re interested in more of the options:


Happy hunting :)

Veil-PowerView v1.4

Veil-PowerView has gone through another large set of modifications, resulting in its versioning to 1.4. Here are the changes in no particular order:

  • Get-UserProperties was built, stealing directly from @obscuresec‘s great post on the topic located here. Related, Invoke-UserDescSearch was expanded and changed to Invoke-UserFieldSearch, which now allows you to specify the user field to search for wildcard terms. We’ll have a post up soon on using these methods together.
  • Get-NetGroupUsers was combined into Get-NetGroup for standardization.
  • The -Debug flag for meta-functions now replaces the old -Verbose functionality, with the -Verbose flag now outputting a status for when several machines are processed.
  • Invoke-Sharefinder had serveral additional exclusion options added and its output changed to just spit out raw share paths.
  • Set-MacAttribute was added in from Powersploit- see @obscuresec‘s post on the topic on his blogInvoke-CopyFile automatically invokes this when replacing files in order to match a target’s MAC properties.
  • Invoke-SearchFiles was added, which recursively searches a local or remote network path for files with various specifications. Terms can be specific, MAC attributes filtered one, and more – check out the source for complete flags and options.
  • Invoke-FileFinder was added, which utilizes Invoke-SearchFiles to crawl the network for target data. Lots of flags here too.
  • Several methods were added that attempt to enumerate local machine information: Get-NetLocalGroups to get local groups on a target, Get-NetLocalGroup to get members of a local group, and Get-NetLocalServices to enumerate local services.
  • Invoke-HostEnum was added, which will run all available host enumerate functions on a single target (note: this potentially produces a good chunk of data, just for a single host).
  • A lingering bug was finally fixed that would crash execution of some of the meta-functions when executed against large numbers of machines, usually in the 2000-4000 range. Have to be careful of those access violations when playing with raw memory and API access :)

Thanks again to @obscuresec for posting some great Powershell information that I shameless stole and integrated into PowerView – all credit to Chris for coming up with those ideas. We’re also going to have a few PowerView posts coming up in the next few weeks, including a usage guide, information on abusing user description fields, and an exe trojanation guide. Oh, and the Veil-Framework was recently accepted to Blackhat Arsenal– come stop by to talk about all the tools in the framework, including a new post-exploitation tool being released at Defcon.


Veil-PowerView v1.3

Veil-PowerView has had even more recent changes, culminating in the release of version 1.3:

  • The optional “-CheckShareAccess” flag that can be passed to Invoke-Netview and Invoke-ShareFinder should now accurately record shares that you currently have access to.
  • Get-NetGroups and Get-NetGroupUsers now accept wildcards for the -GroupName passed.
  • Get-NetServers was combined into Get-NetComputers, which now accepts wildcards for the -HostName, -OperatingSystem, and -ServicePack to query AD for.
  • Invoke-FindVulnSystems was implemented, which uses Get-NetComputers to query AD for machines that are likely vulnerable to MS08-067.

There’s also been a major rewrite in how PowerView invokes various Windows API methods (such as NetShareEnum). The standard approach most resources recommend for .dll access is through using the Add-Type method and a member definition to expose specific methods, documented here. You might ask, if this works, why change anything? Two main reasons- first, while this method actually compiles C# code on the fly in memory, some temporary files actually touch disk. As an attacker, refraining from any/all disk access when possible is a good philosophy to maintain. And second, since some code has to be JIT compiled, this method will actually fail in some environments, where some csc.exe/.NET wonkiness can mess stuff up.

Luckily, @mattifestation wrote an excellent post on an alternative method to access the Windows native API. His post can explain it better than I can, but a tldr; is that you can use some native .NET functionality to resolve the address of any method in a loaded .dll. You can then build a custom delegate that models the method you’re intending to call and invoke whatever functionality you need. Graeber also has an article on building structs and enums without having to invoke the csc compilation method as well. All .dll imports and structs in PowerView were rewritten using these methods, leaving disk pristine and expanding the environments you can run PowerView in.

Happy (user) hunting :)

Veil-PowerView v1.1

Veil-PowerView has gotten a few changes over the past week or so. As mentioned previously, right after its release, Carlos Perez and the PowerSploit guys, @obscuresec and @mattifestation, gave some great feedback on how to make PowerView standards compliant. At the short March 2014 NovaHackers presentation given on PowerView, Rob Fuller (@mubix) gave some more great feedback on tweaks and features to add. Veil-Powerview v1.1 is the implementation of those suggestions, and integrates the following changes:

  • The verbs for all “Net-*” functions have been changed to “Get-Net*” and “Invoke-Net*” as appropriate.
  • The verbs for the meta functions have all been changed to “Invoke-*” (i.e. Invoke-Netview).
  • The method Invoke-UserDescSearch has been added, and will pull all AD user data and search account descriptions for particular keywords, defaulting to “password”.
  • Invoke-Netview and Invoke-ShareFinder now both have a “-CheckShareAccess” flag that will only display found shares that the local user has access to (through the use of the Check-Path cmdlet).
  • Invoke-ShareFinder now includes all shares by default, with an “-ExcludeShares” flags to exclude common shares.
  • Use of ‘return’ has been greatly reduced.
  • adsi is implemented in more places instead of straight API calls – for example, Get-NetServers now uses an adsisearcher instead of API calls to get ALL server host names from Active Directory.
  • Write-Host and Write-Output have been eliminated, with functions now returning pure objects.

I’m sure a few things were missed, so let us know as problems or suggestions arise. Also, the functions Get-NetConnections and Get-NetFiles were implemented to enumerate the connections and open files on servers with more granularity. Unfortunately, these calls need a user to be local admin on a target server, but they still have their specific uses. For anyone wanting to get going on writing powershell, I highly recommend checking out Carlos’ style guide, some of his examples, as well as the awesome examples from the PowerSploit project.

Hunting for Domain Users With the Veil-Framework

Time for a followup on the remaining functionality of Veil-PowerView. Today I’ll cover the two most interesting features released, Invoke-UserHunter and Invoke-StealthUserHunter.

As detailed previously, Veil-PowerView started as a pure powershell replacement for various net domain enumeration commands used to gain situational awareness on a Windows network. It expanded into some metafunctions such as Invoke-Netview (a port of Rob Fuller’s netview.exe), Invoke-ShareFinder to find interesting network shares, and Invoke-FindLocalAdminAccess (a port of local_admin_search_enum.rb). These functions are interesting and useful, but we soon realized that we could do a few more really interesting tricks utilizing all this existing powershell AD functionality and Windows API calls.

Invoke-UserHunter chains together particular aspects of Invoke-Netview to find where specific users are logged in on the current network. It can utilize a delay/jitter between host enumerations and works as follows:

  1. The current user and domain are pulled with Get-NetCurrentUser and Get-NetDomain, respectively
  2. Machines on the domain are queried (and the resulting list shuffled) using Get-NetServers, or by reading in a host list
  3. A specific group is queried for users using Get-NetGroup (which defaults to ‘domain admins’), or a specific username is specified, or a user list is given
  4. For each machine in the target list, Get-NetSessions and Get-NetLoggedon are used to see what users are logged in and/or have current sessions (and from where). The script will sleep for a delay between each host enumeration, if specified
  5. The results are compared against the target user list, and matches are displayed
  6. Found machines can optionally be checked for local admin access with Invoke-CheckLocalAdminAccess

Invoke-StealthUserHunter takes a more subtle, ‘red-teamy’ approach to hunting down user locations. It will issue one group query to build a target user list with Get-NetGroup, and one query to find all users (and detailed user information) in the domain with Get-NetUsers. It will then extract all servers found from user HomeDirectory entries, and run one Get-NetSessions call against each found file server (after the delay/jitter if specified) to get current user sessions on those targets. The results of the sessions calls are compared against the target user list, and matches are highlighted. While not as accurate as Invoke-UserHunter as only the file servers in a domain are touched, Invoke-StealthUserHunter is significantly stealthier as only as a handful of queries are made.

The end result? As a normal domain user, running these functions can tell you exactly where domain administrators (or other target users) are logged into, and  can optionally tell whether you have local admin access to those boxes. One some domains this can help you point -> click -> get DA :)

Quick sidenote- I received some great feedback from Carlos Perez concerning how to make PowerView standards compliant. I’ll be integrating his suggestions over the next week or so, but a side effect is that many of the method names are likely going to change. This post and last weeks will be updated appropriately with the updated usage. Also, I’m going to be helping @obscuresec and @mattifestation get some of PowerView’s functionality into PowerSploit soon, so keep your ears open for updates.


We like to envision the Veil-Framework as extended beyond just generating and delivering AV-evading executables. The theme underlying our development efforts has been one of evasion and stealth, leading us to view the Veil-Framework not as a single program, but as a collection of tools that aim to bridge the gap between pentesting and red-team toolsets. Some of the releases in the coming year will extend beyond just executable generation, and may not integrate into existing codebases the same way Veil-Catapult was able to. However, the theme of evasion will still link together everything in spirit, if not in code.

With that said, I’d like to announce the most recent addition to the Veil-Framework, Veil-PowerView, a pure powershell tool for network situational awareness.  First off, thanks to @davidpmcguire for inspiration, @mubix for building netview.exe and open sourcing it, the offensive powershell community (@obscuresec@mattifestation, and DarkOperator) for showing how proper powershell is done, and @zeknox, @smilingraccoon, and r3dy for the local_admin_search_enum idea in Metasploit.

We recently were on an pentest where a client had implanted an interesting defense- the disabling of all “net *” commands on domain machines. At first, this might appear like a novel attack mitigation, as it initially thew a wrench in some of our normal post-exploitation activities. During our post assessment breakdown however, we started brain storming way around this particular defense in case we encountered it again. Bypassing it completely ended up being trivial through the use of powershell.

This assessment started the development of Veil-PowerView, released today. By taking advantage of native powershell AD hooks and the ability to invoke Win32 API functionality, a complete, pure powershell replacement for the common “net *” commands we typical use was implemented. These include common things like Get-NetGroup for listing detailed information about specific domain groups, Get-NetShare to get share information for a specific host, Get-NetUser to get information for a specific domain user, and so on. There are also the slightly more non-traditional functions of Invoke-CheckLocalAdminAccess to see if the current user has local admin access on a target host, Get-NetGroupUsers to get complete, detailed information on all users in a particular group (not just usernames), Get-NetLoggedon to get users currently logged onto a machine, and so on.

Inspired by Rob Fuller (@mubix)’s netview.exe tool, more interesting metafunctions were then built, chaining together the previously implemented net functionality. The first endeavor was a full powershell implementation of netview.exe, Invoke-Netview, with a few tweaks added in. Very similar to the original netview.exe, here’s how the core functionality works:

  1. Get-NetDomain is run to query the principal domain
  2. Get-NetServers is run to pull a complete list of all active machines on the domain, which is then randomized (Get-NetServers utilizes a Win32-api implementation of NetServerEnum to query for active machines of server type 2). A host list can optionally be specified with “-HostList HOSTS.txt”
  3. Get-NetServers is run three additional times, querying for three specific server types- domain controllers, backup domain controllers, and SQL servers (i.e. Get-NetServers -ServerType 8)
  4. For each machine found in the domain, Get-NetSessions is run each host to query the current sessions on the machine (Get-NetSessions utilizes a Win32-api implementation of NetSessionEnum)
  5. Get-NetLoggedon is then run against each server to get the users currently logged onto the machine (Get-NetLoggedon utilizes a Win32-api implementation of NetWkstaUserEnum).
  6. Get-NetShare is then run against each host to numerate all available shares on the machine (Get-NetShare utilizes a Win32-api implementation of NetShareEnum)
  7. Nicely formatted output is displayed for each host as appropriate

Invoke-Netview has a few additional options missing from the original netview.exe implementation. “-ExcludeShares” will exclude common fileshares (C$, IPC$, PRINT$, etc.) from the results. “-Delay X” introduces a delay of X seconds between each host enumeration, and “-Jitter .X” adds a +/- .X percent jitter to the delay interval to randomize behavior.

Invoke-ShareFinder utilizes similar functionality to Invoke-Netview. It runs Get-NetServers to get all domain machines (or accepts an optional host list as well), randomizes the list, and then runs Get-NetShare to get all active shares on each target machine. Common shares are filtered out by default, giving you a nice list of interesting shares to investigate. The delay/jitter specification is also available.

Invoke-FindLocalAdminAccess is a powershell port of the metasploit local_admin_search_enum.rb module written by zeknox, smilingraccoon, and r3dy. It does the same Get-NetServers/hostlist/shuffle stuff, and then runs Invoke-CheckLocalAdminAccess against each host, which utilizes the Win32-api call OpenSCManagerW with full permissions to see if the local user current has local admin access on target machines. Again, the delay/jitter specification is also available in case you don’t want to try to connect to the service manage of every machine in domain as quickly as possible.

All functions should hopefully be documented and attributed appropriately. I put links and references for every source I drew from, and did my best to cite all prior art. If I accidentally put in functionality already implemented previously by the badass offensive powershell community, please please please let me know so I can put proper attribution in.

That should hopefully be enough for initial digestion- a post will be pushed in a couple of days detailing the most interesting functionality published, Invoke-UserHunter and Invoke-StealthUserHunter. That’s where the real fun with Veil-PowerView begins ;)