def manage_app(app_id): if request.method == 'POST': status = request.args.get('status') params = {'status': status} result = qpylib.REST('POST', '/api/gui_app_framework/applications/%s' % app_id, params=params) if result.status_code != 200: return jsonify("QRadar returned {0} ({1})".format( str(result.status_code), json.dumps(result.json()["message"]))), 500 return jsonify("App status set to %s" % status), 200 elif request.method == 'DELETE': result = qpylib.REST('DELETE', '/api/gui_app_framework/applications/%s' % app_id) if result.status_code != 204: return jsonify("QRadar returned {0} ({1})".format( str(result.status_code), json.dumps(result.json()["message"]))), 500 return jsonify("App " + app_id + " deleted"), 200
def test_rest_uses_env_vars_when_set(env_sec_admin_token, env_qradar_console_fqdn): responses.add('GET', 'https://myhost.ibm.com/testing_endpoint', status=200) response = qpylib.REST('GET', 'testing_endpoint', verify='dummycert', headers={'Host': '127.0.0.1'}) assert response.status_code == 200 assert responses.calls[0].request.method == 'GET' assert responses.calls[0].request.url == 'https://myhost.ibm.com/testing_endpoint' assert responses.calls[0].request.headers['SEC'] == '12345-testing-12345-testing'
def test_rest_sets_version_header(env_qradar_console_fqdn): responses.add('GET', 'https://9.101.234.169/testing_endpoint', status=200) response = qpylib.REST('GET', 'testing_endpoint', verify='dummycert', version='12') assert response.status_code == 200 assert responses.calls[0].request.method == 'GET' assert responses.calls[0].request.url == 'https://9.101.234.169/testing_endpoint' assert responses.calls[0].request.headers['Version'] == '12'
def test_rest_sets_version_header(env_qradar_console_fqdn): responses.add('GET', 'https://myhost.ibm.com/testing_endpoint', status=200) response = qpylib.REST('GET', 'testing_endpoint', verify='dummycert', version='12', headers={'Host': '127.0.0.1'}) assert response.status_code == 200 assert responses.calls[0].request.method == 'GET' assert responses.calls[0].request.url == 'https://myhost.ibm.com/testing_endpoint' assert responses.calls[0].request.headers['Version'] == '12'
def get_offenses(): offense_range = request.args.get('range') response = qpylib.REST('get', '/api/siem/offenses', None, headers={'Range': offense_range}) return {'offenses': response.json()}
def get_entity_by_id(id, entity_endpoint, headers): try: full_entity_endpoint = entity_endpoint + '/' +str(id) response = qpylib.REST('GET', full_entity_endpoint, headers=headers) if response.status_code != 200: qpylib.log('API returned an error. Error: {0}'.format(response.content), level='error') return response.json() except Exception, e: qpylib.log('Unable to retrieve entity records from QRadar. Error: {0}'.format(str(e)), level='error')
def test_rest_allows_put(env_qradar_console_fqdn): responses.add('PUT', 'https://myhost.ibm.com/testing_endpoint', status=201) response = qpylib.REST('PUT', 'testing_endpoint', headers={'Host': '127.0.0.1'}) assert response.status_code == 201 assert responses.calls[0].request.method == 'PUT' assert responses.calls[ 0].request.url == 'https://myhost.ibm.com/testing_endpoint'
def query_ariel_databases(): try: response = qpylib.REST('get', '/api/ariel/databases') qpylib.log('response=' + str(response.json())) return response except Exception as ex: qpylib.log( 'Error calling REST api GET /api/ariel/databases: ' + str(ex), 'ERROR') raise
def get_offense_severity(offense_id): params = {'filter': 'id={0}'.format(offense_id), 'fields': 'severity'} offense_api_response = qpylib.REST(rest_action='GET', request_url='/api/siem/offenses', params=params) offenses_json = offense_api_response.json() offense_json = offenses_json[0] if 'severity' in offense_json: return offense_json['severity'] return 0
def get_offenses(): offenses_endpoint = '/api/siem/offenses' headers = {"Content-type": "application/json", "Accept" : "application/json"} try: response = qpylib.REST('GET', offenses_endpoint, headers=headers) if response.status_code != 200: qpylib.log('API returned an error. Error: {0}'.format(response.content), level='error') return response.json() except Exception, e: qpylib.log('unable to retrieve offense records from QRadar. Error: {0}'.format(str(e)), level='error')
def test_rest_uses_sec_cookie_when_env_var_not_set(env_qradar_console_fqdn): test_sec_cookie_value = 'seccookie-12345-seccookie' cookie = http.dump_cookie("SEC", test_sec_cookie_value) app = Flask(__name__) with app.test_request_context(headers={"COOKIE": cookie}): responses.add('GET', 'https://myhost.ibm.com/testing_endpoint', status=200) response = qpylib.REST('GET', 'testing_endpoint', verify='dummycert', headers={'Host': '127.0.0.1'}) assert response.status_code == 200 assert responses.calls[0].request.method == 'GET' assert responses.calls[0].request.url == 'https://myhost.ibm.com/testing_endpoint' assert responses.calls[0].request.headers['SEC'] == test_sec_cookie_value
def test_rest_uses_input_values(mock_api_auth, mock_console_address): responses.add('GET', 'https://9.101.234.169/testing_endpoint', json={'success': True}, status=200) response = qpylib.REST('GET', 'testing_endpoint', verify='dummycert') assert responses.calls[ 0].request.url == 'https://9.101.234.169/testing_endpoint' assert 'Basic' in responses.calls[0].request.headers['Authorization'] assert response.status_code == 200
def get_asset_type(asset_id): params = { 'filter': 'id={0}'.format(asset_id), 'fields': 'interfaces(ip_addresses(type))' } asset_type = 'None' asset_api_response = qpylib.REST(rest_action='GET', request_url='/api/asset_model/assets', params=params) assets_json = asset_api_response.json() asset_json = assets_json[0] if 'interfaces' in asset_json: if 'ip_addresses' in asset_json['interfaces'][0]: if 'type' in asset_json['interfaces'][0]['ip_addresses'][0]: asset_type = asset_json['interfaces'][0]['ip_addresses'][0][ 'type'] return asset_type
def index(): # Retrieve the API versions, parsing into a JSON list response = qpylib.REST('get', '/api/help/versions') versions = response.json() # Iterate over the features and determine which ones are enabled enabled_features = [] for feature in FEATURES: enabled_features.append({ 'name': feature['name'], 'enabled': is_feature_enabled(feature, versions) }) return render_template('index.html', latest=get_latest_version(versions), versions=versions, features=enabled_features)
def test_rest_uses_input_and_env_values(env_qradar_console_fqdn): responses.add('GET', 'https://myhost.ibm.com/testing_endpoint', json={'success': True}, status=200) response = qpylib.REST('GET', 'testing_endpoint', version='12', headers={'Host': '127.0.0.1'}) assert response.status_code == 200 assert responses.calls[0].request.method == 'GET' assert responses.calls[ 0].request.url == 'https://myhost.ibm.com/testing_endpoint' assert responses.calls[0].request.headers['Version'] == '12' assert responses.calls[0].request.headers['Host'] == '127.0.0.1' assert responses.calls[0].request.headers[ 'SEC'] == '12345-testing-12345-testing'
def get_ariel_databases(): try: ariel_databases = qpylib.REST('get', '/api/ariel/databases') options = {} for db_name in ariel_databases.json(): options[db_name] = db_name qpylib.log("Ariel DB name: " + db_name) item = { 'id': 'ArielDBs', 'title': 'Ariel DB names', 'HTML': render_template('ariel.html', options=options) } return json.dumps(item) except Exception as ex: qpylib.log( 'Error calling REST api GET /api/ariel/databases: ' + str(ex), 'ERROR') raise
def restData(): try: qpylib.log("hi") headers = {'content-type' : 'text/plain'} searchQuery = {'query_expression' : "select sourceip, destinationip, sourceport, destinationport, sourcebytes, destinationbytes, sourcepackets, destinationpackets from \"flows\" limit 5",} apiResponse = qpylib.REST( 'post', 'api/ariel/searches', headers=headers, params=searchQuery) qpylib.log(apiResponse.content) response = json.loads(apiResponse.content) search_id = (response['search_id']) qpylib.log('SEARCH ID :: %s' % response['search_id']) params = {} # options = {} # for arielSearch in apiResponse.json(): # options[arielSearch] = arielSearch.capitalize() # qpylib.log( "Search value " + arielSearch) # return json.dumps({'id':'arielSearch', 'title':'search id', 'HTML':render_template("testAPICall.html", options=options) } ) return searchIDData(search_id) #return json.dumps({'id':'arielSearch', 'title':'search id'}) except Exception as e: qpylib.log( "Error " + str(e), level='error' )
def get_app_status_data(): # Use qpylib REST helper method to make a call to QRadar GAF API and return all apps result = qpylib.REST('GET', '/api/gui_app_framework/applications') if result.status_code != 200: return jsonify("QRadar returned {0} ({1})".format( str(result.status_code), json.dumps(result.json()["message"]))), 500 # Extract relevant details from response, excluding the app manager app itself app_details = [(app.get("manifest").get("name", "No Name"), app.get("application_state").get("application_id", "No ID"), app.get("manifest").get("version", "No Version"), app.get("application_state").get("status", "No Status"), app.get("manifest").get("uuid", "No UUID")) for app in result.json() if app.get("manifest").get("uuid") != OWN_UUID] return jsonify(app_details)
def searchIDData(search_id): try: headers = {'content-type' : 'text/plain'} while True: statusResponse = qpylib.REST( 'get', 'api/ariel/searches/%s' % search_id, headers=headers) response = json.loads(statusResponse.content) qpylib.log('STATUS :: %s' % response['status']) qpylib.log('SEARCH_ID :: %s' % response['search_id']) status = response['status'] statusSearch_id = response['search_id'] if status == "COMPLETED": break else: time.sleep(3) return flowData(statusSearch_id) except Exception as e: qpylib.log( "Error " + str(e), level='error' )
def get_entity(entity_endpoint, headers, query=None, method='GET', fields='', filter=''): try: full_request = str(entity_endpoint) is_fields = False if fields != '': full_request += '?fields=' + fields is_fields = True if filter != '': if is_fields: full_request += '&filter=' + filter else: full_request += '?filter=' + filter response = qpylib.REST(method, full_request, headers=headers, params=query) if response.status_code != 200: qpylib.log('API returned an error. Error: {0}'.format(response.content), level='error') return response.json() except Exception, e: qpylib.log('Unable to retrieve entity records from QRadar. Error: {0}'.format(str(e)), level='error')
def get_certificate_management_app(): params = { 'filter': 'manifest(name)="QRadar Certificate Management" and application_state(status)="RUNNING"', 'fields': 'application_state' } response = qpylib.REST(rest_action='GET', request_url='/api/gui_app_framework/applications', params=params) if not response.status_code == 200: qpylib.log('Failed to get Certificate Management App') jsonResult = response.json() address = "" if len(jsonResult) > 0: for app_id in jsonResult: cert_management_id = app_id['application_state']['application_id'] console_ip = qpylib.get_console_address() address = "https://{0}/console/plugins/{1}/app_proxy/#/browse/uploadRoot".format( console_ip, cert_management_id) return address
def offenseHeader(offense_id): headers = { 'content_type': 'application/json', 'Version': OFFENSES_API_VERSION } params = {'fields': 'offense_source'} restReturn = qpylib.REST('GET', 'api/siem/offenses/' + str(offense_id), headers=headers, params=params) lastrep = None offenseSource = None cats = None try: if restReturn.status_code == 200: restReturnJson = restReturn.json() qpylib.log('Offenses API returned: %s' % restReturnJson, level='debug') offenseSource = restReturnJson['offense_source'] xResponse = requests.get( 'https://api.xforce.ibmcloud.com/ipr/history/' + offenseSource, auth=(API_KEY, API_PASS)) if xResponse.status_code == 200: xJson = xResponse.json() qpylib.log('Xforce API returned: %s' % xJson, level='debug') history = xJson.get("history") lastrep = history[-1] cats = lastrep.get("cats").keys() html = render_template('xforce_details.html', ip=offenseSource, rep=lastrep, cats=cats) return jsonify({'html': html}) except Exception as e: html = render_template('xforce_details.html', ip=offenseSource, rep=lastrep, cats=cats, error=str(e)) return jsonify({'html': html})
def test_rest_rejects_unsupported_method(env_qradar_console_fqdn): with pytest.raises(ValueError, match='Unsupported REST action was requested'): qpylib.REST('PATCH', 'testing_endpoint', verify='dummycert', headers={'Host': '127.0.0.1'})
def test_rest_allows_delete(env_qradar_console_fqdn): responses.add('DELETE', 'https://myhost.ibm.com/testing_endpoint', status=204) response = qpylib.REST('DELETE', 'testing_endpoint', verify='dummycert', headers={'Host': '127.0.0.1'}) assert response.status_code == 204 assert responses.calls[0].request.method == 'DELETE' assert responses.calls[0].request.url == 'https://myhost.ibm.com/testing_endpoint'
def test_rest_uses_manifest_console_ip_when_env_var_not_set(): responses.add('GET', 'https://9.123.234.101/testing_endpoint', status=200) response = qpylib.REST('GET', 'testing_endpoint', verify='dummycert') assert response.status_code == 200 assert responses.calls[0].request.method == 'GET' assert responses.calls[0].request.url == 'https://9.123.234.101/testing_endpoint'
def test_rest_fails_when_fqdn_env_var_not_set(): with pytest.raises(KeyError, match='Environment variable QRADAR_CONSOLE_FQDN is not set'): qpylib.REST('GET', 'testing_endpoint', verify='dummycert', headers={'Host': '127.0.0.1'})
def test_rest_allows_delete(env_qradar_console_fqdn): responses.add('DELETE', 'https://9.101.234.169/testing_endpoint', status=204) response = qpylib.REST('DELETE', 'testing_endpoint', verify='dummycert') assert response.status_code == 204 assert responses.calls[0].request.method == 'DELETE' assert responses.calls[0].request.url == 'https://9.101.234.169/testing_endpoint'
def get_offense_by_id(offense_id): response = qpylib.REST('get', ('/api/siem/offenses/' + offense_id)) return {'offense': response.json()}
def flowData(statusSearch_id): try: headers = {'content-type' : 'text/plain'} #range = {"range":"items=0-5"} flowDataOptions = qpylib.REST( 'get', 'api/ariel/searches/%s' % statusSearch_id + '/results', headers=headers) #options = {} #group = {} #flow = flowDataOptions.json() #for flowInfo in flowDataOptions.json(): #options[flowInfo] = flowInfo.capitalize() #qpylib.log( "Search value " + flowInfo) #flowInfo2 = json.loads(flowDataOptions.content) #flowData = {} flowData = flowDataOptions.json() qpylib.log(json.dumps(flowData)) #qpylib.log(flowData) #flowDataJson = json.loads(flowData) #json = flowDataOptions.json() #qpylib.log(json) geoIpData = [] geoIpDataDestination = [] #for x in flowDataOptions.json(): # sourceIps['ipAddr'] = x['flows']['sourceip'] # qpylib.log( "result source ip " + x) qpylib.log('flowData flows: ' + json.dumps(flowData['flows'],indent=2)) for x in flowData['flows']: flowsData = {} #destinationIP = {} qpylib.log('inside flowdata loop') #sourceIP['ipAddr'] = flowData['flows']['sourceip'] flowsData['ipAddr'] = x['sourceip'] flowsData['ipAddrDest'] = x['destinationip'] flowsData['sourcePort'] = x['sourceport'] flowsData['destinationPort'] = x['destinationport'] flowsData['sourceBytes'] = x['sourcebytes'] flowsData['destinationBytes'] = x['destinationbytes'] flowsData['sourcePackets'] = x['sourcepackets'] flowsData['destinationPackets'] = x['destinationpackets'] #flowDataJson = json.loads(flowData) #qpylib.log(flowDataJson) #sourceIP[ipAddr] = flowDataJson['sourceip'] qpylib.log('source ip: ' + json.dumps(x['sourceip'])) qpylib.log('destination ip: ' + json.dumps(x['destinationip'])) qpylib.log('source port: ' + json.dumps(x['sourceport'])) #qpylib.log('source ip ipadd ' + json.dumps(sourceIP['ipAddr'])) #geoIpData.extend(sourceIP and destinationIP) geoIpData.append(flowsData) #geoIpData.append(destinationIP) #geoIpData = dict(sourceIP.items() + destinationIP.items()) qpylib.log('geoIpData : ' + json.dumps(geoIpData, indent=2)) for y in geoIpData: ipaddr = y['ipAddr'] qpylib.log('inside flowdata loop y') # write function where you request response from new freegeoip api # eg. locationData = return of getLocationData(ipaddr) #y['locationData'] = locationData locationData = getLocationData(ipaddr) qpylib.log('getLocationData result: ' + json.dumps(locationData,indent=2)) y['sourceLocationData'] = locationData for b in geoIpData: ipaddrdest = b['ipAddrDest'] qpylib.log('inside flowdata loop dest b') locationDataDest = getLocationDataDest(ipaddrdest) qpylib.log('getLocationDataDest result: ' + json.dumps(locationDataDest,indent=2)) b['destinationLocationData'] = locationDataDest qpylib.log('final geoIpData : ' + json.dumps(geoIpData, indent = 2)) ''' qpylib.log('final geoIpDataDestination : ' + json.dumps(geoIpDataDestination, indent = 2)) flowsData = [5]*(len(geoIpData)+len(geoIpDataDestination)) flowsData[::2] = geoIpData flowsData[1::2] = geoIpDataDestination qpylib.log('final DATA : ' + json.dumps(flowsData, indent = 2)) #data = geoIpData + geoIpDataDestination #qpylib.log('final DATA : ' + json.dumps(data, indent = 2)) ''' ''' for x in flowData['flows']: sourceIP = {} qpylib.log('inside flowdata loop') #sourceIP['ipAddr'] = flowData['flows']['sourceip'] sourceIP['ipAddr'] = x['sourceip'] #flowDataJson = json.loads(flowData) #qpylib.log(flowDataJson) #sourceIP[ipAddr] = flowDataJson['sourceip'] qpylib.log('source ip: ' + json.dumps(x['sourceip'])) #qpylib.log('source ip ipadd ' + json.dumps(sourceIP['ipAddr'])) geoIpData.append(sourceIP) qpylib.log('geoIpData : ' + json.dumps(geoIpData, indent=2)) for y in geoIpData: ipaddr = y['ipAddr'] qpylib.log('inside flowdata loop y') # write function where you request response from new freegeoip api # eg. locationData = return of getLocationData(ipaddr) #y['locationData'] = locationData locationData = getLocationData(ipaddr) qpylib.log('getLocationData result: ' + json.dumps(locationData,indent=2)) y['sourceLocationData'] = locationData qpylib.log('final geoIpData : ' + json.dumps(geoIpData, indent = 2)) for a in flowData['flows']: qpylib.log('inside flowdata loop dest') destinationIP = {} destinationIP['ipAddrDest'] = a['destinationip'] qpylib.log('destination ip: ' + json.dumps(a['destinationip'])) geoIpDataDestination.append(destinationIP) qpylib.log('geoIpDataDestination : ' + json.dumps(geoIpData, indent=2)) for b in geoIpDataDestination: ipaddrdest = b['ipAddrDest'] qpylib.log('inside flowdata loop dest b') locationDataDest = getLocationDataDest(ipaddrdest) qpylib.log('getLocationDataDest result: ' + json.dumps(locationDataDest,indent=2)) b['destinationLocationData'] = locationDataDest qpylib.log('final geoIpDataDestination : ' + json.dumps(geoIpDataDestination, indent = 2)) #data = geoIpData + geoIpDataDestination #qpylib.log('final DATA : ' + json.dumps(data, indent = 2)) ''' return render_template("map.html", data=json.dumps(geoIpData), base_url=qpylib.get_app_base_url()) #return render_template("map.html", data=json.dumps(data), base_url=qpylib.get_app_base_url()) except Exception as e: qpylib.log( "Error ---- " + str(e), level='error' )