Пример #1
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '--url',
        required=True,
        help='IP or FQDN for Vectra brain (http://www.example.com)')
    group = parser.add_mutually_exclusive_group(required=True)
    group.add_argument('--token', help='api token')
    group.add_argument('--user', help='username for basic auth')
    parser.add_argument('--csv', help='output to csv', action='store_true')
    parser.add_argument('--list_hosts',
                        help='add host list to csv',
                        action='store_true')
    parser.add_argument(
        '--all-hosts',
        action='store_true',
        help='return active and inactive hosts (only active hosts by default)')

    args = vars(parser.parse_args())
    print args

    if args['user']:
        args['password'] = getPassword()
        vc = vectra.VectraClient(url=args['url'],
                                 user=args['user'],
                                 password=args['password'])
    else:
        vc = vectra.VectraClient(url=args['url'], token=args['token'])

    total_count = 0
    subnets = {}

    for page in vc.get_all_hosts(all=args['all_hosts'],
                                 fields='name,last_source'):
        for host in page.json()['results']:
            if not host['last_source']:
                continue
            octet = re.search('(?P<subnet>(\d+\.){3})\d+', host['last_source'])
            network = "{subnet}0".format(subnet=octet.group('subnet'))
            if not subnets.get(network):
                subnets[network] = {'count': 0, 'hosts': []}
            subnets[network]['count'] += 1
            subnets[network]['hosts'].append(host['name'])
            total_count += 1

    # TODO numeric sorting
    if args['csv']:
        for key in sorted(subnets.iterkeys()):
            print "{key},{count},".format(key=key,
                                          count=subnets[key]['count']),
            if args['list_hosts']:
                print " ".join(subnets[key]['hosts'])
            else:
                print
    else:
        pprint.pprint(subnets, width=40)

    print "\n\n{:<18} {count}".format('total host count:', count=total_count)
Пример #2
0
def main():
    parser = argparse.ArgumentParser()
    parser = commonArgs(parser)
    parser.add_argument('-c',
                        '--category',
                        choices=[
                            "botnet", "command", "reconnaissance", "lateral",
                            "exfiltration"
                        ],
                        help='detection category')
    parser.add_argument('-t',
                        '--type',
                        dest='detection_type',
                        help='detection type')
    parser.add_argument('--src',
                        dest='src_ip',
                        help='ip address of source host')
    parser.add_argument('--threat',
                        dest='threat_gte',
                        type=int,
                        help='minimum threat score')
    parser.add_argument('--certainty',
                        type=int,
                        dest='certainty_gte',
                        help='minimum certainty score')
    parser.add_argument('--host',
                        dest='host_id',
                        help='host id attributed to detection')

    args = vars(parser.parse_args())

    if args['user']:
        args['password'] = getPassword()
        vc = vectra.VectraClient(url=args['url'],
                                 user=args['user'],
                                 password=args['password'])
    else:
        vc = vectra.VectraClient(url=args['url'], token=args['token'])

    resp = vc.get_detections(category=args.get('category', None),
                             certainty_gte=args.get('certainty_gte', None),
                             detection_type=args.get('detection_type', None),
                             fields=args.get('fields', None),
                             host_id=args.get('host_id', None),
                             order=args.get('order', None),
                             page=args.get('page', None),
                             page_size=args.get('page_size', None),
                             src_ip=args.get('src_ip', None),
                             state=args.get('state', None),
                             threat_gte=args.get('threat_gte', None))

    print resp.json()
Пример #3
0
def main():
    parser = argparse.ArgumentParser()
    subparsers = parser.add_subparsers(dest='action')

    proxy_list = subparsers.add_parser('list', help='list configured proxies')
    proxy_list = commonArgs(proxy_list)

    proxy_add= subparsers.add_parser('add', help='create proxies')
    proxy_add = commonArgs(proxy_add)
    proxy_add.add_argument('host', help='host to add to proxy list')

    # parser_file = subparsers.add_parser('file',
    #                                     help='Load data from file')
    # parser_file.add_argument('filename',
    #                                     help='file to import data')

    args = vars(parser.parse_args())

    if args['user']:
        print("This script only supports v2 of the API. Please use --token")
        exit()
    else:
        vc = vectra.VectraClient(url=args['url'], token=args['token'])

    if args['action'] == 'list':
        proxies = vc.get_proxies().json()['proxies']
        pprint.pprint(proxies)
    elif args['action'] == 'add':
        resp = vc.add_proxy(host=args['host'])
        pprint.pprint(resp.json()['proxy'])
