Exemplo n.º 1
0
def searchESForBROAttackers(es, threshold):
    begindateUTC = toUTC(datetime.now() - timedelta(hours=2))
    enddateUTC = toUTC(datetime.now())
    qDate = pyes.RangeQuery(qrange=pyes.ESRange(
        'utctimestamp', from_value=begindateUTC, to_value=enddateUTC))
    q = pyes.ConstantScoreQuery(pyes.MatchAllQuery())
    qBro = pyes.QueryFilter(pyes.MatchQuery('category', 'bro_notice',
                                            'phrase'))
    qErr = pyes.QueryFilter(
        pyes.MatchQuery('details.note',
                        'MozillaHTTPErrors::Excessive_HTTP_Errors_Attacker',
                        'phrase'))
    q = pyes.FilteredQuery(q, pyes.BoolFilter(must=[qBro, qErr]))

    results = es.search(q, size=1000, indices='events,events-previous')
    # grab results as native es results to avoid pyes iteration bug
    # and get easier access to es metadata fields
    rawresults = results._search_raw()['hits']['hits']

    # Hit count is buried in the 'sub' field
    # as: 'sub': u'6 in 1.0 hr, eps: 0'
    # cull the records for hitcounts over the threshold before returning
    attackers = list()
    for r in rawresults:
        hitcount = int(r['_source']['details']['sub'].split()[0])
        if hitcount > threshold:
            attackers.append(r)
    return attackers
Exemplo n.º 2
0
def esSearch(es, begindateUTC=None, enddateUTC=None):
    resultsList = list()
    if begindateUTC is None:
        begindateUTC = toUTC(datetime.now() -
                             timedelta(minutes=options.aggregationminutes))
    if enddateUTC is None:
        enddateUTC = toUTC(datetime.now())
    try:
        # search for events within the date range that haven't already been alerted (i.e. given an alerttimestamp)
        qDate = pyes.RangeQuery(qrange=pyes.ESRange(
            'utctimestamp', from_value=begindateUTC, to_value=enddateUTC))
        q = pyes.ConstantScoreQuery(pyes.MatchAllQuery())
        q = pyes.FilteredQuery(q, pyes.BoolFilter(must=[qDate]))

        q = q.search()

        qagg = pyes.aggs.TermsAgg(name='category', field='category')
        q.agg.add(qagg)
        results = es.search(query=q, indices=['events'])

        mozdefstats = dict(utctimestamp=toUTC(datetime.now()).isoformat())
        mozdefstats['summary'] = 'Aggregated category counts'
        mozdefstats['processid'] = os.getpid()
        mozdefstats['processname'] = sys.argv[0]
        mozdefstats['details'] = dict(counts=list())
        for bucket in results.aggs['category']['buckets']:
            entry = dict()
            entry[bucket['key']] = bucket['doc_count']
            mozdefstats['details']['counts'].append(entry)
        return mozdefstats

    except pyes.exceptions.NoServerAvailable:
        logger.error(
            'Elastic Search server could not be reached, check network connectivity'
        )
Exemplo n.º 3
0
def esSearch(es, begindateUTC=None, enddateUTC=None):
    resultsList = list()
    if begindateUTC is None:
        begindateUTC = toUTC(datetime.now() - timedelta(minutes=options.aggregationminutes))
    if enddateUTC is None:
        enddateUTC = toUTC(datetime.now())
    try:
        # search for aggregated event stats summaries within the date range 
        qDate = pyes.RangeQuery(qrange=pyes.ESRange('utctimestamp', from_value=begindateUTC, to_value=enddateUTC))
        q = pyes.ConstantScoreQuery(pyes.MatchAllQuery())
        q = pyes.FilteredQuery(q,pyes.BoolFilter(must=[qDate,
                                                       pyes.TermFilter('_type', 'mozdefstats')]))
        results=es.search(query=q,size=100,indices=['events','events-previous'])
        
        #avoid pyes iteration bug
        rawresults = results._search_raw()
        
        #examine the results
        #for each details.counts, append the count
        #as a list to the stats dict
        stats=dict()
        for r in rawresults['hits']['hits']:
            for i in r['_source']['details']['counts']:
                #print(i.values()[0])
                if i.keys()[0] not in stats.keys():
                    stats[i.keys()[0]]=list()
                stats[i.keys()[0]].append(i.values()[0])

        # make a dictionairy of user-defined
        # aggregation threshold percentages
        aggregationthresholds = dict(zip(options.aggregations,
                                         options.aggregationthresholds))

        
        #for our running history of counts per category
        #do some simple stats math to see if we
        #should alert on anything
        for s in stats:
            alert = False
            smean=round(numpy.mean(stats[s]))
            sstd=round(numpy.std(stats[s]))
            stat = round((sstd/smean)*100, 2)
            if s in aggregationthresholds.keys():
                if stat > aggregationthresholds[s]:
                    alert = True
            elif  stat > options.defaultthreshold:
                alert = True

            if alert: 
                print('{0} {1}%: \n\t\t{2} \n\t\t{3} \n\t\t{4}'.format(
                                                s,
                                                stat,
                                                stats[s],
                                                smean,
                                                sstd
                                                )
                      )        

    except pyes.exceptions.NoServerAvailable:
        logger.error('Elastic Search server could not be reached, check network connectivity')
