Authority is a Windows machine running Active Directory that has an open SMB share containing ansible vault encrypted credentials. Once decrypted, one of the credentials can be used to login to the configuration manager for PWM (a password self-service for LDAP directories). This grants access to a configuration XML file that can be modified to reveal the plaintext password for a service account on the system. The obtained credentials can be used to make a WinRM connection to the machine. During enumeration of the AD environment, a vulnerable certificate template (ESC1) is discovered that gives machines in the Domain Computers group the right to request a certificate as any user in the domain, this can be leveraged to authenticate to the LDAPS server and perform actions on the system as the administrator
, resulting in a system shell (nt authority/system
).
nmap
scan:
┌──(kali㉿kali)-[~/Desktop/HTB/Authority]
└─$ nmap -sC -sV 10.10.11.222
Starting Nmap 7.94 ( https://nmap.org ) at 2023-07-20 12:43 EDT
Nmap scan report for authority.htb (10.10.11.222)
Host is up (0.041s latency).
Not shown: 987 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
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2023-07-20 20:43:10Z)
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: authority.htb, Site: Default-First-Site-Name)
<...snip...>
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: authority.htb, Site: Default-First-Site-Name)
<...snip...>
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: authority.htb, Site: Default-First-Site-Name)
3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: authority.htb, Site: Default-First-Site-Name)
8443/tcp open ssl/https-alt
<...snip...>
Service Info: Host: AUTHORITY; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and required
|_clock-skew: mean: 3h59m59s, deviation: 0s, median: 3h59m59s
| smb2-time:
| date: 2023-07-20T20:43:52
|_ 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 58.51 seconds
Most notable open ports:
- 53 (DNS)
- 80 (HTTP)
- 88 (Kerberos)
- 445 (SMB)
- 389, 3268 (LDAP)
- 636, 3269 (LDAPS)
- 8443 (HTTPS)
Active Directory:
- domain name: authority.htb
- hostname: AUTHORITY
First, I visited the webpage on port 80 which was just a default page for a Microsoft IIS server and it didn't seem to have anything useful.
I proceeded with the typical Windows machine enumeration and checked if the open SMB port accepted anonymous logon and it did. The Development share had read permission:
spider_plus
from crackmapexec
listed all the files from the readable share:
The generated JSON file from spider_plus
:
{
"Development": {
<...snip...>
"Automation/Ansible/ADCS/defaults/main.yml": {
"atime_epoch": "2023-04-23 18:50:28",
"ctime_epoch": "2023-03-17 09:20:48",
"mtime_epoch": "2023-04-23 18:50:28",
"size": "1.54 KB"
},
<...snip...>
"Automation/Ansible/LDAP/defaults/main.yml": {
"atime_epoch": "2023-03-17 09:20:48",
"ctime_epoch": "2023-03-17 09:20:48",
"mtime_epoch": "2023-04-23 18:51:08",
"size": "1.02 KB"
},
<...snip...>
"Automation/Ansible/PWM/defaults/main.yml": {
"atime_epoch": "2023-04-23 18:51:38",
"ctime_epoch": "2023-03-17 09:20:48",
"mtime_epoch": "2023-04-23 18:51:38",
"size": "1.55 KB"
},
<...snip...>
"Automation/Ansible/SHARE/tasks/main.yml": {
"atime_epoch": "2023-03-17 09:20:48",
"ctime_epoch": "2023-03-17 09:20:48",
"mtime_epoch": "2023-03-17 09:37:52",
"size": "1.83 KB"
}
}
}
The Development share contained some interesting directories, so I downloaded it:
There were a few files that contained credentials. However, the most interesting was /PWM/defaults/main.yml
which had encrypted ansible vault credentials:
ansible-vault
requires a vault password for decryption:
I needed to format the encrypted data into a compatible hash for JtR
with ansible2john
:
Then, JtR
was able to crack the hash:
With the cracked vault password, I was able to decrypt the ansible vault data in PWM/defaults/main.yml
:
While looking for a place where these credentials could be used, I checked the webpage running on port 8443
which was a password manager application (PWM):
None of the creds worked on the initial sign in page, but one worked on the configuration manager login page:
The configuration manager panel had an option to import a configuration or download the current one:
So, I downloaded the configuration:
The XML contained an encrypted password for the svc_ldap
user:
At the top of the XML file, there's a comment that mentions how to store values unencrypted by setting the storePlaintextValues property to true:
Therefore, I edited the config file to include the following property:
I imported the modified config which signed out of the current session and restarted the application. After logging back in, I downloaded the new config to confirm that the new property was added:
This allowed me to view the plaintext password of the svc_ldap
user:
Attempting to authenticate with crackmapexec
verified that the creds were valid:
With the valid creds, I used bloodhound-python
to collect AD data:
After importing the data into bloodhound
, I found that svc_ldap
could PSRemote into the DC, this was a strong indication that I could make a WinRM connection to the machine:
evil-winrm
established a connection as the svc_ldap
user:
As part of the process of enumerating AD for potential vectors to escalate privileges, I ran Certipy to look for any vulnerable certificate templates:
certipy
found that the CorpVPN template had an ESC1 vulnerability:
The template above is vulnerable due to the following configurations:
-
Client Authentication
:True
- an issued certificate can be used for client authentication purposes. -
Enrollee Supplies Subject
:True
- a Subject Alternative Name can be specified which allows a certificate to be requested as another user on the system (e.g.,administrator
). -
Requires Manager Approval
:False
- a requested certificate doesn't require approval from a user with certificate manager permissions. -
Authorized Signatures Required
:0
- no authorized signatures are required to sign the CSR for the CA to accept it. -
Enrollment Rights
:AUTHORITY.HTB\Domain Computers
- this gives low-level users the ability to request a certificate by simply joining a computer to the domain.
So, first I used Impacket to join a computer to the domain:
Then, I requested a certificate with certipy
as the newly created machine account. I specified the certificate authority, dns name, CorpVPN template, and supplied the user principal name of administrator@authority.htb
:
When I tried to authenticate with the certificate, I received a Kerberos session error:
This was most likely occurring due to an issue with smart card logon.
As stated in the Microsoft Docs:
There's a useful tool that accounts for a situation like this by providing a way to authenticate against an LDAP server with SChannel: PassTheCert
To use passthecert.py
, I extracted the cert and key from the pfx with certipy
:
Then, I was able to use the cert and key to run the whoami
action to verify that the certificate was for the administrator
:
I spawned an LDAP shell and added svc_ldap
to the Domain Admins group:
crackmapexec
confirmed that the svc_ldap
user now had administrative access:
Finally, I used psexec.py
from Impacket to login as svc_ldap
and obtain a shell as nt authority\system
: