I’ve been a huge fan of the Ebowla project and find keying payloads valuable in both standard penetration testing engagements along with red team operations. Using environmental keying helps evade sandbox detection, makes it harder on endpoint security products, and can slow down incident response. There’s not many techniques out there that can have an impact on all the above defenses.
I commonly use scripting languages, such as PowerShell/VBS/JS, as an initial execution vector for phishing or when setting up persistence. I went down the rabbit hole to create GoGreen, which incorporates environmental keying to protect scripting languages from to get the benefits from this technique. Throughout this post I will outline the advantages, limitations, and how incorporating another keying technique can further improve your payloads.
As mentioned above, Ebowla is the first application of environmental keying payloads and the result of Josh Pitt‘s great research into this technique. Please check out the slides from his presentations along with his project. A base understanding of those materials is assumed going forward.
Environmental Keying High Level Review
First off, why is environmental keying powerful? At a high level, we encrypt your “malicious payload” (such as CACTUSTORCH) with a series of variables you expect to be on the target workstation. These variables could be a file path you expect, maybe you know Photoshop will be installed: “C:\Program files 86\Adobe\Photoshop CS6”. Or maybe you expect to know the username, system architecture, and domain name: “jdoeamd64contoso.com”.
The final payload will NOT include the value of these variables, which means the payload does NOT include the decryption key for your final payload. It will search for all file paths on a system, pull in environmental variables, and then try combinations attempting to decrypt the final payload and execute it if successful. Again, if you’re fuzzy on this or want more info, see the research from above in Previous Work.
Environmental Keying with GoGreen
GoGreen takes a lot of what Ebowla offers and just applies it to PowerShell (v2+), JScript, or VBScript.
This is done by the payload by spidering/walking the directory tree from a start directory (such as C:\Program Files) and harvesting all file paths found. Next, it reads in all environment variables specified in the code (which is chosen by you in the config file), and creates all possible combinations (not permutations). Then goes the following steps:
- Loop through all file paths
- For each file path, loop through each combination of environmental vars
- Build a key with: sha512([file path][env var combo])
- Try first 32 chars of sha512 hash above as key
- If error, or sha512(decrypted) doesn’t match payload hash, move onto next key
Below is a sample config file for GoGreen. This will start spidering the file paths at C:\Program Files (x86)” and only go two folder paths deep (for performance). The actual key will be the PathKey, which is keying on whether Office is installed. It will also include generating all possible combinations of the five listed environmental variables, while only using three.
"StartDir": "C:\\Program Files (x86)",
"PathKey": "C:\\Program Files (x86)\\Microsoft Office\\root",
Environmental Keying Trade Offs
As you see above, I only chose a spidering depth of 2. While this will quickly speed up harvesting all the file pahts to start trying to decyrpt, it also makes a far less number of possibilities if you were to not specify a depth at all and grab all folders and files under the start directory. This is a deployment consideration you must take into account and understand your needs. The more environmental variables and more file/folder paths, the longer it will take and the CPU will definitely spike as it goes on.
The limitation of using environmental keying with scripting languages, is the ease of decrypting and finding the final payload once the environmental keys or target system is identified. Obviously, since scripting languages are in cleartext (and not compiled binaries), it is easy to modify the output from GoGreen to determine the final payload.
As an example, let’s say I discover an active phishing attack in my environment. After responding to the event I get my hands on the payload, an HTA. After reviewing the source code it could be determined that it is attempting to decrypt off of environmental variables and I identify the line with “eval”:
The “eval” statement will execute the decrypted payload if the variables exist. I could edit the JScript code inside the HTA to replace “eval” with Wscript.Echo and write it to a new .js file. Finally, I could use some means to execute this script on all the targeted end users’ workstations. If the expected environment variables exist, it will print out the final payload to the screen. I will then either have the shellcode or the C2 server address.
I still see value in using this technique to get through sandbox detections or bypass endpoint security products, and it still may slow down the incident response. Although I think using a compiled binary with Ebowla would be better as you would need to reverse the binary and then likely perform dynamic analysis of the payload with the right environmental values.
I should note, I am a penetration tester by trade and if any blue teamers have a different idea or approach to responding to these types of payloads, let me know!
Strengthening GoGreen with HTTP Keying
I wanted to make my payloads even more difficult for incident responders which reminded me of this blog post on HTTP keying. I noticed this Veil payload type is no longer included in Veil 3.0, but you can still use it in the unsupported version of Veil-Evasion.
HTTP Keying is a technique where you host a webpage somewhere on the Internet. The payload reaches out to this webpage, hashes the HTML response, and uses that hash as the key to decrypt the payload. The benefit here is that you have full control over this decryption key and you can remove it, as you can easily change the pages contents to your liking. Below is two easy examples to demonstrate the power here:
- Create a web page, setup the HTTP keying, then change the page to something else. Have the payload keep checking and trying to decrypt (similar to a beacon). After waiting several hours, switch the web page back to the original and the payload should decrypt and execute your underlying payload.
- You set scheduled task persistence on your beachhead calling back to your longhaul domain. You expect the persistence to call back every day at 9am. You set the expected webpage to decrypt your payload at 8:58am and revert back to a 404 page after you receive your call back.
Those are just two examples that can be further expanded on. Let’s go over how this works with GoGreen. I decided to have GoGreen first setup the HTTP Keying code, and then use environmental keying to mask the HTTP Keying code. The steps go as follows:
- GoGreen uses environmental keying (directory/env vars) to decrypt and execute code
- The code decrypted will handle the HTTP keying, which is executed
- The new executed code will go out to HttpKeyUrl and hash the page
- The new executed code will use the hash and decrypt and execute your payload
The benefit here is at first glance, the payload is doing environmental keying, with no code that initiates an HTTP call. For PowerShell , this means there is no “Net.WebClient” in here.
Due to differing charsets and other side effects of hashing and encrypting text, along with other factors such as different languages, GoGreen will output a “tester” file which can be used to verify that the HTTP key is setup appropriately. To avoid headaches here, it’s recommended to use a simple web page. Even the standard Microsoft 403 page would be benign and something that would be easy to use.
Putting It All Together
Putting all the pieces together, below I have a configuration setup for environmental keys: Office folder path and expecting the target username to be “username”. I also have set the configuration to grab an HTTP key at a given URL and to retry 300 times before giving up and exiting. For more information on how to use GoGreen see the README on the GitHub page. There is also releases for Windows, Linux and Mac for those that don’t want to setup Golang.
GoGreen will generate all the keys and code needed and will also access the site provided in the configuration and determine the HTTP Key. You can also specify a custom key if you prefer with
GoGreen -httpkey <HttpKey>. The result will output both the payload file and an HTTP key “tester” file. I would recommend running the tester file with your HTTP Key page up to ensure the payload format generates the same key.
The payload file is now ready to deploy on your target!
I think keying payloads is incredibly beneficial to offensive operations. If you are dropping persistence with a scripting language you are running a risk if it gets identified by the blue team.
While these keying techniques don’t make it impossible, it may buy you time during an operation to stay in the network and keep your infrastructure protected. It also gives the blue team some new things to learn and be prepared for.