Skip to content

Instantly share code, notes, and snippets.

@brad-anton
Last active March 30, 2018 12:16
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brad-anton/2bc0ac9dd6292dc1e830ad12741368ff to your computer and use it in GitHub Desktop.
Save brad-anton/2bc0ac9dd6292dc1e830ad12741368ff to your computer and use it in GitHub Desktop.
Using the Exploit Kit Tracker

Client Library

An example client library can be found in client.py. To use:

>>> from client import ektracker_client
>>> e = ektracker_client('your_api_key') 

>>> e.add_tag('rig', 'rig exploit kit', [ 'http://www.google.com/', 'http://www.test.com' ], ['.*', '[a-f]{1,}'])
Uploading Tag: {'signatures': ['.*', '[a-f]{1,}'], 'references': ['http://www.google.com/', 'http://www.test.com'], 'name': 'rig', 'description': 'rig exploit kit'}
{u'message': u'Added Tag', u'result': u'SUCCESS'}

>>> e.add_entry('http://api_clienttest.com', tags=['rig', 'seamless'])
Uploading Entry: {'url': 'http://api_clienttest.com', 'timestamp': datetime.datetime(2017, 6, 19, 21, 2, 28, 8769), 'references': None, 'tags': ['rig', 'seamless']}
{u'message': u'Added Entry', u'result': u'SUCCESS'}

>>> e.get_entries()
{u'data': [{u'tags': [u'rig', u'seamless'], u'url': .......

Objects

ektracker monitors exploit kit campaigns by storing an Entry for every observed host.

Entry

Element Data Type Description
Timestamp Datetime When the campaign was observed.
URL String The IP, host, or full URL observed.
Tags List of Strings Optional. See below. Any associated tags, if the tag does not already exist, it will be created.
References List of Strings Optional. URLs that may offer evidence or further detail into this specific entry.

Tags

Element Data Type Description
Name String The name of the tag, can be an exploit kit, campaign, or anything else
Description String A sentence describing the tag.
References List of Strings Optional. URLs that may offer further detail into this specific tag.
Signature List of Strings Optional. Regular expressions that may be applicable to detecting this tag.

API

ektracker was built to be used mostly via its API. Endpoints are

/api/entries/

Detail Description
Endpoint /api/entries
Purpose Retrieve a list of entries over the last 30 days.
Accepts None
Returns A JSON object containing a list of messages entries for the last 30 days.

/api/add/entry/

Detail Description
Endpoint /api/add/entry/
Purpose Add a new entry
Accepts api_key, url, timestamp, tags (optional), references (optional)
Returns Success or Failure

/api/add/tag/

Detail Description
Endpoint /api/add/tag/
Purpose Add a new tag
Accepts api_key, name, description, references (optional), signatures (optional)
Returns Success or Failure
"""
client.py
@brad_anton
A simple client for ektracker.
Example:
from client import ektracker_client
e = ektracker_client('api_key')
print e.add_tag('rig', 'rig exploit kit', [ 'http://www.google.com/', 'http://www.test.com' ], ['.*', '[a-f]{1,}'])
print e.add_entry('http://api_clienttest.com', tags=['rig', 'seamless'])
print e.add_entry('http://api_clienttest.com', tags=['neutrino'])
print e.add_entry('http://api_clienttest.com', tags=['spartan'])
print e.add_entry('http://api_clienttest.com', tags=['rig', 'psuedoDarkleech'])
print e.get_entries()
"""
import requests
from datetime import datetime
def to_obj(item, obj):
result = []
if isinstance(item, list):
for i in item:
result.append(obj(i))
elif isinstance(item, str):
result.append(obj(i))
elif type(item) == obj:
result.append(item)
return result if result else None
def json_serial(obj):
"""JSON serializer for objects not serializable by default json code"""
# http://stackoverflow.com/questions/11875770/how-to-overcome-datetime-datetime-not-json-serializable-in-python
if isinstance(obj, datetime):
return (obj - datetime.fromtimestamp(0)).total_seconds()
raise TypeError ("Type not serializable")
class Entry(object):
def __init__(self, url=None, timestamp=None, tags=None, references=None):
self.url = url
self.timestamp = timestamp
if self.timestamp is None:
self.timestamp = datetime.utcnow()
self.tags = to_obj(tags, Tag)
self.references = to_obj(references, Reference)
def todict(self):
return { 'url': self.url, 'timestamp': self.timestamp,
'tags': self.tags if self.tags is None else [ t.name for t in self.tags ],
'references': self.references if self.references is None else [ r.reference for r in self.references ]
}
class Tag(object):
def __init__(self, name, description=None, references=None, signatures=None):
self.name = name
self.description = description
self.references = to_obj(references, Reference)
self.signatures = to_obj(signatures, Signature)
def __repr__(self):
return '{}'.format(self.__dict__)
def todict(self):
return { 'name': self.name, 'description': self.description,
'references': self.references if self.references is None else [ r.reference for r in self.references ],
'signatures': self.signatures if self.signatures is None else [ r.signature for r in self.signatures ]
}
class Reference(object):
def __init__(self, reference):
self.reference = reference
class Signature(object):
def __init__(self, signature):
self.signature = signature
class ektracker_client:
def __init__(self, api_key, host='ektracker.com', port=80):
self.server = 'http://{}:{}'.format(host, port)
self.api_key = api_key
self.entries = []
def _post(self, endpoint, params=None):
"""Internal function to prep and make POST requests to the server.
"""
ep = '{}/{}'.format(self.server, endpoint)
data = { 'api_key': self.api_key }
if params:
data.update(params)
try:
res = requests.post(ep, data=data)
res.raise_for_status()
except (requests.exceptions.Timeout, requests.exceptions.HTTPError) as e:
print res.text
raise Exception('[!] Unable to query ektracker: {}'.format(e))
return res.json()
def _get(self, endpoint, params=None):
ep = '{}/{}'.format(self.server, endpoint)
try:
res = requests.get(ep, params=params)
res.raise_for_status()
except (requests.exceptions.Timeout, requests.exceptions.HTTPError) as e:
raise Exception('[!] Unable to query ektracker: {}'.format(e))
return res.json()
def add_tag(self, name, description, references=None, signatures=None):
t = Tag(name, description, references, signatures)
print 'Uploading Tag: {}'.format(t.todict())
return self._post('api/add/tag/', params=t.todict())
def add_entry(self, url, timestamp=None, tags=None, references=None):
e = Entry(url, timestamp, tags, references)
print 'Uploading Entry: {}'.format(e.todict())
return self._post('api/add/entry/', params=e.todict())
def get_entries(self, start=None, end=None):
return self._get('api/entries/')
if __name__ == '__main__':
with open('client_config.json') as f:
from json import load
config = load(f)
e = ektracker_client(config['api_key'])
print e.add_tag('rig', 'rig exploit kit', [ 'http://www.google.com/', 'http://www.test.com' ], ['.*', '[a-f]{1,}'])
print e.add_entry('http://api_clienttest.com', tags=['rig', 'seamless'])
print e.add_entry('http://api_clienttest.com', tags=['neutrino'])
print e.add_entry('http://api_clienttest.com', tags=['spartan'])
print e.add_entry('http://api_clienttest.com', tags=['rig', 'psuedoDarkleech'])
print e.get_entries()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment