NETRESEC Network Security Blog - Tag : C2

Targeting Process for the SolarWinds Backdoor

The SolarWinds Orion backdoor, known as SUNBURST or Solorigate, has been analyzed by numerous experts from Microsoft, FireEye and several anti-virus vendors. However, we have noticed that many of the published reports are either lacking or incorrect in how they describe the steps involved when a client gets targeted by the threat actors. We have therefore decided to publish this writeup, which is based on the analysis we did of the SolarWinds backdoor when creating our SunburstDomainDecoder tool.

UPDATE March 1, 2021

Fixed errors in the Stage 2 beacon structure and added a CyberChef recipe link. DNS queries are not DGA related

The DNS communication between the backdoored SolarWinds Orion clients and the authoritative name server for is not caused by a Domain Generation Algorithm (DGA), it's actually a fully functional two-way communication C2 channel. The clients encode information, such as the internal AD domain and installed security applications into the DNS queries and the DNS responses from the name server are used to instruct the clients to continue beaconing, stop beaconing or to target a client by proceeding to what we call Stage 2 operation. Thus, the authoritative name server for was actually the C2 server for Stage 1 and 2 operation of the SolarWinds backdoor.

SolarWinds Backdoor State Diagram

Image: SolarWinds Backdoor State Diagram

Command: Continue Beaconing

The default response from the name server is the "Continue Beaconing" command, which indicates that the threat actors have not yet decided if the SolarWinds client is of interest for further activity. Receiving a DNS A record in any of the following net ranges instructs the SolarWinds backdoor to continue beaconing:


In "Stage 1" operation the SUNBURST client starts out in the "New" mode where it exfiltrates the internal AD domain name. The AD domain data is often split into multiple DNS queries to reduce the length of each DNS query. The client later proceeds to the "Append" mode when the full AD domain has been exfiltrated. In "Append" mode the client transmits a list of installed or running security applications to the DNS C2 server, as we have described in our Extracting Security Products from SUNBURST DNS Beacons blog post. The client remains in Append mode until it gets either terminated or targeted.

Note: It is also possible to reset a client back to the "New" mode with a so-called "Ipx" command, but that is out of scope for this blog post.

Command: Stop Beaconing

The stop beaconing command terminates the DNS beaconing, so that the client no longer retrieves any commands from the C2 server. The C2 communication is stopped after receiving a DNS DNS A or AAAA record in any of the following ranges:

  • fc00:: - fe00::
  • fec0:: - ffc0::
  • ff00::

Command: Target Client

A SUNBURST client that has been "targeted" will change a flag called rec.dnssec in the source code from false to true. We call this flag the "Stage 2" flag, which must be set in order for the client to accept a CNAME record and proceed to Stage 3. Symantec refer to the Stage 2 flag as "a bit flag representing whether the previous DNS response successfully contained partial or full instructions to start the secondary HTTP communication channel".

A DNS A record in any of the following three IP ranges can be used to set the "Stage 2" flag:


The state of the Stage 2 flag is actually signaled in the DNS queries, which is how we managed to identify the AD domains of 23 targeted organizations just by analyzing SUNBURST DNS queries.

Stage 2 DNS Request Structure

The structure of the SUNBURST DNS queries in Stage 1 is pretty well described by Prevasio and Symantec, so we will not cover those in this blog post. Instead we will focus specifically on the structure of the DNS queries transmitted in Stage 2 operation, where the clients request a CNAME record from the name server.

As we have explained previously the exfiltrated data gets base32 encoded, using the custom alphabet "ph2eifo3n5utg1j8d94qrvbmk0sal76c", in order to ensure that only valid domain name characters are used in the DNS beacons.

The structure of the Stage 2 request, before it gets base32 encoded and appended as an subdomain, looks like this:

Field Size Description
XOR Key 8 bits A value between 0x01 and 0x7F used to XOR encrypt the rest of the data.
GUID 64 bits Client ID encrypted using 16 bit rotating XOR with the last 15 bits of Timestamp and the Stage 2 flag.
Packet Type 4 bits A value of 0x1, could in theory be 0x2 but that's very unlikely.
Timestamp 19 bits Number of 30 minute periods since start of 2010 (UTC).
Stage 2 Flag 1 bit A flag set to "1" in Stage 2 operation, otherwise "0".
SolarWinds Backdoor Stage 2 DNS Beacon Structure

Image: Stage 2 beacon structure of the SolarWinds backdoor

The base32 encoding not only uses a custom alphabet, it also employs a reversed endianess and byte order compared to "normal" implementations. We have created a CyberChef recipe that performs this custom base32 decoding, so that the structure can be verified more easily. A list with 45 different Stage 2 subdomains can be found in our Finding Targeted SUNBURST Victims with pDNS blog post. Feel free to replace the input to our CyberChef recipe with any of those subdomains.

Sleep Timers

The DNS responses from the name server not only controls how the SolarWinds backdoor should transition between the various stages, it also controls for how long the backdoor should wait before sending the next DNS beacon.

The delay is assigned by AND-ing the last octet of the received IP address with bitmask 0x54. The result from the AND operation is then used to select a sleep interval in the table below, within which the client picks a random number of minutes to sleep.

AND Result Name Sleep Interval
0x00 1 hour 30-120 minutes
0x04 4 hours 240-300 minutes
0x10 8 hours 480-600 minutes
0x14 1 day 1440-1560 minutes
0x40 3 days 4320-5760 minutes
0x44 1 week 10020-10140 minutes
0x50 2 weeks 20100-20220 minutes
0x54 1 month 43140-43260 minutes

An exception to the table above is clients that have entered Stage 2, which will only wait one to three minutes before requesting a CNAME.

Example DNS C2 for a Non-Targeted Client

