Lee Kirkpatrick

DGA Detection

Blog Post created by Lee Kirkpatrick Employee on Feb 1, 2017

In one of my previous posts (Shannon. Have you seen my Entropy?) I touched on using a custom Java entropy calculator within the ESA to calculate the entropy values for domains to assist with detecting Domain Generation Algorithms (DGA's); the post was more theory than practical so I decided to implement and test it in my lab so I could share the implementation with you all.

 

The basic principle behind this form of DGA detection is to calculate an entropy value for each domain seen and store this value in an ESA window. We can then use the values in the ESA window to calculate an average entropy for the domains seen within an environment, this subsequently allows an alert to be generated if any domains exceed the average entropy by 1.3x.

 

As an example, let's take the following four domains from the Alexa top 100 (this will be what we use as an example baseline, the rule attached to this post would actually monitor your network for what is normal):-

 

  • google.com
  • youtube.com
  • facebook.com
  • baidu.com

 

Running these each through the entropy calculator we receive the following values:-

 

DomainEntropy
google.com2.6464393446710157
youtube.com3.095795255000934
facebook.com3.0220552088742
baidu.com3.169925001442312
Average2.983553702497115

 

Using this average as our baseline, we can then say that anything that is greater than 1.3x (3.87861981324625) this average, let me know about it as this is a high entropy value.

 

Taking the following values from Zeus tracker and calculating their entropy values, we can see the results:-

 

DomainEntropyStatus
circleread-view.com.mocha2003.mochahost.com
3.952216429463629Alert
cynthialemos1225.ddns.net
3.952216429463629
Alert
moviepaidinfullsexy.kz
4.061482186720775Alert
039b1ee.netsolhost.com
3.754441845713345No alert

 

Example of the alert output below:-

 

 

Rule Logic

@Name('Learning Phase Variable')
//Change the learningPhaseMinutes variable to the number of minutes for the rule to learn
CREATE VARIABLE INTEGER learningPhaseMinutes = 1440;

 

@Name('Calculate Learning Phase')
on pattern[Every(timer:at(*, *, *, *, *))] set learningPhaseMinutes = learningPhaseMinutes - 1;

 

@Name('Create Entropy Window')
CREATE WINDOW aliasHostEntropy.win:length(999999).std:unique(entropy) (entropy double);

 

@Name('Insert entropy into Window')
INSERT INTO aliasHostEntropy
SELECT calcEntropy(alias_host) as entropy FROM Event(alias_host IS NOT NULL AND learningPhaseMinutes > 1);

 

@Name('Alert')
@RSAAlert
SELECT *, (SELECT avg(entropy) FROM aliasHostEntropy as Average), (SELECT calcEntropy(alias_host) FROM Event.win:length(1) as Entropy) FROM Event(learningPhaseMinutes <= 1 AND calcEntropy(alias_host) > 1.3* (SELECT avg(entropy) FROM aliasHostEntropy));

 

 

If you are interested in implementing this DGA Detection rule, I wrote up a little guide on how to do so. Everything you need is attached to this post.

 

DISCLAIMER: The information within this blog post is here to show the capabilities of the NetWitness product and avenues of exploration to help thwart the adversary. This content is provided as-is with no RSA direct support, use it at your own risk. Additionally, you should always confirm architecture state before running content that could impact the performance of your NetWitness architecture. 

Outcomes