InternetExplorer.Application for C2

Introduction

Given the time of year, I want to share with everyone the gift that keeps giving this holiday season. This isn’t a groundbreaking revelation, it’s a well-known COM object that is already included in the Empire project. The InternetExplorer.Application object gives attackers a programmatic interface to use Internet Explorer (or Edge) as a vehicle for communicating with their command-and-control (C2) servers. There’s a ton of advantages to this and I feel this COM object hasn’t received the attention it deserves.

Previous Work

To the best of my knowledge Empire is the best “weaponized” example of using this COM object for C2 operations. It looks like @harmjoy wrote the ie_com listener and also mentions it in this post. All the PowerShell code used in this post stemmed from the Empire implementation. It’s also worth mentioning, the Thunderstruck module also uses the IE COM object!

This was a fantastic post by @Arno0x0x which demonstrated using websockets for C2, and his implementation uses the IE COM object as the vehicle for communications. He does a great job of demonstrating the power of this COM object.

I’m sure there’s more work out there, but I think those two are a good starting point.

The Problem

There were two main problems I have been looking to solve which eventually led me here.

  1. How can I avoid tools detecting network connections initiated from uncommon applications (such as powershell.exe, mshta.exe, msbuild.exe, etc.)?
  2. I’d like to use domain fronting from JS, VBS or VBA!

Problem 1 – Evading detective controls

With the emergence of Sysmon, EDR products, and other detective controls on endpoints, I get worried about the capabilities of defenders. For example, Sysmon Event ID 3 detects initiated network connections and this can easily be set up to alert on HTTP connections started from applications such as powershell.exe or mshta.exe. I’ve also seen some security products in client networks that detect or even prevent initiated network connections from “unapproved” applications. Building off the “live off the land” technique that we all know and love, the IE COM object quickly came into my head.

Problem 2 – Domain Fronting with COM objects

There have been some use cases where it would be nice to use domain fronting from JScript, VBScript or VBA. Even in situations where you may just want to use JS/VBS/VBA to pull down and execute more code, domain fronting can help make sure you’re able to get out an environment with restrictive egress controls. If you are unfamiliar with domain fronting, here’s the initial research paper, and two blog posts which help show practical use cases from Cobalt Strike and MDSec.

These are the COM objects that I have used in the past for HTTP communications: Msxml2.XMLHTTP, Microsoft.XMLHTTP, and WinHttp.WinHttpRequest.5.1. Of those three, only the first two are proxy aware. All three use the “setRequestHeader” method to set or override HTTP request headers, although it is not possible to overwrite the “Host” header. When I started testing the IE COM object, it was found that it is possible to set the “Host” header to an arbitrary value, which is the requirement for domain fronting.

What is InternetExplorer.Application?

The InternetExplorer.Application COM object implements the IWebBrowser2 interface. If you’re a fan of James Forshaw’s OleViewDotNet you’ll need to investigate the IWebBrowser2 interface to see all the methods and properties. A snippet from OleViewDotNet is below:

oleview-ie_com

Properties exist to make sure the window stays hidden to the end user and naturally there are methods to browse to various websites and get access to the HTML via the Document property. Below is a snippet This property can be accessed in C# or C++ by casting a IHTMLDocument, IHTMLDocument2, or IHTMLDocument3 interface. Enough on the low level code stuff, see below for PoC’s in JScript, VBScript, PowerShell, and C#.

Note: Most places you will see online will recommend adding the references MSHTML and SHDocVw to your C# project which will allow easy use of this COM object. I found that this may cause problems in certain situations, such as execution under DotNetToJscript or execution from a WMI Event Listener. The PoC C# code accesses these COM objects via reflection and I haven’t had any errors since, feedback welcome!

https://gist.github.com/leoloobeek/f468d34e81795239a8f8bac03646cf59

PowerShell Download Cradle

Regardless of whether you feel PowerShell’s days are nearly over, it seems wrong to not share a PowerShell oneliner to download and execute with the IE COM object. (aka PowerShell IEX download cradle). This cradle pulls down a base64 string, decodes it and executes. This is helpful as some characters in larger scripts may be rendered differently in IE, see the Limitations section for more info.

ie_com-mimikatz

Limitations and Caveats

When using this COM object it’s important to keep in mind that you are using Internet Explorer (or Edge). Rather than other ways we are more familiar with, such as PowerShell’s Net.WebClient, IE is actually browsing to the URL you specify rather than sending an HTTP request and getting the results into a variable. Below is a list of some issues you may run into.

Valid SSL/TLS certificate required

Internet Explorer (and Edge) don’t like self-signed certificates and will warn the user when attempting to access a site with an invalid certificate. This behavior will occur with the COM object and you will not get the HTML response you’re expecting. If you want to use secure communications, you will need a valid cert, otherwise you will have to use HTTP.

Browsing to non-HTML sources may result in a file download

If you browse out to a URL with, for example, a .exe extension, IE will handle it just as it normally would, by attempting a file download (and SmartScreen filter probably will get upset). Given this information, its likely not a good option for getting a raw byte stream unless you base64 encode it.

Browsing to non-HTML sources may result in unexpected HTML tags

Depending on the content-type returned from the HTTP server, IE will try to help out the end user by throwing in some extra HTML tags. For example, if you browse out to a URL with a .txt extension and the server responds with content-type: text/plain, it will place <pre></pre> tags outside of your content. If you were planning on taking that text and sending it right into execution, you will run into problems. If you control the web server, make the appropriate configuration or code changes to always return text/html as the content type. Make sure to use “.html” or similar extensions with Apache and you shouldn’t run into any issues.

