Example #1
0
    def __init__(self, ioc, type, config, queues):
        self.config = config
        self.module_name = __name__.split(".")[-1]
        self.types = ["MD5", "SHA256"]
        self.search_method = "Onpremises"
        self.description = "Search IOC in CuckooSandbox database"
        self.author = "Conix"
        self.creation_date = "02-03-2017"
        self.type = type
        self.ioc = ioc
        self.queues = queues
        self.verbose = "GET"
        self.headers = self.config["user_agent"]
        self.proxy = self.config["proxy_host"]

        length = len(self.config['cuckoosandbox_api_url'])
        if length != len(self.config['cuckoosandbox_web_url']) \
           and length <= 0:
            mod.display(
                self.module_name, self.ioc, "ERROR",
                "Cuckoosandbox fields in btg.cfg are missfilled, checkout commentaries."
            )
            return None

        for indice in range(len(self.config['cuckoosandbox_api_url'])):
            api_url = self.config['cuckoosandbox_api_url'][indice]
            web_url = self.config['cuckoosandbox_web_url'][indice]
            self.search(api_url, web_url, indice)
Example #2
0
    def search(self, api_url, web_url, indice):
        mod.display(self.module_name, "", "INFO", "Searching...")
        if ("cuckoosandbox_api_url" in self.config
                and "user_agent" in self.config and "proxy_host" in self.config
                and "requests_timeout" in self.config):

            if self.type in ["MD5"]:
                url = "%s/files/view/md5/%s" % (api_url, self.ioc)
            elif self.type in ["SHA256"]:
                url = "%s/files/view/sha256/%s" % (api_url, self.ioc)

            request = {
                'url': url,
                'headers': self.headers,
                'module': self.module_name,
                'ioc': self.ioc,
                'verbose': self.verbose,
                'proxy': self.proxy,
                'server_id': indice
            }
            json_request = json.dumps(request)
            store_request(self.queues, json_request)
        else:
            mod.display(
                self.module, self.ioc, "ERROR",
                "Check if you have filled cuckoosandbox fields in btg.cfg")
Example #3
0
 def search(self):
     mod.display(self.module_name, "", "INFO", "Searching...")
     if "malekal_local" in self.config:
         if self.config["malekal_local"]:
             self.localSearch()
     if "malekal_remote" in self.config:
         if self.config["malekal_remote"]:
             self.remoteSearch()
Example #4
0
    def search(self):
        mod.display(self.module_name, self.ioc, "INFO",
                    "Search in MalwareConfig ...")

        if self.type in ["MD5", "SHA256"]:
            self.webpage_crawling()
        else:
            self.cache_search()
Example #5
0
 def cleanups_lock_cache(real_path):
     for file in listdir(real_path):
         file_path = "%s%s/" % (real_path, file)
         if file.endswith(".lock"):
             mod.display("MAIN",
                         message_type="DEBUG",
                         string="Delete locked cache file: %s" %
                         file_path[:-1])
             remove(file_path[:-1])
         else:
             if path.isdir(file_path):
                 Utils.cleanups_lock_cache(file_path)
Example #6
0
 def createLoggingFolder():
     if not isdir(config["log_folder"]):
         try:
             makedirs(config["log_folder"])
         except:
             mod.display(
                 "MAIN",
                 message_type="FATAL_ERROR",
                 string="Unable to create %s directory. (Permission denied)"
                 % config["log_folder"])
             sys.exit()
         chmod(config["log_folder"], 0o777)
Example #7
0
async def fetch_post(url, session, headers, proxy, data, module, ioc, timeout,
                    auth, server_id, verify):
    try:
        async with session.post(url, data=data, headers=headers,
                                proxy=proxy, timeout=timeout,
                                auth=auth, ssl=verify) as response:
            return await response.text(), response.status, module, ioc, server_id
    except:
        mod.display(module,
                    ioc,
                    message_type="ERROR",
                    string="Failed to connect to %s" % (url))
