Talos Vulnerability Report


Natus Xltek EEG NeuroWorks RequestForPatientInfoEEGfile Code Execution Vulnerability

April 4, 2018
CVE Number



An exploitable Code Execution vulnerability exists in the RequestForPatientInfoEEGfile functionality of Natus Xltek NeuroWorks 8. A specially crafted network packet can cause a stack buffer overflow resulting in arbitrary command execution. An attacker can send a malicious packet to trigger this vulnerability.

Tested Versions

Natus Xltek NeuroWorks 8

Product URLs


CVSSv3 Score

10 - CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H


CWE-121 - Stack-based Buffer Overflow


Natus NeuroWorks 8 provides a networking solution for the Natus Xltek EEG products. In particular, it is used to monitor and review study data from anywhere on the network. This advisory looks into the NWStorage service bundled with NeuroWorks.

Modules associated with this advisory are below:

0:000> lm vm Storage
start    end        module name
00400000 00471000   storage    (no symbols)
    Loaded symbol image file: c:\Neuroworks\storage.exe
    Image path: c:\Neuroworks\storage.exe
    Image name: storage.exe
    Timestamp:        Wed Nov 06 10:11:09 2013 (527A863D)
    CheckSum:         0006EC3D
    ImageSize:        00071000
    File version:
    Product version:

During the processing of the RequestForPatientInfoEEGfile command, NWStorage attempts to open an EEG file based on a path requested by the client. This path construction is shown below:

.text:00433BD2 3E8                 push    0               ; Ext
.text:00433BD4 3EC                 lea     edx, [esp+3ECh+file_name]
.text:00433BDB 3EC                 push    edx             ; Filename
.text:00433BDC 3F0                 push    0               ; Dir
.text:00433BDE 3F4                 push    0               ; Drive
.text:00433BE0 3F8                 lea     this, [esp+3F8h+fullPath]  // Client supplied path
.text:00433BE4 3F8                 call    ds:ATL::CSimpleStringT<char,1>::operator char const *(void)
.text:00433BEA 3F8                 push    eax             ; FullPath
.text:00433BEB 3FC                 call    ds:__imp___splitpath       // [0]
.text:00433BF1 3FC                 lea     eax, [esp+3FCh+str]
.text:00433BF5 3FC                 push    eax
.text:00433BF6 400                 call    ds:GetTempDirectory(void)  // [1]
.text:00433BFC 400                 add     esp, 18h
.text:00433BFF 3E8                 mov     byte ptr [esp+3E8h+var_4], 7
.text:00433C07 3E8                 lea     this, [esp+3E8h+file_name]
.text:00433C0E 3E8                 push    this
.text:00433C0F 3EC                 mov     this, eax
.text:00433C11 3EC                 call    ds:ATL::CSimpleStringT<char,1>::operator char const *(void)
.text:00433C17 3EC                 push    eax
.text:00433C18 3F0                 lea     edx, [esp+3F0h+tmp_path]   // [3]
.text:00433C1F 3F0                 push    offset Format   ; "%s%s.eeg"
.text:00433C24 3F4                 push    edx             ; Dest
.text:00433C25 3F8                 call    ds:__imp__sprintf          // [2]

NWStorage extracts the wanted filename by calling splitpath on client supplied data [0]. This, along with a temp directory [1], are used in a sprintf call [2] to create the wanted EEG file to open. The destination of this sprintf is a buffer on the stack [3]. The combination of temp directory and client supplied filename causes the tmp_path variable to be overrun, overwritting the Structured Exception Handler on the stack.

The state of the SEH chain before the sprintf call is shown below:

eak=017c19a0 ebx=00000004 ecx=0012f7bc edx=0012fa7c esi=0268fe54 edi=017c8fb0
eip=00433c25 esp=0012f798 ebp=0268fe70 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
00433c25 ff1594c64400    call    dword ptr [storage+0x4c694 (0044c694)] ds:0023:0044c694={MSVCR90!sprintf (78552e73)}
0:000> !exchain
0012fb84: storage+48334 (00448334)
0012fc2c: mfc90+21b11a (787fb11a)
0012fcb4: mfc90+21912d (787f912d)
0012fd1c: mfc90+21b1c1 (787fb1c1)
0012fdc0: USER32!InvertRect+b76 (77d7631b)
0012fe1c: USER32!InvertRect+b76 (77d7631b)
0012fe64: ntdll!KiUserApcDispatcher+48 (77f06b60)
0012ff78: storage+40d4a (00440d4a)
0012ffc4: ntdll!RtlAddMandatoryAce+342 (77ede195)
Invalid exception stack at ffffffff

The state of the SEH chain after the sprintf call is shown below:

0:000> p
eax=00000114 ebx=00000004 ecx=270800df edx=0012fb8f esi=0268fe54 edi=017c8fb0
eip=00433c2b esp=0012f798 ebp=0268fe70 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
00433c2b 83c410          add     esp,10h
0:000> !exchain
0012fb84: deadbeef
Invalid exception stack at 6d636161

By causing an exception before the stack cookie is checked, the overwritten exception handler is called, resulting in arbitrary code execution.

Crash Information

(33c.2c0): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000000 ebx=00000000 ecx=deadbeef edx=77f06d8d esi=00000000 edi=00000000
eip=deadbeef esp=0012f0d8 ebp=0012f0f8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246
deadbeef ??              ???


2017-06-16 - Vendor Disclosure
2017-07-15 - Vendor Acknowledged
2018-04-04 - Public Release


Discovered by Cory Duplantis of Cisco Talos.