Sometimes during an Information Security Assessment I find myself spending a fair amount of effort locating a server or workstation with a specific user logged into it. This could be because I am searching for a box with a Domain Admin, or maybe my engagement’s scope has a CTF style scope that requires me to find a single user logged into a large enterprise domain.
Whatever the reason, this processes can sometimes take a long time. Especially on a sizable network. Like most security auditors I’m not a big fan of doing the same thing over and over again so I decided to build a tool to help automate this process.
First we query HKEY_USERS to find out how many legitimate SIDs are currently logged in. We should see an output simalr to this.
C:Usersserveradmin>reg.exe query HKU
HKEY_USERS.DEFAULT
HKEY_USERSS-1-5-19
HKEY_USERSS-1-5-20
HKEY_USERSS-1-5-21-3064359591-4294004252-2834161185-1104
HKEY_USERSS-1-5-21-3064359591-4294004252-2834161185-1104_Classes
HKEY_USERSS-1-5-21-3064359591-4294004252-2834161185-500
HKEY_USERSS-1-5-21-3064359591-4294004252-2834161185-500_Classes
HKEY_USERSS-1-5-18
C:Usersserveradmin>
If we sift through this output we can see that there are only two valid SIDs. UserID ‘1104’ and ‘500’. To figureout what the proper username for a particluar sid you simply need to query the ‘Volatile Environment’ key like this.
C:Usersserveradmin>reg.exe query "HKUS-1-5-21-3064359591-4294004252-2834161185-1104Volatile Environment"
HKEY_USERSS-1-5-21-3064359591-4294004252-2834161185-1104Volatile Environment
LOGONSERVER REG_SZ \GOKU
USERDNSDOMAIN REG_SZ DBZ-VULN.NET
USERDOMAIN REG_SZ DBZ-VULN
USERNAME REG_SZ serveradmin
USERPROFILE REG_SZ C:Usersserveradmin
HOMEPATH REG_SZ Usersserveradmin
HOMEDRIVE REG_SZ C:
APPDATA REG_SZ C:UsersserveradminAppDataRoaming
LOCALAPPDATA REG_SZ C:UsersserveradminAppDataLocal
HKEY_USERSS-1-5-21-3064359591-4294004252-2834161185-1104Volatile Environment1
C:Usersserveradmin>
As you can see this registry key has all the information we care about. We can throw this into an auxiliary module and make use of some existing Metasploit code to execute these commands from an authenticated admin user without having to upload any binaries to the target. With the power of Ruby threads we can cover a large network in a fraction of the time that it would take to do this one system at a time.
The module can be run one of two ways. Either specify an individual user such as ‘DOMAIN\Administrator’ and it will locate which system that user is logged into. Or run it without specifying the datastore[‘USERNAME’] variable and it will simply tell you the names of all users logged into all systems specified with datastore[‘RHOSTS’].
Download Module: Source
Share this article
Why not command “query session”?
Genius!
Hmmm, Although I like that command it’s quick and easy. It doesn’t seem to differentiate between local and domain user accounts.
I suppose, when you pentesting infrastructure, you have a general idea about network. Сertainly, domain account is important information, but
it’s necessary.
* it’s not necessary
Doesn’t appear to be working… ran against the server network with username left blank.
[+] (sesnsored) –
[+] (sesnsored) –
[+] (sesnsored) –
[+] (sesnsored) –
[+] (sesnsored) –
[+] (sesnsored) –
[+] (sesnsored) –
[*] Executing cleanup on host: (sesnsored)
[+] (sesnsored) –
[*] Executing cleanup on host: (sesnsored)
[+] (sesnsored) –
[*] Executing cleanup on host: (sesnsored)
[*] Scanned 163 of 256 hosts (063% complete)
[-] (sesnsored) – Login Failed: The server responded with error: STATUS_LOGON_FAILURE (Command=115 WordCount=0)
[-] (sesnsored) – Login Failed: The server responded with error: STATUS_LOGON_FAILURE (Command=115 WordCount=0)
[+] (sesnsored) –
[*] Executing cleanup on host: (sesnsored)
[*] Executing cleanup on host: (sesnsored)
[+] (sesnsored) –
[*] Executing cleanup on host: (sesnsored)
[+] (sesnsored) –
[*] Scanned 187 of 256 hosts (073% complete)
[+] (sesnsored) –
[*] Executing cleanup on host: (sesnsored)
[*] Scanned 206 of 256 hosts (080% complete)
[*] Scanned 232 of 256 hosts (090% complete)
[*] Scanned 256 of 256 hosts (100% complete)
[*] Auxiliary module execution completed
Module options (auxiliary/scanner/smb/loggedin_users):
Name Current Setting Required Description
—- ————— ——– ———–
RHOSTS (sesnsored) yes The target address range or CIDR identifier
RPORT 445 yes The Target port
SMBDomain WORKGROUP no The Windows domain to use for authentication
SMBPass (sesnsored) no The password for the specified username
SMBSHARE C$ yes The name of a writeable share on the server
SMBUser (sesnsored) no The username to authenticate as
THREADS 30 yes The number of concurrent threads
USERNAME no The name of a specific user to search for
I believe I have fixed or at least improved on this issue. Please retest if you have a chance and let me know.
Also, if I may add, it would be nice if there was a summary at the end of the scan, instead of having to filter through the output and find the specific instances where the module stated that “user logged into X.X.X.X”. It could do both in terms of output (list the individual instances where the user is logged in, as well as “Executing cleanup on host: X.X.X.X” and other errors), but at the end of the scan, it would state “User ______ is logged into the following hosts:”. Just a thought. An FYI, in addition, I found an instance where it reported the error specified previously (HKU NoMethodError) on a host where I confirmed the account I was searching for (domain admin) was currently logged in, so just a bug report. Again, fantastic module, and much appreciated.
Renton, as far as you can tell do the hosts who return errors all share the same OS. Also do the errors return from the same hosts consistently after multiple attempts to run the module?
Would you be willing to post a screenshot of the output as well as a show options? Just blank out the ‘smbpass’ option as I trust you entered that right :)
Well, to be honest, I don’t feel comfortable with the screenshots, but the options are set as follows:
RHOSTS: X.X.X.X/24
RPORT: 445
SMBDomain: YYYY
SMBPass: ZZZZZZZZZZZZZZZZ
SMBSHARE: C$
SMBUser: administrator
THREADS: 10
USERNAME: YYYYadministrator
Note that the YYYY domain is set properly, and the ZZZZZZZZZZZZZZZZ password is set properly as well. When run against the subnet, the module informed me that 5 different hosts did have the domain admin logged in, but I also got the discussed error from time to time on various hosts. Here is some sample module output that includes that error:
{*] Executing cleanup on host: X.X.X.X
[*] Executing cleanup on host: X.X.X.X
[*] Executing cleanup on host: X.X.X.X
[-] X.X.X.X – Error getting command output. Rex::Proto::SMB::Exceptions::ErrorCode. The server responded with error: STATUS_OBJECT_NAME_NOT_FOUND (Command=45 WordCount=0).
[-] X.X.X.X – Error runigy query against HKU. NoMethodError. undefined method `each_line’ for nil:NilClass
[-] X.X.X.X – There was an error undefined method `each’ for #
[*] Executing cleanup on host: X.X.X.X
[+] YYYYadministrator logged into X.X.X.X
And this goes on. Scanning the subnet, this module shows that 5 hosts have YYYYadministrator logged in at that time, so the module does work, but seemingly at random, some show that error output above. One of them is a server where I am currently authenticated as domain admin, so I know there is an active domain admin user session. I tried changing the RHOSTS option to just the IPv4 address of that server, and when I executed the module again, I saw a series of cmd.exe boxes open and close quickly on that machine; this time, however, the module output did not specify the error above, it simply reported:
[*] Executing cleanup on host: X.X.X.X
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
Therefore indicating there was no a currently open domain admin session on that machine, which I know not to be the case. Again, there are no firewalls running internally, the domain, username, and password options are all set properly (as evidenced by the fact that it found 5 different hosts within the subnet that had an active domain admin user session). All in all, when scanning the /24 CIDR block, I received that error on 12 hosts, at least one of which I have definitively confirmed there is an active domain admin user session running.
Anyway, I hope this helps. Sorry I can’t provide any further information. And again, great module. Very useful.
Thank you for the module, very helpful. Just wanted to make you aware, I ran this against our internal domain, and I got multiple instances of this error (internal IPv4 addresses have been replaced with X.X.X.X for privacy reasons):
[-] X.X.X.X – Error getting command output. Rex::Proto::SMB::Exceptions::ErrorCode. The server responded with error: STATUS_OBJECT_NAME_NOT_FOUND (Command=45 WordCount=0).
[-] X.X.X.X – Error runigy query against HKU. NoMethodError. undefined method `each_line’ for nil:NilClass
[-] X.X.X.X – There was an error undefined method `each’ for #
I used the standard options, specifying domain admin credentials, and didn’t change the share from the default C$ or the port from the default 445. Firewalls are not in play internally. The module returned that the specified username was logged into a few hosts, but the output was surrounded by random instances of that error, making me not fully trust the results as being complete. Is this a known issue? Thank you in advance for your module, and for any assistance.