Below is an example of DNS queries and responses from a SUNBURST client that wasn't targeted by the threat actors. These particular queries and responses come from a post on SolarWinds' community forum.

  • 2020-07-04 00:03 UTC
    Query: if9prvp9o36mhihw2hrs260g12eu1 ⇒ AD domain "omeros.local"
    Response: ⇒ sleep 1h, then Continue
  • 2020-07-04 01:08 UTC
    Query: hnhb3v1b37dvv09icg0edp0 ⇒ Carbon Black is running
    Response: ⇒ sleep 1 day, then Continue
  • 2020-07-05 01:15 UTC
    Query: ea99hr2sfen95nkjlc5g ⇒ Nothing new to report
    Response: ⇒ sleep 1 day, then Continue
  • 2020-07-06 02:42 UTC
    Query: 707gigk9vbc923hf27fe ⇒ Nothing new to report
    Response: ⇒ sleep 1 day, then Continue
  • 2020-07-07 03:52 UTC
    Query: 6eivqct649pcg0g16ol4 ⇒ Nothing new to report
    Response: ⇒ Stop DNS beacon

Note: Queried domain names in this list are subdomains of

Example DNS C2 for a Targeted Client

Disclaimer: We have very few DNS queries and responses for targeted victims, hence the transactions below are improvised based on data from VriesHd, Joe Słowik and FireEye. Please view these transactions as an example of what the communication might look like for a targeted victim rather than what actually happened to this particular target.

  • 2020-06-11 04:00 UTC
    Query: r8stkst71ebqgj66ervisu10bdohu0gt ⇒ AD domain, part 1 "central.pima.g"
    Response: ⇒ Sleep 1h, then Continue
  • 2020-06-11 05:00 UTC
    Query: ulfmcf44qd58t9e82w ⇒ AD domain, part 2 "ov"
    Response: ⇒ Sleep 1h, then Continue
  • 2020-06-11 06:00 UTC
    Query: p50jllhvhmoti8mpbf6p2di ⇒ Nothing to report
    Response: ⇒ Sleep 8h, then Continue
  • 2020-06-11 14:00 UTC
    Query: (?) ⇒ Nothing new to report
    Response: ⇒ Sleep 8h, then Continue
  • 2020-06-11 22:35 UTC
    Query: j5uqlssr1hfqnn8hkf172mp ⇒ Nothing to report
    Response: ⇒ Target client for Stage 2 operation (1-3 minutes sleep)
  • 2020-06-11 22:37 UTC
    Query: 7sbvaemscs0mc925tb99 ⇒ Client in Stage 2 operation, requesting CNAME
    Response: ⇒ CNAME for Stage 3 HTTPS C2 server

Note: Queried domains in this list are subdomains of


We hope this blog post clears up any misunderstandings regarding the targeting process of the SolarWinds backdoor and highlights the significance of the Stage 2 flag.

We warmly welcome any feedback or questions you might have regarding this writeup, please feel free to contact us or reach out to us through Twitter.

Posted by Erik Hjelmvik on Wednesday, 17 February 2021 20:22:00 (UTC/GMT)

Tags: #SolarWinds #SUNBURST #Solorigate #FireEye #Microsoft #CNAME #STAGE2 #DNS #C2 #ASCII-art

More... Share  |  Facebook   Twitter   Reddit   Hacker News Short URL:

Finding Targeted SUNBURST Victims with pDNS

Our SunburstDomainDecoder tool can now be used to identify SUNBURST victims that have been explicitly targeted by the attackers. The only input needed is passive DNS (pDNS) data for subdomains.

Companies and organizations that have installed trojanized a SolarWinds Orion update containing the SUBURST backdoor will send DNS queries for seemingly random subdomains of Some of these DNS queries actually contain the victim's internal AD domain encoded into the subdomain, as explained in our blog post Reassembling Victim Domain Fragments from SUNBURST DNS.

Three Stages of SUNBURST Backdoor Operation

Most SUNBURST victims were luckily not targeted by the attackers. This means that the backdoor never made it past "STAGE1" of the infection process. Nevertheless, the attackers did choose to proceed to "STAGE2" with some victims. As explained in FireEye's blog post SUNBURST Additional Technical Details, the "C2 coordinator" can proceed to the next stage by responding with a DNS A record pointing to an IP address within any of these three ranges:


According to FireEye's "Diagram of actor operations and usage of SUNBURST", the decision to proceed to the next stage is based upon whether or not the victim's internal AD domain is "interesting to attack".

Note: "STAGE2" is referred to as "associated mode" in FireEye's blog post.

SUNBURST backdoors that have entered STAGE2 will allow CNAME records in DNS responses to be used as new C2 domains.

Sunburst stages 1 to 3 (passive, associated and active)

We have discovered that the SUNBURST backdoor actually uses a single bit in the queried subdomain in order to flag that it has entered STAGE2 and is accepting new C2 domains in CNAME records. This bit is called flag, ext or dnssec in the malicious SUNBURST implant and can be extracted from DNS queries that have an encoded timestamp, such as those indicating which security products that are installed.

Detecting STAGE2 DNS Requests

Our SunburstDomainDecoder tool has now been updated to include a "STAGE2" tag in the output for DNS queries containing this stage 2 flag. This means that organizations like national CERTs, who perform incident response coordination and victim notification, can now use SunburstDomainDecoder in order to identify and notify targeted SUNBURST victims that have entered STAGE2.

Here's the output we get when feeding SunburstDomainDecoder with Bambenek's uniq-hostnames.txt passive DNS data and only displaying lines containing "STAGE2":

SunburstDomainDecoder.exe < uniq-hostnames.txt | findstr STAGE2
22334A7227544B1E 2020-09-29T04:00:00.0000000Z,STAGE2 5qbtj04rcbp3tiq8bo6t
FC07EB59E028D3EE 2020-06-13T09:00:00.0000000Z,STAGE2 6a57jk2ba1d9keg15cbg
1D71011E992C3D68 2020-06-11T22:30:00.0000000Z,STAGE2 7sbvaemscs0mc925tb99
F90BDDB47E495629 2020-06-13T08:30:00.0000000Z,STAGE2 gq1h856599gqh538acqn
DB7DE5B93573A3F7 2020-06-20T02:30:00.0000000Z,STAGE2 ihvpgv9psvq02ffo77et
3C327147876E6EA4 2020-07-22T17:00:00.0000000Z,STAGE2 k5kcubuassl3alrf7gm3
3C327147876E6EA4 2020-07-23T18:30:00.0000000Z,STAGE2 mhdosoksaccf9sni9icp

