This is practical walkthrough of Internal Penetration Testing Challenge on TryHackMe. There are already several walkthroughs are available of the aforementioned challenge on the Internet, however this will be little bit different as I am going to explain the behind the scenes as well as reasons behind using specific technique to accomplish the goal.
Passwords and Flags will be redacted to encourage you to solve those challenges on your own.
Goal of this challenge is to find and acquire user.txt and root.txt flag.
First Things First
Deploy the target machine (this machine might take upto 3–5 minutes to load and accessible)
There are two ways to access the deployed target machine.
1) Use attacker box — Provided by TryHackMe, it consist of all the required tools available for attacking.
2) Use OpenVpn configuration file to connect your machine (kali linux) to their network.
For the sake of demonstration I am using OpenVPN connection on my machine (macOS) and THM (attacker machine)
We have to append internal.thm and point it to target machines IP address inside hosts file on attacker machine.
We won't be using Metasploit for this challenge
Initially we will start with modifying the hosts file.
All of my further commands will be executed as normal user not as root. So, if you’re also not executing all the commands as root then make sure to use sudo, as it can give you permission to change system configuration.
Use any of your favorite text editor to modify hosts file.
Reason 1 to edit hosts file: As you probably already know, if you make any type of request to any hostname, the domain name gets translated to an IP address. In TCP/IP, only the IP address is transferred and not the hostname. In services such as HTTP(S), you also transfer the hostname in the “Host” HTTP header. If you visit a website through the URL with IP address in it, the Host header will contain the IP address. If you visit the URL with the hostname in it, the Host header will contain that hostname. Then it depends on the web server how it will process the request based on that header. In TLS handshake, you can also send the hostname in the “server_name” extension. So if the underlying back-end services only respond to the hostname, the easiest solution to send it natively is to modify your hosts file. The software that you use (e.g. a web browser) will do the rest. Credits: u/AMDcze (reddit).
Reason 2: One IP address can host multiple websites on same webserver through virtual hosting (vhost) technique. If by any chance the target server has any multiple websites then it would be hard to figure out which is which. By pointing DNS in hosts file you are actually saying your apps to target only the specific domain.
Reason 3: What if there are any subdomains? How to enumerate them without domain itself? While enumerating you have to expect that there’s a possibility of subdomain, to that you need domain itself. You can enumerate subdomain through an IP address.
Let’s start our enumeration with Nmap. In this section we will start to find ports, services and its version.
Nmap flags: -F (Fast scan, top 100 ports), -sV (Service Version scan) and -Pn (no ping scan).
Honestly I use fast scan most of the time, as it can produce result in minimum time. Once I have initial ports, I keep enumerating them from different tab and in parallel I perform full port scan. The reason behind this is, full port scan take more time to finish.
Target has two open ports 22 and 80 with service version information. If we do a little quick version vulnerability check on exploit-db, then there are none. The present version of Apache is 2.4.46 and present OpenSSH version is 8.4. When we compare the present version of both ports with the result then its pretty obvious that it’s not very old version and that might be the reason there are no public exploits are available based on version.
If we visit the web server then we get the below result. It’s just a default page of Apache which is running on Ubuntu.
Let’s Enumerate HTTP further using GoBuster. Gobuster is a tool used to brute-force URIs, DNS, Vhosts and S3 buckets.
We are using GoBuster for specific reason and that would be to find directories on hxxp://internal.thm. We are hoping to find any login pages.
As you can see from above on going process, it already found a directory that is /blog. If we visit hxxp://internal.thm/blog then we see a blog with one single post named as “Hello World”.
It’s obvious now that this is designed using WordPress application. We have a user called “admin”, who posted this blog.
Let’s find out the version of this WordPress application. We can do this without any tools (passive). Right click on blog page and click on “Show Page Source”
Within a site’s source code and on certain hidden pages, you may be able to find the version number. To do that press “ctrl + f and type ver” (ver is short of version)
As you can see the red circle, it’s version number for wordpress. That is 5.4.2. If we do a quick version vulnerability check on exploit-db then there are none.
If we look at the blog then you can see log in option in the blog. If we click on that than it can redirect to login page of wordpress.
As of this moment we don’t know the username and password. However, we can able to enumerate usernames through different techniques.
WordPress Username Enumeration
Technique 1: Look at the post on blog
Technique 2: In a default installation you should be able to find the users of a site by iterating through the user id’s and appending them to the sites URL. For example /?author=1, adding 2 then 3 etc.
As you can see, I tried /?author 1 and 2, both time results varied.
Technique 3: Enumerate Users through Guessing
We get an error, but this error is informative. As it says “password for admin is incorrect”. That means, there is a user named “admin”.
I tried some other user name, and the error is “username unknown”.
Technique 3: Using WPscan application
WPScan is a free, for non-commercial use, black box WordPress security scanner written for security professionals and blog maintainers to test the security of their WordPress websites.
Using above command we are going to scan the blog for security vulnerabilities as well as username enumeration (-e u).
After the result we are interested in two things one is outdated theme which is being used and username. This outdated theme might come in handy as we go along.
Without any critical vulnerability we can get in, so we have to somehow get the login credentials. This is possible using Bruteforce technique.
WPScan also Bruteforce usernames and passwords, this is an aggressive technique. Might generate lot of logs and events on server side. As this is a testing box, we don’t need to worry about logs.
We already know the username, so we provide “admin” and for password we use “RockYou.txt” for wordlist attack.
Now we have username and password for WordPress Login.
We got in, what’s next? We already know that a specific theme is outdated, let’s visit that using theme editor. Go to appearance and click “theme editor”.
There are some theme files. Where we can update our theme accordingly. There are also some PHP files.
We can use PHP to get the reverse shell using php-reverse-shell payload of Pentestmonkey (hxxps://github.com/pentestmonkey/php-reverse-shell). Either you can download on your machine or if you are using Kali Linux, it’s already there. We have to edit it to add our attacker machine IP address and port address. We are doing this because, after this .php file execution it gives us a reverse shell on specified IP address and port.
Change $ip and $port to your machines IP and Port. Note: it’s okay if you want to go with the default port.
Now copy all the content of php-reverse-shell.php file and go to the theme editor of WordPress and click on “404 Template”
Remove everything from that file and paste the copied content and click on “update file”
So, we are going to execute a custom php script on server and upon execution we get a reverse shell on our attacker machine. Once we have reverse shell, then we can further move towards our goal to get “user.txt” and “root.txt” flags
On your machine (Kali Linux) set up a listener to receive incoming connection from target machine. To do that we are going to use NetCat (nc).
Netcat is a computer networking utility for reading from and writing to network connections using TCP or UDP. The command is designed to be a dependable back-end that can be used directly or easily driven by other programs and scripts. -Wikipedia
-l (Listen mode, for inbound connects)
-n (Suppress name/port resolutions)
-p (Specify local port for remote connects)
So, we are almost set to receive remote connection from target machine. Only one thing is left to do, that is to execute that 404.php file. To do that, we first need to find where that file is.
Most of the theme are located inside /wp-content/ and theme related contents are inside /wp-content/themes/. So, our theme name is twenty seventeen, that means the file will be inside /wp-content/themes/twentyseventeen/404.php
Let’s visit the 404.php from url using hxxp://internal.thm/blog/wp-content/themes/twentyseventeen/404.php
Now we have a reverse shell on our machine (kali linux). Let’s move around and find out who’s the user of this machine.
There is one user named “aubreanna”. If you try to enter then it gives you error, thats because we don’t have permission to access that folder.
At this moment we can try a lot of things to escalate our privileges to take fully control over machine.
Privilege Escalation — User
Now we have initial access over target machine, but it’s not enough to retrive user.txt and root.txt flags. So, we have to gain higher level of access through either a vulnerability/misconfiguration.
Initially we will go with LinPeas (Linux Privilege Escalation) script. (https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/linPEAS). One of the best script to find privilege escalation paths.
We have to upload linpeas.sh file to target machine. Again, there are many ways to do this. I am going to use “updog” application to host my files for access. (use the power of internet how to install updog, it’s pretty easy)
Once its available to access, now we use “wget” command to download the specific file to a temporary folder (/tmp)
Now move to tmp folder and check it.
we have the file and now we need to execute that file using below command
$ bash linpeas.sh
It gives you a lot things on screen. But, follow the color code as they have mentioned in their blog.
RED/YELLOW: 95% a PE vector
RED: You must take a look at it
LightCyan: Users with console
Blue: Users without console & mounted devs
Green: Common things (users, groups, SUID/SGID, mounts, .sh scripts, cronjobs)
LightMangeta: Your username
It’s literally a haystack, so we need to concentrate on RED/Yellow stuff.
There are some things which came to my attention.
We have wordpress configuration.
SSH root login (only works if we have root password)
Let’s check the phpmyadmin configuration for any infomration.
One specific file has interesting information.
phpmyadmin username and password to access. If you go back to gobuster’s result then we can see that there’s a “phpmyadmin” page.
If we visit it then we can see there’s a login page to access.
This would give us access to database with the credential which we got from config-db.php file, but it would not help use to escalate privileges.
Let’s move around the filesystem and find out is there anything interesting. It’s really hard to find out without a specific goal in mind. Whenever I get a initial access to linux machine, I usually execute locate command to find specific files or folders. Most of the CTF boxs flags are stored in text file (.txt). Let’s start there and then move accordingly.
So, there nothing much to get by that command. Let’s do a wildcard search using the same command.
$ locate *.txt
The result data will be huge. It takes time to find what we are looking for. But fortunately just after executing that command we got an interesting folder with interesting file.
If we look into that file then we see credentials are user “aubreanna”.
So, now we can login into “aubreanna” user with these credentials. To login we can either ssh into her account or use “su” command to login directly.
if we try to use “su” command then it gives us an error.
The reason behind this error is, when we Netcat (nc) and gets a reverse shell then these shell are not fully interactive TTY, these are not bash or zsh shell.
You can check which shell you are using by below command
There are limitations for /bin/sh
Some commands, like
sshrequire a proper terminal to run
STDERR usually isn’t displayed
Can’t properly use text editors like
No up arrow history
No job control and ETC
So, lets upgrade it to proper bash. Most linux OS have python installed so we can use python pty module. The pty module let’s you spawn a psuedo-terminal that can fool commands like
su into thinking they are being executed in a proper terminal.
Let’s check again now which shell we are using
Let’s login using su -l command and input the password
Now we are inside local user, let’s find the user.txt flag.
Privilege Escalation — Root
We already got user.txt flag, now we move to retrieve root.txt by escalating current user privileges to root. At this stage we can again try the same “LinPeas” script to find some vulnerability to escalate, but it’s a dead end. However, in “aubreanna” home folder there’s a Jenkins.txt file.
The file consist text saying it’s running on specific IP and Port on localhost. But the IP address is different than out deployed machine, if we check ifconfig result then we get the clear idea.
As you can see, there’s a docker running on target machine with 172 series IP address, so Jenkins is inside docker running on port 8080. Even if we try to access that docker IP and Port using our browser it’s not reachable. So, to access it we are going to use SSH tunneling technique to forward Jenkins ip:port to our attacker machine’s ip:port. We have exit all the logins and reverseshell. From attackers (kali linux) terminal execute below command and type the password which we retrieved from wp-save.txt file.
To access Jenkins, type localhost:6767 in your browser to access it.
We need credentials to access Jenkins. Even if we try the regular passwords like admin:admin or admin:password, it won’t work. We have to bruteforce this using some tools like Hydra.
Hydra is a parallelized login cracker which supports numerous protocols to attack. It is very fast and flexible, and new modules are easy to add. This tool makes it possible for researchers and security consultants to show how easy it would be to gain unauthorized access to a system remotely.
We also need BurpSuite to collect some variables of HTTP GET/POST request.
Note: Due to some weird reasons I couldn't able to crack using THM attacker machine. I deployed my on kali machine on vm and then it worked.
Now we have Jenkins password. Use it login and click on “manage jenkins” and find “script console”.
Jenkins has lovely Groovy script console that permits anyone to run arbitrary Groovy scripts inside the Jenkins master runtime. Groovy is a very powerful language which offers the ability to do practically anything Java can do.
So, we use this groovy script console to run our java reverse shell. Before you execute java reverse shell make sure to run netcat (nc -lvnp 4444) on your attacker machine (kali linux)
Once you input the java reverse shell code (change the IP and port) and click on run button to execute our code on target server.
Spawn bash using /bin/bash -i command
Now we are in docker environment not actual target server. Some of the commands will not work in docker environment, for example locate command which we used last time to find any text files with credentials. So, this time we use another command.
After executing the command, the first item is /opt/note.txt. Previously we found wp-save.txt in /opt too. Let’s check what is in that text file.
The message is from Aubreanna and left root credentials. Using these root credentials we can ssh into target machine.
Once we are in, we look for our last flag, root.txt
Now we have both flags, user.txt and root.txt
Thank you for reading this blog. While attempting this challenge I learned so many things. This was unique target with unique vulnerability.