Detecting the Neutrino Exploit Kit

Bill Miskimen
Sr. Security Analyst

The Neutrino Exploit Kit has made several changes in technique and delivery over the past few years. These changes in techniques, combined with the demise of hugely popular Angler Exploit Kit, have helped Neutrino become one of the most used Exploit Kits on the market today. The group behind Neutrino appears to be updating its exploitation techniques and payloads on almost a monthly basis, if not every few weeks. In this article, we'll look into how the Neutrino Exploit Kit works and some good ways to detect it. We’ll review some high-level details around the kit itself and how front-line defenders can rapidly, easily, and accurately identify Neutrino activity in an enterprise environment – all without needing to understand complex underlying details like compressed flash objects, where coffee comes from, and whether or not the Internet truly is housed in a black box at the top of Big Ben. After reading this, analysts should be able to look at an unlabeled packet capture of reasonable size and quickly identify if any Neutrino activity is present, whether it was successful, and provide a walkthrough/timeline of events around the malicious activity in question.

When trying to identify Neutrino EK traffic in your environment, one of the first things you need to understand is the general flow of a successful infection. In this example we’ll skip over the initial exploit used to deliver the EK since it tends to vary, and instead focus exclusively on traffic around the kit itself. So what does a complete Neutrino exploit chain look like today? Let's start with a basic overview of Neutrino, and some general rules of thumb to go by when analyzing Neutrino traffic.

For the Neutrino Exploit Kit, a complete infection chain (excluding any redirection or gates - so really, from the landing page through payload) consists of four (4) HTTP requests, as pictured in Figure 1 below. These requests are made in the order of:
Landing Page --> Flash Exploit --> "Blank" Chunk --> Malicious Payload

Figure 1 - Three complete exploit chains merged into one PCAP file and filtered for simplicity. As you can see, each successful exploit chain consists of four HTTP requests, with the fourth request containing the malicious payload.

The URI structure for these requests is very similar to that being utilized by Angler in Spring of 2016 before it left the active market, and Neutrino is fairly consistent in its use of file extensions. Here are some rules to go by:

  • The URI itself will amount to gibberish when scrutinized, but may pass casual inspection.
  • Filename extensions will vary for the landing page, "blank" chunk and the payload, but NOT for the flash exploit.
    • Flash exploit will always have a .swf extension
    • Other requests may have no extension, .htm or .html

Neutrino is also very consistent with its use of headers, MIME types and infrastructure:

  • The use of Nginx as the server
  • The use of chunked transfer encoding
  • Consistent MIME types
    • Text/html for the landing page and "blank" chunk
    • Application/x-shockwave-flash for the flash exploit and fingerprinting
    • Application/octet-stream for the obfuscated payload

One final rule-of-thumb with Neutrino involves how you can expect the streams to be reconstructed in a tool like Wireshark. The first three requests generally form one stream, with the payload forming a second stream. Occasionally this rule is broken and you will have three streams: the landing page and flash exploit forming one stream, a second stream for the "blank" chunk, and a third stream for the payload. This is less common but something to keep in mind.

By itself, none of these things serves as a strong indicator, but it does help front-line analysts start to triage potentially malicious traffic and being to narrow-in on Neutrino activity. For example, assuming you were logging standard HTTP response headers (or have access to PCAP), your pseudocode to find what we've just discussed might look something like this:

&& http.content_type "text/html","application/x-shockwave-flash","application/octect-stream"
&& http.server contains "nginx"
&& http.extension "","htm","html","swf"
&& http.request.method == "GET"
where [count(http.request) by host.src, host.dst within timespan(15 seconds)] <= 4

The first HTTP request is to the landing page. Fortunately for us network defenders, the group behind the Neutrino Exploit Kit appears to have opted for simplicity in their landing page design, and this simplicity makes it quite easy to detect. It consists of a predictable HTML structure with very few values that change - see Figure 2 below. We do see infrequent updates to this structure, but each page is generally used for at least a week, sometimes longer. While in use, this is an excellent method of detection, assuming that your visibility isn't restricted as a result of the landing page being Gzip'd (and working with a tool that cannot natively gunzip the content for you).

Figure 2 - Aside from the marked content, the landing page is entirely static across campaigns and domains. When values are identical (such as "vutgcvttj" in the example above), you can expect that pairing to be consistent across landing pages.

To give an idea of how frequently this general structure changes, here is a table listing observed landing page structures since 1 July 2016:

Current landing page: 28 July - 17 August
Landing Page 6: 22 July - 28 July
Landing Page 5: 18 July - 21 July
Landing Page 4: 14 July - 15 July
Landing Page 3: 11 July- 13 July
Landing Page 2: 06 July - 08 July
Landing Page 1: 01 July

After the landing page, the victim is directed to the flash exploit, which is the second HTTP request in our infection chain. We're not going to go into a deep-dive on the contents of this exploit, or how it works - there are plenty of open source resources that show the exploit code and analysis down to the assembly level. Instead, we're going to briefly touch on indicators that you can use as a part of your investigation to determine whether you are truly looking at the Neutrino Exploit Kit. Assuming that this page meets the general rules-of-thumb presented earlier in this blog for Neutrino, the key item to look for in this stream are gibberish variable (symbol) names at the very end of the zlib compressed (CWS) flash file. Below is a sample image, extracted from a reconstructed stream in Wireshark, of just what I mean:

Figure 3 - The symbols exposed in the CWS file are gibberish, a sign that the file’s authors may be attempting to obfuscate their code’s functionality and intentions.

Following the flash exploit, the last HTTP request we see before the payload is what I like to call the "blank chunk," which you will form the response payload. There are two possible variants - one that is truly a "blank" chunk, consisting of no content, and a variant that I call "blank 14". In my experience, unless you are dealing with the AfraidGate campaign, you'll only encounter the first, truly blank variant.

Figure 4 - An example of the "blank chunk" response. Note that this response truly has no content.

Figure 5 -  An example of the "blank 14 chunk" response. This response does contain content, but for the sake of simplicity for Tier 1 analysts, we continue to refer to it as blank.

At this point, if everything worked out according to plan (for the attacker), your next and final stream in the infection chain will be the malicious payload Neutrino so desperately wants to share with the world. Precisely what that payload consists of will vary, but expect delivery to take place with a MIME type of application/octet-stream.

References and Notes:

All PCAP files used to create the images in this blog post were sourced from and Their work is outstanding, and the contribution they provide to the security community is invaluable. If you're not already a regular subscriber to their blog, then I HIGHLY recommend you change that.