Example #8
0
 def Search(self):
     mod.display(self.module_name, "", "INFO",
                 "Search in Alienvault OTX ...")
     try:
         if "otx_api_keys" in self.config:
             otx = OTXv2(self.config["otx_api_keys"])
             if self.type == "IPv4":
                 indicator = IndicatorTypes.IPv4
             if self.type == "IPv6":
                 indicator = IndicatorTypes.IPv6
             if self.type == "domain":
                 indicator = IndicatorTypes.DOMAIN
             if self.type == "URL":
                 indicator = IndicatorTypes.URL
             if self.type == "MD5":
                 indicator = IndicatorTypes.FILE_HASH_MD5
             if self.type == "SHA1":
                 indicator = IndicatorTypes.FILE_HASH_SHA1
             if self.type == "SHA256":
                 indicator = IndicatorTypes.FILE_HASH_SHA256
             result = otx.get_indicator_details_full(indicator, self.ioc)
         else:
             mod.display(
                 self.module_name,
                 self.ioc,
                 message_type="ERROR",
                 string=
                 "Please check if you have otx_api_keys field in btg.cfg")
             return None
     except:
         mod.display(
             self.module_name, self.ioc, "ERROR",
             "Could not perform the request, either you did not fill the otx_api_keys field or the key maximum request is reached"
         )
         return None
     try:
         if self.ioc == str(result["general"]["indicator"]):
             _id = str(result["general"]["pulse_info"]["pulses"][0]["id"])
             tags = ""
             for tag in result["general"]["pulse_info"]["pulses"][0][
                     "tags"]:
                 tags = tags + "%s " % tag
             mod.display(
                 self.module_name, self.ioc, "FOUND",
                 "Tags: %s| https://otx.alienvault.com/pulse/%s/" %
                 (tags, _id))
     except:
         mod.display(self.module_name,
                     self.ioc,
                     message_type="NOT_FOUND",
                     string="Nothing found in OTX")
     return None
Example #9
0
 def createModuleFolder(self):
     if not isdir(self.config["temporary_cache_path"]):
         try:
             makedirs(self.config["temporary_cache_path"])
         except:
             mod.display("%s.cache" % self.module_name,
                         "FATAL_ERROR",
                         "Unable to create %s directory. (Permission denied)" % self.config["temporary_cache_path"])
             sys.exit()
         chmod(self.config["temporary_cache_path"], 0o770)
     if not isdir(self.temp_folder):
         mkdir(self.temp_folder)
         chmod(self.temp_folder, 0o770)
Example #10
0
def module_worker_response(response_text, response_status, module,
                           ioc, server_id):
    """
        Load modules in python instance to treat the response
    """
    obj = importlib.import_module("BTG.modules."+module)
    try:
        obj.response_handler(response_text, response_status,
                             module, ioc, server_id)
    except:
        mod.display("worker_tasks",
                    "ERROR",
                    "Something went wrong when worker try to load response_handler from %s" % (module))
Example #11
0
    def search(self):
        mod.display(self.module_name, "", "INFO", "Searching...")
        self.url = "https://iris-h.services/api/search?hash=" + self.ioc

        request = {'url': self.url,
                   'headers': self.headers,
                   'module': self.module_name,
                   'ioc': self.ioc,
                   'verbose': self.verbose,
                   'proxy': self.proxy
                   }
        json_request = json.dumps(request)
        store_request(self.queues, json_request)
Example #12
0
 def search(self):
     mod.display(self.module_name, "", "INFO", "Searching...")
     url = "http://www.nothink.org/blacklist/"
     paths = [
         "blacklist_snmp_year.txt",
         "blacklist_ssh_year.txt",
         "blacklist_telnet_year.txt"
     ]
     for path in paths:
         try:
             content = Cache(self.module_name, url, path, self.search_method).content
         except NameError as e:
             mod.display(self.module_name,
                         self.ioc,
                         "ERROR",
                         e)
             return None
         for line in content.split("\n"):
             if self.ioc in line:
                 mod.display(self.module_name,
                             self.ioc,
                             "FOUND",
                             "%s%s" % (url, path))
                 return None
     mod.display(self.module_name,
                 self.ioc,
                 "NOT_FOUND",
                 "Nothing found in nothink feeds")