Пример #4
0
def main():
    parser = argparse.ArgumentParser()
    subparsers = parser.add_subparsers(dest='type')

    parser_hostname = subparsers.add_parser('hostname', help='Set key asset flag based on hostname')
    parser_hostname = commonArgs(parser_hostname)
    parser_hostname.add_argument('target',
                                 help='hostname or file name with list of hostnames')

    parser_ip = subparsers.add_parser('ip',
                                      help='Set key asset flag based on ip address')
    parser_ip = commonArgs(parser_ip)
    parser_ip.add_argument('target',
                           help='ip address or file name with list of ip addresses')

    parser_id = subparsers.add_parser('id', help='Set key asset based on id')
    parser_id = commonArgs(parser_id)
    parser_id.add_argument('target',
                           help='host id or file name with list of ids')


    args = vars(parser.parse_args())
    vc = vectra.VectraClient(url=args['url'], token=args['token'])

    set_ka = True if not args['unset'] else False

    if args['file'] and args['type'] == 'hostname':
        hostfile = open(args['target'], 'r')
        for host in hostfile.readlines():
            try:
                host_id = vc.get_hosts(name=host.strip()).json()['results'][0]['id']
                resp = vc.set_key_asset(host_id=host_id, set=set_ka)
                respCode(args, resp, host.strip())
            except IndexError:
                print host.strip() + " is not present in Vectra"
    elif args['file'] and args['type'] == 'ip':
        hostfile = open(args['target'], 'r')
        for host in hostfile.readlines():
            try:
                host_id = vc.get_hosts(last_source=host.strip()).json()['results'][0]['id']
                resp = vc.set_key_asset(host_id=host_id, set=set_ka)
                respCode(args, resp, host.strip())
            except IndexError:
                print host.strip() + " is not present in Vectra"
    else:
        if args['type'] == 'hostname':
            hosts = vc.get_hosts(name=args['target']).json()['results']
            for host in hosts:
                resp = vc.set_key_asset(host_id=host['id'], set=set_ka)
                respCode(args, resp, args['target'])
        if args['type'] == 'ip':
            hosts = vc.get_hosts(last_source=args['target']).json()['results']
            for host in hosts:
                resp = vc.set_key_asset(host_id=host['id'], set=set_ka)
                respCode(args, resp, args['target'])
        if args['type'] == 'id':
            resp = vc.set_key_asset(host_id=args['target'], set=set_ka)
            respCode(args, resp, args['target'])
Пример #5
0
def retrieve_c2hosts(args, db):
    vc = vectra.VectraClient(url=args['url'], token=args['token'])
    wl = args.get('dst_wl', [])

    if bool(args.get('state', None)) and bool(args.get('triaged', None)):
        detections = vc.get_detections(detection_category='command & control',
                                       state=args['state'],
                                       is_triaged=args['triaged'],
                                       page_size=1000).json()
    elif args.get('triaged', None):
        detections = vc.get_detections(detection_category='command & control',
                                       is_triaged=args['triaged'],
                                       page_size=1000).json()
    else:
        detections = vc.get_detections(detection_category='command & control',
                                       page_size=1000).json()

    for detection in detections['results']:
        ips = []
        if (detection['src_host']['threat'] >= args['c2_threat_score']
                and detection['src_host']['certainty'] >=
                args['c2_certainty_score']):

            if detection['detection_type'] == 'Suspect Domain Activity':
                for detail in detection['grouped_details']:
                    ips += detail['dns_response'].split(
                        ',') if detail['dns_response'] else []
                ips = list(set(ips))
            elif detection[
                    'detection_type'] == 'Suspicious HTTP':  # or detection['detection_type'] == 'Hidden DNS Tunnel':
                for detail in detection['grouped_details']:
                    ips.extend(detail['dst_ips'])
            #elif detection['detection_type'] == 'Multi-home Fronted Tunnel':
            #    for detail in detection['grouped_details']:
            #        ips.extend(detail['cdn_ips'])
            elif detection['detection_type'] == 'Suspicious Relay':
                ips = detection['summary']['origin_ips']
            elif (detection['detection_type']
                  == 'Vectra Threat Intelligence Match'
                  or detection['detection_type'] == 'Hidden DNS Tunnel' or
                  detection['detection_type'] == 'Multi-home Fronted Tunnel'):
                pass
            else:
                ips = detection['summary']['dst_ips']

        if detection['groups'] and wl:
            ips = remove_wl_ips(detection, wl, vc, ips)

        db.insert({'id': detection['id'], 'dst_ips': ips})