Most of these subdomains are listed in FireEye's Indicator_Release_NBIs.csv file as having CNAME pointers to other SUNBURST C2 domains like: freescanonline[.]com, deftsecurity[.]com and thedoccloud[.]com. But the first domain, with GUID 22334A7227544B1E, was actually not part of FireEye's IOC data.

Even more STAGE2 domains and GUID values can be found by analyzing other passive DNS resources, such as this passive DNS dump on pastebin by Rohit Bansal.

curl -s | SunburstDomainDecoder.exe | findstr STAGE2
E258332529826721 2020-07-18T05:00:00.0000000Z,STAGE2 1dbecfd99ku6fi2e5fjb
2039AFE13E5307A1 2020-05-30T14:30:00.0000000Z,STAGE2 4n4vte5gmor7j9lpegsf
22334A7227544B1E 2020-09-29T04:00:00.0000000Z,STAGE2 5qbtj04rcbp3tiq8bo6t
FC07EB59E028D3EE 2020-06-13T09:00:00.0000000Z,STAGE2 6a57jk2ba1d9keg15cbg
1D71011E992C3D68 2020-06-11T22:30:00.0000000Z,STAGE2 7sbvaemscs0mc925tb99
1D71011E992C3D68 2020-06-11T22:30:00.0000000Z,STAGE2 7sbvaemscs0mc925tb99
F90BDDB47E495629 2020-06-13T08:30:00.0000000Z,STAGE2 gq1h856599gqh538acqn
F90BDDB47E495629 2020-06-13T08:30:00.0000000Z,STAGE2 gq1h856599gqh538acqn
DB7DE5B93573A3F7 2020-06-20T02:30:00.0000000Z,STAGE2 ihvpgv9psvq02ffo77et
DB7DE5B93573A3F7 2020-06-20T02:30:00.0000000Z,STAGE2 ihvpgv9psvq02ffo77et
3C327147876E6EA4 2020-07-23T18:30:00.0000000Z,STAGE2 mhdosoksaccf9sni9icp

After removing the domains already present in FireEye's IOC we're left with the following FQDN's that have been requested by SUNBURST backdoors in STAGE2:


Update January 7, 2021

Paul Vixie kindly shared his SunburstDomainDecoder output on Twitter yesterday. Paul's results show that the victim with GUID FC07EB59E028D3EE, which corresponds to the "[.]com" CNAME entry in FireEye's IOC, was Pima County. This means that 3C327147876E6EA4 is the only GUID among the CNAME records published by FireEye that cannot yet be tied to a victim organization. Paul's data also reveals two new STAGE2 victim GUIDs (65A28A36F24D379D and 8D2267C5A00796DA).

Update January 12, 2021

With help of SunburstDomainDecoder 1.9 and passive DNS data from Dancho Danchev we've been able to verify that Palo Alto have installed the maliocous SUNBURST backdoor and that it entered into STAGE2 opreration on September 29, 2020. Palo Alto's CEO Nikesh Arora has confirmed that they were hit by SUNBURST (or "SolarStorm" as they call it).

Update January 25, 2021

On December 17 VriesHd tweeted a link to a Google Docs spreatsheet containing aggregated SUNBURST DNS request data.

Might be helpfull with the SolarWinds/SUNBURST data to combine one another, so here's all the data (subdomain, region, first seen date, decrypted DGA) that I'm personally aware of in a Google sheet atm. Feel free to comment with new or updated information

One month later VriesHd made some substatial additions to the "SB2" spreadsheet, which by then contained several new STAGE2 victims. We have since then actively been trying to reach out to the targeted organizations, either directly or through CERT organizations, who perform incident response coordination and help with the victim notification process. VriesHd's passive DNS collection has now been incorporated into the SUNBURST STAGE2 Victim Table below.

Targeted SUNBURST Victims

Here's a summary of the STAGE2 beacons from SUNBURST victims that can be extracted from publicly available data:

