Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added function to download all JSON reports #2

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 80 additions & 6 deletions python/detectify-2.7.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
from base64 import b64encode, b64decode
import sys
import time
import json
from os import walk

# Detectify public API endpoint, no trailing slash
# Python 2.7
Expand Down Expand Up @@ -93,34 +95,104 @@ def get_domains(api_key, secret_key):
path = "/domains/"
req = request(api_key, secret_key, path, 'GET')
if req != None:
print eval(req.text)
print json.loads(req.text)

def get_domain_profiles(api_key, secret_key, domain_token):
path = "/profiles/"+domain_token+"/"
req = request(api_key, secret_key, path, 'GET')
if req != None:
print eval(req.text)
print json.loads(req.text)

def get_all_profiles(api_key, secret_key):
path = "/profiles/"
req = request(api_key, secret_key, path, 'GET')
if req != None:
return eval(req.text)
return json.loads(req.text)

def profiles_scan_status(api_key, secret_key):
profiles = get_all_profiles(api_key, secret_key);
profiles = get_all_profiles(api_key, secret_key)
if profiles != None:
for scan in profiles:
#print i["token"]
scan_status(scan["token"], api_key, "")
scan_status(scan["token"], api_key, secret_key)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch


def get_scan_reports(api_key, secret_key, profile):
path = "/reports/"+profile+"/"
req = request(api_key, secret_key, path, 'GET')
if req != None:
return json.loads(req.text)

def get_findings_report(api_key, secret_key, profile, report):
path = "/fullreports/"+ profile +"/"+report+"/"
req = request(api_key, secret_key, path, 'GET')
if req != None:
return json.loads(req.text)

def profiles_findings(api_key, secret_key):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you possibly add some comments and/or update function name to be more accurate on what it does?

#We get all scan profiles
profiles = get_all_profiles(api_key, secret_key)
reports = []
all_reports = {}

#We get all the reports of all profiles, and
#construct a dict with that info
for profile in profiles:
#reports on profile
reports = get_scan_reports(api_key, secret_key, profile["token"])
all_reports[profile["endpoint"]] = {"token": profile["token"], "reports": list([x["token"] for x in reports])}

total = 0
for i in all_reports.keys():
total += len(all_reports[i]["reports"])

#Gets the files already downloaded to skip them
report_files = []
for (dirpath, dirnames, filenames) in walk("."):
report_files.extend(filenames)
report_files = [files for files in report_files if ".json" in files]
break

#Deletes the reports already downloaded from the download list
for files in report_files:
scan, report = (files.split(".json")[0]).split("_")
if scan in all_reports.keys():
if report in all_reports[scan]["reports"]:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would recommend to make sure the report was completed when last downloaded, incomplete reports should be replaced. You can use the stopped timestamp to check if the report is complete.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was checking now on this, and when downloading the reports, I was expecting that they were already finished before being stored as report; in the case of using the stopped timestamp, that value is represented as empty?

Also, at that point of the code I am working with only the filenames, not the full report data, so this check should be done at #L141 or #L142 when I am going through the reports. Will check on that.

all_reports[scan]["reports"].remove(report)
else:
print "Report %s not in profile %s" % (report, scan)
else:
print "Profile not in list"

to_download = 0
for i in all_reports.keys():
to_download += len(all_reports[i]["reports"])
print "To download "+str(to_download)+"/"+str(total)

total = to_download
to_download = 0

#Downloads one by one the reports and saves them to disk
for profile in all_reports.keys():
for report in all_reports[profile]["reports"]:
to_download+=1
filename = profile+"_"+report+".json"
print "Downloading "+str(to_download)+"/"+str(total)
file = open(filename,"w")
file.write(json.dumps(get_findings_report(api_key, secret_key, all_reports[profile]["token"], report)))
file.close()

print "[DONE] All reports downloaded"




secretKey = 'SGVsbG8sIHdvcmxkISBJIGFtIGEgdGVhcG90IQ=='
scanProfile = ''
apiKey = ''
domainToken = ''



#ALL TESTS
#API token needs to have the privileges to do the tasks

Expand All @@ -138,4 +210,6 @@ def profiles_scan_status(api_key, secret_key):
get_domain_profiles(apiKey, secretKey, domainToken)
print "[TEST] Get Profiles Scan Status"
#profile_scans_status includes the test of get_all_profiles and scan_status functions
profiles_scan_status(apiKey, secretKey)
#profiles_scan_status(apiKey, secretKey)
#Gets all the reports of all scans and saves to JSON
#profiles_findings(apiKey, secretKey)