Example #13
0
def response_handler(response_text,
                     response_status,
                     module,
                     ioc,
                     server_id=None):
    if response_status == 200:
        try:
            json_content = json.loads(response_text)
        except:
            mod.display(module, ioc, "ERROR",
                        "VirusTotal json_response was not readable.")
            return None

        if "positives" in json_content and json_content["positives"] > 0:
            mod.display(
                module, ioc, "FOUND", "Score: %d/%d | %s" %
                (json_content["positives"], json_content["total"],
                 json_content["permalink"]))
        else:
            mod.display(module, ioc, "NOT_FOUND",
                        "Nothing found in Virustotal")
    else:
        mod.display(module, ioc, "ERROR",
                    "VirusTotal response.code_status : %d" % (response_status))
    return None
Example #14
0
    def search(self):
        mod.display(self.module_name, "", "INFO", "Searching...")
        url = "https://www.spamhaus.org/drop/"
        paths = [
            "drop.txt",
            "edrop.txt",
            "dropv6.txt",
        ]
        for path in paths:
            try:
                content = Cache(self.module_name, url, path,
                                self.search_method).content
            except NameError as e:
                mod.display(self.module_name, self.ioc, "ERROR", e)
                return None
            for line in content.split("\n"):
                try:
                    if line[0] != ';':
                        if IPAddress(self.ioc) in IPNetwork(
                                line.split(" ")[0]):
                            mod.display(self.module_name, self.ioc, "FOUND",
                                        "%s%s" % (url, path))
                except:
                    pass

        mod.display(self.module_name, self.ioc, "NOT_FOUND",
                    "Nothing found in SpamHaus feeds")
Example #15
0
def response_handler(response_text, response_status, module, ioc, server_id):
    web_url = cfg['misp_url'][server_id]
    if response_status == 200:
        try:
            json_response = json.loads(response_text)
        except:
            mod.display(module,
                        ioc,
                        message_type="ERROR",
                        string="Misp json_response was not readable.")
            return None

        if "Attribute" in json_response["response"]:
            displayed = []
            for attr in json_response["response"]["Attribute"]:
                event_id = attr["event_id"]
                if event_id not in displayed:
                    displayed.append(event_id)
                    mod.display(module,
                                ioc,
                                "FOUND",
                                "Event: %sevents/view/%s" % (web_url,
                                                             event_id))
                    return None
            mod.display(module,
                        ioc,
                        "NOT_FOUND",
                        "Nothing found in Misp:%s database" % (web_url))
            return None
    else:
        mod.display(module,
                    ioc,
                    message_type="ERROR",
                    string="Misp connection status : %d" % (response_status))
Example #16
0
 def Search(self):
     mod.display(self.module_name, "", "INFO", "Search in misp crawler...")
     with requests.Session() as s:
         try:
             self.loginRequest(s)
             allEvents = self.searchAttribute(s)
             for event in allEvents:
                 if "misp_crawler_url" in self.config:
                     # TODO: And what is the response is empty, NOT_FOUND ?
                     mod.display(
                         self.module_name, self.ioc, "FOUND",
                         "Event: %s/events/view/%s" %
                         (self.config["misp_crawler_url"], event))
                 else:
                     mod.display(
                         self.module_name,
                         self.ioc,
                         message_type="ERROR",
                         string=
                         "Check if you have misp_crawler_url in btg.cfg")
         except:
             mod.display(
                 self.module_name,
                 self.ioc,
                 message_type="ERROR",
                 string=
                 "Could not perform the request, checkout btg.cfg at [%s]" %
                 (self.module_name))
Example #17
0
 def search(self):
     mod.display(self.module_name, "", "INFO", "Searching...")
     url = "https://www.dshield.org/feeds/"
     paths = [
         "suspiciousdomains_Low.txt",
         "suspiciousdomains_Medium.txt",
         "suspiciousdomains_High.txt"
     ]
     for path in paths:
         try:
             content = Cache(self.module_name, url, path, self.search_method).content
         except NameError as e:
             mod.display(self.module_name,
                         self.ioc,
                         "ERROR",
                         e)
             return None
         for line in content.split("\n"):
             try:
                 if line[0] != '#':
                     if line.lower() == self.ioc.lower():
                         mod.display(self.module_name,
                                     self.ioc,
                                     "FOUND",
                                     "%s%s" % (url, path))
                         return None
             except:
                 pass
     mod.display(self.module_name,
                 self.ioc,
                 "NOT_FOUND",
                 "Nothing found in dhsield feeds")