GUID Subdomain Timestamp (UTC) AD Domain
FF1E34A864BCE106 dh1usc8287hr46bia74a 2020-05-14 14:30 nsanet.local
E5E2AD2B6DE697D6 70fov85qclvubqhf9vlh 2020-05-16 19:30
FF1E34A864BCE106 2die0g7i5kgkki628gaj 2020-05-18 11:30 nsanet.local
3E8DF7FF13FC8D38 7hpaqi751fqoei2fdv8m 2020-05-18 16:30 HQ.FIDELIS
FF1E34A864BCE106 tsem12v1rn620hatfol2 2020-05-20 14:30 nsanet.local
FF1E34A864BCE106 a0hmuoveln2400sfvf6n 2020-05-20 16:30 nsanet.local
0C1A5A27B297FE46 k0biaol9fc84ummfn7vi 2020-05-26 11:30
A887B592B7E5B550 m4apr0vu9qnomtun3b9t 2020-05-26 20:00 WincoreWindows.local
2039AFE13E5307A1 4n4vte5gmor7j9lpegsf 2020-05-30 14:30
06A4EA63C80EE24A 9q5jifedn8aflr4ge3nu 2020-05-31 12:00
9850F550BD1010F2 gth7uravpvaapoi86834 2020-05-31 20:00
E5E2AD2B6DE697D6 8k56mm0b876uvf5e7rd3 2020-06-01 19:00
2039AFE13E5307A1 laog1ushfp80e3f18cjg 2020-06-03 01:30
06A4EA63C80EE24A ntlcvjpqc57t9kb8ac75 2020-06-03 23:30
1D71011E992C3D68 7sbvaemscs0mc925tb99 2020-06-11 22:30
F90BDDB47E495629 gq1h856599gqh538acqn 2020-06-13 08:30
FC07EB59E028D3EE 6a57jk2ba1d9keg15cbg 2020-06-13 09:00
583141933D242B0D f25k66k5hu68fneu7ocd 2020-06-16 06:00 logitech.local
52CE2BAFD69B2D0E f2co92njkm9od5eu7btg 2020-06-16 18:30
FACC72E2207CD69F rkspr9a19fl8r5ipggi1 2020-06-17 01:00 fox.local
3256C1BCAF74B5FC p0a7jjdp4eq9o2vok1mt 2020-06-18 07:00
92DC5436D54898CD lusq9mg6j1e3jii5f66o 2020-06-18 17:30
DB7DE5B93573A3F7 ihvpgv9psvq02ffo77et 2020-06-20 02:30
59956D687A42F160 o49qi0qbfm37o6jul639 2020-06-23 06:00 wctc.msft
123EDA14721C3602 p5iokg3v9tntqcbo77p2 2020-06-29 08:30
123EDA14721C3602 84v0j8kkbvqf8ntt4o9f 2020-06-30 10:30
2F52CFFCD8993B63 0tvuasje2vc2i2413m6i 2020-07-01 16:30 mgt.srb.europa*
65A28A36F24D379D 7u32o0m6ureci8h5eo6k 2020-07-02 01:00
2F52CFFCD8993B63 en1clufg22h2uca27ro3 2020-07-03 06:00 mgt.srb.europa*
2F52CFFCD8993B63 s2r15kp335mnlq65i6ce 2020-07-03 09:00 mgt.srb.europa*
DB4013DDA16F6A40 up1vj67jjj9tpvceu7ak 2020-07-08 01:00 los.local
123EDA14721C3602 l0vos8o9m5p3m8of7g96 2020-07-10 22:00
E5E2AD2B6DE697D6 8kr7r16da442u75egv1s 2020-07-15 14:00
A13731B17632C726 ttj6cro8jm6cfma8noo7 2020-07-17 12:30
E5E2AD2B6DE697D6 gh1so69rl1sgrgf38gr5 2020-07-17 15:00
E258332529826721 1dbecfd99ku6fi2e5fjb 2020-07-18 05:00
123EDA14721C3602 epm95unblvj984s2ovqh 2020-07-22 11:00
3C327147876E6EA4 k5kcubuassl3alrf7gm3 2020-07-22 17:00
3C327147876E6EA4 mhdosoksaccf9sni9icp 2020-07-23 18:30
F2C9AC93206ABF47 onpqb88oq440lq82p7lb 2020-07-24 05:00
123EDA14721C3602 0qthjq50jbdvnjq16o8f 2020-07-27 17:00
123EDA14721C3602 gu6r7k260p6afq3ticso 2020-07-28 17:30
936F78AB73AA3022 i4d2krbn2f92jo3uj8r9 2020-08-04 05:00
936F78AB73AA3022 et2gu9tg5ckrsvaj5bom 2020-08-05 06:00
22334A7227544B1E 5qbtj04rcbp3tiq8bo6t 2020-09-29 04:00 paloaltonetworks*

Sources: John Bambenek, Joe Słowik, Rohit Bansal, Dancho Danchev , Paul Vixie, FireEye and VriesHd.

Identifying More SUNBURST STAGE2 Victims

Companies and organizations with access to more passive DNS resources will hopefully be able to use SunburstDomainDecoder to identify additional targeted SUNBURST victims that have progressed to STAGE2.

Download SunburstDomainDecoder

Our tool SunburstDomainDecoder is released under a Creative Commons CC-BY license, and can be downloaded here:

You can also read more about SunburstDomainDecoder in our blog post Reassembling Victim Domain Fragments from SUNBURST DNS.

Posted by Erik Hjelmvik on Monday, 04 January 2021 21:11:00 (UTC/GMT)

Tags: #Netresec #pDNS #SUNBURST #SolarWinds #Solorigate #SunburstDomainDecoder #SolarStorm #STAGE2 #avsvmcloud #C2

More... Share  |  Facebook   Twitter   Reddit   Hacker News Short URL:

Extracting Security Products from SUNBURST DNS Beacons

The latest version of our SunburstDomainDecoder (v1.7) can be used to reveal which endpoint protection applications that are installed on trojanized SolarWinds Orion deployments. The security application info is extracted from DNS queries for "" subdomains, which is used by SUNBURST as a beacon and C2 channel.

Here's an example showing that City of Kingston, Ontario, Canada were running Windows Defender on their trojanized SolarWinds deployment back in June:

C:\> SunburstDomainDecoder.exe < uniq-hostnames.txt | findstr F9A9387F7D252842
F9A9387F7D252842 2020-06-16T00:00:00.0000000Z,​WindowsDefender_RUNNING,WindowsDefender_STOPPED lt5ai41qh5d53qoti3mkmc0
F9A9387F7D252842 olc62cocacn7u2q22v02eu
F9A9387F7D252842 2020-06-17T00:00:00.0000000Z q94idf4sjbem0rait7gv
F9A9387F7D252842 city.kingston. r1qshoj05ji05ac6eoip02jovt6i2v0c

The "F9A9387F7D252842" value is the victim's unique SUNBURST GUID. See our blog post Reassembling Victim Domain Fragments from SUNBURST DNS for more info about how the GUID value is encoded into the DNS traffic.

You can also run SunburstDomainDecoder in Linux, with help of Mono, like this:

$ mono SunburstDomainDecoder.exe < uniq-hostnames.txt | grep 76330B4D49BF7EC4
76330B4D49BF7EC4 LABELMAR e8fh1ravufms0qpt00gudir2951udivf
76330B4D49BF7EC4 2020-05-30T12:30:00.0000000Z,​ESET_RUNNING,ESET_STOPPED gp27ssesmvnpkgff7rc0eok
76330B4D49BF7EC4 nde5gaefm oiltaoj08jjd8h12vnr4tur5h

The file "uniq-hostnames.txt" is a publicly available SUNBURST passive DNS repository created by Bambenek Consulting.

Security Product Statistics

It is also possible to use the passive DNS data shared by Bambenek, Joe Słowik and others to compute statistics of which security products that are popular among SolarWinds' customers.

Application Count
Windows Defender 150
Windows Defender ATP 1
MS Azure ATP /
Defender for Identity
Carbon Black 21
CrowdStrike Falcon 25
FireEye 9
F-Secure 0
SUNBURST Security Applications Chart

