Claves SSH en pentesting: robar id_rsa, crackearla y dejar la tuya
Cómo usar claves SSH en una intrusión: leer un id_rsa con un LFI, crackear su passphrase con ssh2john, escribir tu clave en authorized_keys y resolver los errores típicos.
Una clave SSH privada es una contraseña que no caduca y que nadie vigila. En Hack The Box aparecen en dos sentidos: robas la de un usuario (con un LFI, un backup o un repositorio) para entrar como él, o escribes la tuya en su authorized_keys para tener una shell estable. Las dos cosas se resuelven en un par de comandos si sabes dónde mirar y qué significan los errores.
Lo mínimo que tienes que saber
- La clave privada (
id_rsa,id_ed25519,id_ecdsa) es la que te da acceso. Empieza por-----BEGIN OPENSSH PRIVATE KEY-----o-----BEGIN RSA PRIVATE KEY-----. - La clave pública (
.pub) va en~/.ssh/authorized_keysdel usuario en el servidor. Quien tenga la privada correspondiente entra sin contraseña. - Una privada puede estar cifrada con una passphrase. Entonces necesitas crackearla antes de usarla.
- SSH es muy estricto con los permisos: si tu fichero de clave lo puede leer cualquiera, se niega a usarlo.
Requisitos
openssh-clientyjohn(conssh2john, que viene con el paquetejohnde Kali).putty-toolssi te encuentras una clave.ppk:sudo apt install putty-tools.- Para practicar: OpenAdmin (clave cifrada), LaCasaDePapel (clave leída con un LFI) y Postman (escribir tu clave con Redis).
Caso 1: leer la clave de otro usuario
Si tienes una lectura de ficheros (LFI, XXE, un SSRF con file://), primero saca los usuarios de /etc/passwd y después prueba las rutas típicas:
/home/<usuario>/.ssh/id_rsa
/home/<usuario>/.ssh/id_ed25519
/home/<usuario>/.ssh/id_ecdsa
/root/.ssh/id_rsa
Si ya estás dentro de la máquina, búscalas todas:
find / -name "id_*" -o -name "authorized_keys*" -o -name "*.pem" -o -name "*.ppk" 2>/dev/null \
| grep -v -E "^/(proc|usr/share|sys)"
Guarda la clave en tu máquina y úsala:
chmod 600 id_rsa
ssh -i id_rsa [email protected]
Truco
Si no sabes de quién es la clave, mira el final de la .pub si la tienes (suele acabar en usuario@host) o saca la pública de la privada con ssh-keygen -y -f id_rsa. El comentario del final te da el nombre.
Caso 2: la clave tiene passphrase
Si al usarla SSH te pide Enter passphrase for key 'id_rsa':, está cifrada. Puedes confirmarlo mirando la cabecera (Proc-Type: 4,ENCRYPTED en las antiguas) o con:
ssh-keygen -y -f id_rsa
Para crackearla, conviértela al formato de John y pásale un diccionario:
ssh2john id_rsa > id_rsa.hash
john --wordlist=/usr/share/wordlists/rockyou.txt id_rsa.hash
bloodninjas (id_rsa)
Esa es la passphrase de la clave de joanna en OpenAdmin. Con ella, ssh -i id_rsa [email protected] y escribes la passphrase cuando te la pida. En Valentine la clave cifrada está en la web en hexadecimal (xxd -r -p la devuelve a texto) y la passphrase sale de la memoria filtrada por Heartbleed.
Nota
Hashcat también sirve: ssh2john genera formatos como $sshng$0$... o $sshng$6$.... Para las claves nuevas con bcrypt ($sshng$2$ o $sshng$6$) John es más cómodo y, de todas formas, son lentas de crackear: no esperes recorrer rockyou entero.
Caso 3: escribir tu propia clave
Si puedes escribir en el home de un usuario (una shell como él, una escritura arbitraria de ficheros o un servicio mal configurado), deja tu clave y entra por SSH. Es más estable que cualquier reverse shell.
En tu máquina, genera un par nuevo sin passphrase:
ssh-keygen -t ed25519 -f ./pwn -N ''
cat pwn.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... kali@kali
En la víctima, como el usuario objetivo:
mkdir -p ~/.ssh && chmod 700 ~/.ssh
echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... kali@kali' >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
Y desde tu máquina:
ssh -i pwn [email protected]
Las formas de escribir la clave cambian según la máquina:
- Redis sin contraseña que corre como un usuario con home: Postman. Cambias el directorio de trabajo de Redis a
~/.sshy guardas tu clave comoauthorized_keys. - Un PUT de WebDAV en un servicio que corre como root: Broker.
- Un webshell como el usuario que ya tiene
.ssh: Traceback. - Un
sudocon un binario que escribe ficheros (comoiptables-save): Backfire.
Caso 4: claves de PuTTY
Una clave .ppk (formato de PuTTY, típica de entornos Windows) hay que convertirla a OpenSSH:
puttygen clave.ppk -O private-openssh -o id_rsa
chmod 600 id_rsa
ssh -i id_rsa [email protected]
Es lo que pasa en Keeper: dentro de la base de datos de KeePass hay una clave de PuTTY para root.
Caso 5: autoridad de certificación de SSH
Algunos servidores no usan authorized_keys sino certificados firmados por una CA (TrustedUserCAKeys en /etc/ssh/sshd_config). Si consigues la clave privada de la CA, firmas tu clave para el usuario que quieras:
ssh-keygen -s ca_key -I pwn -n root -V +1h pwn.pub
ssh -i pwn [email protected]
El -n root es el principal que tendrá tu certificado. Lo tienes en Principal.
Errores típicos
WARNING: UNPROTECTED PRIVATE KEY FILE!ybad permissions: te faltachmod 600 id_rsa.Load key "id_rsa": invalid formatoerror in libcrypto: la clave se copió mal. Falta el salto de línea final, tiene finales de línea de Windows (dos2unix id_rsa) o se perdieron saltos de línea al copiar desde el navegador.Permission denied (publickey)con tu clave escrita: el servidor ignoraauthorized_keyssi el home o~/.sshtienen permisos de escritura para otros (StrictModes). Ponchmod 700 ~/.sshychmod go-w ~. Revisa también que el usuario sea el correcto.sign_and_send_pubkey: no mutual signature supportedono matching host key type found: el servidor es antiguo y usassh-rsacon SHA-1, que tu cliente desactiva. Añade-o PubkeyAcceptedKeyTypes=+ssh-rsa -o HostKeyAlgorithms=+ssh-rsa.ssh2johnno reconoce la clave: actualiza John (las versiones antiguas no entienden el formatoOPENSSH PRIVATE KEY) o llama al script conpython3 /usr/share/john/ssh2john.py.
Y después
Con una sesión SSH estable puedes reenviar puertos internos (ssh -L), como explica la guía de port forwarding y pivoting. Tienes el punto de claves SSH en la checklist de post-explotación, y si te encuentras más contraseñas por el camino, sigue el método de buscar contraseñas tras la intrusión.