Example #18
0
 def localSearch(self):
     """ Search in local directory """
     mod.display("%s_local" % self.module_name,
                 string="Browsing in local directory")
     if "malekal_files_path" in self.config:
         for root, dirs, files in os.walk(
                 self.config["malekal_files_path"]):
             folder = os.path.basename(root)
             for file in files:
                 if file == self.ioc:
                     mod.display(
                         "%s_local" % self.module_name, self.ioc, "FOUND",
                         "%s%s/%s" %
                         (self.config["malekal_files_path"], folder, file))
                     return None
         mod.display("%s_local" % self.module_name,
                     self.ioc,
                     message_type="NOT_FOUND",
                     string="Nothing found in Malekal_local")
         return None
     else:
         mod.display(
             "%s_local" % self.module_name, self.ioc, "ERROR",
             "Check if you have malekal_files_path field in btg.cfg ")
         return None
Example #19
0
def module_worker_request(module, argument, type, queues):
    """
        Load modules in python instance to build url to request
    """
    mod.display(string="Load: %s/%s.py" % (config["modules_folder"], module))
    obj = importlib.import_module("BTG.modules."+module)
    for c in dir(obj):
        if module+"_enabled" in config:
            if module == c.lower() and config[module+"_enabled"]:
                getattr(obj, c)(argument, type, config, queues)
        else:
            mod.display("worker_tasks",
                        "INFO",
                        "Module : %s -- not configured" % (module))
Example #20
0
 def search(self):
     mod.display(self.module_name, "", "INFO", "Search in VirusTotal ...")
     try:
         if "virustotal_api_keys" in self.config:
             try:
                 self.key = random.Random(self.ioc).choice(
                     self.config["virustotal_api_keys"])
             except:
                 mod.display(
                     self.module_name,
                     message_type="ERROR",
                     string=
                     "Check if you have filled virustotal_api_keys in btg.cfg"
                 )
                 return None
         else:
             mod.display(
                 self.module_name,
                 message_type="ERROR",
                 string=
                 "Check if you have virustotal_api_keys field in btg.cfg")
             return None
     except:
         mod.display(self.module_name, self.ioc, "ERROR",
                     "Please provide your authkey.")
         return None
     if self.type in ["URL", "domain", "IPv4"]:
         request = self.searchURL()
     else:
         request = self.searchReport()
     store_request(self.queues, request)
Example #21
0
 def search(self):
     mod.display(self.module_name, "", "INFO", "Searching...")
     url = "https://torstatus.blutmagie.de/"
     paths = [
         "ip_list_all.php/Tor_ip_list_ALL.csv",
         "query_export.php/Tor_query_EXPORT.csv",
         "ip_list_exit.php/Tor_ip_list_EXIT.csv"
     ]
     for path in paths:
         try:
             content = Cache(self.module_name, url, path, self.search_method).content
         except NameError as e:
             mod.display(self.module_name,
                         self.ioc,
                         "ERROR",
                         e)
             return None
         if self.ioc in content:
             mod.display(self.module_name,
                         self.ioc,
                         "FOUND",
                         "%s%s" % (url, path))
             return None
     mod.display(self.module_name,
                 self.ioc,
                 "NOT_FOUND",
                 "Nothing found in TorIps feeds")
Example #22
0
async def fetch_get(url, session, headers, proxy, module, ioc,
                    timeout, auth, server_id, verify):
    """
        code from aiohttp.readthedocs.io
    """
    try:
        async with session.get(url, headers=headers, proxy=proxy,
                               timeout=timeout,
                               auth=auth, ssl=verify) as response:
            return await response.text(), response.status, module, ioc, server_id
    except:
        mod.display(module,
                    ioc,
                    message_type="ERROR",
                    string="Failed to connect to %s, server was probably too slow and request has been dropped out" % (url))
