Skip to content

Commit 714f0fc

Browse files
author
Etienne Stalmans
committed
Extra commenting
1 parent 7f2822d commit 714f0fc

File tree

3 files changed

+43
-11
lines changed

3 files changed

+43
-11
lines changed

FFanalyse.py

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
#!/usr/bin/python
22

3+
"""
4+
Domain analysis script. Performs a DNS query and examines the response to determine if domain is Fast-Flux.
5+
Also performs a check using multiple methods to determine whether domain name was algorithmically generated (DGA).
6+
Author: Etienne Stalmans
7+
Version: 1.0 (2013)
8+
"""
9+
310
import sys,string
411
import getopt
512
import dns.resolver
@@ -15,7 +22,7 @@ def main(self,domain,verbose):
1522
'server_rotate': 0,'server':[] }
1623
self.verbose = verbose
1724
self.domain = domain
18-
self.gl = Geolocate.Geolocate('GeoIPCity.dat')
25+
self.gl = Geolocate.Geolocate('GeoLiteCity.dat')
1926
self.geoIP = pygeoip.GeoIP('GeoIPASNum.dat')
2027
self.urla = URLAnalysis.urlanalyse()
2128
self.urla.main('output_b.dgt','output_m.dgt')
@@ -69,7 +76,10 @@ def get_asn(self,ip):
6976
return [asnrec.split(' ')[0],country]
7077

7178
def get_dns(self,qname):
72-
79+
"""
80+
Perform the DNS query and send the result to the analyzer.
81+
@param qname the domain to query
82+
"""
7383
rdtype=dns.rdatatype.A
7484
rdclass=dns.rdataclass.IN
7585
request = dns.message.make_query(qname, rdtype, rdclass)
@@ -92,7 +102,13 @@ def get_dns(self,qname):
92102
self.analyse(response)
93103

94104
def analyse(self,response):
95-
105+
"""
106+
Perform analysis on a DNS query response.
107+
Checks for Fast-Flux using modified Holz classifier, Jaroslaw/Patrycja classifier.
108+
Checks for Fast-Flux using Geolocation
109+
Checks for DGA using multiple statistical classifiers
110+
@param response from the DNS query
111+
"""
96112
qname = str(response.question).split()[1] #Query Name
97113

98114
network_ranges = [] #A record responses
@@ -132,14 +148,14 @@ def analyse(self,response):
132148
if '.' in str(a): #weak check that it is an IP address returned
133149
answers.append(str(a))
134150

135-
a_ttl = response.answer[0].ttl
136-
a_count = len(answers)
151+
a_ttl = response.answer[0].ttl #get the TTL
152+
a_count = len(answers) #the number of IP addresses returned
137153

138154
if a_count > 0:
139155
for ip in answers:
140156
ip = str(ip)
141157
st = ip[:ip.rfind('.')]
142-
asnd = self.get_asn(st)
158+
asnd = self.get_asn(ip)
143159
if asnd:
144160
asn,country = asnd
145161
if country not in countries:
@@ -151,8 +167,8 @@ def analyse(self,response):
151167

152168

153169
diff_count = len(network_ranges) #number of IP ranges we have
154-
country_count= len(countries)
155-
asn_count = len(asns)
170+
country_count= len(countries) #number of countries that host A records
171+
asn_count = len(asns) #number of netblocks
156172
if a_ttl <= 300:
157173
ttl_score = 1
158174

@@ -172,12 +188,11 @@ def analyse(self,response):
172188
print "Modified Jaroslaw/Patrycja: Score (%i) Classified (%s)"%(jp_score,"\033[91mFast-Flux\033[0m" if jp_score>=18 else "\033[92mClean\033[0m")
173189
print "Rule Based: %s"%("\033[91mFast-Flux\033[0m" if diff_count!=0 and a_count>=2 or ns_count>1 and ((diff_count>=1 and asn_count>1)or ttl_score == 1) else "\033[92mClean\033[0m")
174190
print "\n---- Geolocation ----"
175-
self.gl.calcValues(answers)
191+
self.gl.calcValues(answers) #do geolocation check
176192
print "\n---- URL Analysis ----"
177-
self.urla.checkDomain(qname)
193+
self.urla.checkDomain(qname) #do check for DGA
178194

179195
def setOpts(argv):
180-
#defaults
181196
parser = argparse.ArgumentParser()
182197
parser.add_argument('-d', '--domain',dest='domain',action='store',required=True,
183198
help="A Domain to analyse")

TrainURLAnalysis.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22
import sys
33
import pickle
44

5+
"""
6+
Simple script to generate frequencies distributions of characters and bigrams based on a dataset.
7+
Author: Etienne Stalmans ([email protected])
8+
Version: 1.0 (2013)
9+
"""
10+
511
class trainer:
612
def __init__(self):
713
if len(sys.argv)<4:

URLAnalysis.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,22 @@
55
import os
66
import math
77

8+
"""
9+
Performs Domain name analysis using different statistical techniques. Aims to detect whether a domain is a DGA.
10+
Author: Etienne Stalmans ([email protected])
11+
Version: 1.4 (2013)
12+
"""
13+
814
BIGRAM = 0
915
UNIGRAM = 1
1016

1117
class urlanalyse:
1218
def main(self,safe_in,malicious_in):
19+
"""
20+
Initialize the frequency tables. Uses pretrained input obtained from TrainURLAnalysis.py
21+
@param safe_in the trained frequency set for "clean" domains or known non-DGA values (english dictionary ect)
22+
@param malicious_in the trained frequency set for "DGA" domains (confiker,kraken,torpig,ect)
23+
"""
1324
s_in = open(safe_in,'rb')
1425
m_in = open(malicious_in,'rb')
1526

0 commit comments

Comments
 (0)