It is worth mentioning that SUNBURST does not report status for several other major endpoint protection vendors, such as Kaspersky, McAfee and Symantec, Sophos and Trend Micro.

Download SunburstDomainDecoder

Our tool SunburstDomainDecoder is released under a Creative Commons CC-BY license, and can be downloaded here:

You can also read more about SunburstDomainDecoder in our blog post Reassembling Victim Domain Fragments from SUNBURST DNS.

Posted by Erik Hjelmvik on Tuesday, 29 December 2020 09:38:00 (UTC/GMT)

Tags: #SunburstDomainDecoder #SUNBURST #SolarWinds #Solorigate #DNS #Windows Defender #Carbon Black #FireEye #ESET #F-Secure #C2 #beacon

More... Share  |  Facebook   Twitter   Reddit   Hacker News Short URL:

Examining an x509 Covert Channel

Jason Reaves gave a talk titled “Malware C2 over x509 certificate exchange” at BSides Springfield 2017, where he demonstrated that the SSL handshake can be abused by malware as a covert command-and-control (C2) channel.

Jason Reaves presenting at BSides Springfield 2017

He got the idea while analyzing the Vawtrak malware after discovering that it read multiple fields in the X.509 certificate provided by the server before proceeding. Jason initially thought these fields were used as a C2 channel, but then realized that Vawtrak performed a variant of certificate pinning in order to discover SSL man-in-the-middle attempts.

Nevertheless, Jason decided to actually implement a proof-of-concept (PoC) that uses the X.509 certificate as a C2 channel. Jason’s code is now available on GitHub along with a PCAP file demonstrating this covert C2 channel. Of course I couldn’t resist having a little look at this PCAP file in NetworkMiner.

The first thing I noticed was that the proof-of-concept PCAP ran the SSL session on TCP 4433, which prevented NetworkMiner from parsing the traffic as SSL. However, I was able to parse the SSL traffic with NetworkMiner Professional just fine thanks to the port-independent-protocol-identification feature (a.k.a Dynamic Port Detection), which made the Pro-version parse TCP 4433 as SSL/TLS.

X.509 certificates extracted from PCAP with NetworkMiner
Image: X.509 certificates extracted from PCAP with NetworkMiner

A “normal” x509 certificate size is usually around 1kB, so certificates that are 11kB should be considered as anomalies. Also, opening one of these .cer files reveals an extremely large value in the Subject Key Identifier field.

X.509 certificate with MZ header in the Subject Key Identifier field

Not only is this field very large, it also starts with the familiar “4D 5A” MZ header sequence.

NetworkMiner additionally parses details from the certificates that it extracts from PCAP files, so the Subject Key Identifier field is actually accessible from within NetworkMiner, as shown in the screenshot below.

Parameters tab in NetworkMiner showing X.509 certificate details

You can also see that NetworkMiner validates the certificate using the local trusted root certificates. Not surprisingly, this certificates is not trusted (certificate valid = FALSE). It would be most unlikely that anyone would manage to include arbitrary data like this in a signed certificate.

Extracting the MZ Binary from the Covert X.509 Channel

Even though NetworkMiner excels at pulling out files from PCAPs, this is definitively an occasion where manual handling is required. Jason’s PoC implementation actually uses a whopping 79 individual certificates in order to transfer this Mimikatz binary, which is 785 kB.

Here’s a tshark oneliner you can use to extract the Mimikatz binary from Jason's example PCAP file.

tshark -r mimikatz_sent.pcap -Y 'ssl.handshake.certificate_length gt 2000' -T fields -e x509ce.SubjectKeyIdentifier -d tcp.port==4433,ssl | tr -d ':\n' | xxd -r -p > mimikatz.exe

Detecting x509 Anomalies

Even though covert channels using x509 certificates isn’t a “thing” (yet?) it’s still a good idea to think about how this type of covert signaling can be detected. Just looking for large Subject Key Identifier fields is probably too specific, since there are other fields and extensions in X.509 that could also be used to transmit data. A better approach would be to alert on certificates larger than, let’s say, 3kB. Multiple certificates can also be chained together in a single TLS handshake certificate record, so it would also make sense to look for handshake records larger than 8kB (rough estimate).

Bro IDS logo

This type of anomaly-centric intrusion detection is typically best done using the Bro IDS, which provides easy programmatic access to the X.509 certificate and SSL handshake.

There will be false positives when alerting on large certificates in this manner, which is why I recommend to also check if the certificates have been signed by a trusted root or not. A certificate that is signed by a trusted root is very unlikely to contain malicious data.

Posted by Erik Hjelmvik on Tuesday, 06 February 2018 12:13:00 (UTC/GMT)

Tags: #malware #C2 #SSL #TLS #certificate #NetworkMiner #PCAP #x509 #X.509 #PIPI #Bro #IDS #tshark

More... Share  |  Facebook   Twitter   Reddit   Hacker News Short URL:

Detecting Periodic Flows with CapLoader 1.4

CapLoader 1.4 logo

I am happy to announce a new release of our super-fast PCAP handling tool CapLoader! One of the new features in CapLoader makes it even easier to detect malicious network traffic without having to rely on blacklists, such as IDS signatures.

The new version of CapLoader includes new features such as:

  • Services Tab (more details below)
  • Input filter to limit number of parsed frames
  • Flow Transcript in Hosts and Services tabs
  • Keyword filtering
  • Full filtering capability for all tabs
  • Wireshark style coloring of flows, services and hosts

Services Tab

The biggest addition to version 1.4 of CapLoader is the Services tab, which presents a somewhat new way of aggregating the flows found in a PCAP file. Each row (or “service”) in the services tab represents a unique combination of <Client-IP, Server-IP, Server-port and Transport-protocol>. This means that if a single host makes multiple DNS requests to, then all those flows will be merged together as one row in the services tab.

CapLoader Services tab showing DNS requests to

