From 117c1ec9bee03b6f5d55253854b9e13f1eb66f2c Mon Sep 17 00:00:00 2001 From: David Sackmary Date: Sun, 28 Dec 2014 09:39:27 -0800 Subject: [PATCH 1/9] Create fim_hashes_to_virustotal.py This program outputs the hashes from the baseline and stores it in a file. I then hand-edit the output so that I have a file with only the hashes. (something to clean up when I'm smarter...) I then run 'uirusu.rb' which tests the hashes against VirusTotal. --- fim_hashes_to_virustotal.py | 70 +++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 fim_hashes_to_virustotal.py diff --git a/fim_hashes_to_virustotal.py b/fim_hashes_to_virustotal.py new file mode 100644 index 0000000..31116c6 --- /dev/null +++ b/fim_hashes_to_virustotal.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python2.7 +# +# take hash from baseline and send to virustotal +# input - baseline scan from Halo +# output - results from VirusTotal.com +# David Sackmary +# Tim Spencer (authored apiget.py, included here) +# +clientid = '173268a5' +clientsecret = '7444180d91b9b59000e429e57357a816' +host = 'api.cloudpassage.com' + +import urllib +import httplib +import base64 +import json + +# Get the access token used for the API calls. +connection = httplib.HTTPSConnection(host) +authstring = "Basic " + base64.b64encode(clientid + ":" + clientsecret) +header = {"Authorization": authstring} +params = urllib.urlencode({'grant_type': 'client_credentials'}) +connection.request("POST", '/oauth/access_token', params, header) +response = connection.getresponse() +jsondata = response.read().decode() +data = json.loads(jsondata) +key = data['access_token'] + +# Do the real request using the access token in the headers +tokenheader = {"Authorization": 'Bearer ' + key} +connection.request("GET", "/v1/servers", '', tokenheader) +response = connection.getresponse() +jsondata = response.read().decode() +data = json.loads(jsondata) + +# print out everything in a pretty way +#print json.dumps(data, sort_keys=True, indent=4) + +# iterate through the list and print out the hostnames as an example of +# how to handle json data +#servers = data['servers'] +#for server in servers: +# print server['hostname'] +# print server['kernel_name'] + + +# Get id for fim policy +#connection.request("GET", "/v1/fim_policies/", '', tokenheader) +#response = connection.getresponse() +#jsondata = response.read().decode() +#data = json.loads(jsondata) +#print data + +# print 'contents' for the given baseline +connection.request("GET", "/v1/fim_policies/be64cab06fdf0132a4ba3c764e10c221/baselines/cd20d5406fdf0132fe6f3c764e10c220/details", '', tokenheader) +response = connection.getresponse() +jsondata = response.read().decode() +data = json.loads(jsondata) +#print json.dumps(data, sort_keys=True, indent=4) + +#HELP - I can't parse objects or contents. not yet sure why... +contents = data['baseline']['details']['targets']#['objects']['contents'] +for content in contents: + print json.dumps(content, sort_keys=True, indent=4) + +#At this point, I have a file which can easily be grepped, and then pipe the hashes to virustotal. +#I am currently using a ruby program named 'uirusu' to interface with virustotal. I will recode +#this in python for this example. (?) + +connection.close() From a12e9e1088cedc48bb70dfe59b4ea241d4743711 Mon Sep 17 00:00:00 2001 From: David Sackmary Date: Wed, 31 Dec 2014 04:20:18 -0800 Subject: [PATCH 2/9] Update fim_hashes_to_virustotal.py add try/except to skip over null values --- fim_hashes_to_virustotal.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fim_hashes_to_virustotal.py b/fim_hashes_to_virustotal.py index 31116c6..809bed0 100644 --- a/fim_hashes_to_virustotal.py +++ b/fim_hashes_to_virustotal.py @@ -59,9 +59,12 @@ #print json.dumps(data, sort_keys=True, indent=4) #HELP - I can't parse objects or contents. not yet sure why... +try: contents = data['baseline']['details']['targets']#['objects']['contents'] for content in contents: print json.dumps(content, sort_keys=True, indent=4) +except: + pass #At this point, I have a file which can easily be grepped, and then pipe the hashes to virustotal. #I am currently using a ruby program named 'uirusu' to interface with virustotal. I will recode From 9d28e3abebeb8ae5849a2265b7b1c833c9a0854b Mon Sep 17 00:00:00 2001 From: David Sackmary Date: Fri, 2 Jan 2015 00:43:27 -0800 Subject: [PATCH 3/9] Create api.py --- api.py | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 api.py diff --git a/api.py b/api.py new file mode 100644 index 0000000..cbb66dc --- /dev/null +++ b/api.py @@ -0,0 +1,72 @@ +#!/usr/bin/python +# +# DON'T FORGET TO SET THE API KEY/SECRET. +# +# Ash's code. being used as a base for gathering FIM scans so I can upload hashes to VirusTotal. + + + +import urllib +import httplib +import base64 +import json +import urlparse +import sys + +def apihit(host,conntype,authtoken,queryurl,reqbody,prox): + retdata = '' + if (prox['host'] != '') and (prox['port'] != ''): + useproxy = True + else: + useproxy = False + + if useproxy == True: + connection = httplib.HTTPSConnection(prox['host'], prox['port']) + connection.set_tunnel(host, 443) + else: + connection = httplib.HTTPSConnection(host) + tokenheader = {"Authorization": 'Bearer ' + authtoken, "Content-type": "application/json", "Accept": "text/plain"} + if conntype == "GET": + connection.request(conntype, queryurl, '', tokenheader) + else: + connection.request(conntype, queryurl, json.dumps(reqbody), tokenheader) + response = connection.getresponse() + respbody = response.read().decode('ascii', 'ignore') + try: + jsondata = respbody.decode() + retdata = json.loads(jsondata) + except: + retdata = respbody.decode() + connection.close() + return retdata + +def get_auth_token(host,clientid,clientsecret,prox): + queryurl = '/oauth/access_token' + if (prox['host'] != '') and (prox['port'] != ''): + useproxy = True + else: + useproxy = False + if useproxy == True: + connection = httplib.HTTPSConnection(prox['host'], prox['port']) + connection.set_tunnel(host, 443) + else: + connection = httplib.HTTPSConnection(host) + authstring = "Basic " + base64.b64encode(clientid + ":" + clientsecret) + header = {"Authorization": authstring} + params = urllib.urlencode({'grant_type': 'client_credentials'}) + connection.request("POST", queryurl, params, header) + response = connection.getresponse() + jsondata = response.read().decode() + data = json.loads(jsondata) + try: + if data['scope'] != 'read': + print "You shouldn't be uing a RW key for this script. You should really be using a RO key." + except: + print "We're having trouble getting a session token. Please check your API key." + print "Error output: " + print data + sys.exit() + key = data['access_token'] + connection.close() + return key + From 560e492897a0e32389ffc609c9cc68b54e464070 Mon Sep 17 00:00:00 2001 From: David Sackmary Date: Fri, 9 Jan 2015 05:36:39 -0800 Subject: [PATCH 4/9] Update fim_hashes_to_virustotal.py --- fim_hashes_to_virustotal.py | 1 + 1 file changed, 1 insertion(+) diff --git a/fim_hashes_to_virustotal.py b/fim_hashes_to_virustotal.py index 809bed0..cf2543f 100644 --- a/fim_hashes_to_virustotal.py +++ b/fim_hashes_to_virustotal.py @@ -52,6 +52,7 @@ #print data # print 'contents' for the given baseline +# note to self.. this baseline is hardcoded. add logic here... connection.request("GET", "/v1/fim_policies/be64cab06fdf0132a4ba3c764e10c221/baselines/cd20d5406fdf0132fe6f3c764e10c220/details", '', tokenheader) response = connection.getresponse() jsondata = response.read().decode() From bad68bb7cbb1d30e74e9fbde4915db05ec00ef60 Mon Sep 17 00:00:00 2001 From: David Sackmary Date: Tue, 31 Mar 2015 14:42:41 -0700 Subject: [PATCH 5/9] move keys to a safer place --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..83274a0 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +config.conf From 39d259bea66ec61baf68a3bcbafdcc2451d8a52a Mon Sep 17 00:00:00 2001 From: David Sackmary Date: Tue, 31 Mar 2015 14:48:42 -0700 Subject: [PATCH 6/9] move API keys to a safer place Inform user where to find their API keys in the portal and keep the keys here. This file can never accidentally upload to Git because it is in the .gitignore file. --- config.conf | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 config.conf diff --git a/config.conf b/config.conf new file mode 100644 index 0000000..8b2977f --- /dev/null +++ b/config.conf @@ -0,0 +1,12 @@ +''' +Your account's Halo ID and Secret Key are findable here: https://portal.cloudpassage.com/settings/users + +Variables: +clientid: API Key ID +clientsecret: API Secret Key +host: API host +''' + +clientid = '' +clientsecret = '' +host = 'api.cloudpassage.com' From b451f15fe36ee551aae7966741b10065090b69e8 Mon Sep 17 00:00:00 2001 From: David Sackmary Date: Tue, 31 Mar 2015 14:55:22 -0700 Subject: [PATCH 7/9] move API keys to a safer place --- apiget.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/apiget.py b/apiget.py index 503ce35..7b8a952 100755 --- a/apiget.py +++ b/apiget.py @@ -6,10 +6,13 @@ # This should be a lot simpler than it is, but none of the oath2 # modules seem to work well, so we do it by hand here. # -clientid = 'XXXXXXXX' -clientsecret = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' -host = 'api.cloudpassage.com' +# This information is findable at https://portal.cloudpassage.com/settings/users +config ={} +execfile("config.conf",config) +clientid = config['clientid'] #these must be defined in config.conf +clientsecret = config['clientsecret'] #these must be defined in config.conf +host = config['host'] import urllib import httplib From dbb97660eac1b89dc08132cc83da8df2f3fb80d0 Mon Sep 17 00:00:00 2001 From: David Sackmary Date: Wed, 1 Apr 2015 11:38:34 -0700 Subject: [PATCH 8/9] Delete api.py move to my WAM git.. --- api.py | 72 ---------------------------------------------------------- 1 file changed, 72 deletions(-) delete mode 100644 api.py diff --git a/api.py b/api.py deleted file mode 100644 index cbb66dc..0000000 --- a/api.py +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/python -# -# DON'T FORGET TO SET THE API KEY/SECRET. -# -# Ash's code. being used as a base for gathering FIM scans so I can upload hashes to VirusTotal. - - - -import urllib -import httplib -import base64 -import json -import urlparse -import sys - -def apihit(host,conntype,authtoken,queryurl,reqbody,prox): - retdata = '' - if (prox['host'] != '') and (prox['port'] != ''): - useproxy = True - else: - useproxy = False - - if useproxy == True: - connection = httplib.HTTPSConnection(prox['host'], prox['port']) - connection.set_tunnel(host, 443) - else: - connection = httplib.HTTPSConnection(host) - tokenheader = {"Authorization": 'Bearer ' + authtoken, "Content-type": "application/json", "Accept": "text/plain"} - if conntype == "GET": - connection.request(conntype, queryurl, '', tokenheader) - else: - connection.request(conntype, queryurl, json.dumps(reqbody), tokenheader) - response = connection.getresponse() - respbody = response.read().decode('ascii', 'ignore') - try: - jsondata = respbody.decode() - retdata = json.loads(jsondata) - except: - retdata = respbody.decode() - connection.close() - return retdata - -def get_auth_token(host,clientid,clientsecret,prox): - queryurl = '/oauth/access_token' - if (prox['host'] != '') and (prox['port'] != ''): - useproxy = True - else: - useproxy = False - if useproxy == True: - connection = httplib.HTTPSConnection(prox['host'], prox['port']) - connection.set_tunnel(host, 443) - else: - connection = httplib.HTTPSConnection(host) - authstring = "Basic " + base64.b64encode(clientid + ":" + clientsecret) - header = {"Authorization": authstring} - params = urllib.urlencode({'grant_type': 'client_credentials'}) - connection.request("POST", queryurl, params, header) - response = connection.getresponse() - jsondata = response.read().decode() - data = json.loads(jsondata) - try: - if data['scope'] != 'read': - print "You shouldn't be uing a RW key for this script. You should really be using a RO key." - except: - print "We're having trouble getting a session token. Please check your API key." - print "Error output: " - print data - sys.exit() - key = data['access_token'] - connection.close() - return key - From 539c6b45ebe6db8198dfd7f6fbfbb8e772d5187f Mon Sep 17 00:00:00 2001 From: David Sackmary Date: Wed, 1 Apr 2015 11:38:52 -0700 Subject: [PATCH 9/9] Delete fim_hashes_to_virustotal.py move to my WAM git --- fim_hashes_to_virustotal.py | 74 ------------------------------------- 1 file changed, 74 deletions(-) delete mode 100644 fim_hashes_to_virustotal.py diff --git a/fim_hashes_to_virustotal.py b/fim_hashes_to_virustotal.py deleted file mode 100644 index cf2543f..0000000 --- a/fim_hashes_to_virustotal.py +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/env python2.7 -# -# take hash from baseline and send to virustotal -# input - baseline scan from Halo -# output - results from VirusTotal.com -# David Sackmary -# Tim Spencer (authored apiget.py, included here) -# -clientid = '173268a5' -clientsecret = '7444180d91b9b59000e429e57357a816' -host = 'api.cloudpassage.com' - -import urllib -import httplib -import base64 -import json - -# Get the access token used for the API calls. -connection = httplib.HTTPSConnection(host) -authstring = "Basic " + base64.b64encode(clientid + ":" + clientsecret) -header = {"Authorization": authstring} -params = urllib.urlencode({'grant_type': 'client_credentials'}) -connection.request("POST", '/oauth/access_token', params, header) -response = connection.getresponse() -jsondata = response.read().decode() -data = json.loads(jsondata) -key = data['access_token'] - -# Do the real request using the access token in the headers -tokenheader = {"Authorization": 'Bearer ' + key} -connection.request("GET", "/v1/servers", '', tokenheader) -response = connection.getresponse() -jsondata = response.read().decode() -data = json.loads(jsondata) - -# print out everything in a pretty way -#print json.dumps(data, sort_keys=True, indent=4) - -# iterate through the list and print out the hostnames as an example of -# how to handle json data -#servers = data['servers'] -#for server in servers: -# print server['hostname'] -# print server['kernel_name'] - - -# Get id for fim policy -#connection.request("GET", "/v1/fim_policies/", '', tokenheader) -#response = connection.getresponse() -#jsondata = response.read().decode() -#data = json.loads(jsondata) -#print data - -# print 'contents' for the given baseline -# note to self.. this baseline is hardcoded. add logic here... -connection.request("GET", "/v1/fim_policies/be64cab06fdf0132a4ba3c764e10c221/baselines/cd20d5406fdf0132fe6f3c764e10c220/details", '', tokenheader) -response = connection.getresponse() -jsondata = response.read().decode() -data = json.loads(jsondata) -#print json.dumps(data, sort_keys=True, indent=4) - -#HELP - I can't parse objects or contents. not yet sure why... -try: -contents = data['baseline']['details']['targets']#['objects']['contents'] -for content in contents: - print json.dumps(content, sort_keys=True, indent=4) -except: - pass - -#At this point, I have a file which can easily be grepped, and then pipe the hashes to virustotal. -#I am currently using a ruby program named 'uirusu' to interface with virustotal. I will recode -#this in python for this example. (?) - -connection.close()