Skip to content

CyberSecLabs Outdated Write-up

Outdated is a beginner linux box from cyberseclabs.co.uk which uses an older version of ProFTPD and a visible NFS share we can mount to gain an initial shell and then gain root using a kernel exploit. For this write-up we’ll be looking at how we can use commands listed on a discovered exploit to gain a shell entirely manual (nothing too crazy), let’s get started!

Recon

Fire up autoenum by navigating to its directory running ./autoenum.sh and pass the IP of the box (172.31.1.22).

We’ll then be prompted to choose a scan profile to run (I tend to opt for aggr).

PORT      STATE SERVICE  VERSION
21/tcp    open  ftp      ProFTPD 1.3.5
22/tcp    open  ssh      OpenSSH 5.9p1 Debian 5ubuntu1.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   1024 12:6b:ae:92:45:a3:2d:d6:45:1c:ad:4f:37:23:4d:3b (DSA)
|   2048 24:4a:81:08:4b:cc:bb:a7:c9:da:3b:17:39:ad:a0:61 (RSA)
|_  256 0c:2b:07:32:18:8c:1a:86:e3:fa:c4:09:de:f5:0f:a0 (ECDSA)
111/tcp   open  rpcbind  2-4 (RPC #100000)
| rpcinfo: 
|   program version    port/proto  service
|   100000  2,3,4        111/tcp   rpcbind
|   100000  2,3,4        111/udp   rpcbind
|   100000  3,4          111/tcp6  rpcbind
|   100000  3,4          111/udp6  rpcbind
|   100003  2,3,4       2049/tcp   nfs
|   100003  2,3,4       2049/tcp6  nfs
|   100003  2,3,4       2049/udp   nfs
|   100003  2,3,4       2049/udp6  nfs
|   100005  1,2,3      32790/udp6  mountd
|   100005  1,2,3      42899/tcp   mountd
|   100005  1,2,3      48483/udp   mountd
|   100005  1,2,3      49206/tcp6  mountd
|   100021  1,3,4      34044/tcp   nlockmgr
|   100021  1,3,4      42154/udp6  nlockmgr
|   100021  1,3,4      59459/tcp6  nlockmgr
|   100021  1,3,4      60675/udp   nlockmgr
|   100024  1          33154/udp6  status
|   100024  1          36257/tcp6  status
|   100024  1          45207/tcp   status
|   100024  1          60548/udp   status
|   100227  2,3         2049/tcp   nfs_acl
|   100227  2,3         2049/tcp6  nfs_acl
|   100227  2,3         2049/udp   nfs_acl
|_  100227  2,3         2049/udp6  nfs_acl
2049/tcp  open  nfs_acl  2-3 (RPC #100227)
34044/tcp open  nlockmgr 1-4 (RPC #100021)
34955/tcp open  mountd   1-3 (RPC #100005)
39483/tcp open  mountd   1-3 (RPC #100005)
42899/tcp open  mountd   1-3 (RPC #100005)
45207/tcp open  status   1 (RPC #100024)

Taking a look at the script output, we can see a few things that stick out. There is no http port present, ftp is version 1.x (we are used to seeing 3.x), we have this service called rpcbind that takes up 90% of the script, and towards the end we can see nfs and mountd services listed as well.

We are used to seeing an http port open but there are many cases where http isn’t the way. There may be no webserver on the box or the webserver will have nothing of interest to us. There are two interesting things we see on this box (we can rule out ssh, for now at least). We have the ftp version that seemed rather outdated (pun intended ) and then we have rpcinfo listings along with the nfs/mountd. According to this, it looks like we might be able to do something with the rpcinfo service as we do see nfs listed a few times.

Enumerating NFS

According to the link above, we’ll see that may be able to interact with the NFS service. We are lead to this, which gives us more information on enumerating nfs. Before we check to see if we can pull files from this service, let’s do a little digging into what this nfs is and why we care about it.

NFS? What is it and Why Should I Care?

NFS is short for Network File Share, this gives us a big hint about what this is all about. Just from the name we can tell that it’s some kind of share over a network. If you don’t already know what a share is, a share is basically a storage medium containing some kind of data on a machine or on a network. More info on NFS here. All we really need to know is that we can potentially get shares this service and it’s over the network.

Querying and Mounting an NFS Share

Whenever we find that a share, any kind of share,the first thing we want to know is if it’s open. If it is, we may be able to get information off of it. We can see if there are any visible nfs shares we can mount using the showmount -e [IP]. Mounting a share is the process of moving it over to our machine.

Looks like we can mount the /var/nfsbackups share. Before mounting the share, we need to create a directory for it. I like to name my nfs mounts nfs_mnt, but feel free to name yours whatever you’d like. After creating the directory to store the share, we’ll mount it by running the following command.

We can see that we’ve successfully mounted the /var/nfsbackups share. Looks like we have three users on this box, let’s take a look and see if we can get anything off this share.

Doesn’t look like there is anything we can use stored in the shares, let’s go back to ftp and see if we can do anything with that.

Leveraging FTP Exploit and NFS Share to Gain a Shell

We saw that the version for ftp is rather old, let’s look around and see if we can find anything for that version.

Seems like there are a few exploits for this version. This 'mod copy' shows up twice, once as a meta exploit and the other as a normal script, which piques my interest a bit. Let’s pull down that second one and see what it’s all about.

Breaking Down mod copy Exploit for Manual Exploitation

We can use the searchsploit -m [exploit_id] opt to move the exploit to our working directory. Once we’ve pulled down the exploit, let’s take a look at the main chunk.

Let’s break this down. We can ignore the banner.

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

The line above is opening a tcp socket(AF_INET says the socket will use ipv4 and SOCK_STREAM makes the socket tcp) and storing it in the object s. We can now use this object to connect to something and interact with it. The if statement is checking if there is the correct number of args being passed to the script (it’s checking for 4 args but we are only passing three because that function stores the elements in a list and lists start at index[0], hence the 4).

        server = sys.argv[1] #Vulnerable Server
        directory = sys.argv[2] # Path accessible from web .....
        cmd = sys.argv[3] #PHP payload to be executed

These lines are just assigning variables to the args we passed, this isn’t important. The part of the exploit we want to be looking as is this next part.

        s.connect((server, 21))
        s.recv(1024)
        print '[ + ] Connected to server [ + ] \n'
        s.send('site cpfr /etc/passwd')
        s.recv(1024)
        s.send('site cpto ' + evil)
        s.recv(1024)
        s.send('site cpfr /proc/self/fd/3')
        s.recv(1024)
        s.send('site cpto ' + directory + 'infogen.php')
        s.recv(1024)
        s.close()
        print '[ + ] Payload sended [ + ]\n'
        print '[ + ] Executing Payload [ + ]\n'
        r = requests.get('http://' + server + '/infogen.php') #Executing PHP payload through HTTP

According to this, the script is connecting to ftp and sending the site cpfr and site cpto commands to move around files. Maybe we can use these commands to fetch files from the ftp. Let’s give it a shot.

FTP to RCE (kinda)

We’ll connect to the ftp using nc and see if we can fetch /etc/passwd and move it to the NFS share we have mounted.

As we can see, we have copied over the /etc/passwd file to our share and have renamed it passwd. Let’s take a look and see if there are any hashes in this file. Hashes are usually stored in the /etc/shadow file but they can sometimes be in the /etc/passwd file too and its always worth a look if we have access to this file.

There don’t seem to be any hashes. If there were, they’d be where the x is. That x tells linux to look for the hashes in /etc/shadow. But we do learn something useful. Looking towards the end of the file we see this

daniel:x:1000:1000:daniel,,,:/home/daniel:/bin/bash

Seems like this is the only normal user on the box. Not only to we have a valid user, but we also have this users home directory. We know we can copy files, but can we copy entire directories?

We’ve successfully copied over the users daniel’s home directory! We have access to the access.txt file so grab that hash and get credit for that. Looking at the hidden files, we can see that there is a .ssh dir with read exec perms.

Exploring the .ssh Dir and Gaining a Shell

Having access to this directory is something we want. This directory contains the id_rsa file, which allows us to connect to ssh without having to supply a password. We can use the -i arg with ssh to pass the id_rsa file. Let’s give it a go.

And we have an initial shell! It’s worth noting that sometimes you’ll be prompted for a passphrase. In this case we can use the ssh2john util to convert the passphrase to a hash and try to crack it.

Priv Esc

Now that we’ve gained a shell, let’s do some basic post exploitation enumeration. We’ll run the usual commands and see what information we can get and go from there.

Post-exploitation Enumeration

The usual suspects are enough to tell us what we need to escalate our privs.

If you run any linux post enum scripts, you’ll see that there isn’t really anything interesting aside from the kernel. We have a kernel version so let’s take a look and see what we can find on this kernel version.

Looking around for exploits for this version I found this. We have the exploit number so let’s use searchsploit to move the exploit to the working directory.

Exploiting the Kernel and Getting Root

Let’s take a look at the exploit

Looks like we have a complete usage guide, but let’s make sure we have gcc on the machine. gcc is a binary used to compile C code.

We’ve verified we can compile the code on the target machine, let’s get the exploit on the box and compile and run to try and get a root shell. Since this is a linux box, we can use wget or curl to get the file transferred over.

Now that we have the exploit on the machine, let’s work on compiling and running it.

We are root!

Published inCyberSecLabsLinux