Пример #6
0
def retrieve_detections(args, db):
    vc = vectra.VectraClient(url=args['url'], token=args['token'])
    wl = args.get('dst_wl', [])

    if bool(args.get('state', None)) and bool(args.get('triaged', None)):
        detections = vc.get_detections(detection_type=args.get(
            'detection_type', None),
                                       state=args['state'],
                                       is_triaged=args['triaged'],
                                       page_size=1000).json()

    elif args.get('triaged', None):
        detections = vc.get_detections(detection_type=args.get(
            'detection_type', None),
                                       is_triaged=args['triaged'],
                                       page_size=1000).json()

    else:
        detections = vc.get_detections(detection_type=args.get(
            'detection_type', None),
                                       page_size=1000).json()

    logging.debug(
        '{count} detections were returned with detection {detection}'.format(
            count=detections['count'],
            detection=args.get('detection_type', None)))

    for detection in detections['results']:
        ips = []
        if detection['detection_type'] == 'Suspect Domain Activity':
            for detail in detection['grouped_details']:
                ips += detail['dns_response'].split(
                    ',') if detail['dns_response'] else []
            ips = list(set(ips))
        elif detection['detection_type'] == 'Suspicious HTTP':
            for detail in detection['grouped_details']:
                ips.extend(detail['dst_ips'])
        elif detection['detection_type'] == 'Suspicious Relay':
            ips = detection['summary']['origin_ips']
        else:
            ips = detection['summary']['dst_ips']

        if detection['groups'] and wl:
            ips = remove_wl_ips(detection, wl, vc, ips)

        logging.debug(f'det_id:{detection["id"]}, dst_ips:{ips}')
        db.insert({'id': detection['id'], 'dst_ips': ips})
        logging.debug(f'{str(ips)} added to block list')
Пример #7
0
def main():
    parser = argparse.ArgumentParser()
    subparsers = parser.add_subparsers(dest='action')

    # Host score subparser
    parser_score = subparsers.add_parser(
        'score', help='retrieve hosts base on threat/certainty score')
    parser_score = commonArgs(parser_score)
    parser_score.add_argument(
        '-t',
        '--threat',
        dest='threat_gte',
        type=int,
        help='minimum threat score (default: %(default)s)',
        default=75)
    parser_score.add_argument(
        '-c',
        '--certainty',
        type=int,
        dest='certainty_gte',
        help='minimum certainty score (default: %(default)s)',
        default=75)

    # Host tags subparser
    parser_tags = subparsers.add_parser(
        'tags', help='retrieve hosts base on threat/certainty score')
    parser_tags = commonArgs(parser_tags)
    parser_tags.add_argument('-g',
                             '--tags',
                             required=True,
                             help='tags assigned to hosts')

    # Advanced query
    parser_adv = subparsers.add_parser(
        'advance', help='retrieve hosts base on threat/certainty score')
    parser_adv = commonArgs(parser_adv)
    parser_adv.add_argument(
        '-c',
        '--certainty',
        type=int,
        dest='certainty_gte',
        help='minimum certainty score (default: %(default)s)')
    parser_adv.add_argument('-g', '--tags', help='tags assigned to hosts')
    parser_adv.add_argument('-i',
                            '--ip',
                            dest='last_source',
                            help='ip address of host')
    parser_adv.add_argument('-k',
                            '--key_asset',
                            action='store_true',
                            help='host marked as a key asset')
    parser_adv.add_argument('-m',
                            '--mac',
                            dest='mac_address',
                            help='mac address of host')
    parser_adv.add_argument('-t',
                            '--threat',
                            dest='threat_gte',
                            type=int,
                            help='minimum threat score (default: %(default)s)')

    args = vars(parser.parse_args())

    if args['user']:
        args['password'] = getPassword()
        vc = vectra.VectraClient(url=args['url'],
                                 user=args['user'],
                                 password=args['password'])
    else:
        vc = vectra.VectraClient(url=args['url'], token=args['token'])

    resp = vc.get_hosts(certainty_gte=args.get('certainty_gte', None),
                        threat_gte=args.get('threat_gte', None),
                        tags=args.get('tags', None),
                        last_source=args.get('last_source', None),
                        is_key_asset=args.get('key_asset', None),
                        mac_address=args.get('mac_address', None))

    print resp.json()
Пример #8
0
parser_file.add_argument('filename', help='file to import data')

args = vars(parser.parse_args())

if args['action'] == 'file':
    filename = open(args['filename'], 'r')
    response = json.loads(filename.read())
else:
    if args['user']:
        args['password'] = getPassword()
    else:
        print('This script only supports v1 of the API. Please use --user')
        exit(0)

    vc = vectra.VectraClient(url=args['url'],
                             user=args['user'],
                             password=args['password'])

    response = vc.get_detections(state=args['state'],
                                 page_size=args['page_size'],
                                 page=args['page'],
                                 fields=args['fields'],
                                 order=args['order']).json()

