コード例 #1
0
def process_json(data, jsondata):
    logger.info('Processing JSON data.')
    logger.info('Data received:\n{}'.format(jsondata))
    # process Google device data
    if jsondata.get('scan_results'):
        aps = parse_google(jsondata['scan_results'])
        if aps:
            logger.info('Parsed access points: {}'.format(aps))
            coords = get_coords_from_google(aps)
            if all([x for x in coords.values()]):
                add_beacon(
                    target_guid=data['target'],
                    agent=data['agent'],
                    ip=data['ip'],
                    port=data['port'],
                    useragent=data['useragent'],
                    comment=data['comment'],
                    lat=coords['lat'],
                    lng=coords['lng'],
                    acc=coords['acc'],
                )
                return True
            else:
                logger.error('Invalid coordinates data.')
        else:
            # handle empty data
            logger.info('No AP data received.')
    else:
        # handle unrecognized data
        logger.info('Unrecognized data received from the agent.')
コード例 #2
0
ファイル: processors.py プロジェクト: crbarahona/honeybadger
def process_ip(data):
    logger.info('Processing IP address.')
    coords = get_coords_from_ipstack(data['ip'])
    if not all([x for x in coords.values()]):
        # No data. try again with the fallback.
        logger.info('Using fallback API.')
        coords = get_coords_from_ipinfo(data['ip'])

    if all([x for x in coords.values()]):
        add_beacon(target_guid=data['target'],
                   agent=data['agent'],
                   ip=data['ip'],
                   port=data['port'],
                   useragent=data['useragent'],
                   comment=data['comment'],
                   lat=coords['lat'],
                   lng=coords['lng'],
                   acc='Unknown',
                   country=coords['country_name'],
                   region=coords['region_name'],
                   city=coords['city'])
        return True
    else:
        logger.error('Invalid coordinates data.')
    return False
コード例 #3
0
def process_known_coords(data):
    logger.info('Processing known coordinates.')
    add_beacon(
        target_guid=data['target'],
        agent=data['agent'],
        ip=data['ip'],
        port=data['port'],
        useragent=data['useragent'],
        comment=data['comment'],
        lat=data['lat'],
        lng=data['lng'],
        acc=data['acc'],
    )
    return True
コード例 #4
0
ファイル: plugins.py プロジェクト: jasonthename/honeybadger
def get_coords_from_uniapple(ip):
    logger.info('Geolocating via Uniapple API.')
    url = 'http://uniapple.net/geoip/?ip={}'.format(ip)
    content = urllib2.urlopen(url).read()
    logger.info('Uniapple API response:\n{}'.format(content))
    jsondata = None
    try:
        jsondata = json.loads(content)
    except ValueError as e:
        logger.error('{}.'.format(e))
    data = {'lat': None, 'lng': None}
    if jsondata:
        data['lat'] = jsondata['latitude']
        data['lng'] = jsondata['longitude']
    return data
コード例 #5
0
def process_ip(data):
    logger.info('Processing IP address.')
    coords = get_coords_from_uniapple(data['ip'])
    if all([x for x in coords.values()]):
        add_beacon(
            target_guid=data['target'],
            agent=data['agent'],
            ip=data['ip'],
            port=data['port'],
            useragent=data['useragent'],
            comment=data['comment'],
            lat=coords['lat'],
            lng=coords['lng'],
            acc='Unknown',
        )
        return True
    else:
        logger.error('Invalid coordinates data.')
    return False
コード例 #6
0
ファイル: plugins.py プロジェクト: syh4ck/honeybadger
def get_coords_from_ipstack(ip):
    logger.info('Geolocating via Ipstack API.')
    url = 'http://api.ipstack.com/{0}?access_key={1}'.format(
        ip, app.config['IPSTACK_API_KEY'])
    response = requests.get(url)
    logger.info('Ipstack API response:\n{}'.format(response.content))
    jsondata = None
    try:
        jsondata = response.json()
    except ValueError as e:
        logger.error('{}.'.format(e))

    data = {'lat': None, 'lng': None}

    # Avoid the KeyError. For some reason, a successful API call to Ipstack doesn't include
    #   the 'success' key in the json result, but a failed call does, and the value is False
    if 'success' in jsondata and not jsondata['success']:
        logger.info('Ipstack API call failed: {}'.format(
            jsondata['error']['type']))
        # Return with empty data so the caller knows to default to the fallback API
        return data

    if jsondata:
        data['lat'] = jsondata['latitude']
        data['lng'] = jsondata['longitude']
    return data
コード例 #7
0
ファイル: plugins.py プロジェクト: syh4ck/honeybadger
def get_coords_from_google(aps):
    logger.info('Geolocating via Google Geolocation API.')
    url = 'https://www.googleapis.com/geolocation/v1/geolocate?key={}'.format(
        app.config['GOOGLE_API_KEY'])
    data = {"wifiAccessPoints": []}
    for ap in aps:
        data['wifiAccessPoints'].append(ap.serialized_for_google)
    data_json = json.dumps(data)
    headers = {'Content-Type': 'application/json'}
    response = requests.post(url=url, data=data_json, headers=headers)
    logger.info("Google API response: {}".format(response.content))
    jsondata = None
    try:
        jsondata = response.json()
    except ValueError as e:
        logger.error('{}.'.format(e))
    data = {'lat': None, 'lng': None, 'acc': None}
    if jsondata:
        data['acc'] = jsondata['accuracy']
        data['lat'] = jsondata['location']['lat']
        data['lng'] = jsondata['location']['lng']
    return data