This view makes it easy to see if a host is frequently accessing a particular network service. CapLoader even shows if the requests are made with regular intervals, in which case we measure the regularity and determine the most likely period between connections. The idea for measuring regularity comes from Sebastian Garcia's Stratosphere IPS, which can identify botnets by analyzing the periodicity of flows going to a C2 server.

Malware Example: Kovter.B

Here's what the Services tab looks like when loading 500 MB of PCAP files from a network where one of the hosts has been infected with malware (Win32/Kovter.B).

CapLoader service ordered on regularity

The services in the screenshot are sorted on the “Regularity” column, so that the most periodic ones are shown at the top. Services with a regularity value greater than 20 can be treated as periodic. In our case we see the top two services having a regularity of 36.9 with an estimated period of roughly 6h 2min. We can visualize the periodic behavior by opening the flows for those two services in a new instance if CapLoader. To do this, simply select the two services' rows, right-click the PCAP icon (in the top-right corner) and select “Open With > CapLoader”

CapLoader Flows tab with periodicly accessed service

As you can see in the flows tab, these services are accessed by the client on a regular interval of about 6h 2min. Doing a flow transcript of one such flow additionally reveals that the payload seems suspicious (not HTTP on TCP 80).

CapLoader transcript of Kovter.B C2 attempt (hex)
Image: Kovter.B malware trying to communicate with a C2 server

The Kovter malware failed to reach the C2 server in the attempt above, but there is a successful connection going to a C2 server at every 3'rd hour (see service number 8 in the list of the most periodically accessed services). Here's a flow transcript of one such beacon:

CapLoader Transcript of Kovter.B C2 traffic
Image: Kovter.B malware talking to C2 server at

Legitimate Periodic Services

Seven out of the 10 most periodically accessed services are actually caused by the Kovter malware trying to reach various C2 servers. The three most periodically accessed services that aren't malicious are:

  • Service #3 is a legitimate Microsoft service (SeaPort connecting to
  • Service #5 is a mail client connecting to the local POP3 server every 30 minutes.
  • Service #6 is Microsoft-CryptoAPI updating its Certificate Revocation List from every 5 hours.

Signature-Free Intrusion Detection

As shown in this blog post, analyzing the regularity of services is an efficient way of detecting C2 beacons without having to rely on IDS signatures. This method goes hand-in-hand with our Rinse-Repeat Intrusion Detection approach, which can be used to find malicous network traffic simply by ignoring traffic that seems “normal”.


Several bugs have been fixed in CapLoader 1.4, such as:

  • Support for frames with Captured Length > Real Lenght (Thanks to Dietrich Hasselhorn for finding this bug)
  • Delete key is no longer hijacked by the “Hide Selected Flows” button (Thanks to Dominik Andreansky for finding this bug).
  • CapLoader GUI now looks okay even with graphics are scaled through "custom sizing". Thanks to Roland Wagner for finding this.

Downloading CapLoader 1.4

The regularity and period detection is available in our free trial version of CapLoader. To try it out simply grab a copy here: (no registration needed)

All paying customers with an older version of CapLoader can grab a free update to version 1.4 at our customer portal.

UPDATE June 2, 2016

We're happy to announce that it is now possible to detect Kovter's C2 communication with help of an IDS signature thanks to Edward Fjellskål. Edward shared his IDS signature "NT TROJAN Downloader/Malware/ClickFraud.Win32.Kovter Client CnC Traffic" on the Emerging-Sigs mailing list yesterday. We have worked with Edward on this and the signature has been verified on our Kovter C2 dataset.

UPDATE June 8, 2016

Edward Fjellskål's IDS signature "ET TROJAN Win32.Kovter Client CnC Traffic" has now been published as an Emerging Threats open rule with SID 2022861.

#alert tcp $HOME_NET any -> $EXTERNAL_NET any (msg:"ET TROJAN Win32.Kovter Client CnC? Traffic"; flow:established,to_server; dsize:4<>256; content:!"HTTP"; content:"|00 00 00|"; offset:1; depth:3; pcre:"/^[\x11\x21-\x26\x41\x45\x70-\x79]/R"; content:!"|00 00|"; distance:0; byte_jump:1,0,from_beginning,post_offset 3; isdataat:!2,relative; pcre:!"/\x00$/"; reference:url,; classtype:trojan-activity; sid:2022861; rev:1;)

Posted by Erik Hjelmvik on Monday, 23 May 2016 11:55:00 (UTC/GMT)

Tags: #CapLoader #PCAP #C2 #beacon #Intrusion Detection

More... Share  |  Facebook   Twitter   Reddit   Hacker News Short URL:

CapLoader 1.3 Released

CapLoader Logo

A new version of our heavy-duty PCAP parser tool CapLoader is now available. There are many new features and improvements in this release, such as the ability to filter flows with BPF, domain name extraction via passive DNS parser and matching of domain names against a local white list.

Filtering with BPF

The main focus in the work behind CapLoader 1.3 has been to fully support the Rinse-Repeat Intrusion Detection methodology. We've done this by improving the filtering capabilities in CapLoader. For starters, we've added an input filter, which can be used to specify IP addresses, IP networks, protocols or port numbers to be parsed or ignored. The input filter uses the Berkeley Packet Filter (BPF) syntax, and is designed to run really fast. So if you wanna analyze only HTTP traffic you can simply write “port 80” as your input filter to have CapLoader only parse and display flows going to or from port 80. We have also added a display filter, which unlike Wireshark also uses BPF. Thus, once a set of flows is loaded one can easily apply different display filters, like “host” or “net”, to apply different views on the parsed data.

CapLoader BPF Input Filter and Display Filter
Image: CapLoader with input filter "port 80 or port 443" and display filter "not net".

The main differences between the input filter and display filter are:

  • Input filter is much faster than the display filter, so if you know beforehand what ports, protocols or IP addresses you are interested in then make sure to apply them as an input filter. You will notice a delay when applying a display filter to a view of 10.000 flows or more.
  • In order to apply a new input filter CapLoader has to reload all the opened PCAP files (which is done by pressing F5). Modifying display filters, on the other hand, only requires you to press Enter or hit the “Apply” button.
  • Previously applied display filters are accessible in a drop-down menu in the GUI, but no history is kept of previous input filters.

