Ghost
Recon
└─$ grep ghost /etc/hosts
10.10.11.24 ghost.htb core.ghost.htb DC01.ghost.htb federation.ghost.htbDNS (53)
SMB (Enumeration)
Looks like we will need credentials to get something out of SMB.
HTTP (8008)
Port 80 enumeration was unsuccessful, so moved on to next http server.
Ghost CMS
Ghost CMS version 5.78 is running on nginx 1.18.0:


On unsuccessful login or Forgot Password action request is made to API:

Ghost Content API
Going back to Homepage, I thought Search was useless, but inspecting the request we see it's making a request to backend. request looks like raw SQL:

Endpoint list can be found in docs itself: https://ghost.org/docs/content-api/?ref=docslab.electronthemes-ghost.com#endpoints
This key doesn't have any permissions on admin API, endpoints: https://ghost.org/docs/admin-api/#endpoints
Gitea (Enumeration)
CMS seemed secure enough to fight off any plain attacks as mentioned on their page: https://ghost.org/docs/security/ and nothing really was working. Port 8443 was serving Ghost Core at core.ghost.htb which later redirects to federation.ghost.htb. Application is quite vast, so there could be more subdomains. Testing subdomains on 8008 port:
Application only allows internal logins, no registration. 2 users and no repositories (or no permissions to view as anonymous). Gitea version doesn't seem vulnerable to any CVEs.

Hmm... nothing was making sense about the application..
Intranet
app on intranet subdomain uses LDAP

Try payloads from swisskyrepo/PayloadsAllTheThings/LDAP Injection > payloads
Using payload *:* we are able to get in!

Users:
kathryn.holland
Kathryn Holland
sysadmin
cassandra.shelton
Cassandra Shelton
sysadmin
robert.steeves
Robert Steeves
sysadmin
florence.ramirez
Florence Ramirez
IT
justin.bradley
Justin Bradley
IT, Remote Management Users
arthur.boyd
Arthur Boyd
IT
beth.clark
Beth Clark
HR
charles.gray
Charles Gray
HR
jason.taylor
Jason Taylor
HR
intranet_principal
Intranet Principal
principal
gitea_temp_principal
Gitea_Temp Principal
principal
Another subdomain in Forum:

Brute Passwords via LDAP
Brute the passwords via LDAP injection:
Creds:
kathryn.holland:fgevlfymxrksvu9bCreds:gitea_temp_principal:szrr8kpc3z6onlqf
Note: Not sure why, but sometimes script didn't brute the whole passwords. test if password works, if it doesn't try
password*to verify.
Gitea (gitea_temp_principal)
Login with gitea_temp_principal account and we get few repositories:

Intranet
api-dev seems to be open on intranet subdomain.

http://gitea.ghost.htb:8008/ghost-dev/intranet/src/branch/main/backend/src/main.rs
http://gitea.ghost.htb:8008/ghost-dev/intranet/src/branch/main/backend/src/api/dev/scan.rs
http://gitea.ghost.htb:8008/ghost-dev/intranet/src/branch/main/frontend/src/helpers/fetch.ts
Something tricky is going on with frontend, the API paths are all hardcoded and there's no way to interact with function.
Blog
Public API Key:
a5af628828958c976a3b6cc81a

http://gitea.ghost.htb:8008/ghost-dev/blog/src/branch/main/docker-compose.yml
http://gitea.ghost.htb:8008/ghost-dev/blog/src/branch/main/Dockerfile
Private API Key:
659cdeec9cd6330001baefbf(?)
There's interesting request made via extra parameter in posts-public.js
http://gitea.ghost.htb:8008/ghost-dev/blog/src/branch/main/posts-public.js#L113
First I tried making request to get the important file, but was unlucky.
Testing for LFI with /etc/hosts is a success!
Leak the environment variables:
Find the usage of key:

