The flaw exists in BwPAlarm.dll due to improper validation of user-supplied data when processing an IOCTL 70022 RPC message. The attacker can control the size of a heap buffer to be allocated as well as the data to be copied to the buffer. Note that Advantech was already aware of this issue when we reported it; however, we discovered it independently.
Proof of Concept
Below is the disassembly of the IOCTL 70022 handler. Comments have been added for clarity.
.text:0700399E ioctl_70022: ; CODE XREF: _BwRPCPAlarmService+75↑j
.text:0700399E ; DATA XREF: .text:jpt_7003855↓o
.text:0700399E mov ebx, [ebp+arg_pInbuf] ; jumptable 07003855 case 10022
.text:070039A1 xor edi, edi
.text:070039A3 mov [ebp+arg_pOutbuf], edi
.text:070039A6 mov eax, [ebx]
.text:070039A8 mov edx, [ebx+4]
.text:070039AB mov [ebp+dw0], eax
.text:070039AE mov eax, [ebx+8] ; attacker-controlled
.text:070039B1 push eax ; heap buf size controlled by attacker
.text:070039B2 push 3Dh ; '='
.text:070039B4 mov [ebp+dw4], edx
.text:070039B7 call _calloc
.text:070039BC add ebx, 0Ch
.text:070039BF push 3Bh ; ';' ; Val
.text:070039C1 push ebx ; Str
.text:070039C2 mov [ebp+arg_InbufLen_pHeapBuf], eax
...
.text:07003A3C push 16h
.text:07003A3E lea eax, [edi-16h]
.text:07003A41 push edx
.text:07003A42 push eax ; copy to heap buf
.text:07003A43 mov [edi-18h], cx
.text:07003A47 call strlcpy(char *,char const *,uint)
.text:07003A4C lea ecx, [ebp+var_168]
.text:07003A52 push 25h ; '%'
.text:07003A54 push ecx
.text:07003A55 push edi ; copy to heap buf
.text:07003A56 call strlcpy(char *,char const *,uint)
.text:07003A5B mov eax, [ebp+arg_OutbufLen]
.text:07003A5E lea ebx, [esi+1]
.text:07003A61 inc eax
.text:07003A62 push 3Bh ; ';' ; look for next string token separated by ';'
.text:07003A64 push ebx
.text:07003A65 mov [ebp+arg_OutbufLen], eax
.text:07003A68 add edi, 3Dh ; '='
.text:07003A6B call _strchr
.text:07003A70 mov esi, eax
.text:07003A72 add esp, 2Ch
.text:07003A75 test esi, esi
.text:07003A77 jnz process_next_str_token_in_input_buffer
...
The following shows the crash of webvrpcs.exe and the access violation is exploitable:
0:010> g
(1428.678): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
*** WARNING: Unable to verify checksum for C:\WebAccess\Node\BwPAlarm.dll
eax=00000001 ebx=02e4e495 ecx=00000015 edx=034af6ff esi=02400000 edi=034af64d
eip=070027db esp=034aead0 ebp=034af734 iopl=0 nv up ei ng nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010286
BwPAlarm+0x27db:
070027db 8816 mov byte ptr [esi],dl ds:002b:02400000=10
0:009> kb
ChildEBP RetAddr Args to Child
034aead4 07003a4c 023fffff 034af64c 00000016 BwPAlarm+0x27db
*** WARNING: Unable to verify checksum for C:\WebAccess\Node\webvrpcs.exe
*** ERROR: Module load completed but symbols could not be loaded for C:\WebAccess\Node\webvrpcs.exe
034af734 004049de 00002726 023f0bc0 02e40050 BwPAlarm+0x3a4c
WARNING: Stack unwind information not available. Following frames may be wrong.
034af9d0 00402cc1 002828e0 006de0d0 00011186 webvrpcs+0x49de
034afa1c 00401370 002828e0 006de0d0 00011186 webvrpcs+0x2cc1
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Windows\syswow64\RPCRT4.dll -
034afb60 7db85feb 002829a4 1e092dea 002872d0 webvrpcs+0x1370
034afb98 7db8648b 00401260 002829a4 034afc3c RPCRT4!NdrOutInit+0x11d
034afbf0 7db86365 00000001 00000000 00000000 RPCRT4!RpcBindingInqObject+0x2aa
034afc14 7dbc7e25 002829a4 00000000 00000000 RPCRT4!RpcBindingInqObject+0x184
034afca0 7dbc8174 00000b74 002828e0 0028295c RPCRT4!I_RpcFilterDCOMActivation+0x3891
034afcb4 7dbc83b9 00000000 002734a0 00272ab0 RPCRT4!I_RpcTransServerNewConnection+0x118
034afce0 7dbc8b6a 002734a0 02000b8c 00000000 RPCRT4!I_RpcTransServerNewConnection+0x35d
034afd40 7dbd74e7 00000000 002734a0 00000b8c RPCRT4!I_RpcTransServerNewConnection+0xb0e
034afd54 7dbebfff 00280210 0000000c 00000000 RPCRT4!RpcMgmtSetAuthorizationFn+0x6528
034afd78 7dbec1f8 00280210 0000000c 00000000 RPCRT4!I_RpcInitHttpImports+0x78e
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Windows\syswow64\KERNELBASE.dll -
034afdb0 7d888369 00000b8c 00000000 00272c30 RPCRT4!I_RpcInitHttpImports+0x987
034afdd4 7dee4cd6 034afe74 002632e0 00272c30 KERNELBASE!CreateThreadpoolWait+0x62
034afe30 7debfb4b 034afe74 00251018 00272c30 ntdll!WinSqmStartSession+0x399
034aff88 7dd7343d 00266a60 034affd4 7dea9812 ntdll!TpSetTimer+0x3bf
034aff94 7dea9812 00266a60 e91c4c39 00000000 kernel32!BaseThreadInitThunk+0x12
034affd4 7dea97e5 7dec04ac 00266a60 ffffffff ntdll!RtlInitializeExceptionChain+0x63
034affec 00000000 7dec04ac 00266a60 00000000 ntdll!RtlInitializeExceptionChain+0x36
0:009> .load msec.dll
0:009> !exploitable
!exploitable 1.6.0.0
Exploitability Classification: EXPLOITABLE
Recommended Bug Title: Exploitable - User Mode Write AV starting at BwPAlarm+0x00000000000027db (Hash=0x46a88e71.0x5200d855)
User mode write access violations that are not near NULL are exploitable.