Example #23
0
async def bound_fetch(sem, session, request, timeout):
    url, module_name, ioc, verbose, headers, proxy, auth, server_id, verify = filler(request)
    if verbose == "GET":
        # Getter function with semaphore.
        async with sem:
            return await fetch_get(url, session, headers, proxy, module_name,
                                   ioc, timeout, auth, server_id, verify)
    elif verbose == "POST":
        data = request['data']
        # Getter function with semaphore.
        async with sem:
            return await fetch_post(url, session, headers, proxy, data, module_name,
                                    ioc, timeout, auth, server_id, verify)
    else:
        mod.display(module_name,
                    ioc,
                    message_type="ERROR",
                    string="Associated HTTP verbose for %s, is neither GET nor POST" % (url))
Example #24
0
    def __init__(self, args, modules):
        redis_host, redis_port, redis_password = init_redis()
        try:
            conn = redis.StrictRedis(host=redis_host,
                                     port=redis_port,
                                     password=redis_password)
        except:
            mod.display("MAIN",
                        message_type="FATAL_ERROR",
                        string="Cannot establish connection with Redis")
            sys.exit()

        global observable_list
        queues = [working_queue, request_queue]

        if args.file == "False":
            observable_list = args.observables
        else:
            observable_list = []
            for file in args.observables:
                with open(file, "r") as f1:
                    try:
                        observable_list = list(
                            set(observable_list +
                                f1.read().strip().splitlines()))
                    except:
                        mod.display(
                            "MAIN",
                            message_type="FATAL_ERROR",
                            string="Something went wrong with the argument file"
                        )
                    finally:
                        f1.close()

        for argument in observable_list:
            type = self.checkType(argument.lower())
            if "split_observable" in config and config["split_observable"]:
                if type == "URL" or type == "domain":
                    self.extend_IOC(argument.lower(), observable_list)
            matching_list = Utils.gen_matching_type_modules_list(modules, type)
            cluster.add_cluster(argument.lower(), matching_list, dictname,
                                conn)
            self.run(argument.lower(), type, matching_list, queues)
        print("Every IOCs have been enqueued, BTG is processing ...\n")
Example #25
0
    def subprocess_launcher():
        """
            Subprocess loop to launch rq-worker
        """
        processes = []
        max_worker = number_of_worker()
        worker_path = dirname(__file__) + '/lib/run_worker.py '
        worker_params = '%s' % (working_queue)
        worker_call = 'python3 ' + worker_path + worker_params
        poller_path = dirname(__file__) + '/lib/poller.py '
        poller_params = '%s %s' % (working_queue, request_queue)
        poller_call = 'python3 ' + poller_path + poller_params
        try:
            for i in range(max_worker):
                processes.append(
                    subprocess.Popen([worker_call],
                                     shell=True,
                                     preexec_fn=setsid).pid)
            processes.append(
                subprocess.Popen([poller_call], shell=True,
                                 preexec_fn=setsid).pid)
        except:
            mod.display(
                "MAIN",
                message_type="FATAL_ERROR",
                string="Could not launch workers and/or poller subprocesses")
            sys.exit()

        supervisor_path = dirname(__file__) + '/lib/hypervisor.py '
        supervisor_params = '%d %s %s' % (getpid(), fp, working_queue)
        for process in processes:
            supervisor_params += ' ' + str(process)
        supervisor_call = 'python3 ' + supervisor_path + supervisor_params
        try:
            processes.append(
                subprocess.Popen([supervisor_call],
                                 shell=True,
                                 preexec_fn=setsid).pid)
        except:
            mod.display("MAIN",
                        message_type="FATAL_ERROR",
                        string="Could not launch supervisor subprocess")
            sys.exit()
        return processes