RCE
The application lives on intranet.ghost.htb, not ghost.htb :/
Looks like we are root in the container.
Reverse Shell (intranet container)
Get a reverse shell:
database.sqlite is just migration tables from gitea.
Run linpeas:
First I focused on env variable usage:
Docker is started with entrypoint script:
SSH file in /root/.ssh/controlmaster is a socket file... (?)
Looks like we are able to ssh into the other box without password?... Interesting
Run linpeas. curl/wget was not available, but python3 is and with built-in one-liner we can download the files.
Nothing eye catching, but we are part of the domain controller and since this is a Windows box we can get the loot for Bloodhound.
Bash doesn't like exe files and bloodhound-python needs user credentials to work, so no enumeration :/
Kerberos Cache
What are the "/tmp/kerb5cc_<user-id>" files exactly?
If you want to use a pre-existing credentials cache on the host from inside a container, you can mount it into the container, and set the KRB5CCNAME environment variable
Using Kerberos authentication with NetExec
I wasn't able to go far with kerberos cache, HackerRecipies > Pass the ticket was not working as user didn't have any privileges.
ADIDNS poisoning
If we go back to forum there's a user who ran some script, but dns was not configured. We can take advantage of that with HackerRecipies > ADIDNS poisoning method.

Crack the hash:
evil-winrm (justin.bradley)
Creds:
justin.bradley:Qwertyuiop1234$$
User.txt
Privilege Escalation (adfs_gmsa$)
Defender is active 💀
Note:
sh.exeisSharpHound.exe
Luckily we can use python version and get "loot" remotely.
Note: Make sure to use
CEbranch version collector, master branch doesn't work with Community Edition Bloodhound.

HackerRecipies > ReadGMSAPasswordNetexec > Dump gMSA
Privilege Escalation (mssqlserver)
Welp... that was useless.

HTTPs (8443)
I decided to take a step back for now. When we go to core.ghost.htb we are asked to login into AD Federation


For now I just logged in as justin:
Creds:
GHOST\justin.bradley:Qwertyuiop1234$$

SAML is a protocol for Single Sign-On (SSO). It lets users log in once and then access multiple services without needing to log in again. SAML passes authentication information between an Identity Provider (IdP) and a Service Provider (SP), so your credentials are verified by the IdP and the service just checks the token. It’s a way to securely manage user authentication across different platforms.
_The SAMLRequest parameter is a compressed and encoded version of the raw XML snippet, utilizing Deflate compression and base64 encoding.
Decode request Onelogin > Base64 Decode + Inflate
Golden SAML Attack
While searching around for SAML and ADFS I came to blog: Exploring the Golden SAML Attack Against ADFS
Attack Tutorial: How the Golden SAML Attack Works
The blog demonstrates authentication into Office365, but we need SAML

GitHub also includes an example: Generate a SAML 2.0 token for some app:
Note: Later I found useful repo: InternalAllTheThings > Active Directory - Federation Services
Data needed:
DKM Key:
dkm.keyTKS Key:
tks.keyDomain:
core.ghost.htbendpoint:
https://core.ghost.htb:8443/adfs/saml/postResponsenameidformat:
urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddressnameid:
Administrator@ghost.htbrpidentifier:
https://core.ghost.htb:8443assertions:
<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"><AttributeValue>Administrator@ghost.htb</AttributeValue></Attribute>
Get Keys:
Get dkm.key from Private Key: (I took second as first)
Get tks.key from Encrypted Token Signing Key:
Get endpoint for SAML:
Now after gathering the requirements we are ready to spoof the account and login.
Using the given "Response" was not working as it Internal Server Error
Going back to the ADFSDump.exe we also got some rules, which indicates that we need upn and CommonName assertions in the spoof command:
Microsoft > The Role of Claims
UPN
The user principal name (UPN) of the user
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn
Common Name
The common name of the user
http://schemas.xmlsoap.org/claims/CommonName
Make the request to endpoint:

Request to view the request in browser:

