Skip to content

Commit

Permalink
Relased OSTrICa 0.5
Browse files Browse the repository at this point in the history
  • Loading branch information
Ptr32Void committed Jul 1, 2016
1 parent 2fcb2c3 commit 10117af
Show file tree
Hide file tree
Showing 74 changed files with 54,376 additions and 0 deletions.
66 changes: 66 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,69 @@ To generate the graph 2 commands are available:

![OSTrICa Graph]( https://github.com/Ptr32Void/OSTrICa/blob/master/docs/OstricaGraph.png "OSTrICa Graph" )

## Currently available plugins
The following list contains the currently available plugins:
* `BlackLists` - Developer `Ptr32Void`
* `CymruWhois` - Developer `Ptr32Void`
* `DeepViz` - Developer `Ptr32Void`
* `DomainBigData` - Developer `Ptr32Void`
* `NortonSafeWeb` - Developer `Ptr32Void`
* `PyWhois` - Developer `Ptr32Void`
* `SafeBrowsing` - Developer `Ptr32Void`7
* `SpyOnWeb` - Developer `Ptr32Void`
* `TCPIPutils` - Developer `Ptr32Void`
* `VirusTotal` - Developer `Ptr32Void`
* `WebSiteInformer` - Developer `Ptr32Void`
* `WhoisXmlApi` - Developer `Ptr32Void`

## How to develop new Plugins
Plugins are stored in the directory named `Plugins`.
To create a new Plugin you need to create a new subdirectory under `Plugins` and within that new directory a new `__init__.py` should be added.

OSTrICa will call 2 functions within each plugins `run` and `data_visualization`, defined as follow:
```python
# intelligence is the IoC provided (eg.: something@yahoo.com)
# extraction_type is the typology (eg.: an MD5 or email, etc)
def run(intelligence, extraction_type):
# function run is the core part of the plugin. It is used to collect the information and afterwards it returns back JSON data as per below:
.... code used to collect Intelligence ....
# a dictionary where extraction_type is the type (md5, email, etc) and intelligence_dictionary is the JSON data collected by the plugin
return {'extraction_type': extraction_type, 'intelligence_information':intelligence_dictionary}



# nodes are passed by OSTrICa itself and should never be overwritten but updated because they might contain details related to the previously collected information
# edges are passed by OSTrICa itself and should never be overwritten but updated because they might contain details related to the previously collected information
# json_data is the json output collected by the plugin
def data_visualization(nodes, edges, json_data):
```

It is also mandatory to return `nodes` and `edges` from `data_visualization` as they are used by OSTrICa. If there is no data to be visualized it is possible to return the nodes/edges with following code:
```python
def data_visualization(nodes, edges, json_data):
return nodes, edges
```

You should also add the following import and variables at the top of the file.
```python
from ostrica.utilities.cfg import Config as cfg # used to include configuration data

# used to identify what kind of data the plugin can extract:
# ip = IP Address information
# domain = Domain information
# asn = ASN information
# md5 = MD5 information
# sha256 = SHA256 information
# email = Email information
extraction_type = [cfg.intelligence_type['ip'], cfg.intelligence_type['domain'], cfg.intelligence_type['asn']]
# True if plugin is enabled, False if not
enabled = True
# Plugin Version
version = 0.1
# Developer(s) name and contact
developer = 'Your Name <Your Email>'
# Plugin Description
description = 'Plugin used to collect information about IPs, domains or ASNs on SafeBrowsing'
# True if visualization module is available for the plugin, False otherwise
visual_data = True
```
194 changes: 194 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
#-------------------------------------------------------------------------------
# Name: OSTrICa - Open Source Threat Intelligence Collector
# Purpose: Collection and visualization of Threat Intelligence data
#
# Author: Roberto Sponchioni - <rsponchioni@yahoo.it> @Ptr32Void
#
# Created: 20/12/2015
# Licence: This file is part of OSTrICa.
#
# OSTrICa is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# OSTrICa is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with OSTrICa. If not, see <http://www.gnu.org/licenses/>.
#-------------------------------------------------------------------------------
import json
import sys
import uuid
import os

from ostrica.utilities.Ostrica import OSTrICa
from ostrica.utilities.cfg import Config as cfg
from ostrica.utilities.OstriViz import OstriViz


class OstricaConsole:

def __init__(self):
self.ostrica = OSTrICa()
self.visualization = OstriViz()
self.domains = []
self.ips = []
self.asn = []
self.sha256 = []
self.md5 = []
self.email = []

self.nodes = {}
self.edges = {}
self.rnd_fn = None
self.rnd_report_fn = None
self.original_intel = []

def generate_ostrica_graph(self, graph_typology=''):
if self.rnd_fn is None:
self.rnd_fn = '%s.html' % (str(uuid.uuid4()))

self.visualization.generate_graph(self.rnd_fn, self.nodes, self.edges, self.original_intel, graph_typology)

def help(self):
print 'Following options are available\n'
print '\tdomain - used to collect domains information'
print '\tExample: domain=google.com or domain=google.com,yahoo.com'
print '\tip - used to collect IP information'
print '\tExample: ip=8.8.8.8 or ip=8.8.8.8,173.194.68.99'
print '\tmd5 - used to collect MD5 information'
print '\tsha256 - used to collect SHA256 information'
print '\tasn - used to collect ASN information'
print '\temail - used to collect email information'
print '\tgraph - generate a graph based on all the information collected'
print '\tcola_graph - generate a graph based on all the information collected where nodes do not overlap (it might take a while to generate the graph if there are lots of nodes)'
print '\tgclean - clear graph information'
print '\tshow - show all information that will be collected'
print '\trun - extract intelligece information'
print '\thelp - this help'
print '\tplugins - show available plugins'

def clean_ostrica_graph(self):
self.edges = {}
self.edges = {}
self.rnd_fn = None
self.rnd_report_fn = None

def run_ostrica(self):
if self.rnd_report_fn == None:
self.rnd_report_fn = str(uuid.uuid4())
filename = os.path.join(os.getcwd(), 'report', self.rnd_report_fn)
fh = open(filename, 'a')
self.ostrica.intelligence_gathering()
for intel in self.ostrica.intelligence:
self.nodes, self.edges = self.ostrica.plugin_data_visualization(self.nodes, self.edges, intel)
fh.write( json.dumps(intel, sort_keys=True, indent=4, separators=(',', ': ')) )

print 'Output created in %s' % (filename)
fh.close()

def plugins_info(self):
self.ostrica.plugins_info()

def clear_ostrica_queue(self):
self.ostrica.clear_intelligence_queue()

def show_ostrica_queue_elements(self):
for ostrica_queue in self.ostrica.extract_intelligence_queue_items():
print ostrica_queue

def domain_intelligence(self, domains):
for domain in domains:
self.original_intel.append(domain)
self.ostrica.update_intelligence_queue({'extraction_type': cfg.intelligence_type['domain'], 'intelligence_information': domain})

def ip_intelligence(self, ips):
for ip in ips:
self.original_intel.append(ip)
self.ostrica.update_intelligence_queue({'extraction_type': cfg.intelligence_type['ip'], 'intelligence_information': ip})

def asn_intelligence(self, asns):
for asn in asns:
self.original_intel.append(asn)
self.ostrica.update_intelligence_queue({'extraction_type': cfg.intelligence_type['asn'], 'intelligence_information': asn})

def email_intelligence(self, emails):
for email in emails:
self.original_intel.append(email)
self.ostrica.update_intelligence_queue({'extraction_type': cfg.intelligence_type['email'], 'intelligence_information': email})

def md5_intelligence(self, md5s):
for md5 in md5s:
self.original_intel.append(md5)
self.ostrica.update_intelligence_queue({'extraction_type': cfg.intelligence_type['md5'], 'intelligence_information': md5})

def sha256_intelligence(self, sha256s):
for sha256 in sha256s:
self.original_intel.append(sha256)
self.ostrica.update_intelligence_queue({'extraction_type': cfg.intelligence_type['sha256'], 'intelligence_information': sha256})

def parse_intelligence_type(self, intelligence_type, intelligence_data):
if intelligence_type.strip() == 'run':
self.run_ostrica()
self.clear_ostrica_queue()
elif (intelligence_type.strip() == 'quit' or
intelligence_type.strip() == 'exit' or
intelligence_type.strip() == 'q'):
sys.exit(0)
elif intelligence_type.strip() == 'clear':
self.clear_ostrica_queue()
elif intelligence_type.strip() == 'show':
self.show_ostrica_queue_elements()
elif intelligence_type.strip() == 'graph':
self.generate_ostrica_graph()
elif intelligence_type.strip() == 'cola_graph':
self.generate_ostrica_graph('cola')
elif intelligence_type.strip() == 'gclean':
self.clean_ostrica_graph()
elif intelligence_type.strip() == 'domain':
self.domain_intelligence(intelligence_data)
elif intelligence_type.strip() == 'ip':
self.ip_intelligence(intelligence_data)
elif intelligence_type.strip() == 'asn':
self.asn_intelligence(intelligence_data)
elif intelligence_type.strip() == 'md5':
self.md5_intelligence(intelligence_data)
elif intelligence_type.strip() == 'sha256':
self.sha256_intelligence(intelligence_data)
elif intelligence_type.strip() == 'email':
self.email_intelligence(intelligence_data)
elif intelligence_type.strip() == 'help':
self.help()
elif intelligence_type.strip() == 'plugins':
self.plugins_info()
else:
print 'Unknown command.'

def console(self):
while 1:
data_input = raw_input("> ")
intelligence = data_input.split('=')
if len(intelligence) == 2:
intelligence_type = intelligence[0].strip()
intelligence_data = intelligence[1].split(',')
self.parse_intelligence_type(intelligence_type, intelligence_data)
else:
intelligence_type = intelligence[0].strip()
self.parse_intelligence_type(intelligence_type, '')

def main():
print '%s v.%s - %s' % (cfg.tool_name, cfg.version, cfg.tool_description)
print 'Developed by: %s <%s>' % (cfg.developer, cfg.developer_email)
print 'write "help" for help'

ostrica_console = OstricaConsole()
ostrica_console.console()


if __name__ == '__main__':
main()

Loading

0 comments on commit 10117af

Please sign in to comment.