diff --git a/README.md b/README.md index c0f74e2..557c6da 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ By providing an easy to use interactive command line application, users are able This project has taken motivation from the greats that came before it such as SpiderFoot, Harpoon, and DataSploit. Much thanks to those great authors for contributing to the world of open source. -The application is written with Python 2.7 in mind and has been successfully tested on OSX and Ubuntu 16.04 environments. +The application is written with Python 3.6 in mind and has been successfully tested on MacOS. This is a beta of the final application and as such there may be some bugs or other weirdness during usage. For the most part Omnibus is fully functional and can be used to begin OSINT investigation right away. diff --git a/lib/cache.py b/lib/cache.py index d9bead0..16f4b9c 100644 --- a/lib/cache.py +++ b/lib/cache.py @@ -8,15 +8,16 @@ from redis import Redis -from common import error +from .common import error -from common import get_option +from .common import get_option -from common import utf_decode -from common import utf_encode +from .common import utf_decode +from .common import utf_encode class RedisCache(object): + def __init__(self, config): self.host = get_option('redis', 'host', config) self.port = int(get_option('redis', 'port', config)) @@ -24,12 +25,10 @@ def __init__(self, config): self.ttl = 999999 try: - self.db = Redis(db=self.database, host=self.host, - port=self.port, socket_timeout=None) + self.db = Redis(db=self.database, host=self.host, port=self.port, socket_timeout=None) except: self.db = None - def receive(self, queue_name): """ Return most recent message from a given Redis queue""" try: @@ -41,7 +40,6 @@ def receive(self, queue_name): error('[redis] failed to receive message from queue %s (error: %s)' % (queue_name, str(err))) pass - def delete(self, names): """ Remove one or more keys by name """ try: @@ -49,12 +47,10 @@ def delete(self, names): except Exception as err: error('[redis] failed to delete artifacts (error: %s)' % str(err)) - def exists(self, key): """ Check if value exists by key """ return self.db.exists(key) - def get(self, key): """ Get a value from redis by key """ retval = self.db.get(key) @@ -62,7 +58,6 @@ def get(self, key): return utf_decode(retval) return retval - def set(self, key, value, ttl=None): """ Set a value in cache with optional TTL """ if ttl is None: @@ -73,7 +68,6 @@ def set(self, key, value, ttl=None): self.db.setnx(key, value) self.db.expire(key, ttl) - def flush(self): """ Flush opened database entirely """ self.db.flushdb() diff --git a/lib/common.py b/lib/common.py index 8e09d7a..db5f52d 100644 --- a/lib/common.py +++ b/lib/common.py @@ -5,7 +5,7 @@ import json import string import datetime -import ConfigParser +import configparser from pygments import lexers from pygments import highlight @@ -72,12 +72,15 @@ def pp_json(data): if data is None: warning('No data returned from module.') else: - print(highlight(unicode(json.dumps(data, indent=4, default=jsondate), 'UTF-8'), - lexers.JsonLexer(), formatters.TerminalFormatter())) + print(highlight( + json.dumps(data, indent=4, default=jsondate), + lexers.JsonLexer(), + formatters.TerminalFormatter(), + )) def get_option(section, name, conf): - config = ConfigParser.ConfigParser() + config = configparser.ConfigParser() if not os.path.exists(conf): error('configuration file %s does not exist!' % conf) return None @@ -165,7 +168,7 @@ def mkdir(path): else: try: os.mkdir(path) - os.chmod(path, 0777) + os.chmod(path, 0x1FF) # 0777 permissions return True except: return False @@ -177,7 +180,7 @@ def lookup_key(session, artifact): valid_key = False if session is None: - return (valid_key, value) + return valid_key, value try: artifact = int(artifact) @@ -186,7 +189,7 @@ def lookup_key(session, artifact): except: pass - return (valid_key, value) + return valid_key, value def utf_decode(data): @@ -238,32 +241,31 @@ def is_email(address): return bool(re.match(re_email, address)) -def is_hash(string): +def is_hash(string_): """ Check if string is a valid hash and if so what kind """ - if re.match(re_md5, string): + if re.match(re_md5, string_): return 'md5' - elif re.match(re_sha1, string): + elif re.match(re_sha1, string_): return 'sha1' - elif re.match(re_sha256, string): + elif re.match(re_sha256, string_): return 'sha256' - elif re.match(re_sha512, string): + elif re.match(re_sha512, string_): return 'sha512' else: return False -def is_btc_addr(string): +def is_btc_addr(string_): """Check if string is matches as a Bitcoin address. @note: This does not verify that the string is a VALID BTC address, only that it matches the regex pattern of BTC addresses. """ - if re.match(re_btc, string): + if re.match(re_btc, string_): return 'btc' return False - def detect_type(artifact): """ Determine type of given argument """ if is_ipv4(artifact): diff --git a/lib/dispatch.py b/lib/dispatch.py index deb9896..924ef10 100644 --- a/lib/dispatch.py +++ b/lib/dispatch.py @@ -5,15 +5,15 @@ ## import importlib -from common import info -from common import error -from common import success -from common import warning +from .common import info +from .common import error +from .common import success +from .common import warning -from common import lookup_key -from common import detect_type +from .common import lookup_key +from .common import detect_type -from models import create_artifact +from .models import create_artifact class Dispatch(object): @@ -44,9 +44,9 @@ def __init__(self, db): ], } - def machine(self, session, artifact): """ Run all modules against an artifact of a given type """ + modules = [] is_key, value = lookup_key(session, artifact) if is_key and value is None: @@ -77,8 +77,13 @@ def machine(self, session, artifact): if self.db.exists(artifact['type'], {'name': artifact['name']}): for child in result['children']: - child_artifact = create_artifact(child['name'], parent=artifact['name'], - _type=child['type'], source=child['source'], subtype=child['subtype']) + child_artifact = create_artifact( + child['name'], + parent=artifact['name'], + _type=child['type'], + source=child['source'], + subtype=child['subtype'], + ) if not self.db.exists(child['type'], {'name': child['name']}): self.db.insert_one(child['type'], child_artifact) @@ -97,7 +102,6 @@ def machine(self, session, artifact): success('Machine completed') - def submit(self, session, module, artifact, no_argument=False): """ Run a single module against an artifact """ if no_argument: @@ -135,8 +139,13 @@ def submit(self, session, module, artifact, no_argument=False): if self.db.exists(artifact['type'], {'name': artifact['name']}): for child in result['children']: - child_artifact = create_artifact(child['name'], parent=artifact['name'], - _type=child['type'], source=child['source'], subtype=child['subtype']) + child_artifact = create_artifact( + child['name'], + parent=artifact['name'], + _type=child['type'], + source=child['source'], + subtype=child['subtype'], + ) if not self.db.exists(child['type'], {'name': child['name']}): self.db.insert_one(child['type'], child_artifact) @@ -155,11 +164,8 @@ def submit(self, session, module, artifact, no_argument=False): else: warning('Failed to get module results (%s)' % module) - def run(self, module, artifact): """ Load Python library from modules directory and execute main function """ - results = None - try: ptr = importlib.import_module('lib.modules.%s' % module) except Exception as err: diff --git a/lib/http.py b/lib/http.py index dfec737..22fbb7a 100644 --- a/lib/http.py +++ b/lib/http.py @@ -32,12 +32,12 @@ def post(*args, **kwargs): try: req = requests.post(*args, **kwargs) except: - return (False, None) + return False, None if req.status_code == 200: - return (True, req) + return True, req else: - return (False, req) + return False, req def get(*args, **kwargs): @@ -52,9 +52,9 @@ def get(*args, **kwargs): try: req = requests.get(*args, **kwargs) except: - return (False, None) + return False, None if req.status_code == 200: - return (True, req) + return True, req else: - return (False, req) + return False, req diff --git a/lib/models.py b/lib/models.py index 2344c19..7f384a0 100644 --- a/lib/models.py +++ b/lib/models.py @@ -4,24 +4,24 @@ # starter data models for host, email, and user artifacts ## -from common import is_ipv4 -from common import is_ipv6 -from common import is_fqdn -from common import is_hash +from .common import is_ipv4 +from .common import is_ipv6 +from .common import is_fqdn +from .common import is_hash -from common import warning -from common import timestamp -from common import detect_type +from .common import warning +from .common import timestamp +from .common import detect_type artifact_types = ['host', 'email', 'user', 'bitcoin', 'hash'] class Artifact(object): - def __init__(self, name, type, source=None, subtype=None, case_id=None): + def __init__(self, name, type_, source=None, subtype=None, case_id=None): self.name = name self.created = timestamp() - self.type = type + self.type = type_ self.subtype = subtype self.source = source self.parent = None @@ -69,7 +69,7 @@ def create_artifact(artifact_name, _type=None, source=None, subtype=None, parent warning('Artifact must be one of: email, ipv4, fqdn, user, hash, bitcoin address') return None - created = Artifact(name=artifact_name, type=artifact_type, subtype=subtype, source=source) + created = Artifact(name=artifact_name, type_=artifact_type, subtype=subtype, source=source) if parent is not None: created.parent = parent diff --git a/lib/modules/blockchain.py b/lib/modules/blockchain.py index 48ecfb5..32a80f5 100644 --- a/lib/modules/blockchain.py +++ b/lib/modules/blockchain.py @@ -3,18 +3,18 @@ # omnibus - deadbits # blockchain.info address lookup ## -from http import get -from common import warning +from ..common import warning +from ..http import get class Plugin(object): + def __init__(self, artifact): self.artifact = artifact self.artifact['data']['blockchain'] = None self.headers = {'User-Agent': 'OSINT Omnibus (https://github.com/InQuest/Omnibus)'} - def run(self): url = 'https://blockchain.info/rawaddr/%s' % self.artifact['name'] diff --git a/lib/modules/censys.py b/lib/modules/censys.py index 8159de7..9fc6dc1 100644 --- a/lib/modules/censys.py +++ b/lib/modules/censys.py @@ -4,13 +4,13 @@ # censys.io module ## -from http import get - -from common import get_apikey -from common import warning +from ..common import get_apikey +from ..common import warning +from ..http import get class Plugin(object): + def __init__(self, artifact): self.artifact = artifact self.artifact['data']['censys'] = None @@ -19,7 +19,6 @@ def __init__(self, artifact): raise TypeError('API keys cannot be left blank | set all keys in etc/apikeys.json') self.headers = {'User-Agent': 'OSINT Omnibus (https://github.com/InQuest/Omnibus)'} - def run(self): url = 'https://censys.io/api/v1/view/ipv4/%s' % self.artifact['name'] diff --git a/lib/modules/clearbit.py b/lib/modules/clearbit.py index 9ad62e8..4f61d62 100644 --- a/lib/modules/clearbit.py +++ b/lib/modules/clearbit.py @@ -3,13 +3,14 @@ # omnibus - deadbits. # clearbit email lookup module ## -from http import get -from common import warning -from common import get_apikey +from ..common import get_apikey +from ..common import warning +from ..http import get class Plugin(object): + def __init__(self, artifact): self.artifact = artifact self.artifact['data']['clearbit'] = None diff --git a/lib/modules/csirtg.py b/lib/modules/csirtg.py index f3c9b9d..9ef9829 100644 --- a/lib/modules/csirtg.py +++ b/lib/modules/csirtg.py @@ -1,11 +1,12 @@ -from csirtgsdk.client import Client +from csirtgsdk.client.http import HTTP from csirtgsdk.search import Search -from common import get_apikey -from common import warning +from ..common import get_apikey +from ..common import warning class Plugin(object): + def __init__(self, artifact): self.artifact = artifact self.artifact['data']['csirtg'] = None @@ -15,7 +16,7 @@ def __init__(self, artifact): def run(self): try: - client = Client(remote='https://csirtg.io/api', token=self.api_key) + client = HTTP(remote='https://csirtg.io/api', token=self.api_key) search = Search(client) data = search.search(self.artifact['name']) diff --git a/lib/modules/cybercure.py b/lib/modules/cybercure.py index b35ec2c..7ca9f4f 100644 --- a/lib/modules/cybercure.py +++ b/lib/modules/cybercure.py @@ -4,17 +4,17 @@ # Module to implement indicators search functionality in cybercure.ai api # ## -from http import get -from common import warning +from ..common import warning +from ..http import get class Plugin(object): + def __init__(self, artifact): self.artifact = artifact self.artifact['data']['cybercure'] = None - def run(self): url = 'http://api.cybercure.ai/feed/search?value=%s' % self.artifact['name'] headers = {'User-Agent': 'OSINT Omnibus (https://github.com/InQuest/Omnibus)'} diff --git a/lib/modules/cymon.py b/lib/modules/cymon.py index c6ef4e8..eb920ca 100644 --- a/lib/modules/cymon.py +++ b/lib/modules/cymon.py @@ -3,13 +3,15 @@ # omnibus - deadbits. # cymon.io module ## + import cymon -from common import get_apikey -from common import warning +from ..common import get_apikey +from ..common import warning class Plugin(object): + def __init__(self, artifact): self.artifact = artifact self.artifact['data']['cymon'] = None @@ -18,21 +20,18 @@ def __init__(self, artifact): raise TypeError('API keys cannot be left blank | set all keys in etc/apikeys.json') self.api = cymon.Cymon(self.api_key) - def ip(self): try: self.artifact['data']['cymon'] = self.api.ip_lookup(self.artifact['name']) except Exception as err: warning('Caught exception in module (%s)' % str(err)) - def fqdn(self): try: self.artifact['data']['cymon'] = self.api.domain_lookup(self.artifact['name']) except Exception as err: warning('Caught exception in module (%s)' % str(err)) - def run(self): if self.artifact['subtype'] == 'ipv4': self.ip() diff --git a/lib/modules/dnsbrute.py b/lib/modules/dnsbrute.py index 6aa3ba7..7208615 100644 --- a/lib/modules/dnsbrute.py +++ b/lib/modules/dnsbrute.py @@ -12,11 +12,12 @@ from OTXv2 import OTXv2 import IndicatorTypes -from common import get_apikey -from common import warning +from ..common import get_apikey +from ..common import warning class Plugin(object): + def __init__(self, artifact): self.artifact = artifact self.artifact['data']['dnsbrute'] = {} @@ -30,7 +31,6 @@ def __init__(self, artifact): if self.otx_api_key == '': raise TypeError('API keys cannot be left blank | set all keys in etc/apikeys.json') - def otx(self): otx_server = 'https://otx.alienvault.com/' otx_conn = OTXv2(self.otx_api_key, server=otx_server) @@ -50,7 +50,6 @@ def otx(self): self.artifact['data']['dnsbrute']['otx'] = domains - def vt(self): url = 'https://www.virustotal.com/vtapi/v2/domain/report' params = {'domain': self.artifact['name'], 'apikey': self.api_key} diff --git a/lib/modules/dnsresolve.py b/lib/modules/dnsresolve.py index 73fe160..b4ed54a 100644 --- a/lib/modules/dnsresolve.py +++ b/lib/modules/dnsresolve.py @@ -6,17 +6,18 @@ import dns.resolver -from common import warning -from common import detect_type +from ..common import warning +from ..common import detect_type class Plugin(object): + def __init__(self, artifact): self.artifact = artifact self.artifact['data']['dnsresolve'] = None - - def get_record(self, domain, record): + @staticmethod + def get_record(domain, record): results = [] try: @@ -32,7 +33,6 @@ def get_record(self, domain, record): return results - def run(self): domain = self.artifact['name'] diff --git a/lib/modules/fullcontact.py b/lib/modules/fullcontact.py index 513a6b1..7f357e9 100644 --- a/lib/modules/fullcontact.py +++ b/lib/modules/fullcontact.py @@ -3,13 +3,14 @@ # omnibus - deadbits # fullcontact.com ## -from http import get -from common import get_apikey -from common import warning +from ..common import get_apikey +from ..common import warning +from ..http import get class Plugin(object): + def __init__(self, artifact): self.artifact = artifact self.artifact['data']['fullcontact'] = None @@ -21,11 +22,12 @@ def __init__(self, artifact): 'User-Agent': 'OSINT Omnibus (https://github.com/InQuest/Omnibus)' } - def run(self): try: - status, response = get('https://api.fullcontact.com/v2/person.json?email=%s' % self.artifact['name'], - headers=self.headers) + status, response = get( + 'https://api.fullcontact.com/v2/person.json?email=%s' % self.artifact['name'], + headers=self.headers, + ) if status: self.artifact['data']['fullcontact'] = response.json() diff --git a/lib/modules/geoip.py b/lib/modules/geoip.py index 43214b1..313520f 100644 --- a/lib/modules/geoip.py +++ b/lib/modules/geoip.py @@ -3,10 +3,10 @@ # omnibus - deadbits. # geolocation for hosts ## -from http import get -from common import get_apikey -from common import warning +from ..common import get_apikey +from ..common import warning +from ..http import get class Plugin(object): @@ -20,7 +20,6 @@ def __init__(self, artifact): 'Accept-Encoding': 'gzip, deflate', 'User-Agent': 'OSINT Omnibus (https://github.com/InQuest/Omnibus)'} - def run(self): url = 'http://api.ipstack.com/%s?access_key=%s&hostname=1' % (self.artifact['name'], self.api_key) diff --git a/lib/modules/github.py b/lib/modules/github.py index 2d4d450..7a3982c 100644 --- a/lib/modules/github.py +++ b/lib/modules/github.py @@ -3,17 +3,17 @@ # omnibus - deadbits # search github for active users ## -from http import get -from common import warning +from ..common import warning +from ..http import get class Plugin(object): + def __init__(self, artifact): self.artifact = artifact self.artifact['data']['github'] = None - def run(self): url = 'https://api.github.com/users/%s' % self.artifact['name'] headers = {'User-Agent': 'OSINT Omnibus (https://github.com/InQuest/Omnibus)'} diff --git a/lib/modules/hackedemails.py b/lib/modules/hackedemails.py index 9e64b99..2642b07 100644 --- a/lib/modules/hackedemails.py +++ b/lib/modules/hackedemails.py @@ -3,17 +3,17 @@ # omnibus - deadbits # hacked-emails.com ## -from http import get -from common import warning +from ..common import warning +from ..http import get class Plugin(object): + def __init__(self, artifact): self.artifact = artifact self.artifact['data']['hackedemails'] = None - def run(self): url = 'https://hacked-emails.com/api?q=%s' % self.artifact['name'] headers = {'User-Agent': 'OSINT Omnibus (https://github.com/InQuest/Omnibus)'} diff --git a/lib/modules/he.py b/lib/modules/he.py index a0e7211..27cd9c2 100644 --- a/lib/modules/he.py +++ b/lib/modules/he.py @@ -5,19 +5,18 @@ ## import re -from BeautifulSoup import BeautifulSoup +from bs4 import BeautifulSoup -from http import get - -from common import warning +from ..common import warning +from ..http import get class Plugin(object): + def __init__(self, artifact): self.artifact = artifact self.artifact['data']['he'] = None - def ip(self): url = 'http://bgp.he.net/ip/%s#_dns' % self.artifact['name'] headers = {'User-Agent': 'OSINT Omnibus (https://github.com/InQuest/Omnibus)'} @@ -35,7 +34,6 @@ def ip(self): except Exception as err: warning('Caught exception in module (%s)' % str(err)) - def fqdn(self): url = 'http://bgp.he.net/dns/%s#_whois' % self.artifact['name'] headers = {'User-Agent': 'OSINT Omnibus (https://github.com/InQuest/Omnibus)'} @@ -45,14 +43,13 @@ def fqdn(self): result = [] if status: - pattern = re.compile('\/dns\/.+\".title\=\".+\"\>(.+)<\/a\>', re.IGNORECASE) + pattern = re.compile('/dns/.+\".title=\".+\">(.+)', re.IGNORECASE) hosts = re.findall(pattern, response.text) for h in hosts: result.append(h.strip()) except Exception as err: warning('Caught exception in module (%s)' % str(err)) - def run(self): if self.artifact['subtype'] == 'ipv4': self.artifact['data']['he'] = self.ip() diff --git a/lib/modules/hibp.py b/lib/modules/hibp.py index 5cdf57a..2311a6d 100644 --- a/lib/modules/hibp.py +++ b/lib/modules/hibp.py @@ -3,18 +3,18 @@ # omnibus - deadbits # haveibeenpwned ## -from http import get -from common import warning +from ..common import warning +from ..http import get class Plugin(object): + def __init__(self, artifact): self.artifact = artifact self.artifact['data']['hibp'] = {'breaches': None, 'pastes': None} self.headers = {'User-Agent': 'OSINT Omnibus (https://github.com/InQuest/Omnibus)'} - def breaches(self): url = 'https://haveibeenpwned.com/api/v2/breachedaccount/%s' % self.artifact['name'] @@ -25,7 +25,6 @@ def breaches(self): except Exception as err: warning('Caught exception in module (%s)' % str(err)) - def pastes(self): url = 'https://haveibeenpwned.com/api/v2/pasteaccount/%s' % self.artifact['name'] @@ -36,7 +35,6 @@ def pastes(self): except Exception as err: warning('Caught exception in module (%s)' % str(err)) - def run(self): self.breaches() self.pastes() diff --git a/lib/modules/ipinfo.py b/lib/modules/ipinfo.py index 4a2e4ee..3bac4d8 100644 --- a/lib/modules/ipinfo.py +++ b/lib/modules/ipinfo.py @@ -3,13 +3,14 @@ # omnibus - deadbits. # ipinfo module ## -from http import get -from common import warning -from common import get_apikey +from ..common import get_apikey +from ..common import warning +from ..http import get class Plugin(object): + def __init__(self, artifact): self.artifact = artifact self.artifact['data']['ipinfo'] = None @@ -18,7 +19,6 @@ def __init__(self, artifact): raise TypeError('API keys cannot be left blank | set all keys in etc/apikeys.json') self.headers = {'User-Agent': 'OSINT Omnibus (https://github.com/InQuest/Omnibus)'} - def run(self): url = 'http://ipinfo.io/%s/json?token=%s' % (self.artifact['name'], self.api_key) diff --git a/lib/modules/ipvoid.py b/lib/modules/ipvoid.py index 125341a..20d7d22 100644 --- a/lib/modules/ipvoid.py +++ b/lib/modules/ipvoid.py @@ -3,20 +3,19 @@ # omnibus - deadbits. # ipvoid module ## -from BeautifulSoup import BeautifulSoup +from bs4 import BeautifulSoup -from http import get - -from common import warning +from ..common import warning +from ..http import get class Plugin(object): + def __init__(self, artifact): self.artifact = artifact self.artifact['data']['ipvoid'] = None self.headers = {'User-Agent': 'OSINT Omnibus (https://github.com/InQuest/Omnibus)'} - def run(self): url = 'http://www.ipvoid.com/scan/%s/' % self.artifact['name'] diff --git a/lib/modules/keybase.py b/lib/modules/keybase.py index cb1adb3..c89a90f 100644 --- a/lib/modules/keybase.py +++ b/lib/modules/keybase.py @@ -3,18 +3,18 @@ # omnibus - deadbits. # keybase user search ## -from http import get -from common import warning +from ..common import warning +from ..http import get class Plugin(object): + def __init__(self, artifact): self.artifact = artifact self.artifact['data']['keybase'] = None self.headers = {'User-Agent': 'OSINT Omnibus (https://github.com/InQuest/Omnibus)'} - def run(self): url = 'https://keybase.io/_/api/1.0/user/lookup.json?usernames=%s' % self.artifact['name'] diff --git a/lib/modules/malwarepatrol.py b/lib/modules/malwarepatrol.py index 121fb62..2e7b300 100644 --- a/lib/modules/malwarepatrol.py +++ b/lib/modules/malwarepatrol.py @@ -3,13 +3,14 @@ # omnibus - deadbits # malware patrol search ## -from http import get -from common import warning -from common import get_apikey +from ..common import get_apikey +from ..common import warning +from ..http import get class Plugin(object): + def __init__(self, artifact): self.artifact = artifact self.artifact['data']['malwarepatrol'] = None @@ -18,7 +19,6 @@ def __init__(self, artifact): raise TypeError('API keys cannot be left blank | set all keys in etc/apikeys.json') self.headers = {'User-Agent': 'OSINT Omnibus (https://github.com/InQuest/Omnibus)'} - def run(self): url = 'http://lists.malwarepatrol.net/cgi/getfile?receipt=%s&product=8&list=smoothwall' % self.api_key diff --git a/lib/modules/nmap.py b/lib/modules/nmap.py index 961b788..659a8f3 100644 --- a/lib/modules/nmap.py +++ b/lib/modules/nmap.py @@ -6,15 +6,15 @@ from libnmap.process import NmapProcess from libnmap.parser import NmapParser -from common import warning +from ..common import warning class Plugin(object): + def __init__(self, artifact): self.artifact = artifact self.artifact['data']['nmap'] = None - def run(self): nm = NmapProcess(targets=str(self.artifact['name']), options='-sT -sV -Pn -T5 -p21,22,23,25,80,6667,1337') nm.run() diff --git a/lib/modules/otx.py b/lib/modules/otx.py index 3d7027c..53467bb 100644 --- a/lib/modules/otx.py +++ b/lib/modules/otx.py @@ -3,18 +3,18 @@ # omnibus - deadbits. # alienvault otx module ## -from http import get -from common import warning +from ..common import warning +from ..http import get class Plugin(object): + def __init__(self, artifact): self.artifact = artifact self.artifact['data']['otx'] = None self.headers = {'User-Agent': 'OSINT Omnibus (https://github.com/InQuest/Omnibus)'} - def ip(self): url = 'https://otx.alienvault.com:443/api/v1/indicators/IPv4/%s/' % self.artifact['name'] @@ -26,7 +26,6 @@ def ip(self): except Exception as err: warning('Caught exception in module (%s)' % str(err)) - def host(self): url = 'https://otx.alienvault.com:443/api/v1/indicators/domain/%s/' % self.artifact['name'] @@ -38,7 +37,6 @@ def host(self): except Exception as err: warning('Caught exception in module (%s)' % str(err)) - def hash(self): url = 'https://otx.alienvault.com:443/api/v1/indicators/file/%s/' % self.artifact['name'] @@ -50,7 +48,6 @@ def hash(self): except Exception as err: warning('Caught exception in module (%s)' % str(err)) - def run(self): if self.artifact['type'] == 'host': if self.artifact['subtype'] == 'ipv4': diff --git a/lib/modules/passivetotal.py b/lib/modules/passivetotal.py index fc7f805..190d859 100644 --- a/lib/modules/passivetotal.py +++ b/lib/modules/passivetotal.py @@ -5,13 +5,13 @@ ## from requests.auth import HTTPBasicAuth -from http import get - -from common import warning -from common import get_apikey +from ..common import get_apikey +from ..common import warning +from ..http import get class Plugin(object): + def __init__(self, artifact): self.artifact = artifact self.artifact['data']['passivetotal'] = None @@ -20,7 +20,6 @@ def __init__(self, artifact): raise TypeError('API keys cannot be left blank | set all keys in etc/apikeys.json') self.headers = {'User-Agent': 'OSINT Omnibus (https://github.com/InQuest/Omnibus)'} - def run(self): url = 'https://api.passivetotal.org/v2/dns/passive/unique?query=%s' % self.artifact['name'] diff --git a/lib/modules/pgp.py b/lib/modules/pgp.py index a55fda4..3e2d2b2 100644 --- a/lib/modules/pgp.py +++ b/lib/modules/pgp.py @@ -5,21 +5,20 @@ ## import re -from BeautifulSoup import BeautifulSoup +from bs4 import BeautifulSoup -from http import get - -from common import re_email -from common import warning +from ..common import re_email +from ..common import warning +from ..http import get class Plugin(object): + def __init__(self, artifact): self.artifact = artifact self.artifact['data']['pgp'] = None self.headers = {'User-Agent': 'OSINT Omnibus (https://github.com/InQuest/Omnibus)'} - def fqdn(self): url = 'http://pgp.mit.edu/pks/lookup?op=index&search=%s' % self.artifact['name'] @@ -51,7 +50,6 @@ def fqdn(self): except Exception as err: warning('Caught exception in module (%s)' % str(err)) - def email(self): url = 'http://pgp.mit.edu/pks/lookup?op=index&search=%s' % self.artifact['name'] @@ -82,7 +80,6 @@ def email(self): except Exception as err: warning('Caught exception in module (%s)' % str(err)) - def run(self): if self.artifact['type'] == 'email': self.email() diff --git a/lib/modules/rss.py b/lib/modules/rss.py index 1006136..87f5530 100644 --- a/lib/modules/rss.py +++ b/lib/modules/rss.py @@ -6,15 +6,15 @@ import feedparser -from common import warning +from ..common import warning class Plugin(object): + def __init__(self, feed_url): self.url = feed_url self.results = [] - def run(self): try: feed = feedparser.parse(self.url) @@ -33,7 +33,6 @@ def run(self): warning('Caught exception in module (%s)' % str(err)) - def main(artifact): plugin = Plugin(artifact) plugin.run() diff --git a/lib/modules/sans.py b/lib/modules/sans.py index e25df23..e70c411 100644 --- a/lib/modules/sans.py +++ b/lib/modules/sans.py @@ -5,15 +5,15 @@ ## import dshield -from common import warning +from ..common import warning class Plugin(object): + def __init__(self, artifact): self.artifact = artifact self.artifact['data']['sans'] = None - def run(self): try: data = dshield.ip(self.artifact['name']) diff --git a/lib/modules/shodan.py b/lib/modules/shodan.py index 12f638a..675413a 100644 --- a/lib/modules/shodan.py +++ b/lib/modules/shodan.py @@ -3,13 +3,14 @@ # omnibus - deadbits. # shodan search ## -from http import get -from common import warning -from common import get_apikey +from ..common import get_apikey +from ..common import warning +from ..http import get class Plugin(object): + def __init__(self, artifact): self.artifact = artifact self.artifact['data']['shodan'] = None @@ -28,7 +29,6 @@ def fqdn(self): except Exception as err: warning('Caught exception in module (%s)' % str(err)) - def ip(self): url = 'https://api.shodan.io/shodan/host/%s?key=%s' % (self.artifact['name'], self.api_key) @@ -39,7 +39,6 @@ def ip(self): except Exception as err: warning('Caught exception in module (%s)' % str(err)) - def run(self): if self.artifact['subtype'] == 'ipv4': self.ip() diff --git a/lib/modules/threatcrowd.py b/lib/modules/threatcrowd.py index 5299f4a..e936a43 100644 --- a/lib/modules/threatcrowd.py +++ b/lib/modules/threatcrowd.py @@ -5,29 +5,27 @@ ## import threatcrowd -from common import warning +from ..common import warning class Plugin(object): + def __init__(self, artifact): self.artifact = artifact self.artifact['data']['threatcrowd'] = None - def ip(self): try: self.artifact['data']['threatcrowd'] = threatcrowd.ip_report(self.artifact['name']) except Exception as err: warning('Caught exception in module (%s)' % str(err)) - def fqdn(self): try: self.artifact['data']['threatcrowd'] = threatcrowd.domain_report(self.artifact['name']) except Exception as err: warning('Caught exception in module (%s)' % str(err)) - def run(self): if self.artifact['subtype'] == 'ipv4': self.ip() diff --git a/lib/modules/threatminer.py b/lib/modules/threatminer.py index 556d6af..b930868 100644 --- a/lib/modules/threatminer.py +++ b/lib/modules/threatminer.py @@ -3,19 +3,19 @@ # omnibus - deadbits. # threatminer module ## -from http import get -from common import warning -from common import detect_type +from ..common import detect_type +from ..common import warning +from ..http import get class Plugin(object): + def __init__(self, artifact): self.artifact = artifact self.artifact['data']['threatminer'] = None self.headers = {'User-Agent': 'OSINT Omnibus (https://github.com/InQuest/Omnibus)'} - def ip(self): url = 'https://api.threatminer.org/v2/host.php?q=%s&rt=2' % self.artifact['name'] @@ -42,7 +42,6 @@ def ip(self): except Exception as err: warning('Caught exception in module (%s)' % str(err)) - def fqdn(self): sub_url = 'https://api.threatminer.org/v2/domain.php?q=%s&rt=5' % self.artifact['name'] pdns_url = 'https://api.threatminer.org/v2/domain.php?q=%s&rt=2' % self.artifact['name'] @@ -93,7 +92,6 @@ def fqdn(self): except Exception as err: warning('Caught exception in module (%s)' % str(err)) - def hash(self): url = 'https://api.threatminer.org/v2/sample.php?q=%s&rt=3' % self.artifact['name'] @@ -144,7 +142,6 @@ def hash(self): # }] # } - def run(self): if self.artifact['type'] == 'host': if self.artifact['subtype'] == 'ipv4': diff --git a/lib/modules/twitter.py b/lib/modules/twitter.py index 972f928..44110ab 100644 --- a/lib/modules/twitter.py +++ b/lib/modules/twitter.py @@ -4,18 +4,18 @@ # Twitter username search ## -from BeautifulSoup import BeautifulSoup +from bs4 import BeautifulSoup -from http import get +from ..http import get class Plugin(object): + def __init__(self, artifact): self.artifact = artifact self.artifact['data']['twitter'] = None self.headers = {'User-Agent': 'OSINT Omnibus (https://github.com/InQuest/Omnibus)'} - def run(self): url = 'https://www.twitter.com/%s' % self.artifact['name'] @@ -29,12 +29,21 @@ def run(self): self.artifact['data']['twitter']['name'] = soup.find('h1').contents[1].text try: - self.artifact['data']['twitter']['location'] = soup.find('span', class_='ProfileHeaderCard-locationText u-dir').contents[1].text + self.artifact['data']['twitter']['location'] = soup.find( + 'span', + class_='ProfileHeaderCard-locationText u-dir', + ).contents[1].text except: self.artifact['data']['twitter']['location'] = None - self.artifact['data']['twitter']['description'] = soup.find('div', class_='ProfileHeaderCard').contents[5].text - self.artifact['data']['twitter']['created'] = soup.find('div', class_='ProfileHeaderCard-joinDate').contents[3].text + self.artifact['data']['twitter']['description'] = soup.find( + 'div', + class_='ProfileHeaderCard', + ).contents[5].text + self.artifact['data']['twitter']['created'] = soup.find( + 'div', + class_='ProfileHeaderCard-joinDate', + ).contents[3].text except: pass diff --git a/lib/modules/urlvoid.py b/lib/modules/urlvoid.py index 86d2572..0d8e125 100644 --- a/lib/modules/urlvoid.py +++ b/lib/modules/urlvoid.py @@ -3,13 +3,14 @@ # omnibus - deadbits. # urlvoid module - from yolothreat's utilitybelt ## -from BeautifulSoup import BeautifulSoup +from bs4 import BeautifulSoup -from http import get -from common import warning +from ..common import warning +from ..http import get class Plugin(object): + def __init__(self, artifact): self.artifact = artifact self.artifact['data']['urlvoid'] = None @@ -18,7 +19,6 @@ def __init__(self, artifact): 'User-Agent': 'OSINT Omnibus (https://github.com/InQuest/Omnibus)' } - def run(self): url = 'http://urlvoid.com/scan/%s/' % self.artifact['name'] diff --git a/lib/modules/virustotal.py b/lib/modules/virustotal.py index 8ab1ba2..dde30a4 100644 --- a/lib/modules/virustotal.py +++ b/lib/modules/virustotal.py @@ -3,14 +3,15 @@ # omnibus - deadbits. # virustotal module ## -from http import get -from common import warning -from common import get_apikey -from common import detect_type +from ..common import get_apikey +from ..common import detect_type +from ..common import warning +from ..http import get class Plugin(object): + def __init__(self, artifact): self.artifact = artifact self.artifact['data']['virustotal'] = None @@ -22,7 +23,6 @@ def __init__(self, artifact): 'User-Agent': 'OSINT Omnibus (https://github.com/InQuest/Omnibus)' } - def ip(self): parameters = {'ip': self.artifact['name'], 'apikey': self.api_key} url = 'https://www.virustotal.com/vtapi/v2/ip-address/report' @@ -48,7 +48,6 @@ def ip(self): except Exception as err: warning('Caught exception in module (%s)' % str(err)) - def fqdn(self): parameters = {'domain': self.artifact['name'], 'apikey': self.api_key} url = 'https://www.virustotal.com/vtapi/v2/domain/report' @@ -74,12 +73,9 @@ def fqdn(self): except Exception as err: warning('Caught exception in module (%s)' % str(err)) - def hash(self): parameters = {'resource': self.artifact['name'], 'apikey': self.api_key} url = 'https://www.virustotal.com/vtapi/v2/file/report' - - try: status, response = get(url, params=parameters) @@ -96,7 +92,6 @@ def hash(self): except Exception as err: warning('Caught exception in module (%s)' % str(err)) - def run(self): if self.artifact['type'] == 'host': if self.artifact['subtype'] == 'ipv4': diff --git a/lib/modules/wappalyzer.py b/lib/modules/wappalyzer.py index 11d7a2b..dbf19de 100644 --- a/lib/modules/wappalyzer.py +++ b/lib/modules/wappalyzer.py @@ -6,10 +6,11 @@ import Wappalyzer -from common import warning +from ..common import warning class Plugin(object): + def __init__(self, artifact): self.artifact = artifact if not self.artifact['name'].startwith('https://') or not self.artifact['name'].startwith('http://'): @@ -19,7 +20,6 @@ def __init__(self, artifact): self.artifact['data']['wappalyzer'] = None - def run(self): # Everybody hating we just call them skids tho # In love with the OSINt, I ain't never letting go... diff --git a/lib/modules/whois.py b/lib/modules/whois.py index 44505a5..292eea1 100644 --- a/lib/modules/whois.py +++ b/lib/modules/whois.py @@ -3,19 +3,19 @@ # omnibus - deadbits. # whois module ## -import whois - -from common import warning +import whois from ipwhois import IPWhois +from ..common import warning + class Plugin(object): + def __init__(self, artifact): self.artifact = artifact self.artifact['data']['whois'] = None - def ip(self): whois_data = IPWhois(self.artifact['name']) @@ -41,7 +41,6 @@ def ip(self): except Exception as err: warning('Caught unhandled exception: %s' % str(err)) - def fqdn(self): try: results = whois.whois(self.artifact['name']) @@ -49,7 +48,6 @@ def fqdn(self): except: pass - def run(self): if self.artifact['type'] == 'host': if self.artifact['subtype'] == 'ipv4': diff --git a/lib/modules/whoismind.py b/lib/modules/whoismind.py index 4436dea..23499a5 100644 --- a/lib/modules/whoismind.py +++ b/lib/modules/whoismind.py @@ -3,19 +3,19 @@ # omnibus - deadbits. # Whois Mind lookup module ## -import BeautifulSoup +from bs4 import BeautifulSoup -from http import get -from common import warning +from ..common import warning +from ..http import get class Plugin(object): + def __init__(self, artifact): self.artifact = artifact self.artifact['data']['whoismind'] = [] self.headers = {'User-Agent': 'OSINT Omnibus (https://github.com/InQuest/Omnibus)'} - def run(self): url = 'http://www.whoismind.com/emails/%s.html' % self.artifact['name'] diff --git a/lib/modules/yara.py b/lib/modules/yara.py index 0a80b2b..aa967cb 100644 --- a/lib/modules/yara.py +++ b/lib/modules/yara.py @@ -7,13 +7,14 @@ import os import yara -from common import list_dir -from common import get_option +from ..common import list_dir +from ..common import get_option CONF = os.path.abspath('../../etc/omnibus.conf') class Plugin(object): + def __init__(self, artifact): self.artifact = artifact self.artifact['data']['yara'] = None @@ -26,7 +27,6 @@ def __init__(self, artifact): if list_dir(self.rules) == 0: raise TypeError('Invalid YARA rules directory in conf file: No files contained in directory!') - def run(self): results = {'matches': {}} diff --git a/lib/mongo.py b/lib/mongo.py index 53fa0fe..f1f53c6 100644 --- a/lib/mongo.py +++ b/lib/mongo.py @@ -6,9 +6,9 @@ import pymongo -from common import error +from .common import error -from common import get_option +from .common import get_option class Mongo(object): @@ -25,11 +25,9 @@ def __init__(self, config): self.db = self.conn['omnibus'] self.collections = ['email', 'user', 'host', 'hash', 'bitcoin'] - def use_coll(self, collection): return self.db[collection] - def get_value(self, collection, query, key): """ get value of given key from db query """ coll = self.use_coll(collection) @@ -38,7 +36,6 @@ def get_value(self, collection, query, key): return None return result[key] - def exists(self, collection, query): coll = self.use_coll(collection) result = coll.find_one(query) @@ -46,12 +43,12 @@ def exists(self, collection, query): return False return True - - def count(self, collection, query={}): + def count(self, collection, query=None): + if not query: + query = {} coll = self.use_coll(collection) return coll.count(query) - def insert_one(self, collection, data): if isinstance(data, object): data = data.__dict__ @@ -67,7 +64,6 @@ def insert_one(self, collection, data): return str(doc_id) - def update_one(self, collection, query, new_data): coll = self.use_coll(collection) doc_id = None @@ -79,7 +75,6 @@ def update_one(self, collection, query, new_data): return doc_id - def delete_one(self, collection, query): coll = self.use_coll(collection) try: @@ -88,11 +83,11 @@ def delete_one(self, collection, query): error('failed to delete documets: %s' % query) pass - - def find_recent(self, collection, query={}, num_items=25, offset=0): + def find_recent(self, collection, query=None, num_items=25, offset=0): + if not query: + query = {} coll = self.use_coll(collection) total = self.count(collection, query) - result = [] if total < num_items: result = list(coll.find(query)) @@ -105,7 +100,6 @@ def find_recent(self, collection, query={}, num_items=25, offset=0): return result - def find(self, collection, query, one=False): """ return multiple query results as dict or single result as list """ coll = self.use_coll(collection) diff --git a/lib/storage.py b/lib/storage.py index 10ac9a7..5d3994f 100644 --- a/lib/storage.py +++ b/lib/storage.py @@ -6,14 +6,15 @@ import os import json -from common import timestamp +from .common import timestamp -from common import error -from common import success -from common import warning +from .common import error +from .common import success +from .common import warning class JSON(object): + def __init__(self, data, file_path=None, file_name='report.json', create=True): self.data = data self.file_path = None @@ -26,7 +27,6 @@ def __init__(self, data, file_path=None, file_name='report.json', create=True): if file_path: self.set_filepath(file_path, file_name, create) - def set_filepath(self, file_path, file_name, create=True): if os.path.isdir(file_path): self.file_path = os.path.join(file_path, file_name) @@ -38,7 +38,6 @@ def set_filepath(self, file_path, file_name, create=True): error('unable to find directory %s - cannot save report' % file_path) return False - def save(self): if self.file_path: with open(self.file_path, 'wb') as fp: diff --git a/omnibus-cli.py b/omnibus-cli.py index 5f87785..4c831bb 100644 --- a/omnibus-cli.py +++ b/omnibus-cli.py @@ -94,7 +94,6 @@ def __init__(self): if DEBUG: self.do_set('debug true') - def sigint_handler(self, signum, frame): """Ensure Redis DB is cleared before exiting application""" pipe_proc = self.pipe_proc @@ -106,7 +105,6 @@ def sigint_handler(self, signum, frame): raise KeyboardInterrupt('Caught keyboard interrupt; quitting ...') - def default(self, arg): """Override default function for custom error message""" if arg.startswith('#'): @@ -115,7 +113,6 @@ def default(self, arg): error('Unknown command') return - def do_quit(self, _): """Exit Omnibus shell.""" self._should_quit = True @@ -127,61 +124,71 @@ def do_quit(self, _): warning('Closing Omnibus shell ...') return self._STOP_AND_EXIT - - def do_clear(self, arg): + @staticmethod + def do_clear(arg): """Clear the console""" + del arg os.system('clear') - - def do_modules(self, arg): + @staticmethod + def do_modules(arg): """Show module list""" + del arg bold_msg('[ Modules ]') for cmd in help_dict['modules']: print(cmd) - - def do_artifacts(self, arg): + @staticmethod + def do_artifacts(arg): """Show artifact information and available commands""" + del arg bold_msg('[ Artifacts ]') for cmd in help_dict['artifacts']: print(cmd) - - def do_general(self, arg): + @staticmethod + def do_general(arg): """Show general commands""" + del arg bold_msg('[ General Commands ]') for cmd in help_dict['general']: print(cmd) - - def do_sessions(self, arg): + @staticmethod + def do_sessions(arg): """Show session commands""" + del arg bold_msg('[ Session Commands ]') for cmd in help_dict['sessions']: print(cmd) - - def do_redirect(self, arg): + @staticmethod + def do_redirect(arg): """ Show redirection command help """ - info('Omnibus supports command redirection to output files using the ">" character. For example, "cat host zeroharbor.org > zh.json" will pipe the output of the cat command to ./zh.json on disk.') - - - def do_banner(self, arg): + del arg + info( + 'Omnibus supports command redirection to output files using the ">" character. For example, "cat host ' + 'zeroharbor.org > zh.json" will pipe the output of the cat command to ./zh.json on disk.' + ) + + @staticmethod + def do_banner(arg): """Display random ascii art banner""" + del arg print(asciiart.show_banner()) - def do_session(self, arg): """Open a new session""" + del arg self.session = RedisCache(config) if self.session.db is None: error('Failed to connect to Redis back-end. Please ensure the Redis service is running') else: success('Opened new session') - def do_ls(self, arg): """View current sessions artifacts""" + del arg if self.session is None: warning('No active session') return @@ -194,9 +201,9 @@ def do_ls(self, arg): count += 1 info('Active Artifacts: %d' % count) - def do_wipe(self, arg): """Clear currently active artifacts """ + del arg if self.session is not None: info('Clearing active artifacts from cache ...') self.session.flush() @@ -204,14 +211,13 @@ def do_wipe(self, arg): else: warning('No active session; start a new session by running the "session" command') - def do_rm(self, arg): """Remove artifact from session by ID Usage: rm """ try: arg = int(arg) - except: + except TypeError: error('Artifact ID must be an integer') return @@ -224,7 +230,6 @@ def do_rm(self, arg): else: warning('No active session; start a new session by running the "session" command') - def do_new(self, arg): """Create a new artifact @@ -246,13 +251,12 @@ def do_new(self, arg): print('Artifact ID: 1') else: count = 0 - for key in self.session.db.scan_iter(): + for _ in self.session.db.scan_iter(): count += 1 _id = count + 1 self.session.set(_id, artifact.name) print('Artifact ID: %s' % _id) - def do_delete(self, arg): """Remove artifact from database by name or ID @@ -271,7 +275,6 @@ def do_delete(self, arg): artifact_type = detect_type(arg) self.db.delete_one(artifact_type, {'name': arg}) - def do_cat(self, arg): """View artifact details or list API keys @@ -279,7 +282,7 @@ def do_cat(self, arg): cat """ if arg == 'apikeys': data = json.load(open(common.API_CONF, 'rb')) - print json.dumps(data, indent=2) + print(json.dumps(data, indent=2)) else: is_key, value = lookup_key(self.session, arg) @@ -296,8 +299,7 @@ def do_cat(self, arg): if len(result) == 0: info('No entry found for artifact (%s)' % arg) else: - print json.dumps(result, indent=2, separators=(',', ':')) - + print(json.dumps(result, indent=2, separators=(',', ':'))) def do_open(self, arg): """Load text file list of artifacts @@ -334,7 +336,6 @@ def do_open(self, arg): success('Finished loading artifact list') - def do_report(self, arg): """Save artifact report as JSON file @@ -363,7 +364,6 @@ def do_report(self, arg): else: error('Failed to properly save report') - def do_machine(self, arg): """Run all modules available for an artifacts type @@ -372,178 +372,147 @@ def do_machine(self, arg): result = self.dispatch.machine(self.session, arg) pp_json(result) - # def do_abusech(self, arg): # """Search Abuse.ch for artifact details """ # pass - def do_blockchain(self, arg): """Search Blockchain.info for BTC address""" result = self.dispatch.submit(self.session, 'blockchain', arg) pp_json(result) - def do_clearbit(self, arg): """Search Clearbit for email address """ result = self.dispatch.submit(self.session, 'clearbit', arg) pp_json(result) - def do_censys(self, arg): """Search Censys for IPv4 address """ result = self.dispatch.submit(self.session, 'censys', arg) pp_json(result) - def do_csirtg(self, arg): """Search CSIRTG for hash information""" result = self.dispatch.submit(self.session, 'csirtg', arg) pp_json(result) - def do_cybercure(self, arg): """Check if IP intelligence exists at cybercure.ai""" result = self.dispatch.submit(self.session, 'cybercure', arg) pp_json(result) - def do_cymon(self, arg): """Search Cymon for host """ result = self.dispatch.submit(self.session, 'cymon', arg) pp_json(result) - # def do_dnsbrute(self, arg): # """Enumerate DNS subdomains of FQDN """ # pass - def do_dnsresolve(self, arg): """Retrieve DNS records for host """ result = self.dispatch.submit(self.session, 'dnsresolve', arg) pp_json(result) - def do_geoip(self, arg): """Retrieve Geolocation details for host """ result = self.dispatch.submit(self.session, 'geoip', arg) pp_json(result) - def do_fullcontact(self, arg): """Search FullContact for email address """ result = self.dispatch.submit(self.session, 'fullcontact', arg) pp_json(result) - # def do_gist(self, arg): # """Search Github Gist's for artifact as string """ # pass - # def do_gitlab(self, arg): # """Check Gitlab for active username """ # pass - def do_github(self, arg): """Check GitHub for active username""" result = self.dispatch.submit(self.session, 'github', arg) pp_json(result) - def do_hackedemails(self, arg): """Check hacked-emails.com for email address""" result = self.dispatch.submit(self.session, 'hackedemails', arg) pp_json(result) - def do_he(self, arg): """Search Hurricane Electric for host""" result = self.dispatch.submit(self.session, 'he', arg) pp_json(result) - def do_hibp(self, arg): """Check HaveIBeenPwned for email address""" result = self.dispatch.submit(self.session, 'hibp', arg) pp_json(result) - def do_ipinfo(self, arg): """Retrieve ipinfo resutls for host""" result = self.dispatch.submit(self.session, 'ipinfo', arg) pp_json(result) - def do_ipvoid(self, arg): """Search IPVoid for host""" result = self.dispatch.submit(self.session, 'ipvoid', arg) pp_json(result) - def do_isc(self, arg): """Search SANS ISC for host""" result = self.dispatch.submit(self.session, 'sans', arg) pp_json(result) - def do_keybase(self, arg): """Search Keybase for active username""" result = self.dispatch.submit(self.session, 'keybase', arg) pp_json(result) - def do_monitor(self, arg): """Setup active monitors for RSS Feeds, Pastebin, Gist, and other services""" pass - def do_mdl(self, arg): """Search Malware Domain List for host""" pass - def do_nmap(self, arg): """Run NMap discovery scan against host""" result = self.dispatch.submit(self.session, 'nmap', arg) pp_json(result) - def do_otx(self, arg): """Search AlienVault OTX for host or hash artifacts""" result = self.dispatch.submit(self.session, 'otx', arg) pp_json(result) - def do_passivetotal(self, arg): """Search PassiveTotal for host""" result = self.dispatch.submit(self.session, 'passivetotal', arg) pp_json(result) - def do_pastebin(self, arg): """Search Pastebin for artifact as string""" pass - def do_pgp(self, arg): """Search PGP records for email address or user""" result = self.dispatch.submit(self.session, 'pgp', arg) pp_json(result) - # def do_projecthp(self, arg): # """Search Project Honeypot for host""" # pass - # def do_reddit(self, arg): # """Search Reddit for active username""" # pass - def do_rss(self, arg): """Read latest from RSS feed @@ -551,25 +520,23 @@ def do_rss(self, arg): result = self.dispatch.submit(self.session, 'rss', arg, True) pp_json(result) - # def do_securitynews(self, arg): # """Get current cybersecurity headlines from Google News""" # result = self.dispatch.submit(self.session, 'securitynews', arg, True) # pp_json(result) - def do_shodan(self, arg): """Query Shodan for host""" result = self.dispatch.submit(self.session, 'shodan', arg) pp_json(result) - def do_source(self, arg): """Add source to given artifact or most recently added artifact if not specified Usage: source # adds to last created artifact source # adds to specific artifact """ + last = '' if arg == '': last = self.session.receive('artifacts') _type = detect_type(last) @@ -591,41 +558,34 @@ def do_source(self, arg): else: warning('Failed to find last artifact in MongoDB. Run "new " before using the source command') - def do_threatcrowd(self, arg): """Search ThreatCrowd for host""" result = self.dispatch.submit(self.session, 'threatcrowd', arg) pp_json(result) - # def do_totalhash(self, arg): # """Search TotalHash for host""" # pass - def do_twitter(self, arg): """Get Twitter info for username""" result = self.dispatch.submit(self.session, 'twitter', arg) pp_json(result) - def do_urlvoid(self, arg): """Search URLVoid for domain name""" result = self.dispatch.submit(self.session, 'urlvoid', arg) pp_json(result) - # def do_usersearch(self, arg): # """Search Usersearch.com for active usernames""" # pass - def do_virustotal(self, arg): """Search VirusTotal for IPv4, FQDN, or Hash""" result = self.dispatch.submit(self.session, 'virustotal', arg) pp_json(result) - def do_vxvault(self, arg): """Search VXVault for IPv4 or FQDN""" pass @@ -634,13 +594,11 @@ def do_web(self, arg): """Fingerprint webserver""" pass - def do_whois(self, arg): """Perform WHOIS lookup on host""" result = self.dispatch.submit(self.session, 'whois', arg) pp_json(result) - def do_whoismind(self, arg): """Search Whois Mind for domains associated to an email address""" result = self.dispatch.submit(self.session, 'whoismind', arg) diff --git a/requirements.txt b/requirements.txt index a40810b..f73f0ac 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,12 +1,19 @@ -pymongo==3.5.1 +beautifulsoup4==4.9.1 +censys==0.0.8 cmd2==0.8.9 -threatcrowd==0.4 +csirtgsdk==1.1.5 cymon==0.1 -redis==2.10.6 -requests==2.20.0 +dnspython==1.15.0 +dshield==0.2.1 +feedparser==5.2.1 +fuzzyfinder==2.1.0 ipwhois==1.0.0 +OTXv2==1.5.10 +pygments==2.6.1 +pymongo==3.5.1 +python-libnmap==0.7.0 python-whois==0.6.9 -censys==0.0.8 -BeautifulSoup==3.2.1 -fuzzyfinder==2.1.0 -dnspython==1.15.0 +redis==2.10.6 +requests==2.20.0 +threatcrowd==0.4 +yara==1.7.7