if args['summary'] == 'detection':
    srcList = []
    count = []
    for result in response['results']:
        name = result['type_vname']
        srcIp = result['src_ip']
        srcList.append([result['type_vname'], result['src_ip']])
Пример #9
0
def main():
    parser = argparse.ArgumentParser(
        description=
        "Manage Vectra threat feeds (This script is only supported by v2 endpoint which requires token auth)"
    )

    # Command line arguments for creating new threat feed
    subparsers = parser.add_subparsers(dest='action')

    parser_create = subparsers.add_parser('create',
                                          help='Create new threat feed')
    parser_create.add_argument('--feed',
                               required=True,
                               action='store',
                               help='Name for threat feed')

    parser_create.add_argument('--token',
                               required=True,
                               action='store',
                               help='Authentication token')

    parser_create.add_argument(
        '--url',
        required=True,
        action='store',
        help='IP or FQDN for Vectra brain (http://www.example.com)')

    parser_create.add_argument('--file',
                               required=True,
                               action='store',
                               help='SITX file')

    parser_create.add_argument('--category',
                               required=True,
                               action='store',
                               choices=["exfil", "lateral", "cnc"],
                               help='Detection category (case sensitive)')

    parser_create.add_argument('--certainty',
                               required=True,
                               action='store',
                               choices=['Low', 'Medium', 'High'],
                               help='Detection certainty (case sensitive)')

    parser_create.add_argument('--type',
                               required=True,
                               action='store',
                               choices=[
                                   'Anonymization', 'C2', 'Exfiltration',
                                   'Malware Artifacts', 'Watchlist'
                               ],
                               help='Indicator type (case sensitive)')

    parser_create.add_argument('--duration',
                               required=True,
                               action='store',
                               type=int,
                               help='Duration')

    # Command line arguments for updating an existing threat feed
    parser_edit = subparsers.add_parser(
        'update', help='Update STIX file for existing threat feed')
    parser_edit.add_argument('--feed',
                             required=True,
                             action='store',
                             help='Name for threat feed')

    parser_edit.add_argument('--token',
                             required=True,
                             action='store',
                             help='Authentication token')

    parser_edit.add_argument(
        '--url',
        required=True,
        action='store',
        help='IP or FQDN for Vectra brain (http://www.example.com)')

    parser_edit.add_argument('--file',
                             required=True,
                             action='store',
                             help='SITX file')

    # Command line arguments for deleting a threat feed
    parser_delete = subparsers.add_parser('delete', help='Delete threat feed')
    parser_delete.add_argument('--feed',
                               required=True,
                               action='store',
                               help='Name for threat feed')

    parser_delete.add_argument('--token',
                               required=True,
                               action='store',
                               help='Authentication token')

    parser_delete.add_argument(
        '--url',
        required=True,
        action='store',
        help='IP or FQDN for Vectra brain (http://www.example.com)')

    # Command line argument for listing threat feeds
    parser_show = subparsers.add_parser('list',
                                        help='Shows list of all threat feeds')
    parser_show.add_argument('--token',
                             required=True,
                             action='store',
                             help='Authentication token')

    parser_show.add_argument(
        '--url',
        required=True,
        action='store',
        help='IP or FQDN for Vectra brain (http://www.example.com)')

    # print(parser.parse_args())
    args = vars(parser.parse_args())
    vc = vectra.VectraClient(url=args['url'], token=args['token'])

    if args['action'] == 'create':
        feed_id = vc.create_feed(
            name=args['feed'],
            category=args['category'],
            certainty=args['certainty'],
            itype=args['type'],
            duration=args['duration']).json()['threatFeed']['id']
        print 'Threat feed created\nUploading STIX file\n'
        vc.post_stix_file(feed_id=feed_id, stix_file=args['file'])

        print "success"

    if args['action'] == 'update':
        feed_id = vc.get_feed_by_name(name=args['feed'])
        if feed_id:
            vc.post_stix_file(feed_id=feed_id, stix_file=args['file'])
            print "success"
        else:
            print 'Could not find threat feed'

    if args['action'] == 'delete':
        feed_id = vc.get_feed_by_name(name=args['feed'])
        if feed_id:
            vc.delete_feed(feed_id=feed_id)
            print "success"
        else:
            print 'Could not find threat feed'

    if args['action'] == 'list':
        result = vc.get_feeds()

        for e in result.json()['threatFeeds']:
            pprint.pprint(e)
