I have a process that loads an external DLL (sort of a plugin system) where I want to verify that the loaded DLL is signed correctly using Authenticode. After perusing the documentation for WinVerifyTrust and LoadLibrary (and friends) one thing that struck me as significant is that both operations work from a file path to the DLL.
It looks to me that its quite feasible to exploit this to cause my program to load an unsigned DLL, by presenting the program with a signed DLL, causing WinVerifyTrust() to succeed and immediately replacing the DLL with unsigned code before the LoadLibrary() call gets executed (this is a hard race condition, but it can be better controlled if the attacker has some control on the file system, for example when using a networked file system).
The API for WinVerifyTrust() seems to suggest that I can run the verification process on a handle to an open file. If I can open the file, verify the open file handle and then load the library from the same file handle - then I will be safe. Unfortunately LoadLibraryEx() - which would have been my prime suspect for implementing this - documents its hFile parameter as "reserved for future use".
My Next avenue of thought was to load the file contents into memory and then load the DLL from the memory, and I found the library MemoryModule that does this. I was wondering if there is some existing implementation that already goes and combines all this and allows the developer to securely verify and load a DLL, meaning I won't have to write it and maintain it myself.
Any suggestions?
Related
I was reading about it and the part about memory was really confusing. What exactly happens to a DLL after compilation?
Questions that were somewhat bugging me:
Is it loaded into memory only once and all processes that require access to it are given only a pointer to where it is?
When is it loaded? I am sure it isn't just arbitrarily loaded into memory after compilation so is there a special procedure to load it or does Windows load a DLL when a process requires it and keeps it for sharing among other processes?
From the Microsoft docs
Every process that loads the DLL maps it into its virtual address space. After the process loads the DLL into its virtual address, it can call the exported DLL functions.
How does that "mapping" look like? I found that a bit confusing.
I don't know if this is a relevant piece of info but I am specifically interested in custom DLLs (DLLs written by me), not system DLLs
An exe file lists DLLs is wants to link to, so when the loader loads an exe, it loads DLLs that are listed as required, unless they are already loaded. A DLL may run initialization code the first time it loads.
Of course a DLL can be loaded dynamically by name, then it's loaded when the LoadLibrary API call is issued by a program. This is useful to implement dynamically loadable plugins.
Windows keeps a reference counter for each DLL, so when all processes stopped referencing a DLL, either by exiting or explicitly calling FreeLibrary, Windows will unload the DLL, giving it a chance to run any cleanup code.
The idea is quite simple, i.e try to not follow the standard. For example to inject some thing to Firefox, malware need to know that the name of process is 'firefox.exe' or to inject some thing in internet explorer, malware need to know that process is 'iexplorer.exe'. But if Firefox or internet explorer do not follow that convention then it will be hard. Idea is to put a logic to change the name of process. For this the real 'firefox.exe' is replaced with our 'firefox.exe' file. This duplicate file is just a startup , the real Firefox executable is renamed to some `random string.exe'. When system triggers 'firefox.exe', this will open our 'firefox.exe' executable. This executable will in-turn open the real Firefox exectable as 'random string.exe' and also set the dummy process information using the 'SetProcessInformation' API. Using 'SetProcessInformation' we will set false location of the executable so malware is not able to find the real process based on the location.
Can any body suggest how feasible it is (provided SetProcessInformation can set false process location)?
Its probably not worth the trouble.
An attacker just needs a handle to the process, and if you rename the exe you just make it a tiny bit more difficult, but not that much. For example simply monitoring the processes that open the firefox history database or any process that does a DNS lookup for the firefox update server would be good enough for that. Or just MD5 summing all the exes and having a set of known binary images.
Basically if you have some code that can inject DLLs or code into foreign processes you have already lost control of the system.
When my plugin DLL is loaded into the host application's address space, I need to write some data into a file. The problem is that at that point of time this file is already opened by the host process with exclusive write access, and my call to CreateFile fails with ERROR_SHARING_VIOLATION
I wonder, can I somehow obtain the file handle from the host process using WinAPI calls? This looks like a terrible idea, but I really need to write into that file. Does someone have any good ideas about how to resolve this problem?
Open handles can be enumerated via NtQueryInformationProcess and/or NtQuerySystemInformation, but it isn't officially supported (you can find non-Microsoft documentation readily with Google) and may not work in future versions of Windows.
For testing and development purposes, it would be nice to somehow simulate (spurious) file access errors to local files. For example, even if an application has correctly opened a file with the appropriate restrictive sharing flags, it still can happen that an attempt to access the file (through any of the Win32 API functions or your favourite framework, which internally will just call any of the Win32 API functions) can fail.
The only example I ever was able to track down was the virus scanner on a machine, but I guess there could be other reasons. (In this question's comment, Luke mentions something about "File system filter drivers".)
FWIW, I know of a few possibilities to "simulate" file problems, that I do not consider good solutions, either because they require to much manual work or because they don't fit for every app/file:
Place a file on a network drive or removable storage device - that way you can just mess up the device (unplug, disk-full, ...).
Open the application process in Process Explorer and close the handle of the file you want to test.
So the question really is if there are any ((semi)automated) tools that can mess up file access (on an NTFS drive) even though an application has already opened a file with appropriate (for the app) sharing flags.
Holodeck purports to allow Win32 API hooking, which would enable you to manipulate return codes as needed for Fault Injection.
If your API set of interest is well-defined, you could probably do this yourself using the Import Address Table approach described here.
So a .exe file is a file that can be executed by windows, but what exactly does it contain? Assembly language that's processor specific? Or some sort of intermediate statement that's recognized by windows which turns it into assembly for a specific processor? What exactly does windows do with the file when it "executes" it?
MSDN has an article "An In-Depth Look into the Win32 Portable Executable File Format" that describes the structure of an executable file.
Basically, a .exe contains several blobs of data and instructions on how they should be loaded into memory. Some of these sections happen to contain machine code that can be executed (other sections contain program data, resources, relocation information, import information, etc.)
I suggest you get a copy of Windows Internals for a full description of what happens when you run an exe.
For a native executable, the machine code is platform specific. The .exe's header indicates what platform the .exe is for.
When running a native .exe the following happens (grossly simplified):
A process object is created.
The exe file is read into that process's memory. Different sections of the .exe (code, data, etc.) are mapped in separately and given different permissions (code is execute, data is read/write, constants are read-only).
Relocations occur in the .exe (addresses get patched if the .exe was not loaded at its preferred address.)
The import table is walked and dependent DLL's are loaded.
DLL's are mapped in a similar method to .exe's, with relocations occuring and their dependent DLL's being loaded. Imported functions from DLL's are resolved.
The process starts execution at an initial stub in NTDLL.
The initial loader stub runs the entry points for each DLL, and then jumps to the entry point of the .exe.
Managed executables contain MSIL (Microsoft Intermediate Language) and may be compiled so they can target any CPU that the CLR supports. I am not that familiar with the inner workings of the CLR loader (what native code initially runs to boot strap the CLR and start interpreting the MSIL) - perhaps someone else can elaborate on that.
I can tell you what the first two bytes in .exe files contain - 'MZ'. i mean the characters 'MZ'.
It actually represents: Mark Zbikowski. The guy who designed the exe file format.
http://en.wikipedia.org/wiki/Mark_Zbikowski
1's and 0's!
This wikipedia link will give you all the info you need on the Portable Executable format used for Windows applications.
An EXE file is really a type of file known as a Portable Executable. It contains binary data, which can be read by the processor and executed (essentially x86 instructions.) There's also a lot of header data and other miscellaneous content. The actual executable code is located in a section called .text, and is stored as machine instructions (processor specific). This code (as well as other parts of the .EXE) are put into memory, and the CPU is sent to it, where it starts executing. (Note that there's much more interfaces actually happening; this is a simplified explanation).