NetFlow + DNS == true

The “Flows” view in CapLoader gives a great overview of all TCP, UDP and SCTP flows in the loaded PCAP files. However, it is usually not obvious to an analyst what every IP address is used for. We have therefore added a DNS parser to CapLoader, so that all DNS packets can be parsed in order to map IP addresses to domain names. The extracted domain names are displayed for each flow, which is very useful when performing Rinse-Repeat analysis in order to quickly remove “known good servers” from the analysis.

Leveraging the Alexa top 1M list

As we've show in in our previous blog post “DNS whitelisting in NetworkMiner”, using a list of popular domain names as a whitelist can be an effective method for finding malware. We often use this approach in order to quickly remove lots of known good servers when doing Rinse-Repeat analysis in large datasets.

Therefore, just as we did for NetworkMiner 1.5, CapLoader now includes Alexa's list of the 1 million most popular domain names on the Internet. All domain names, parsed from DNS traffic, are checked against the Alexa list. Domains listed in the whitelist are shown in CapLoader's “Server_Alexa_Domian” column. This makes it very easy to sort on this column in order to remove (hide) all flows going to “normal” servers on the Internet. After removing all those flows, what you're left with is pretty much just:

  • Local traffic (not sent over the Internet)
  • Outgoing traffic to either new or obscure domains

Manually going through the remaining flows can be very rewarding, as it can reveal C2 traffic from malware that has not yet been detected by traditional security products like anti-virus or IDS.

Flows in CapLoader with DNS parsing and Alexa lookup
Image: CapLoader with malicious flow to 1.web-counter[.]info (Miuref/Boaxxe Trojan) singled out due to missing Alexa match.

Many new features in CapLoader 1.3

The new features highlighted above are far from the only additions made to CapLoader 1.3. Here is a more complete list of improvements in this release:

  • Support for “Select Flows in PCAP” to extract and select 5-tuples from a PCAP-file. This can be a Snort PCAP with packets that have triggered IDS signatures. This way you can easily extract the whole TCP or UDP flow for each signature match, instead of just trying to make sense of one single packet per alert.
  • Improved packet carver functionality to better carve IP, TCP and UPD packets from any file. This includes memory dumps as well as proprietary and obscure packet capture formats.
  • Support for SCTP flows.
  • DNS parser.
  • Alexa top 1M matching.
  • Input filter and display filter with BPF syntax.
  • Flow Producer-Consumer-Ratio PCR.
  • Flow Transcript can be opened simply by double-clicking a flow.
  • Find form updated with option to hide non-matching flows instead of just selecting the flows that matched the keyword search criteria.
  • New flow transcript encoding with IP TTL, TCP flags and sequence numbers to support analysis of Man-on-the-Side attacks.
  • Faster loading of previously opened files, MD5 hashes don't need to be recalculated.
  • A selected set of flows in the GUI can be inverted simply by right-clicking the flow list and selecting “Invert Selection” or by hitting Ctrl+I.

Downloading CapLoader 1.3

All these new features, except for the Alexa lookup of domain names, are available in our free trial version of CapLoader. So to try out these new features in CapLoader, simply grab a trial download here: (no registration needed)

All paying customers with an older version of CapLoader can grab a free update for version 1.3 at our customer portal.

Posted by Erik Hjelmvik on Monday, 28 September 2015 07:30:00 (UTC/GMT)

Tags: #CapLoader #BPF #Berkeley Packet Filter #Rinse-Repeat #DNS #Alexa #PCAP #Passive DNS #NetFlow #Malware #C2

More... Share  |  Facebook   Twitter   Reddit   Hacker News Short URL:

Observing the Havex RAT

Havex RAT, original 'Street-rat' by Edal Anton Lefterov. Licensed under Creative Commons Attribution-Share Alike 3.0

It has, so far, been publicly reported that three ICS vendors have spread the Havex Remote-Access-Tool (RAT) as part of their official downloads. We've covered the six pieces of software from these three vendors in our blog post ”Full Disclosure of Havex Trojans”. In this blog post we proceed by analyzing network traffic generated by Havex.

Indicators of Compromise

Before going into details of our analysis we'd like to recommend a few other resources that can be used to detect the Havex RAT. There are three Havex IDS signatures available via Emerging Threats. There are also Yara rules and OpenIOC signatures available for Havex. Additionally, the following domains are known to be used in the later versions (043 and 044) of Havex according to Kaspersky:


HTTP Command-and-Control

The Havex RAT Command-and-Control (C2) protocol is based on HTTP POST requests, which typically look something like this:

POST /blogs/wp-content/plugins/buddypress/bp-settings/bpsettings-src.php?id=84651193834787196090098FD80-c8a7af419640516616c342b13efab&​v1=043&​v2=170393861&​q=45474bca5c3a10c8e94e56543c2bd

As you can see, four variables are sent in the QueryString of this HTTP POST request; namely id, v1, v2 and q. Let's take a closer look to see what data is actually sent to the C2 server in the QueryString.

Param Description Common Values
id host identifier id=[random number][random hex]-c8a7af419640516616c342b13efab
id=[random number][random-hex]-003f6dd097e6f392bd1928066eaa3
v1 Havex version 043
v2 Windows version 170393861 (Windows XP)
498073862 (Windows 7)
498139398 (Windows 7, SP1)
q Unknown q=45474bca5c3a10c8e94e56543c2bd (Havex 043)
q=0c6256822b15510ebae07104f3152 (Havex 043)
q=214fd4a8895e07611ab2dac9fae46 (Havex 044)
q=35a37eab60b51a9ce61411a760075 (Havex 044)

Analyzing a Havex PCAP

I had the pleasure to discuss the Havex Malware with Joel Langill, when we met at the 4SICS conference in Stockholm last month. Joel was nice enough to provide me with a 800 MB PCAP file from when he executed the Havex malware in an Internet connected lab environment.

CapLoader Transcript of Havex C2 traffic
Image: CapLoader transcript of Havex C2 traffic

