[Edit 8/13/15] – Here is how the old version 1.9 cmdlets in this post translate to PowerView 2.0:
- Get-NetGroups -> Get-NetGroup
- Get-UserProperties -> Get-UserProperty
- Invoke-UserFieldSearch -> Find-UserField
- Get-NetSessions -> Get-NetSession
- Invoke-StealthUserHunter -> Invoke-UserHunter -Stealth
- Invoke-UserProcessHunter -> Invoke-ProcessHunter -Username X
- Get-NetProcesses -> Get-NetProcess
- Get-UserLogonEvents -> Get-UserEvent
- Invoke-UserEventHunter -> Invoke-EventHunter
[Note] This post is a companion to the Shmoocon ’15 Firetalks presentation I gave, also appropriately titled “I Hunt Sys Admins”. The slides are here and the video is up on Irongeek. Big thanks to Adrian, @grecs and all the other organizers, volunteers, and sponsors for putting on a cool event!
[Edit] I gave an expanded version of my Shmoocon talk at BSides Austin 2015, the slides are up here.
One of the most common problems we encounter on engagements is tracking down where specific users have logged in on a network. If you’re in the lateral spread phase of your assessment, this often means gaining some kind of desktop/local admin access and performing the Hunt -> pop box -> Mimikatz -> profit pattern. Other times you may have domain admin access, and want to demonstrate impact by doing something like owning the CEO’s desktop or email. Knowing what users log in to what boxes from where can also give you a better understanding of a network layout and implicit trust relationships.
This post will cover various ways to hunt for target users on a Windows network. I’m taking the “assume compromise” perspective, meaning that I’m assuming you already have a foothold on a Windows domain machine. I’ll cover the existing prior art and tradecraft (that I know of) and then will show some of the efforts I’ve implemented with PowerView. I really like the concept of “Offense in Depth“- in short, it’s always good to have multiple options in case you hit a snag at some step in your attack chain. PowerShell is great, but you always need to have backups in case something goes wrong.
Existing Tools and Tradecraft
The Sysinternals tool psloggedon.exe has been around for several years. It “…determines who is logged on by scanning the keys under the HKEY_USERS key” as well as using the NetSessionEnum API call. Admins (and hackers) have used this official Microsoft tool for years. One note: some of its functionality requires admin privileges on the remote machine you’re enumerating.
Another “old school” tool we’ve used in the past is netsess.exe, a part of the joeware utilities. It also takes advantage of the NetSessionEnum call, and doesn’t need administrative privileges on a remote host. Think of a “net session” that works on remote machines.
PVEFindADUser.exe is a tool released by the awesome @corelanc0d3r in 2009. Corelanc0d3r talks about the project here. It can help you find AD users, including enumerating the last logged in user for a particular system. However, you do need to have admin access on machines you’re running it against.
Rob Fuller (@mubix’s) netview.exe project is a tool we’ve used heavily since it’s release at Derbycon 2012. It’s a tool to “enumerate systems using WinAPI calls”. It utilizes NetSessionEnum to find sessions, NetShareEnum to find shares, and NetWkstaUserEnum to find logged on users. It can now also check share access, highlight high value users, and use a delay/jitter. You don’t need administrative privileges to get most of this information from a remote machine.
Nmap‘s flexible scripting engine also gives us some options. If you have a valid domain account, or local account valid for several machines, you can use smb-enum-sessions.nse to get remote session information from a remote box. And you don’t need admin privileges!
If you have access to a user’s internal email, you can also glean some interesting information from internal email headers. Search for any chains to/from target users, and check any headers for given email chains. The “X-Originating-IP” header is often present, and can let you trace where a user sent a given email from.
Scott Sutherland (@_nullbind) wrote a post in 2012 highlighting a few other ways to hunt for domain admin processes. Check out techniques 3 and 4, where he details other ways to scan remote machines for specific process owners, as well as how to scan for NetBIOS information of interest using nbtscan. For remote tasklistings, you’ll need local administrator permissions on the targets you’re going after. We’ll return to this in the PowerShell section.
And finally, Smbexec has a checkda module which will check systems for domain admin processes and/or logins. Veil-Pillage takes this a step further with its user_hunter and group_hunter modules, which can give you flexibility beyond just domain admins. For both Smbexec and Veil-Pillage, you will need admin rights on the remote hosts.
Active Directory: It’s a Feature!
Active Directory is an awesome source of information from both offensive and defensive perspectives. One of the biggest turning points in the evolution of my tradecraft was when I began to learn just how much information AD can give up.
Various user fields in Active Directory can give you some great starting points to track down users. The homeDirectory property, which contains the path to a user’s auto-mounted home drive, can give you a good number of file servers. The profilePath property, which contains a user’s roaming profile, can also sometimes give you a few servers to check out as well. Try running something like netsess.exe or netview.exe against these remote servers. They key here is that you’re using AD information to identify servers that several users are likely connected to. And the best part is, you don’t need any elevated privileges to query this type of user information!
Also, Scott wrote another cool post early in 2014 on using service principal names to find locations where domain admin accounts might be. In short, you can use Scott’s Get-SPN PowerShell script to enumerate all servers where domain admins are registered to run services. I highly recommend checking it out for some more information. This is also something that the prolific Carlos Perez talked about at at Derbycon 2014.
Once you get domain admin, but still want to track down particular users, Windows event logs can be a great place to check as well. One of my colleagues (@sixdub) write a great post on offensive event parsing for the purposes of user hunting. We’ll return to this as well shortly.
PowerShell PowerShell PowerShell
Anyone who’s read this blog or seen me speak knows that I won’t shut up about PowerShell, Microsoft’s handy post-exploitation language. PowerShell has some awesome AD hooks and various ways to access the lower-level Windows API. @mattifestation has written about several ways to interact with the Windows API through PowerShell here, here, and here. His most recent release with PSReflect makes it super easy to play with this lower-level access. This is something I’ve written about before.
PowerView is a PowerShell situational-awareness tool I’ve been working on for a while that includes a few functions that help you hunt for users. To find users to target, Get-NetGroups *wildcard* will return groups containing specific wildcard terms. Also, Get-UserProperties will extract all user property fields, and Invoke-UserFieldSearch will search particular user fields for wildcard terms. This can sometimes help you narrow down users to hunt for. For example, we’ve used these functions to find the Linux administrators group and its associated members, so we could then hunt them down and keylog their PuTTY/SSH sessions :)
The Invoke-UserHunter function can help you hunt for specific users on the domain. It accepts a username, userlist, or domain group, and accepts a host list or queries the domain for available hosts. It then runs Get-NetSessions and Get-NetLoggedon against every server (using those NetSessionEnum and NetWkstaUserEnum API functions) and compares the results against the resulting target user set. Everything is flexible, letting you define who to hunt for where. Again, admin privileges are not needed.
Invoke-StealthUserHunter can get you good coverage with less traffic. It issues one query to get all users in the domain, extracts all servers from user.HomeDirectories, and runs a Get-NetSessions against each resulting server. As you aren’t touching every single machine like with Invoke-UserHunter, this traffic will be more “stealthy”, but your machine coverage won’t be as complete. We like to use Invoke-StealthUserHunter as a default, falling back to its more noisy brother if we can’t find what we need.
A recently added PowerView function is Invoke-UserProcessHunter. It utilizes the newly christened Get-NetProcesses cmdlet to enumerate the process/tasklists of remote machines, searching for target users. You will need admin access to the machines you’re enumerating.
The last user hunting function in PowerView is the weaponized version of @sixdub‘s post described above. The Get-UserLogonEvents cmdlet will query a remote host for logon events (ID 4624). Invoke-UserEventHunter wraps this up into a method that queries all available domain controllers for logon events linked to a particular user. You will need domain admin access in order to query these events from a DC.
If I missed any tools or approaches, please let me know!