Example #26
0
    def vxstream_api(self):
        """
        VXstream API Connection
        """

        if 'vxstream_api_keys' in self.config:
            try:
                self.headers['api-key'] = random.Random(self.ioc).choice(
                    self.config['vxstream_api_keys'])
            except:
                mod.display(
                    self.module_name, self.ioc, "ERROR",
                    "Check if you have filled vxstream_api_keys_secret in btg.cfg"
                )
                return None
        else:
            mod.display(
                self.module_name, self.ioc, "ERROR",
                "Check if you have vxstream_api_keys_secret field in btg.cfg")
            return None

        if self.type in ["MD5", "SHA1", "SHA256"]:
            self.url = "https://www.hybrid-analysis.com/api/v2/search/hash"
            self.data = "hash=" + self.ioc
        else:
            self.url = "https://www.hybrid-analysis.com/api/v2/search/terms"
            if self.type in ["IPv4", "IPv6"]:
                self.data = "host=" + self.ioc
            elif self.type == "URL":
                self.data = "url=" + self.ioc
            else:
                self.data = "domain=" + self.ioc

        request = {
            'url': self.url,
            'headers': self.headers,
            'data': self.data,
            'module': self.module_name,
            'ioc': self.ioc,
            'verbose': self.verbose,
            'proxy': self.proxy
        }
        json_request = json.dumps(request)
        store_request(self.queues, json_request)
Example #27
0
    def show_up_errors(start_time, end_time, modules):
        """
            Count errors encountered during execution
        """
        enabled_list = Utils.gen_enabled_modules_list(modules)
        dict_list = []
        for module in enabled_list:
            dict_list.append({"module_name": module, "nb_error": 0})
        log_error_file = config["log_folder"] + config["log_error_file"]
        try:
            with open(log_error_file, "r+") as f:
                try:
                    lines = f.read().strip().splitlines()
                except:
                    mod.display(
                        "MAIN", "FATAL_ERROR",
                        "Could not read %s, checkout your btg.cfg." %
                        (log_error_file))
                    sys.exit()
                finally:
                    f.close()
        except FileNotFoundError:
            return None
        except:
            mod.display(
                "MAIN", "FATAL_ERROR",
                "Could not open %s, checkout your btg.cfg." % (log_error_file))
            sys.exit()

        regex = re.compile("(?<=\[).*?(?=\])")
        start_time = start_time.strftime('%d-%m-%Y %H:%M:%S')
        end_time = end_time.strftime('%d-%m-%Y %H:%M:%S')
        for line in lines:
            match = regex.findall(line)
            log_time = match[0]
            log_module = match[1]
            if log_time >= start_time and log_time <= end_time:
                for dict in dict_list:
                    tmp = "%s%s%s" % (colors.MODULE, dict['module_name'],
                                      colors.NORMAL)
                    if log_module == tmp:
                        dict["nb_error"] = dict["nb_error"] + 1
        return dict_list
Example #28
0
def store_request(queues, request):
    """
        Pushing request:(url, module_name) into a redis_list
    """
    queue_2 = queues[1]
    redis_host, redis_port, redis_password = init_redis()
    try:
        r = redis.StrictRedis(host=redis_host, port=redis_port,
                              password=redis_password, db=0)
    except:
        mod.display("ASYNC_HTTP",
                    "ERROR",
                    "Could not establish connection with Redis in func store_request")
    try:
        r.rpush(queue_2, request)
    except:
        mod.display("ASYNC_HTTP",
                    "ERROR",
                    "Cannot push request: %s to Redis on queue: %s" % (request[0], queue_2))
Example #29
0
def pollout_requests(queue_2, nb_to_do):
    redis_host, redis_port, redis_password = init_redis()
    try:
        r = redis.StrictRedis(host=redis_host, port=redis_port,
                              password=redis_password, db=0)
    except:
        mod.display("ASYNC_HTTP",
                    "ERROR",
                    "Cannot establish connection with Redis in func pollout_requests")
    requests = []
    while len(requests) < nb_to_do:
        request = r.lpop(queue_2)
        if request is None:
            break
        else:
            request = parse_redis_string(request)
            if request is not None:
                requests.append(request)
    return requests
Example #30
0
    def Search(self, misp_url, misp_key, indice):
        mod.display(self.module_name, "", "INFO", "Search in misp...")

        url = '%sattributes/restSearch/json' % (misp_url)
        self.headers['Authorization'] = misp_key
        payload = {'value': self.ioc, 'searchall': 1}
        data = json.dumps(payload)

        request = {'url': url,
                   'headers': self.headers,
                   'data': data,
                   'module': self.module_name,
                   'ioc': self.ioc,
                   'verbose': self.verbose,
                   'proxy': self.proxy,
                   'verify': self.verify,
                   'server_id': indice
                   }
        json_request = json.dumps(request)
        store_request(self.queues, json_request)