Пример #10
0
def retrieve_hosts(args, db):
    vc = vectra.VectraClient(url=args['url'], token=args['token'])
    wl = args.get('src_wl', [])

    if args.get('tags', None):
        hosts = vc.get_hosts(tags=args['tags'],
                             state=args['state'],
                             page_size=1000).json()
        logging.debug(
            f'{hosts["count"]} hosts returned with tags: {args["tags"]}')

        for host in hosts['results']:
            logging.debug('host_id:{}, name:{}, ip:{}'.format(
                host['id'], host['name'], host['last_source']))
            if not in_group_wl(host, wl):
                db.insert({
                    'id': host['id'],
                    'name': host['name'],
                    'ip': host['last_source']
                })
                logging.debug('host ' + host['name'] + ':' +
                              host['last_source'] + ' added to block list')

    if args.get('certainty_gte', None) or args.get('threat_gte', None):
        hosts = vc.get_hosts(certainty_gte=args.get('certainty_gte', 50),
                             threat_gte=args.get('threat_gte', 50),
                             page_size=1000).json()
        logging.debug(
            '{count} hosts returned with score: certainty {certainty} threat {threat}'
            .format(count=hosts['count'],
                    certainty=args.get('certainty_gte', 50),
                    threat=args.get('threat_gte', 50)))

        for host in hosts['results']:
            logging.debug('host_id:{}, name:{}, ip:{}'.format(
                host['id'], host['name'], host['last_source']))
            if not in_group_wl(host, wl):
                db.insert({
                    'id': host['id'],
                    'name': host['name'],
                    'ip': host['last_source']
                })
                logging.debug('host ' + host['name'] + ':' +
                              host['last_source'] + ' added to block list')

    if args.get('src_detection_types', None):
        for src_det_type in args.get('src_detection_types'):
            response = vc.advanced_search(
                stype='hosts',
                page_size=5000,
                query=
                f"host.detection_summaries.detection_type:\"{src_det_type}\"")

            for page in response:
                for host in page.json()['results']:
                    logging.debug('host_id:{}, name:{}, ip:{}'.format(
                        host['id'], host['name'], host['last_source']))
                    if not in_group_wl(host, wl):
                        db.insert({
                            'id': host['id'],
                            'name': host['name'],
                            'ip': host['last_source']
                        })
                        logging.debug('host ' + host['name'] + ':' +
                                      host['last_source'] +
                                      ' added to block list')
Пример #11
0
def vc_v2(request):
    brain = request.config.getoption('--url')
    token = request.config.getoption('--token')
    return vectra.VectraClient(url=brain, token=token)
Пример #12
0
def vc_v1(request):
    brain = request.config.getoption('--url')
    username = request.config.getoption('--user')
    passwd = request.config.getoption('--password')
    return vectra.VectraClient(url=brain, user=username, password=passwd)
Пример #13
0
import sys
import ssl

try:
    import urllib.request
    import urllib.parse
    import requests
    import validators
    import vat.vectra as vectra
    from jose import jwt
    from .config import COGNITO_BRAIN, COGNITO_TOKEN, TENANT_ID, APP_ID, APP_SECRET
except Exception as error:
    print("\nMissing import requirements: %s\n" % str(error))

# Setup Vectra client
VC = vectra.VectraClient(COGNITO_BRAIN, token=COGNITO_TOKEN)

# Suppress Detect certificate warning
requests.packages.urllib3.disable_warnings()
ssl._create_default_https_context = ssl._create_unverified_context

# Setup logging
LOG = logging.getLogger(__name__)

# MS ATP Related URLs
ATP_URL = 'https://api.securitycenter.windows.com/api/'
RESOURCE_APP_ID_URI = "https://api.securitycenter.windows.com"
AUTH_URL = "https://login.windows.net/{}/oauth2/token".format(TENANT_ID)
SECURITY_CENTER_URL = 'https://securitycenter.windows.com/machines/'

Пример #14
0
params = {
    'url': '',
    'token': '',
    'smtp_server': '',
    'smtp_port': '',
    'username': '',
    'password': '',
    'fromAddr': '',
    'toAddr': ''
}

vdb = TinyDB('vectra.json')
ht = vdb.table('hosts')
upd = vdb.table('updates')

vc = vectra.VectraClient(url=params['url'], token=params['token'])
hosts = vc.get_hosts(fields='id,name,last_source').json()['results']


def insert_host(db, host):
    db.insert({
        'id': host['id'],
        'name': host['name'],
        'ip': host['last_source']
    })


def send_message(hosts):
    msg = MIMEMultipart()
    msg['From'] = params['fromAddr']
    msg['To'] = params['toAddr']