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.
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.
There were two main problems I have been looking to solve which eventually led me here.
- How can I avoid tools detecting network connections initiated from uncommon applications (such as powershell.exe, mshta.exe, msbuild.exe, etc.)?
- 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:
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!
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.
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.
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.
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!
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.
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.
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?
That’s all from me. I encourage you all to try out the InternetExplorer.Application COM object if you haven’t already!