Exemplo n.º 4
0
def esLdapResults(begindateUTC=None, enddateUTC=None):
    '''an ES query/facet to count success/failed logins'''
    resultsList = list()
    if begindateUTC is None:
        begindateUTC = datetime.now() - timedelta(hours=1)
        begindateUTC = toUTC(begindateUTC)
    if enddateUTC is None:
        enddateUTC = datetime.now()
        enddateUTC = toUTC(enddateUTC)
    try:
        es = pyes.ES((list('{0}'.format(s) for s in options.esservers)))
        qDate = pyes.RangeQuery(qrange=pyes.ESRange('utctimestamp',
            from_value=begindateUTC, to_value=enddateUTC))
        q = pyes.MatchAllQuery()
        q = pyes.FilteredQuery(q, qDate)
        q = pyes.FilteredQuery(q, pyes.TermFilter('tags', 'ldap'))
        q = pyes.FilteredQuery(q,
            pyes.TermFilter('details.result', 'ldap_invalid_credentials'))
        q2 = q.search()
        q2.facet.add_term_facet('details.result')
        q2.facet.add_term_facet('details.dn', size=20)
        results = es.search(q2, indices='events')

        stoplist = ('o', 'mozilla', 'dc', 'com', 'mozilla.com',
            'mozillafoundation.org', 'org')
        for t in results.facets['details.dn'].terms:
            if t['term'] in stoplist:
                continue
            #print(t['term'])
            failures = 0
            success = 0
            dn = t['term']

            #re-query with the terms of the details.dn
            qt = pyes.MatchAllQuery()
            qt = pyes.FilteredQuery(qt, qDate)
            qt = pyes.FilteredQuery(qt, pyes.TermFilter('tags', 'ldap'))
            qt = pyes.FilteredQuery(qt,
                pyes.TermFilter('details.dn', t['term']))
            qt2 = qt.search()
            qt2.facet.add_term_facet('details.result')
            results = es.search(qt2)
            #sys.stdout.write('{0}\n'.format(results.facets['details.result'].terms))

            for t in results.facets['details.result'].terms:
                #print(t['term'],t['count'])
                if t['term'] == 'ldap_success':
                    success = t['count']
                if t['term'] == 'ldap_invalid_credentials':
                    failures = t['count']
            resultsList.append(dict(dn=dn, failures=failures,
                success=success, begin=begindateUTC.isoformat(),
                end=enddateUTC.isoformat()))

        return(json.dumps(resultsList))
    except pyes.exceptions.NoServerAvailable:
        sys.stderr.write('Elastic Search server could not be reached, check network connectivity\n')
Exemplo n.º 5
0
    def execute(self):
        conn = pyes.ES(self.elastic_hosts)
        queries = []
        filters = []

        filters.append(pyes.TermFilter('account', self.account))
        for field, val in self.conditions:
            if val != '':
                queries.append(pyes.TextQuery(field, val))

        if self.type not in [None, '']:
            queries.append(pyes.TextQuery('type', self.type))

        if self.path not in [None, '']:
            if self.recursive:
                filters.append(pyes.PrefixFilter('path', '%s/' % self.path))
            else:
                queries.append(pyes.TermQuery('dir', self.path))

        if self.marker not in [None, '']:
            filters.append(
                pyes.RangeFilter(pyes.ESRangeOp('name', 'gt', self.marker)))

        q = pyes.MatchAllQuery()
        if len(queries) > 0:
            q = pyes.BoolQuery(queries)

        q = pyes.FilteredQuery(q, pyes.ANDFilter(filters))
        self.logger.info("Running query: %s" % q.serialize())
        results = conn.search(q, self.search_index_name, start=self.start,
                              size=self.limit)
        if self.sort not in [None, '']:
            sort_list = []
            for row in self.sort.split(','):
                sort_data = row.split(' ')
                prefix = ""
                if len(sort_data) > 1 and sort_data[1].lower() == 'desc':
                    prefix = "-"
                if sort_data[0] in SORT_WHITELIST:
                    sort_list.append("{0}{1}".format(prefix, sort_data[0]))
            if sort_list:
                results.order_by(sort_list)
        return results
Exemplo n.º 6
0
    def search_err(self, program, receiver):
        start = "%s CST" % (datetime.astimezonenow() - timedelta(
            hours=self.config['RANGE'])).daysstrftime('%Y/%m/%d %H:%M:%S')
        end = "%s CST" % datetime.astimezonenow().strftime('%Y/%m/%d %H:%M:%S')
        index = "%s_%s" % (program, datetime.astimezonenow().strftime('%Y-%m'))
        q = pyes.RangeQuery(
            pyes.ESRange('datetime', from_value=start, to_value=end))
        q = pyes.FilteredQuery(q, pyes.TermQuery("level", "EROR"))
        conn = pyes.ES(self.config['ES'])
        results = conn.search(indices=index, query=q)

        num = len(results)
        if num == 0:
            return

        _content = ""
        for r in results:
            _content += "%s, %s<br/>" % (r['message'], r['datetime'])
            title = self.config['MAIL']['MAIL_TITLE'] % program
            content = "<b>Program:%s</b></b><br/>From:%s<br/>To:%s<br/><b>Total Num: %d</b><br/><br/><b>Content are:</b><br/>%s" % (
                program, start, end, num, _content)
            self.sendmail(receiver, title, content)