User Flag

We start by doing the usual nmap scans: Pasted image 20250413080502.png Pasted image 20250413080509.png Pasted image 20250413080516.png

For now, in the nmap scan we can notice some interesting things: there is a ghost 5.58 and a /ghost dir. Let’s move on.

Two ports open: ssh and http. Starting with port 80 we do our typical vhost and dir scans on it. Pasted image 20250413080606.png

Pasted image 20250413080609.png Pasted image 20250413080613.png There is a dev vhost, so let’s add it to the /etc/hosts file, and do a dir scan on it: Pasted image 20250413080622.png

We collected a lot of useful information with theses scans. Let’s use it. Checking the http://linkvortext.htb/ghost we are sent to a login panel: Pasted image 20250413080717.png

In the site map file we can find a possible name of a user admin: Pasted image 20250413080728.png

The dev host is not particularly interesting: Pasted image 20250413080740.png

But in our scans we saw that there was a .git dir so let’s dump the repo: Pasted image 20250413080843.png

We receive a repo with a lot of files: Pasted image 20250413080924.png Time to do some searching. One of the very first things to check when interacting with a git repo is to check its status: Pasted image 20250413081036.png

Two files have been changed. Let’s look at them: Pasted image 20250413081053.png

In the Dockerfile we can see that there is a config file copied to the container. Pasted image 20250413081103.png

In the js file we can find many passwords, maybe one of these is the password for the login portal we saw before. So now we only need an email.

Let’s look at the .git to see if we can find one: Pasted image 20250413081137.png

Pasted image 20250413081143.png And we found one. It seems that the email format is [username]@linkvortex.htb So let’s try with admin:

Pasted image 20250413081215.png

And immediately the first password works: Pasted image 20250413081301.png

Looking around the application we can’t find nothing that interesting, so let’s google to see if can find an exploit. Googling for “ghost 5.58”, the first result gives us a list of vulnerabilities. One of those stands out:

Pasted image 20250413081323.png

First this vulnerability seems to have been fixed exactly on the next version of the one we are interacting with. Secondly, is an arbitrary File read. Maybe we can read the file we found that is being copied to the container?

Pasted image 20250413081346.png

Searching for the cve we find something very interesting: Pasted image 20250413081408.png This is some cheeky analysis, but you may notice that the owner to the github repo has the same name of the creator of the box:

Pasted image 20250413081426.png So it seems that we are in the right track!

Looking at the exploit script, it seems we are able to upload symbolic links, disguised them as pictures and the backend doesn’t do any check for this. So the script creates a symbolic link to a file renames it as a .png, zips it and uploads it. Finally it curls the image and we should get the content of the file the symbolic link was point to.

Pasted image 20250413081620.png

Then we call the script: Pasted image 20250413081629.png

Now let’s ask for a file: Pasted image 20250413081642.png And it seems to be working. Now for the file we saw being copied to the docker container /var/lib/ghost/config.production.json:

Pasted image 20250413081657.png Right at the end of this file we conveniently get a username and a passwords.

Let’s see if we can ssh with this credential:

Pasted image 20250413081732.png And we are in. Let’s ssh and get the user flag: Pasted image 20250413081744.png

Root Flag

One of the first things to check is to see if we can run anything as sudo:

Pasted image 20250413081847.png

And sure enough we can. Let’s look at the script: Pasted image 20250413081927.png

Looking at the script it seems to be doing something similar as the previous exploit. Expecting a symbolic link as .png and then moving it to quarantine and printing its content if the $CHECK_CONTENT var is True.

Now, if we pay attention we can see that the script only sets the var CHECK_CONTENT if this var is not zero. So we can do something like:

Pasted image 20250413082009.png

And when we run the script, when it gets to the final if $CHECK_CONTENT its going to run ‘/bin/cat /root/root.txt’ as root and print the flag:

Pasted image 20250413082021.png

Pasted image 20250413082026.png