Have to account for IE being “busy”

If you are browsing to a page with lots of content, missing content, or over a high latency network, IE will need time to get the contents for the page properly. For this, it’s important to check the ‘Busy’ property and sleep your script until it’s no longer busy. If you don’t wait, you may not get all of the returned HTML. All examples in the PoC link above include this.

Can’t Set Cookies

You can override or add HTTP request headers, but you can’t set or override the Cookie header. If your C2 identifies itself using the Cookies headers, I would recommend changing to a different HTTP request header. Empire has used CF-Ray, a common HTTP request header with Cloudflare HTTP traffic. Another option is the If-None-Match header.

Cookie History and Cache

Just like a normal browsing session, all cookies issued will be saved by IE. IE will also cache pages if you don’t have the appropriate cache control headers being sent from the server. It should be noted, all browsing does NOT get saved in the browsing history.

Understand You’re Creating Processes

This is probably obvious, but worth mentioning if you try to limit your process footprint during operations. When you create the IE COM object it will create two IE processes and they will exist until you use the ‘Quit’ method.

Example

Here’s an example to tie in everything and demonstrate the capabilities. For simplicity, we’ll assume a user fell for a phish and the execution would write an HTA file to disk and use mshta.exe to execute it. Why not call the HTA from a web server (e.g. mshta.exe https://domain.com/myhta.hta)? Well I want to avoid any network communications initiated from an exe that isn’t Internet Explorer (or Edge), Check out keying if you want to protect your payload if writing to disk.

The JScript within the HTA will call out to a web server with the IE COM object and obtain additional JScript, base64 encoded. This additional JScript could be C# created with DotNetToJScript. The HTA will then base64 decode the HTTP response and run it with eval(). This will get us to C# execution which is more powerful than JScript. The C# could also use the IE COM object for all continuing network communications.

On top of that, all will go through domain fronting (see https://github.com/vysec/DomainFrontingLists for a good list of frontable domains). I like www.irs.com for the upcoming tax season!

IE COM diagram

Below is sample contents for an HTA file that matches this example:

Open Source Use Cases

Recently a PR I sent into Empire got merged in allowing for domain fronting with the ie_com listener so feel free to play with that! Another good use case of this COM object would be with the TrevorC2. TrevorC2 embeds its taskings in valid HTML and as this COM object works best with accessing HTML from web pages, I think they would be a perfect match!

Defense

Daniel Bohannon @danielhbohannon brought up a great IoC for detection of using the IE COM object. The process creating and using the IE COM object will load ieproxy.dll. By looking for any process loading that DLL (that isn’t iexplore.exe) would be a great way to find attackers attempting to use this COM object.

Below is what this looks like from Sysinternals’ ProcMon when using cscript.exe to call JScript which uses the IE COM object.

ieproxy-load-procmon

With this information, and Daniel pointed this out, we can use Sysmon EID 7 to look for applications loading the ieproxy.dll image. Below is what I added to my Sysmon configuration file to catch any process that isn’t Internet Explorer loading ieproxy.dll.

And the result when using cscript.exe to call JScript to use the IE COM object.

ieproxy-load-sysmon

While we evaded some defenses, other indicators can be found to detect attackers. Other options for detecting this use is to look at other layers of defense, such as looking at network traffic. Has an employee been connecting to websites at abnormal hours? Is there a pattern that indicates automated beaconing behavior? Is an endpoint connecting to an uncategorized domain that has a domain age of 5 days?

Conclusion

That’s all from me. I encourage you all to try out the InternetExplorer.Application COM object if you haven’t already!

Happy Holidays!

Keying Payloads for Scripting Languages

Introduction

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.

Previous Work

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.

Also, check out this blog post from @Killswitch_GUI about HTTP keying. More on that in a bit!

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:

  1. Loop through all file paths
  2. For each file path, loop through each combination of environmental vars
  3. Build a key with: sha512([file path][env var combo])
  4. Try first 32 chars of sha512 hash above as key
  5. 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.

{
"Language": "jscript",
"WSHAutoVersion": "Yes",

"StartDir": "C:\\Program Files (x86)",
"Depth": "2",
"PathKey": "C:\\Program Files (x86)\\Microsoft Office\\root",

"EnvVars": {
"USERNAME": "jdoe",
"COMPUTERNAME": "win7pc35",
"USERDNSDOMAIN": "contoso",
"PROCESSOR_ARCHITECTURE": "",
"LOGONSERVER": ""
},

"Payload": "",
"PayloadPath": "/tmp/CACTUSTORCH.js",
"MinusBytes": "3"
}

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.

GoGreen’s Limitation

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”:

gogreen-eval-statement
Excerpt from GoGreen JScript output highlighting “eval” statement

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:

  1. GoGreen uses environmental keying (directory/env vars) to decrypt and execute code
  2. The code decrypted will handle the HTTP keying, which is executed
  3. The new executed code will go out to HttpKeyUrl and hash the page
  4. The new executed code will use the hash and decrypt and execute your payload
GoGreen Flow
GoGreen Flow

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.

I don’t want to only push GoGreen here, this can also be done by generating a payload with Veil-Evasion to do HTTP Keying and then take the output and put it through Ebowla.

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-example
Example GoGreen configuration and execution

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.

gogreen-httpkey-tester
Running the HTTP Key tester file to ensure key/hashing works as expected

The payload file is now ready to deploy on your target!

Finishing Up

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.

Keying payloads is another cog in your offense-in-depth strategy, and strong when used with obfuscation, red team infrastructure, and other popular techniques in the industry right now.