PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 3e:f8:b9:68:c8:eb:57:0f:cb:0b:47:b9:86:50:83:eb (ECDSA)
|_ 256 a2:ea:6e:e1:b6:d7:e7:c5:86:69:ce:ba:05:9e:38:13 (ED25519)
80/tcp open http Apache httpd
|_http-server-header: Apache
|_http-title: Did not follow redirect to http://linkvortex.htb/
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Navigated to the webapp, didn't find anything special.
Running directory and vhost scanning:
VHOST:
Directory:
Nothing special neither...
So I quickly check the source of the page:
BruteForcing:
Found admin portal:
Great finding:
SQLi:
And trying SQLi:
I tried brute-forcing with custom CeWL list and SQLmap, but I get blacklisted.
I started inspecting the source files and the API endpoints of Ghost CMS better...
That's the key for the content api, though we can't access the admin api with it..
Going back...:
I must do something wrong. I went back and realized I fkd the vhost command, I added --append-domain now and found:
Ran some sub-directory brute-forcing, and found:
Used git-dumper to dump it.
There are quite some files inside:
Let's do some credential hunting:
Many files! Let's use AI, so I will:
And feed the enormous output to AI.
Foothold
Found a match - admin@linkvortex.htb:OctopiFociPilfer45
Honestly, this is the worst box ever! It's super random, feels like there is no intended path. Even this password is in a "test" folder.
File: /extracted-repo/ghost/core/test/utils/fixtures/data-generator.js
// Password = Sl1m3rson99
password: 'Sl1m3rson99',
This appears frequently as a test user password throughout the codebase.
2. Hashed Passwords for Test Users
File: /extracted-repo/ghost/core/test/regression/api/content/authors.test.js & /posts.test.js
const hashedPassword = '$2a$10$FxFlCsNBgXw42cBj0l1GFu39jffibqTqyAGBz7uCLwetYAdBYJEe6';
3. Database Connection Password in CI Workflow
File: /extracted-repo/.github/workflows/ci.yml
mysql root password: 'root'
4. MySQL Authentication in CI
File: /extracted-repo/.github/workflows/ci.yml
authentication plugin: 'caching_sha2_password'
5. Test User "Bad Password" in Regression Tests
File: /extracted-repo/ghost/core/test/regression/api/admin/authentication.test.js
const password = 'OctopiFociPilfer45';
6. Client Certificate Password in Git Dumper Script
File: /home/czr/HTB/LinkVortex/git-dumper/git_dumper.py
client_cert_p12_password=None
This appears to be a parameter in the git_dumper.py script you're using, rather than an actual credential.
7. Various Generated Passwords in Tests
File: /extracted-repo/ghost/core/test/e2e-api/admin/users.test.js
newPassword: '1234abcde!!',
bob@linkvortex:~$ sudo -l
Matching Defaults entries for bob on linkvortex:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty, env_keep+=CHECK_CONTENT
User bob may run the following commands on linkvortex:
(ALL) NOPASSWD: /usr/bin/bash /opt/ghost/clean_symlink.sh *.png
bob@linkvortex:~$ cat /opt/ghost/clean_symlink.sh
#!/bin/bash
QUAR_DIR="/var/quarantined"
if [ -z $CHECK_CONTENT ];then
CHECK_CONTENT=false
fi
LINK=$1
if ! [[ "$LINK" =~ \.png$ ]]; then
/usr/bin/echo "! First argument must be a png file !"
exit 2
fi
if /usr/bin/sudo /usr/bin/test -L $LINK;then
LINK_NAME=$(/usr/bin/basename $LINK)
LINK_TARGET=$(/usr/bin/readlink $LINK)
if /usr/bin/echo "$LINK_TARGET" | /usr/bin/grep -Eq '(etc|root)';then
/usr/bin/echo "! Trying to read critical files, removing link [ $LINK ] !"
/usr/bin/unlink $LINK
else
/usr/bin/echo "Link found [ $LINK ] , moving it to quarantine"
/usr/bin/mv $LINK $QUAR_DIR/
if $CHECK_CONTENT;then
/usr/bin/echo "Content:"
/usr/bin/cat $QUAR_DIR/$LINK_NAME 2>/dev/null
fi
fi
fi