def enrich_beacon_data(self): # Get all lines in rtops that have not been enriched yet (for CS) query = 'implant.id:* AND c2.program: cobaltstrike AND NOT c2.log.type:implant_newimplant AND NOT tags:%s' % info[ 'submodule'] notEnriched = getQuery(query, size=10000, index='rtops-*') # Created a dict grouped by implant ID implantIds = {} for ne in notEnriched: implantId = getValue('_source.implant.id', ne) if implantId in implantIds: implantIds[implantId].append(ne) else: implantIds[implantId] = [ne] hits = [] # For each implant ID, get the initial beacon line for iID in implantIds: initialBeaconDoc = self.get_initial_beacon_doc(iID) # If not initial beacon line found, skip the beacon ID if not initialBeaconDoc: continue for doc in implantIds[iID]: # Fields to copy: host.*, implant.*, process.*, user.* res = self.copy_data_fields( initialBeaconDoc, doc, ['host', 'implant', 'user', 'process']) if res: hits.append(res) return (hits)
def alarm_check(self): # This check queries for UA's that are listed in any blacklist_useragents.conf and do talk to c2* paths on redirectors\n # We will dig trough ALL data finding specific IP related lines and tag them # reading the useragents we trigger on. fname = "/etc/redelk/rogue_useragents.conf" with open(fname) as f: content = f.readlines() uaList = [] for line in content: if not line.startswith('#'): uaList.append(line.strip()) keywords = uaList qSub = "" # add keywords (UA's) to query for keyword in keywords: if qSub == "": qSub = "(http.headers.useragent:%s" % keyword else: qSub = qSub + " OR http.headers.useragent:%s" % keyword qSub = qSub + ") " # q = "%s AND redir.backendname:c2* AND tags:enrich_* AND NOT tags:alarm_* "%qSub q = "%s AND redir.backend.name:c2* AND NOT tags:alarm_useragent" % qSub i = countQuery(q) if i >= 10000: i = 10000 r = getQuery(q, i) if not isinstance(r, type([])): r = [] report = {} report['hits'] = r return (report)
def get_initial_beacon_doc(self, implantId): query = 'implant.id:%s AND c2.program: cobaltstrike AND c2.log.type:implant_newimplant' % implantId initialBeaconDoc = getQuery(query, size=1, index="rtops-*") initialBeaconDoc = initialBeaconDoc[0] if len( initialBeaconDoc) > 0 else False self.logger.debug('Initial beacon line [%s]: %s' % (implantId, initialBeaconDoc)) return (initialBeaconDoc)
def alarm_dummy(self): q = "c2.log.type:ioc AND NOT tags:alarm_*" # iocs = [] # i = countQuery(q, index="rtops-*") # self.logger.debug('Getting 1 document') r = getQuery(q, 100, index="rtops-*") self.logger.debug(r) return (r)
def alarm_check(self): # This check queries for calls to backends that have *alarm* in their name\n q = "redir.backend.name:*alarm* AND NOT tags:%s" % (info['submodule']) i = countQuery(q) if i >= 10000: i = 10000 r = getQuery(q, i) if not isinstance(r, type([])): r = [] report = {} report['hits'] = r return (report)
def alarm_check(self): # This check queries for IP's that aren't listed in any iplist* but do talk to c2* paths on redirectors\n q = "*" i = countQuery(q) if i >= 10000: i = 10000 r = getQuery(q, i) report = {} report['hits'] = [] report['hits'].append(r[0]) report['hits'].append(r[1]) return(report)
def sync_iplist(self, iplist='redteam'): # Get data from config file iplist cfg_iplist = [] fname = '/etc/redelk/iplist_%s.conf' % iplist # Check first if the local config file exists; if not, skip the sync if not os.path.isfile(fname): self.logger.warning( 'File %s doesn\'t exist, skipping IP list sync for this one.' % fname) return with open(fname, 'r') as f: content = f.readlines() for line in content: m = re.match(IP_CIDR_RE, line) if m: cfg_iplist.append((m.group(1), m.group(len(m.groups())))) else: m = re.match(IP_RE, line) if m: cfg_iplist.append( ('%s/32' % m.group(1), m.group(len(m.groups())))) # Get data from ES iplist query = 'iplist.name:%s' % iplist es_iplist_docs = getQuery(query, size=10000, index='redelk-*') # Check if config IP is in ES and source = config_file es_iplist = [] for doc in es_iplist_docs: ip = getValue('_source.iplist.ip', doc) if ip: es_iplist.append((ip, doc)) for ipc, comment in cfg_iplist: found = [item for item in es_iplist if ipc in item] if not found: self.logger.debug('IP not found in ES: %s' % ipc) # if not, add it self.add_es_ip(ipc, iplist, comment) toadd = [] for ipe, doc in es_iplist: # Check if ES IP is in config file found = [item for item in cfg_iplist if ipe in item] if not found: # if not, check if source = config_file if getValue('_source.iplist.source', doc) == 'config_file': # if yes, remove IP from ES self.remove_es_ip(doc, iplist) else: # if not, add it comment = getValue('_source.iplist.comment', doc) if comment: ipa = '%s # From ES -- %s' % (ipe, comment) else: ipa = '%s # From ES' % ipe toadd.append(ipa) self.add_cfg_ips(toadd, iplist) return (toadd)