Hack The Box - Authority

July 20, 2023

Authority

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:

crackmapexec anonymous logon

spider_plus from crackmapexec listed all the files from the readable share:

spider_plus

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:

download development share

There were a few files that contained credentials. However, the most interesting was /PWM/defaults/main.yml which had encrypted ansible vault credentials:

PWM/defaults/main.yml

ansible-vault requires a vault password for decryption:

ansible-vault password required

I needed to format the encrypted data into a compatible hash for JtR with ansible2john:

ansible2john

Then, JtR was able to crack the hash:

cracked ansible-vault password

With the cracked vault password, I was able to decrypt the ansible vault data in PWM/defaults/main.yml:

pwm_admin_login.yml decrypt

pwm_admin_password.yml decrypt

ldap_admin_password.yml decrypt

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):

pwm login page

None of the creds worked on the initial sign in page, but one worked on the configuration manager login page:

config manager password

The configuration manager panel had an option to import a configuration or download the current one:

config manager

So, I downloaded the configuration:

config xml

The XML contained an encrypted password for the svc_ldap user:

encrypted svc_ldap password

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:

storePlaintextValues

Therefore, I edited the config file to include the following property:

new config

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:

view new config

This allowed me to view the plaintext password of the svc_ldap user:

svc_ldap plaintext password

Attempting to authenticate with crackmapexec verified that the creds were valid:

svc_ldap verify creds

With the valid creds, I used bloodhound-python to collect AD data:

bloodhound-python

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:

bloodhound PSRemote

evil-winrm established a connection as the svc_ldap user:

evil-winrm user flag

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 find

certipy found that the CorpVPN template had an ESC1 vulnerability:

vulnerable template

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:

addcomputer

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:

req cert

When I tried to authenticate with the certificate, I received a Kerberos session error:

auth KDC error

This was most likely occurring due to an issue with smart card logon.

As stated in the Microsoft Docs:

Microsoft Docs KDC_ERR_PADATA_TYPE_NOSUPP

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:

extract key and cert

Then, I was able to use the cert and key to run the whoami action to verify that the certificate was for the administrator:

whoami

I spawned an LDAP shell and added svc_ldap to the Domain Admins group:

ldap-shell

crackmapexec confirmed that the svc_ldap user now had administrative access:

verify svc_ldap is domain admin

Finally, I used psexec.py from Impacket to login as svc_ldap and obtain a shell as nt authority\system:

system shell


CTF Writeups | InfoSec Topics

Written by Mike Garrity

Email RSS