I used the command line tool NetworkMinerCLI (in Linux) to automatically extract all HTTP downloads from Joel's PCAP file to disk. This way I also got a CSV log file with some useful metadata about the extracted files. Let's have a closer look at what was extracted:

$ mono NetworkMinerCLI.exe -r new-round-09-setup.pcap
Closing file handles...
970167 frames parsed in 1337.807 seconds.

$ cut -d, -f 1,2,3,4,7,12 new-round-09-setup.pcap.FileInfos.csv | head

SourceIP   SourcePort  DestinationIP  DestinationPort FileSize   Frame   TCP 80   TCP 1238   244 676 B       14   TCP 80   TCP 1261       150 B     1640   TCP 80   TCP 1286   359 508 B     3079   TCP 80   TCP 1311   236 648 B     4855   TCP 80   TCP 1329       150 B    22953   TCP 80   TCP 1338       150 B    94678   TCP 80   TCP 1346       150 B   112417   TCP 80   TCP 1353       150 B   130108   TCP 80   TCP 1365       150 B   147902

Files downloaded through Havex C2 communication are typically modules to be executed. However, these modules are downloaded in a somewhat obfuscated format; in order to extract them one need to do the following:

  • Base64 decode
  • Decompress (bzip2)
  • XOR with ”1312312”

To be more specific, here's a crude one-liner that I used to calculate MD5 hashes of the downloaded modules:

$ tail -c +95 C2_download.html | base64 -d | bzcat -d | xortool-xor -s "1312312" -f - -n | tail -c +330 | md5sum

To summarize the output from this one-liner, here's a list of the downloaded modules in Joel's PCAP file:

Downloaded HTML MD5 Extracted module MD5

All three extracted modules are known binaries associated with Havex. The third module is one of the Havex OPC scanner modules, let's have a look at what happens on the network after this module has been downloaded!

Analyzing Havex OPC Traffic

In Joel's PCAP file, the OPC module download finished at frame 5117. Less then a second later we see DCOM/MS RPC traffic. To understand this traffic we need to know how to interpret the UUID's used by MS RPC.

Marion Marschalek has listed 10 UUID's used by the Havex OPC module in order to enumerate OPC components. However, we've only observed four of these commands actually being used by the Havex OPC scanner module. These commands are:


Of these commands the ”IOPC Browse” is the ultimate goal for the Havex OPC scanner, since that's the command used to enumerate all OPC tags on an OPC server. Now, let's have a look at the PCAP file to see what OPC commands (i.e. UUID's) that have been issued.

$ tshark -r new-round-09-setup.first6000.pcap -n -Y 'dcerpc.cn_bind_to_uuid != 99fcfec4-5260-101b-bbcb-00aa0021347a' -T fields -e frame.number -e ip.dst -e dcerpc.cn_bind_to_uuid -Eoccurrence=f -Eheader=y  ip.dst      dcerpc.cn_bind_to_uuid
5140  000001a0-0000-0000-c000-000000000046
5145  000001a0-0000-0000-c000-000000000046
5172  000001a0-0000-0000-c000-000000000046
5185  9dd0b56c-ad9e-43ee-8305-487f3188bf7a
5193  000001a0-0000-0000-c000-000000000046
5198  55c382c8-21c7-4e88-96c1-becfb1e3f483
5212  00000143-0000-0000-c000-000000000046
5247  000001a0-0000-0000-c000-000000000046
5257  00000143-0000-0000-c000-000000000046
5269  00000143-0000-0000-c000-000000000046
5274  39c13a4d-011e-11d0-9675-0020afd8adb3
5280  39c13a4d-011e-11d0-9675-0020afd8adb3
5285  39227004-a18f-4b57-8b0a-5235670f4468
5286  39227004-a18f-4b57-8b0a-5235670f4468

We can thereby verify that the IOPCBrowse command was sent to one of Joel's OPC servers in frame 5285 and 5286. However, tshark/Wireshark is not able to parse the list of OPC items (tags) that are returned from this function call. Also, in order to find all IOPCBrowse commands in a more effective way we'd like to search for the binary representation of this command with tools like ngrep or CapLoader. It would even be possible to generate an IDS signature for IOPCBrowse if we'd know what to look for.

The first part of an MSRPC UUID is typically sent in little endian, which means that the IOPCBrowse command is actually sent over the wire as:

04 70 22 39 8f a1 57 4b 8b 0a 52 35 67 0f 44 68

Let's search for that value in Joel's PCAP file:

CapLoader 1.2 Find Keyword Window
Image: Searching for IOPCBrowse byte sequence with CapLoader

CapLoader 1.2 flow view
Image: CapLoader with 169 extracted flows matching IOPCBrowse UUID

Apparently 169 flows contain one or several packets that match the IOPCBrowse UUID. Let's do a “Flow Transcript” and see if any OPC tags have been sent back to the Havex OPC scanner.

CapLoader 1.2 Transcript of OPC-DA session
Image: CapLoader Transcript of OPC-DA session

Oh yes, the Havex OPC scanner sure received OPC tags from what appears to be a Waterfall unidirectional OPC gateway.

Another way to find scanned OPC tags is to search for a unique tag name, like “Bucket Brigade” in this example.

Posted by Erik Hjelmvik on Wednesday, 12 November 2014 21:09:00 (UTC/GMT)

Tags: #Havex #PCAP #NSM #ICS #C2 #NetworkMinerCLI #CapLoader

More... Share  |  Facebook   Twitter   Reddit   Hacker News Short URL:


NETRESEC on Twitter

Follow @netresec on twitter:


Recommended Books

» The Practice of Network Security Monitoring, Richard Bejtlich (2013)

» Applied Network Security Monitoring, Chris Sanders and Jason Smith (2013)

» Network Forensics, Sherri Davidoff and Jonathan Ham (2012)

» The Tao of Network Security Monitoring, Richard Bejtlich (2004)

» Practical Packet Analysis, Chris Sanders (2017)

» Windows Forensic Analysis, Harlan Carvey (2009)

» TCP/IP Illustrated, Volume 1, Kevin Fall and Richard Stevens (2011)

» Industrial Network Security, Eric D. Knapp and Joel Langill (2014)