Unknown
CVE-2017-18044 - Commvault Communications Service execCmd Vulnerability
CVE ID
AttackerKB requires a CVE ID in order to pull vulnerability data and references from the CVE list and the National Vulnerability Database. If available, please supply below:
Add References:
Unknown
(1 user assessed)Unknown
(1 user assessed)Unknown
Unknown
Unknown
CVE-2017-18044 - Commvault Communications Service execCmd Vulnerability
MITRE ATT&CK
Collection
Command and Control
Credential Access
Defense Evasion
Discovery
Execution
Exfiltration
Impact
Initial Access
Lateral Movement
Persistence
Privilege Escalation
Topic Tags
Description
A certain message parsing function inside the Commvault service does not properly validate the input of an incoming string before passing it to CreateProcess. As a result, a specially crafted message can inject commands that will be executed on the target operating system. Exploitation of this vulnerability does not require authentication and can lead to SYSTEM level privilege on any system running the cvd daemon.
Add Assessment
Technical Analysis
Introduction
Commvault is a data protection and information management software; an enterprise-level data
platform that contains modules to back up, restore, archive, replicate, and search data.
According to public documentation, the data is protected by installing agent software on the
physical or virtual hosts, which use the OS or application native APIs to protect data in a
consistent state. Production data is processed by the agent on client computers and backuped
up through a data manager (the MediaAgent) to disk, tape, or cloud storage. All data
management activity in the environment is tracked by a centralized server (called CommServe),
and can be managed by administrators through a central user interface. End users can access
protected data using web browsers or mobile devices.
One of the base services of Commvault is vulnerable to a remote command injection attack,
specifically the cvd service. It was a Metasploit submission by @rwincey as PR #9340.
Vulnerable Application
According to the public advisory, Commvault v11 SP5 or prior are vulnerable to this
vulnerability.
The specific vulnerable version I tested was 11.0.80.0, and the software was obtained from
the Metasploit contributor @rwincey. The software is available from our Google Drive at:
Vulnerable Apps –> Commvault –> Commvault_R80_SP5_22September16.exe.
The version of the vulnerable DLL is:
Image path: C:\Program Files\Commvault\ContentStore\Base\CVDataPipe.dll Image name: CVDataPipe.dll Timestamp: Wed Dec 21 11:59:21 2016 (585AC2F9) CheckSum: 002ED404 ImageSize: 002F0000 File version: 11.80.50.60437 Product version: 11.0.0.0 File flags: 1 (Mask 3F) Debug File OS: 40004 NT Win32 File type: 1.0 App File date: 00000000.00000000 Translations: 0409.04b0 CompanyName: Commvault ProductName: Commvault InternalName: CVDataPipe OriginalFilename: CVDataPipe.dll ProductVersion: 11.0.0.0 FileVersion: 11.80.50.60437 PrivateBuild: SpecialBuild: FileDescription: LegalCopyright: Copyright (c) 2000-2016 LegalTrademarks: Comments:
Root Cause Analysis
Based on the information we have from the pull request, the vulnerability is a command injection, so
that’s where we begin reversing.
Usually, there are two ways to execute a command in a C/C++ application, one of them is WinExec()
,
and the other one is CreateProcess()
:
BOOL WINAPI CreateProcess( _In_opt_ LPCTSTR lpApplicationName, _Inout_opt_ LPTSTR lpCommandLine, _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ BOOL bInheritHandles, _In_ DWORD dwCreationFlags, _In_opt_ LPVOID lpEnvironment, _In_opt_ LPCTSTR lpCurrentDirectory, _In_ LPSTARTUPINFO lpStartupInfo, _Out_ LPPROCESS_INFORMATION lpProcessInformation );
Since CreateProcess()
is meant to replace WinExec()
according to Microsoft, we can create a
break point there fist in our debugger (WinDBG), and we hit it:
0:044> g Breakpoint 3 hit kernel32!CreateProcessA: 00000000`76fe8730 4c8bdc mov r11,rsp
Looking at the callstack of this kernel32!CreateProcessA
, we already have a pretty good idea
locating the vulnerability:
0:044> k Child-SP RetAddr Call Site 00000000`11a36b78 000007fe`f378a40f kernel32!CreateProcessA 00000000`11a36b80 000007fe`f377714e CVDataPipe!execCmd+0x7af 00000000`11a3f340 000007fe`f3777a69 CVDataPipe!CVDMessageHandler+0x78e 00000000`11a3fbd0 000007fe`f9cdc58d CVDataPipe!CVDMessageHandler+0x10a9 00000000`11a3fd40 000007fe`f9cdc1b1 CvBasicLib!CvThreadPool::th_defaultWorkerObj+0x3cd 00000000`11a3fe40 000007fe`f9cd2073 CvBasicLib!CvThreadPool::th_defaultWorker+0x51 00000000`11a3fe90 000007fe`f9a84f7f CvBasicLib!CvThread::~CvThread+0x63 00000000`11a3fee0 000007fe`f9a85126 MSVCR120!_callthreadstartex+0x17 [f:\dd\vctools\crt\crtw32\startup\threadex.c @ 376] 00000000`11a3ff10 00000000`76f6f56d MSVCR120!_threadstartex+0x102 [f:\dd\vctools\crt\crtw32\startup\threadex.c @ 354] 00000000`11a3ff40 00000000`770a3281 kernel32!BaseThreadInitThunk+0xd 00000000`11a3ff70 00000000`00000000 ntdll!RtlUserThreadStart+0x1d
There are two things that are interesting. One of them is CVDataPipe!CVDMessageHandler
, and the
other one is CVDataPipe!execCmd
.
CVDataPipe!CVDMessageHandler
is basically a function that handles our packet’s message type.
The Metasploit exploit specifically sends a code of 9h
, which is the message type for execCmd
:
.text:0000000180147103 loc_180147103: ; CODE XREF: CVDMessageHandler(int,selectStruct_t *,CQiSocket,void *):loc_180146D78j .text:0000000180147103 lea rax, [rsp+888h+var_220] ; jumptable 0000000180146D78 case 9 .text:000000018014710B mov [rsp+888h+var_600], rax .text:0000000180147113 mov rdx, [rsp+888h+sock] .text:000000018014711B mov rcx, [rsp+888h+var_600] .text:0000000180147123 call cs:??0CQiSocket@@QEAA@AEBV0@@Z ; CQiSocket::CQiSocket(CQiSocket const &) .text:0000000180147129 mov [rsp+888h+var_5F0], rax .text:0000000180147131 mov r8, [rsp+888h+arg_18] .text:0000000180147139 mov rdx, [rsp+888h+var_5F0] .text:0000000180147141 mov rcx, [rsp+888h+structSelect] .text:0000000180147149 call ?execCmd@@YAXPEAUselectStruct_t@@VCQiSocket@@PEAX@Z ; execCmd(selectStruct_t *,CQiSocket,void *)
If we take a closer look at the execCmd
function, we can tell the purpose of it is for processes such as:
- ifind (For restoring purposes)
- BackupShadow.exe (For archiving)
- Pub (Map file)
- createIndex (A Commvault process for building index)
.text:0000000180159F1B loc_180159F1B: ; CODE XREF: execCmd(selectStruct_t *,CQiSocket,void *)+261j .text:0000000180159F1B ; DATA XREF: .rdata:0000000180286258o .text:0000000180159F1B lea rdx, aIfind ; "ifind" .text:0000000180159F22 lea rcx, [rsp+87B8h+ApplicationName] ; Str .text:0000000180159F2A call cs:strstr .text:0000000180159F30 test rax, rax .text:0000000180159F33 jnz short loc_180159F6D .text:0000000180159F35 lea rdx, aBackupshadow_e ; "BackupShadow.exe" .text:0000000180159F3C lea rcx, [rsp+87B8h+ApplicationName] ; Str .text:0000000180159F44 call cs:strstr .text:0000000180159F4A test rax, rax .text:0000000180159F4D jnz short loc_180159F6D .text:0000000180159F4F lea rdx, aPub ; "Pub" .text:0000000180159F56 lea rcx, [rsp+87B8h+ApplicationName] ; Str .text:0000000180159F5E call cs:strstr ... .text:000000018015A0BA loc_18015A0BA: ; CODE XREF: execCmd(selectStruct_t *,CQiSocket,void *)+307j .text:000000018015A0BA lea rdx, aCreateindex ; "createIndex" .text:000000018015A0C1 lea rcx, [rsp+87B8h+ApplicationName] ; Str .text:000000018015A0C9 call cs:strstr .text:000000018015A0CF test rax, rax .text:000000018015A0D2 jz loc_18015A220
However, if you don’t call one of these processes, the exeCmd
will assume you want to run your
custom process, and pass it to CreateProcess
anyway:
.text:000000018015A361 loc_18015A361: ; CODE XREF: execCmd(selectStruct_t *,CQiSocket,void *)+675j .text:000000018015A361 call cs:GetEnvironmentStrings .text:000000018015A367 mov [rsp+87B8h+var_86A8], rax .text:000000018015A36F lea rax, [rsp+87B8h+StartupInfo] .text:000000018015A377 mov rdi, rax .text:000000018015A37A xor eax, eax .text:000000018015A37C mov ecx, 68h .text:000000018015A381 rep stosb .text:000000018015A383 mov [rsp+87B8h+StartupInfo.cb], 68h .text:000000018015A38E lea rax, [rsp+87B8h+ProcessInformation] .text:000000018015A396 mov rdi, rax .text:000000018015A399 xor eax, eax .text:000000018015A39B mov ecx, 18h .text:000000018015A3A0 rep stosb .text:000000018015A3A2 mov [rsp+87B8h+StartupInfo.dwFlags], 1 .text:000000018015A3AD xor eax, eax .text:000000018015A3AF mov [rsp+87B8h+StartupInfo.wShowWindow], ax .text:000000018015A3B7 lea rax, [rsp+87B8h+ProcessInformation] .text:000000018015A3BF mov [rsp+87B8h+lpProcessInformation], rax ; lpProcessInformation .text:000000018015A3C4 lea rax, [rsp+87B8h+StartupInfo] .text:000000018015A3CC mov [rsp+87B8h+lpStartupInfo], rax ; lpStartupInfo .text:000000018015A3D1 mov [rsp+87B8h+lpCurrentDirectory], 0 ; lpCurrentDirectory .text:000000018015A3DA mov [rsp+87B8h+lpEnvironment], 0 ; lpEnvironment .text:000000018015A3E3 mov [rsp+87B8h+dwCreationFlags], 10h ; dwCreationFlags .text:000000018015A3EB mov [rsp+87B8h+bInheritHandles], 0 ; bInheritHandles .text:000000018015A3F3 xor r9d, r9d ; lpThreadAttributes .text:000000018015A3F6 xor r8d, r8d ; lpProcessAttributes .text:000000018015A3F9 lea rdx, [rsp+87B8h+CommandLine] ; lpCommandLine .text:000000018015A401 lea rcx, [rsp+87B8h+ApplicationName] ; lpApplicationName .text:000000018015A409 call cs:CreateProcessA
It is unclear whether allowing an arbitrary custom process is intentional or not, it is unsafe
anyway considering the cvd process binds to 0.0.0.0, so anybody can access to it.
Would you also like to delete your Exploited in the Wild Report?
Delete Assessment Only Delete Assessment and Exploited in the Wild ReportGeneral Information
References
Additional Info
Technical Analysis
Report as Emergent Threat Response
Report as Exploited in the Wild
CVE ID
AttackerKB requires a CVE ID in order to pull vulnerability data and references from the CVE list and the National Vulnerability Database. If available, please supply below: