dll hijacking, replacing dll in folder - dll

i'm trying to understand how dll hijacking works practically for educational purpose.
I also try to fund some countermeasure as i'm currently programming a software with a friend that contains dll and an executable in a archive.
Currently the best solution i found is to check checksum of dll loaded. Are there better solution ? I want avoid solution like check EV certificat etc...
According the exploitation of dll hijacking if i understand well, the attacker just need to replace the dll by a malicious dll that as malicious code that is executed in entrypoint ?
I have created a dll with messagebox code in c, and i have created a buggy code (executable) to make a proof of concept. This worked fine. (here the image : https://ibb.co/GpDF3sP)
But when i try test it with true software on market this doesn't work. (https://ibb.co/PDLxF59 and https://ibb.co/QJP4Hxj dll is not loaded after i changed it) Any idea ?

Attacker must create same DLL export table as in your DLL. Then he just load your original DLL module in fake one and pass all calls to it, so attacker's DLL will be used like a proxy for each call.
Honestly, if you're loading DLL statically with Windows PE loader, checksum and certificate are not so reliable methods. For example, if I have access to filesystem for write, I can replace your original DLL with fake one, start your process in suspended state, replace DLL to original behind your EXE module, resume your process execution (file moving operation is available even DLL file is using). And you can check DLL checksum and it will be correct for you, but actually you will use fake DLL which already loaded in memory.
For protect you may use algorithm:
Do not use static DLL linkage. Load DLL manually using LoadLibraryEx without calling DllMain with flag LOAD_LIBRARY_AS_IMAGE_RESOURCE
Verify checksum of DLL code in memory, not in the file. If checksum is not valid, do not do next steps
Load all DLL dependencies and call DllMain manually <-- this is most complicated step, so you need to resolve all DLL refs by hands
Load required DLL functions using GetProcAddress or by parsing DLL export table manually, and use them
Of course, this can not avoid checksum verification and it is complicated way, but you can prevent most of simple attack methods.
Depends on deep of implementation step #3, some of DLLs will not work, if you didn't implement thread local storage (TLS) calls

Related

DLL not found on certain machine with luajit FFI

I have built Game Music Emu from source to use with Love2d. (Note: I am not very familiar with C/C++.)
In lua I load the dll with FFI and on my computer it works great, but when I sent my friend the app for testing, his machine doesn't recognize the DLL.
I sent him the love2d binaries with the libgme DLL included to make sure he didn't just misplace the DLL file. So what he is running is the exact same thing I am running.
My code looks like this:
ffi.cdef[[ ... ]]
local gme = ffi.load("libgme")
This is the exact error my friend gets:
lovegme.lua:4: cannot load module 'libgme.dll': The specified module could not be found.
Depending on how libgme is compiled you may have some dependencies that are satisfied on your computer (for example, mingw libraries), but not satisfied on the other computer.
I'd try several things: (1) use the full filename in the load command, (2) use "profile" mode in dependency walker to check what is failing during DLL load, or (3) use the same dependency walker on your machine to see what other DLLs libgme may depend upon and include those in your package/installation as well.

Several short questions about COM .net assemblies, regasm, dll, tlb and guids

All question are related to a .net project dll in .net framework 2.0 that exposes itself as COM.
1) If we don't specify any GUIDs in the source code (typelib, classes, interfaces) who is generating the GUIDs? The compiler or regasm?
2) The GUIDs values exists in the dll, in the tlb or in both files?
3) Any developer with the same source code would generate the very same GUIDs independently on the machine where she builds or run regasm?
4) If I run regasm passing existing dll and tlb files, what happens If the dll and the tlb doesn't match? Regasm regenerate the tlb file with uptodate elements and GUIDs? Or it registers the TypeLib with the current tlb file?
5) What is the point of running regasm with dll and tlb parameters set?
Tlb file is part of what you deploy or it is best practice to only deploy the dll and let regasm generate the tlb on the fly?
6) And last question, is tlb really required? What is the point of having a tlb file? Is not all the information already in the registry? What extra info it provides?
7) When unregistering with regasm, what we need to provide? The dll? The Tlb? Both? What happens if dll (or tlb) doesn't match with existing reg entries? If already registered with tlb option but I run regasm unregister with dll only it would delete the TypeLyb entry too?
8) Regarding bitness, regasm will always generate entries under SysWow64 too? The regasm under Framework64 do the same as the one under Framework?
A type library is the exact equivalent of .NET metadata. It is most of all useful to the client programmer, it makes the compiler and the IDE smart about your library. Providing auto-completion and syntax checking so the odds of a mismatch between his code and yours are minimal. The registration step is necessary so your files can be found back. The type library is normally embedded as a resource in the DLL itself, like .NET metadata, but the .NET build model does not make that easy to do. The client compiler uses the type library info to generate the appropriate COM calls. Guids are a big deal because that is what the client compiler needs to use, identifier names play no role. There is a way to use "late binding" using names, the exact equivalent of Reflection in .NET, but that does not involve a type library.
who is generating the GUIDs?
The CLR does. Every .NET interface or class has one, regardless if it is [ComVisible(true)]. Exposed also through the Type.GUID property. If you didn't use the [Guid] attribute on the type then it runs an algorithm to generate the Guid that uses the type declaration as input. Or in other words, if you make any changes to the type then you can be sure that the Guid will have a different value. Which is the basic reason you should never use the [Guid] attribute, unless you have to create an exact drop-in replacement and cannot recompile client code. The TLBID comes from the AssemblyInfo.cs file that was auto-generated when you created the project.
in the dll, in the tlb or in both files?
It only exists in the DLL when you used the [Guid] attribute, but normally it is generated at runtime as explained above. It is always present in the type library, that's how the client compiler knows to create an object of your class and use its interface(s).
would generate the very same GUIDs
Yes, only the type declaration plays a role.
If I run regasm passing existing dll and tlb files
Regasm can only create a type library, as requested with its /tlb option, it cannot take an existing one. It otherwise does the exact same thing as Tlbexp.exe does, use Reflection to enumerate the types in the assembly to find the [ComVisible(true)] ones and generate the matching type library declaration. The extra thing it does is write the registry key for the type library to HKLM/Software/Classes/Typelib. So the client IDE can find it back.
What is the point of running regasm with dll and tlb parameters set?
No real idea with "dll parameter" might mean. As noted above, use /tlb to generate the type library. Whether or not you deploy the type library depends on its usage, if you don't also provide the client code then you should always deploy it so the client programmer can use it. Other usage of the type library is the subject of this post. If you're not sure how the client programmer is going to use your code then always deploy.
Is not all the information already in the registry?
What's in the registry is limited, only enough info to find the type library file back. The description of your interfaces, their method signatures, guids and the CLSID that the factory function needs is in the type library.
When unregistering with regasm, what we need to provide?
Exact same thing as registering it, you only add /unregister. You must also provide /tlb if you used it previously so the TypeLib registry key can be deleted. It can be pretty important to automate this while you are busy developing and testing the library, since the guids are normally auto-generated you can produce a lot of garbage in the registry. As well as ugly head-scratching when you forget to run Regasm. Project > Properties > Build tab, "Register for COM interop" checkbox. But with the downside that you have to run VS elevated so it can write to the registry.
regasm will always generate entries under SysWow64 too?
SysWow64 plays no role, do always avoid deploying to c:\windows. But yes, bitness does matter, the registry is structured so a 64-bit app cannot accidentally create an object in a 32-bit library and die on an ugly exception. And the other way around. A 32-bit client app will read registry keys from HKLM/Software/WOW6432Node, you only get your registry keys there is you used the 32-bit version of Regasm. Notable perhaps is that it is usually fine to run both flavors of Regasm, given that C# code can run on any platform.

Dynamically linked DLL is loaded immediately after starting the application

I've dynamically linked libhunspell.dll (HunSpell) to my application. It works, but there is a dumb problem which I don't know why it happens.
Even before I use LoadLibrary("path\\to\\libhunspell.dll"); to load it and use it, on the start of the application it attempts to load the library by itself. If I place the libhunspell.dll into the path where my main executable resides, it can load it, otherwise it reports an error, immediately after starting the application - This application has failed to start because LIBHUNSPELL.DLL was not found. Re-installing the application may fix this problem. and the application doesn't start.
I would understand if the LoadLibrary would use invalid path but this happens as soon as the executable runs, even before the first statement in WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int) executes (I've tried to place a breakpoint and it doesn't even reach it, so this happens before).
So, as a result, I must place libhunspell.dll in the same folder as my application executable, and not in the path I want.
This is probably easy to fix although I don't what to look for.
So the question is - how do I avoid it loading it immediately and have it wait until I use LoadLibrary call?
Here is how I linked if it can help:
1) compiled libhunspell.dll in Visual Studio 2015 (I used /MT option to link it statically so it doesn't have VC++ Redistributable as a dependency).
2) created import library (libhunspell.lib) using implib.exe -a -c -f libhunspell.lib libhunspell.dll
3) linked that to the source .cpp unit which is using it using #pragma comment(lib, "libhunspell.lib") (it is RAD Studio 2010 so the .lib is required unlike newer versions).
4) later in the same .cpp used LoadLibrary to load this library and used it.
By linking in the import stubs (libhunspell.lib) the OS will load the DLL for you as it is now a static dependency.
One approach would be specify the library as a delayload dependency: /DELAYLOAD:libhunspell.lib via the linker options. You can then call LoadLibrary on the DLL.
The only other option is to stop including the .lib in the linker step, making it truly a dynamic dependency.
I assume you did Add to project a *.lib file for your DLL. That is a kind of "static" linkage done in the App initialization (prior to your forms are created). So it has two disadvantages.
You DLL must be in the same path as the Apps EXE file
Sometimes DLL file name is locked (can not be changed)
The advantage is that you do not need to do any coding for the DLL loading as the VCL do it for you ... so your app should not contain the LoadLibrary,GetProcAddress calls you just include the *.h file with propper import declarations ...
For dynamic linkage you need to remove the *.lib from your project and use WinAPI LoadLibrary + GetProcAddress for loading your DLL as josh poley suggested. Here an example:
Builder C++ calling VC++ class
Beware there was/(is?) a bug in the GetProcAddress preventing from loading all the functions from your DLL in some cases. Especially if the DLL has old legacy mangling of names the count of functions is high and the DLL was created on compiler incompatible with the mangling in question.

Getting out of DLL Hell with Microsoft.VC90.CRT?

I've built a inproc com server dll which I can package as 1 file or many via the build utility py2exe. When I allow all the dependencies to remain external, I have no issues, but bundling as 1 file produces problems.
When the dll is utilized (either registering it or instantiating a com object from it), it immediately loads MSVCR90.DLL from the path c:\windows\winsxs\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.6871_none_50944e7cbcb706e5\MSVCR90.DLL no matter what I do, I can't change that. There is no information that I can find (using Dependency Walker) to indicate what is causing that to load. It just happens magically...
Then, later on it loads that dll again via an explicit call to LoadLibraryA("MSVCR90.dll") (part of some py2exe black box?), but this time it does not look into the winsxs manifests / directory. Instead it looks to the system path and/or will respect a dll redirection. That's when the problem occurs. If I set the system path to start with c:\windows\winsxs\x86_microsoft.vc90.crt...\ it will load the exact same dll and be happy - but if ANY other file is utilized - inclusive of a copy of the EXACT same dll - but at a different path - then the whole thing blows up. It can't handle using two different files.
How can I fix this? Ideally, I've love to make the initial magic loading of the dll draw upon a private assembly, but no matter what I do with manifests or .dll.local etc it will not respect that until this second dll loading takes place.
Note that with the non-bundled dll (external dependencies) it always uses the winsxs MSVCR90.DLL.
I can "fix" my failure to use the dll by forcing the system path to load the winsxs copy, but that is pretty useless for a deployable com server!
The reason is that you DLL has a manifest that tells the module loader to search also in the SxS storage.
You have several choices
Build your DLL using static linkage. Not using any of the MFC-DLLs (see project settings)
Don't use a side by side manifest for the DLL and still use the MFC DLLs. But beware you have to ship those DLL with your DLL in the local path (see DLL search sequence docs)
Use a later build of VS. Later versions of VS don't use the SxS storage any more and there are no manifests for those DLLs any more.
For the 2. see this article in code project. There is an update for VS-2008 [here].
2
Build your DLL

Could we have 2 DLLs with the same name being loaded in one process

I am talking about win32 dlls, those plain pe files. I am confused after I doing a test compared to what I saw in explorer.exe process.
I wrote a test with following modules:(C++)
DLLLoader.exe links to A.dll in the same folder.
B.dll links to A.dll(2) in another folder. (A.dll(2) is a totally different DLL from A.dll, but with the same name)
DLLLoader.exe will load B.dll explicitly through ::LoadLibrary.
Now I start DllLoader.exe, firstly, A.dll will be loaded, but then when it tries to load B.dll, It just failed: I suspect that is because B.dll thinks A.dll is already loaded in process, but in fact, the loaded one is not the one B.dll wanted, the import/export table can't match, so B.dll is failed to load.
This seems to tell us we can't loaded 2 dlls of same name in the same process, even they are of different path.
But when I used process explorer to monitor loaded modules in Windows's explorer.exe process, I could see following 2 dlls being loaded, with same name:
comctl32.dll User Experience Controls Library C:\WINDOWS\WinSxS...\comctl32.dll
comctl32.dll Common Controls Library C:\WINDOWS\system32\comctl32.dll
Could any of you shed some lights on this?
It basically depens on if you load the dll with its full path or only by file name. The LoadLibraryEx docs cover this pretty well:
If lpFileName does not include a path
and there is more than one loaded
module with the same base name and
extension, the function returns a
handle to the module that was loaded
first.
See http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/b3eaa07f-7f92-4693-8aa1-b8fee0b92d2f/ for a good discussion on how this can be done implicitly for WinXP and up, by activation context (manifests) to control the loading.