MSSQL
PayloadsAllTheThings/SQL Injection/MSSQL Injection
The database doesn't allow us to run xp_cmdshell and when we try to enable it we get RequestError: You do not have permission to run the RECONFIGURE statement.
Get permissions:
server
CONNECT SQL
server
VIEW ANY DATABASE
Get tables from available databases:
The tables were mostly empty and not useful. The words The databases are correctly linked. is oddly suspicious. In PayloadsAllTheThings there's a section for MSSQL Trusted Links
0
1089
DC01
SQL Server
SQLOLEDB
DC01
2024-02-02T20:18:34.940Z
0
0
0
0
DC01
True
True
False
False
False
False
True
False
False
False
True
False
False
1
1249
PRIMARY
SQL Server
SQLOLEDB
PRIMARY
2024-07-27T05:33:22.490Z
0
0
0
0
PRIMARY
False
True
False
False
False
False
True
True
False
False
True
False
False
Hmmmm... weird
Anyway, PayloadsAllTheThings also has EXECUTE in EXECUTE AT SERVER query to exploit trusted database links.
Reverse Shell
Due to Defender I wasn't able to use Powershell #3 (Base64) payload from revshells, so I did curl over shell
Privilege Escalation (CORP system)
SeImpersonatePrivilege is interesting token 👀 HackTricks > Abusing Tokens > SeImpersonatePrivilege
I first tried Juicy Potato, already compiled versions can be found here. But Defender still didn't like that and didn't allow the program to execute, also nc.exe was also flagged as malicious and removed...
Then I tried Generic Potato as suggested by Potatoes - Windows Privilege Escalation post, but couldn't make it work as in needed trigger on localhost and stuff...
While searching about how to use Generic Potato I stumbled upon new notebook: Pentester's Promiscuous Notebook. After GenericPotato EfsPotato was listed, which is a single C# potato exploit that supports SeImpersonatePrivilege.
C# is available on system, so we can compile it and run it:
https://github.com/gwillgues/Reverse-Shells is usually not detected by Defender so we can play with it on different session.

Looks like we are on PRIMARY and we want to be on DC01.
Disable Defender so we can enumerate AD with SharpHound, src
...wot...

Trusted Domains
If we look into the domains, we can observe that both domains have TrustedBy relationship.

Gather some info about domain:
ADRecon made few things easier to enumerate.
Trusts.csv:
corp.ghost.htb
ghost.htb
BiDirectional
Uplevel
Within Forest
1/31/2024 6:33:33 PM
7/22/2024 9:21:26 AM
Forest.csv:
Name
ghost.htb
Functional Level
Windows2016Forest
Domain Naming Master
DC01.ghost.htb
Schema Master
DC01.ghost.htb
RootDomain
ghost.htb
Domain Count
2
Site Count
1
Global Catalog Count
2
Domain
ghost.htb
Domain
corp.ghost.htb
Site
Default-First-Site-Name
GlobalCatalog
DC01.ghost.htb
GlobalCatalog
PRIMARY.corp.ghost.htb
Tombstone Lifetime
180
Recycle Bin (2008 R2 onwards)
Disabled
Privileged Access Management (2016 onwards)
Disabled
LAPS
Disabled
Compters.csv:
PRIMARY$
PRIMARY
PRIMARY.corp.ghost.htb
True
10.0.0.10
Windows Server 2022 Datacenter 10.0 (20348)
0
57
False
True
516
S-1-5-21-2034262909-2733679486-179904498-1000
8/13/2024 9:03:25 PM
6/17/2024 9:51:07 AM
532480
1/31/2024 6:34:00 PM
8/13/2024 9:03:25 PM
CN=PRIMARY,OU=Domain Controllers,DC=corp,DC=ghost,DC=htb
Resources:
Golden Ticket
Steps are replicated from Nairuz Abulhul: Breaking Domain Trusts with Forged Trust Tickets blog. We should have access to \\dc01.ghost.htb\c$, but seems like something went wrong ://
One of the steps used child domain sid for sids, which was wrong. What we need is privileged user or group SID!
After some enumeration Enterprise Admins was the one that worked.
Note: The SID has been applied to above commands.
Privilege Escalation (DC01 system)
Use the generated hash:
Oddly enough the secretsdump worked?!...
The secretsdump dumped both domains, corp and then DC01 so we need to use the DC01 hash :/
Root.txt
Writeups referenced:
Last updated