Sunday, November 29, 2015

Here Hold This: Loading malware with legitimate Win32 applications


I do not often talk about OS specific topics. Even more rarely is that OS Windows. I am, after all, an OS agnostic with a "slight" lean towards Linux. Sometimes though, there is a method that is just too good to pass up writing about. "Here, Hold This" is the name I gave to a tactic for Windows post-exploitation persistence in which you cause a legitimate program run at boot to call your Malware startup routine. The exact method has been around pretty much since the inception of the Windows NT model. It takes advantage of the Windows DLL location search order to trick the program into loading a malicious DLL it believes to be legitimate.

I call it "Here, hold this" (or HHT) because you are placing the Malware object in the care of a legitimate program to later run. The first thing to understanding this persistence method is understanding how Windows NT systems look for included DLLs. The first place Windows checks is a Registry HKEY (HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs). If a DLL is listed in the value, Windows jumps right to the system32 folder version. Not useful for what we want. If a DLL is not found in this key Windows begins to search through a set directory structure until it finds a DLL matching the request. According to MSDN(*):
The REG_SZ registry value name is the name of the DLL without the extension. The registry value data is the name of the DLL with the extension. This entry affects only implicitly loaded DLLs, not DLLs loaded using the LoadLibrary() API.

Without this entry, Windows NT uses the following search order to locate the DLL:
  1. The directory of the executable for the process that is loading the DLL.
  2. The current directory of the process that is loading the DLL.
  3. The \WINNT\SYSTEM32 directory.
  4. The \WINNT directory.
  5. A directory listed in the path environment variable.
Using a fictitious program c:\Program Files (x86)\pup\PuppiesWallpaper.exe that loads a fictitious system32 DLL (c:\Windows\SYSTEM32\abc_nw.dll) I will illustrate how this works:
  1. on boot the Windows system runs PuppiesWallpaper.exe
  2. PuppiesWallpaper.exe attempts to load abc_nw.dll (without full path)
  3. Windows checks the registry and sees that abc_nw.dll is NOT a KnownDLL
  4. Windows checks the folder c:\Program Files (x86)\pup\
  5. Windows checks the folder c:\Users\SomeFolder (assuming this is where the process was launched from)
  6. Windows checks the folder c:\Windows\SYSTEM32\
  7. Windows finds and returns c:\Windows\SYSTEM32\abc_nw.dll 
But what if someone places a malicious file named abc_nw.dll in the program's home directory (c:\Program Files (x86)\pup\abc_nw.dll)? Well, you may have guessed that they would effectively short-circuit the above steps to return the malicious DLL instead of the system's. Alternately, a privileged shell may be able to add the DLL into the c:\Windows\SYSTEM\ directory. The key point to remember is that the malicious DLL must in turn load the appropriate system DLL. That way the PuppiesWallpaper.exe does not crash. The system (and therefore the user), is none the wiser.

Fuzzing for Locations (**)

It is possible to use a fuzzing program to find HHT storage locations. Any program that meets these criteria is susceptible:
  1. The process .exe that loads the DLL is not in the System32 folder
  2. The DLL name is not found in the KnownDlls Key
  3. The DLL is not in the same directory as the .exe already
  4. The DLL is not loaded by any other KnownDLL, as this will make that DLL implicitly known as well.
The last requirement is usually the hardest to satisfy. Suppose run32.dll is in the KnownDLL list. All the DLLs it loads are implicitly known. This means Windows will treat them as known DLLs and start the search in the System32 folder. When the first article I found on the subject was written in 2010 (**), this was not the case.

Now, to effectively fuzz the possible path / dll name combinations we need to
  1. Recursively generate a list of KnownDLLs.
  2. List all software started at boot. Remove any program located in System32
    • [HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run] 
    • [HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServices]
    • [HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServicesOnce]
    • [HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\Userinit]
    • [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run]
    • [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce]
    • [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunServices]
    • [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunServicesOnce]
    • [HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows]
    • It may also be loaded from the [Load] or [Run] sections of your WIN.INI file, found in the Windows directory.
  3. List all DLLs loaded by the remaining programs. The next steps are repeated for each DLL:
  • Remove any DLL who's name is in the KnownDLL List
  • Remove any DLL who's parent dir == the software exe's dir
That is it.  The remaining list of Software DLLs can be hijacked by placing the appropriately named DLL in the EXE's folder.

Detecting HHT Persistence

As with most persistence methods: The best defense is to know your system. Use a File System Integrity Checker to monitor for new DLLs. Build a database of DLL hashes and monitor those for changes. This method does leave a trail to investigate, but it is easier to locate if you start watching before the infection. Then you can you have a message that says "c:\Program Files (x86)\pup\abc_nw.dll was added". You can use Tripwire, Samhain, or if you are feeling experimental, you can fire up one of my pet projects: PyzanoFSIC. This is a file system integrity checking program I am actively developing. It would, however, be excellently suited to monitoring for this type of behavior already. I have included a link below (***).

Other options for detection include Signature Based file scanners. The most popular open source versions of these are ClamAV and YARA. Both allow you to generate signatures which can allow you to identify when a DLL may exhibit this kind of process redirection.

Resources

(*) https://support.microsoft.com/en-us/kb/164501
(**) https://www.fireeye.com/blog/threat-research/2010/07/malware-persistence-windows-registry.html
(***) https://github.com/dreilly369/PyzanoFSIC

No comments:

Post a Comment