コード例 #8
0
ファイル: plugins.py プロジェクト: syh4ck/honeybadger
def get_coords_from_ipinfo(ip):
    # New fallback, ipinfo doesn't require an API key for a certain number of API calls
    logger.info('Geolocating via Ipinfo.io API.')
    url = 'https://ipinfo.io/{}'.format(ip)
    response = requests.get(url)
    logger.info('Ipinfo.io API response:\n{}'.format(response.content))
    jsondata = None
    try:
        jsondata = response.json()
    except ValueError as e:
        logger.error('{}.'.format(e))
    data = {'lat': None, 'lng': None}
    if jsondata and 'loc' in jsondata:
        data['lat'] = jsondata['loc'].split(',')[0]
        data['lng'] = jsondata['loc'].split(',')[1]
    if 'bogon' in jsondata and jsondata['bogon']:
        logger.info('Ipinfo.io cannot geolocate IP {}'.format(ip))
    return data
コード例 #9
0
def api_beacon(target, agent):
    logger.info('{}'.format('=' * 50))
    data = {'target': target, 'agent': agent}
    logger.info('Target: {}'.format(target))
    logger.info('Agent: {}'.format(agent))
    # check if target is valid
    if target not in [x.guid for x in Target.query.all()]:
        logger.error('Invalid target GUID.')
        abort(404)
    # extract universal parameters
    comment = request.values.get('comment', '').decode('base64') or None
    ip = request.environ['REMOTE_ADDR']
    port = request.environ['REMOTE_PORT']
    useragent = request.environ['HTTP_USER_AGENT']
    data.update({
        'comment': comment,
        'ip': ip,
        'port': port,
        'useragent': useragent
    })
    logger.info('Connection from {} @ {}:{} via {}'.format(
        target, ip, port, agent))
    logger.info('Parameters: {}'.format(request.values.to_dict()))
    logger.info('User-Agent: {}'.format(useragent))
    logger.info('Comment: {}'.format(comment))
    data.update(request.values.to_dict())
    # process json payloads
    if request.json:
        if process_json(data, request.json):
            abort(404)
    # process known coordinates
    if all(k in data for k in ('lat', 'lng', 'acc')):
        if process_known_coords(data):
            abort(404)
    # process wireless survey
    elif all(k in data for k in ('os', 'data')):
        if process_wlan_survey(data):
            abort(404)
    # process ip geolocation (fallback)
    process_ip(data)
    abort(404)
コード例 #10
0
def add_beacon(*args, **kwargs):
    b = Beacon(**kwargs)
    db.session.add(b)
    db.session.commit()
    logger.info('Target location identified as Lat: {}, Lng: {}'.format(
        kwargs['lat'], kwargs['lng']))
コード例 #11
0
def process_wlan_survey(data):
    logger.info('Processing wireless survey data.')
    os = data['os']
    _data = data['data']
    content = b64d(_data).decode()
    logger.info('Data received:\n{}'.format(_data))
    logger.info('Decoded Data:\n{}'.format(content))
    if _data:
        aps = []
        if re.search('^mac os x', os.lower()):
            aps = parse_airport(content)
        elif re.search('^windows', os.lower()):
            aps = parse_netsh(content)
        elif re.search('^linux', os.lower()):
            aps = parse_iwlist(content)
        # handle recognized data
        if aps:
            logger.info('Parsed access points: {}'.format(aps))
            coords = get_coords_from_google(aps)
            if all([x for x in coords.values()]):
                add_beacon(
                    target_guid=data['target'],
                    agent=data['agent'],
                    ip=data['ip'],
                    port=data['port'],
                    useragent=data['useragent'],
                    comment=data['comment'],
                    lat=coords['lat'],
                    lng=coords['lng'],
                    acc=coords['acc'],
                )
                return True
            else:
                logger.error('Invalid coordinates data.')
        else:
            # handle unrecognized data
            logger.info('No parsable WLAN data received.')
    else:
        # handle blank data
        logger.info('No data received from the agent.')
    return False
コード例 #12
0
ファイル: views.py プロジェクト: crbarahona/honeybadger
def api_beacon(target, agent):
    logger.info('{}'.format('=' * 50))
    data = {'target': target, 'agent': agent}
    logger.info('Target: {}'.format(target))
    logger.info('Agent: {}'.format(agent))
    # check if target is valid
    if target not in [x.guid for x in Target.query.all()]:
        logger.error('Invalid target GUID.')
        abort(404)
    # extract universal parameters
    comment = b64d(request.values.get('comment', '')).decode() or None
    ip = request.environ['REMOTE_ADDR']
    if (request.headers.get('X-Real-IP')):
        ip = request.headers.get('X-Real-IP')
    port = request.environ['REMOTE_PORT']
    useragent = request.environ['HTTP_USER_AGENT']
    logger.info('Connection from {} @ {}:{} via {}'.format(
        target, ip, port, agent))
    logger.info('Parameters: {}'.format(request.values.to_dict()))
    logger.info('User-Agent: {}'.format(useragent))
    logger.info('Comment: {}'.format(comment))
    data.update(request.values.to_dict())
    data.update({
        'comment': comment,
        'ip': ip,
        'port': port,
        'useragent': useragent
    })
    # process json payloads
    if request.json:
        if process_json(data, request.json):
            abort(404)
    # process known coordinates
    if all(k in data for k in ('lat', 'lng', 'acc')):
        if process_known_coords(data):
            abort(404)
    # process wireless survey
    elif all(k in data for k in ('os', 'data')):
        if process_wlan_survey(data):
            abort(404)
    # process ip geolocation (includes fallback)
    process_ip(data)
    if re.search('\.(png|jpg|gif)$', data['agent'].lower()):
        if os.path.exists(
                os.path.join(os.getcwd(),
                             'server/honeybadger/static/' + data['agent'])):
            return send_from_directory(directory='static',
                                       filename=data['agent'],
                                       as_attachment=False,
                                       cache_timeout=0)
        else:
            abort(404)
    abort(404)