Nebula - Level13 - Shared Libraries
About
There is a security check that prevents the program from continuing execution
if the user invoking it does not match a specific user id.
To do this level, log in as the level13 account with the password
level13. Files for this level can be found in /home/flag13.
##Source code
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
#define FAKEUID 1000
int main(int argc, char **argv, char **envp)
{
int c;
char token[256];
if(getuid() != FAKEUID) {
printf("Security failure detected. UID %d started us, we expect %d\n", getuid(), FAKEUID);
printf("The system administrators will be notified of this violation\n");
exit(EXIT_FAILURE);
}
// snip, sorry :)
printf("your token is %s\n", token);
}
Solution
Upon first glance, this program does nothing. However, the line // snip, sorry :) reveals that the
useful, interesting source code has been removed. Running strings against the binary provides
little useful information. The solution becomes overriding the call to getuid, or attempting to
modify FAKEUID. Modifying FAKEUID would require editing the hexadecimal values of the binary.
Modifying getuid means changing the UID the program thinks it runs as, or loading a library that
overrides the getuid call entirely.
Using LD_PRELOAD, the getuid system call can be overwritten. To do this, copy the
/home/flag13/flag13 file to /home/level13/flag13 in order to remove the SUID bit. SUID binaries
ignore the LD_PRELOAD variable due to security vulnerabilities like this one. The shared
library should be named getuid.c and have the contents
#include <sys/types.h>
uid_t getuid(){
return 1000;
}
Use gcc -fPIC -g -c -o uid.o getuid.c && gcc -shared -W1,-soname,uid.so -o uid.so uid.o -lc to
create the .so file for the library. Execute the program with
export LD_PRELOAD=./uid.so; ./flag13. The program executes, but uses the crafted kernel library in
the current directory to check for the ID.