Fix Tenable stack tracing, no cmd line arguments
This commit is contained in:
Родитель
d3af479a49
Коммит
3d38973214
32
Makefile
32
Makefile
|
@ -13,38 +13,6 @@ build: Dockerfile docker-compose.yml
|
||||||
force-build: Dockerfile docker-compose.yml
|
force-build: Dockerfile docker-compose.yml
|
||||||
docker-compose build --no-cache vautomator
|
docker-compose build --no-cache vautomator
|
||||||
|
|
||||||
.PHONY: fullscan
|
|
||||||
fullscan:
|
|
||||||
docker run -v ${PWD}/results:/app/results -it vautomator:latest ./run.py -a $(TARGET)
|
|
||||||
|
|
||||||
.PHONY: portscan
|
|
||||||
portscan:
|
|
||||||
docker run -v ${PWD}/results:/app/results -it vautomator:latest ./run.py -p $(TARGET)
|
|
||||||
|
|
||||||
.PHONY: nessusscan
|
|
||||||
nessusscan:
|
|
||||||
docker run -v ${PWD}/results:/app/results -it vautomator:latest ./run.py -n $(TARGET)
|
|
||||||
|
|
||||||
.PHONY: observatory
|
|
||||||
observatory:
|
|
||||||
docker run -v ${PWD}/results:/app/results -it vautomator:latest ./run.py -o $(TARGET)
|
|
||||||
|
|
||||||
.PHONY: tlsobs
|
|
||||||
tlsobs:
|
|
||||||
docker run -v ${PWD}/results:/app/results -it vautomator:latest ./run.py -t $(TARGET)
|
|
||||||
|
|
||||||
.PHONY: sshscan
|
|
||||||
sshscan:
|
|
||||||
docker run -v ${PWD}/results:/app/results -it vautomator:latest ./run.py -s $(TARGET)
|
|
||||||
|
|
||||||
.PHONY: direnum
|
|
||||||
direnum:
|
|
||||||
docker run -v ${PWD}/results:/app/results -it vautomator:latest ./run.py -d $(TARGET)
|
|
||||||
|
|
||||||
.PHONY: websearch
|
|
||||||
websearch:
|
|
||||||
docker run -v ${PWD}/results:/app/results -it vautomator:latest ./run.py -w $(TARGET)
|
|
||||||
|
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
test:
|
test:
|
||||||
python -m pytest tests/
|
python -m pytest tests/
|
||||||
|
|
|
@ -220,7 +220,7 @@ class NmapTask(Task):
|
||||||
|
|
||||||
if results:
|
if results:
|
||||||
try:
|
try:
|
||||||
nmap_output = open("/app/results/" + self.tasktarget.targetdomain + "/" + "nmap_tcp.json", "w+")
|
nmap_output = open("/app/results/" + self.tasktarget.targetdomain + "/" + "nmap.json", "w+")
|
||||||
nmap_output.write(json.dumps(results, indent=4, sort_keys=True))
|
nmap_output.write(json.dumps(results, indent=4, sort_keys=True))
|
||||||
return True
|
return True
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|
185
run.py
185
run.py
|
@ -20,153 +20,43 @@ coloredlogs.install(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def parseCmdArgs():
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(usage='run.py [options] target',
|
|
||||||
description="Sequentially run a number of\
|
|
||||||
tasks to perform a vulnerability assessment on a target.")
|
|
||||||
# Note: These two are not implemented yet
|
|
||||||
argument_group = parser.add_mutually_exclusive_group()
|
|
||||||
argument_group.add_argument('-v', '--verbose',
|
|
||||||
action='store_true',
|
|
||||||
help="increase tool verbosity",
|
|
||||||
default=False)
|
|
||||||
argument_group.add_argument('-q', '--quiet',
|
|
||||||
action='store_true',
|
|
||||||
help="quiet run, show almost no output",
|
|
||||||
default=False)
|
|
||||||
|
|
||||||
# target is a positional argument, must be specified
|
|
||||||
parser.add_argument('target',
|
|
||||||
help="host to scan - this could be an IP address, FQDN or a hostname")
|
|
||||||
parser.add_argument('-a',
|
|
||||||
dest='all',
|
|
||||||
action='store_true',
|
|
||||||
help="Run ALL tasks on the target",
|
|
||||||
default=False)
|
|
||||||
parser.add_argument('-p',
|
|
||||||
dest='port_scan',
|
|
||||||
action='store_true',
|
|
||||||
help="Run a port scan (nmap) on the target",
|
|
||||||
default=False)
|
|
||||||
parser.add_argument('-o',
|
|
||||||
dest='httpobs_scan',
|
|
||||||
action='store_true',
|
|
||||||
help="Run HTTP Observatory scan on the target",
|
|
||||||
default=False)
|
|
||||||
parser.add_argument('-t',
|
|
||||||
dest='tlsobs_scan',
|
|
||||||
action='store_true',
|
|
||||||
help="Run TLS Observatory scan on the target",
|
|
||||||
default=False)
|
|
||||||
parser.add_argument('-s',
|
|
||||||
dest='ssh_scan',
|
|
||||||
action='store_true',
|
|
||||||
help="Run ssh_scan on the target",
|
|
||||||
default=False)
|
|
||||||
parser.add_argument('-d',
|
|
||||||
dest='direnum_scan',
|
|
||||||
action='store_true',
|
|
||||||
help="Run directory enumeration scan on the target",
|
|
||||||
default=False)
|
|
||||||
parser.add_argument('-n',
|
|
||||||
dest='nessus_scan',
|
|
||||||
action='store_true',
|
|
||||||
help="Run Tenable.io (Nessus) scan on the target",
|
|
||||||
default=False)
|
|
||||||
parser.add_argument('-w',
|
|
||||||
dest='web_search',
|
|
||||||
action='store_true',
|
|
||||||
help="Search for this target on the web for interesting content",
|
|
||||||
default=False)
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
|
||||||
return args
|
|
||||||
|
|
||||||
|
|
||||||
def setupVA(va_target, arguments):
|
def setupVA(va_target, arguments):
|
||||||
|
|
||||||
if arguments.all:
|
|
||||||
# No smart logic, just add & run all tasks
|
|
||||||
va_target.addTask(task.NessusTask(va_target))
|
|
||||||
va_target.addTask(task.NmapTask(va_target))
|
|
||||||
va_target.addTask(task.SSHScanTask(va_target))
|
|
||||||
va_target.addTask(task.MozillaHTTPObservatoryTask(va_target))
|
|
||||||
va_target.addTask(task.MozillaTLSObservatoryTask(va_target))
|
|
||||||
va_target.addTask(task.WebSearchTask(va_target))
|
|
||||||
va_target.addTask(task.DirectoryBruteTask(va_target, tool="dirb"))
|
|
||||||
|
|
||||||
return va_target
|
|
||||||
|
|
||||||
# Regardless of the type of target, we will run:
|
# Regardless of the type of target, we will run:
|
||||||
# 1. Nessus scan
|
# 1. Nessus scan
|
||||||
# 2. Nmap scan
|
# 2. Nmap scan
|
||||||
# Also kicking of Nessus scan as the first task as it takes time
|
# Also kicking of Nessus scan as the first task as it takes time
|
||||||
# Note: Passed flags can override these
|
va_target.addTask(task.NessusTask(va_target))
|
||||||
if arguments.port_scan:
|
va_target.addTask(task.NmapTask(va_target))
|
||||||
va_target.addTask(task.NmapTask(va_target))
|
|
||||||
va_target.resultsdict.update({'nmap': False})
|
|
||||||
if arguments.nessus_scan:
|
|
||||||
va_target.addTask(task.NessusTask(va_target))
|
|
||||||
va_target.resultsdict.update({'nessus': False})
|
|
||||||
if arguments.ssh_scan:
|
|
||||||
va_target.addTask(task.SSHScanTask(va_target))
|
|
||||||
va_target.resultsdict.update({'sshscan': False})
|
|
||||||
if arguments.web_search:
|
|
||||||
va_target.addTask(task.WebSearchTask(va_target))
|
|
||||||
va_target.resultsdict.update({'websearch': False})
|
|
||||||
|
|
||||||
if "URL" in va_target.getType():
|
if "URL" in va_target.getType():
|
||||||
# We have a URL, means HTTP Obs, TLS Obs,
|
# We have a URL, means HTTP Obs, TLS Obs,
|
||||||
# and directory brute scans are a go
|
# and directory brute scans are a go
|
||||||
# Note: Passed flags can override these
|
|
||||||
if va_target.getType() == "FQDN|URL":
|
if va_target.getType() == "FQDN|URL":
|
||||||
# We can run all tools/tasks
|
# We can run all tools/tasks
|
||||||
if arguments.httpobs_scan:
|
va_target.addTask(task.MozillaHTTPObservatoryTask(va_target))
|
||||||
va_target.addTask(task.MozillaHTTPObservatoryTask(va_target))
|
va_target.addTask(task.MozillaTLSObservatoryTask(va_target))
|
||||||
va_target.resultsdict.update({'httpobs': False})
|
va_target.addTask(task.DirectoryBruteTask(va_target, tool="dirb"))
|
||||||
if arguments.tlsobs_scan:
|
va_target.addTask(task.WebSearchTask(va_target))
|
||||||
va_target.addTask(task.MozillaTLSObservatoryTask(va_target))
|
|
||||||
va_target.resultsdict.update({'tlsobs': False})
|
|
||||||
if arguments.direnum_scan:
|
|
||||||
va_target.addTask(task.DirectoryBruteTask(va_target, tool="dirb"))
|
|
||||||
va_target.resultsdict.update({'dirbrute': False})
|
|
||||||
if arguments.web_search:
|
|
||||||
va_target.addTask(task.WebSearchTask(va_target))
|
|
||||||
va_target.resultsdict.update({'websearch': False})
|
|
||||||
else:
|
else:
|
||||||
if arguments.tlsobs_scan:
|
va_target.addTask(task.MozillaTLSObservatoryTask(va_target))
|
||||||
va_target.addTask(task.MozillaTLSObservatoryTask(va_target))
|
va_target.addTask(task.DirectoryBruteTask(va_target, tool="dirb"))
|
||||||
va_target.resultsdict.update({'tlsobs': False})
|
|
||||||
if arguments.direnum_scan:
|
|
||||||
va_target.addTask(task.DirectoryBruteTask(va_target, tool="dirb"))
|
|
||||||
va_target.resultsdict.update({'dirbrute': False})
|
|
||||||
# HTTP Observatory does not like IPs as a target, skipping
|
# HTTP Observatory does not like IPs as a target, skipping
|
||||||
va_target.resultsdict.update({"httpobs": "PASS"})
|
va_target.resultsdict.update({"httpobs": "PASS"})
|
||||||
# Also skipping web search for the IP address targets
|
# Also skipping web search for the IP address targets
|
||||||
va_target.resultsdict.update({"websearch": "PASS"})
|
va_target.resultsdict.update({"websearch": "PASS"})
|
||||||
elif va_target.getType() == "IPv4":
|
elif va_target.getType() == "IPv4":
|
||||||
if arguments.tlsobs_scan:
|
va_target.addTask(task.MozillaTLSObservatoryTask(va_target))
|
||||||
va_target.addTask(task.MozillaTLSObservatoryTask(va_target))
|
va_target.addTask(task.DirectoryBruteTask(va_target, tool="dirb"))
|
||||||
va_target.resultsdict.update({'tlsobs': False})
|
|
||||||
if arguments.direnum_scan:
|
|
||||||
va_target.addTask(task.DirectoryBruteTask(va_target, tool="dirb"))
|
|
||||||
va_target.resultsdict.update({'dirbrute': False})
|
|
||||||
# Again, HTTP Observatory does not like IPs as a target, skipping
|
# Again, HTTP Observatory does not like IPs as a target, skipping
|
||||||
|
va_target.resultsdict.update({"httpobs": "PASS"})
|
||||||
|
va_target.resultsdict.update({"websearch": "PASS"})
|
||||||
else:
|
else:
|
||||||
# FQDN, we can run all tools/tasks
|
# FQDN, we can run all tools/tasks
|
||||||
if arguments.httpobs_scan:
|
va_target.addTask(task.MozillaHTTPObservatoryTask(va_target))
|
||||||
va_target.addTask(task.MozillaHTTPObservatoryTask(va_target))
|
va_target.addTask(task.MozillaTLSObservatoryTask(va_target))
|
||||||
va_target.resultsdict.update({'httpobs': False})
|
va_target.addTask(task.DirectoryBruteTask(va_target, tool="dirb"))
|
||||||
if arguments.tlsobs_scan:
|
va_target.addTask(task.WebSearchTask(va_target))
|
||||||
va_target.addTask(task.MozillaTLSObservatoryTask(va_target))
|
|
||||||
va_target.resultsdict.update({'tlsobs': False})
|
|
||||||
if arguments.direnum_scan:
|
|
||||||
va_target.addTask(task.DirectoryBruteTask(va_target, tool="dirb"))
|
|
||||||
va_target.resultsdict.update({'dirbrute': False})
|
|
||||||
if arguments.web_search:
|
|
||||||
va_target.addTask(task.WebSearchTask(va_target))
|
|
||||||
va_target.resultsdict.update({'websearch': False})
|
|
||||||
|
|
||||||
return va_target
|
return va_target
|
||||||
|
|
||||||
|
@ -178,8 +68,8 @@ def showScanSummary(result_dictionary):
|
||||||
print("\n====== SCAN SUMMARY ======")
|
print("\n====== SCAN SUMMARY ======")
|
||||||
for one_task, status in result_dictionary.items():
|
for one_task, status in result_dictionary.items():
|
||||||
if status:
|
if status:
|
||||||
if status == "NA":
|
if status == "PASS":
|
||||||
logger.warning("[!] [ :| ] " + one_task + " scan skipped as not specified.")
|
logger.warning("[!] [ :| ] " + one_task + " scan skipped as not applicable to the target.")
|
||||||
elif status == "TIMEOUT":
|
elif status == "TIMEOUT":
|
||||||
logger.warning("[!] [ :| ] " + one_task + " timed out and was killed! Run manually if you like.")
|
logger.warning("[!] [ :| ] " + one_task + " timed out and was killed! Run manually if you like.")
|
||||||
else:
|
else:
|
||||||
|
@ -190,19 +80,18 @@ def showScanSummary(result_dictionary):
|
||||||
print("====== END OF SCAN =======\n")
|
print("====== END OF SCAN =======\n")
|
||||||
|
|
||||||
|
|
||||||
def runVA(scan_with_tasks, outpath, compress_results):
|
def runVA(scan_with_tasks, outpath):
|
||||||
logger.info("[+] Running the scans now. This may take a while...")
|
logger.info("[+] Running all the scans now. This may take a while...")
|
||||||
results = scan_with_tasks.runTasks()
|
results = scan_with_tasks.runTasks()
|
||||||
# results here is a dict
|
# results here is a dict
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
# Return code check is a bit hacky,
|
# Return code check is a bit hacky,
|
||||||
# basically we are ignoring warnings from tar
|
# basically we are ignoring warnings from tar
|
||||||
|
|
||||||
if compress_results:
|
if utils.package_results(outpath).returncode is not 127:
|
||||||
if utils.package_results(outpath).returncode is not 127:
|
logger.info("[+] All done. Tool output from the scan can be found at " + outpath)
|
||||||
logger.info("[+] All done. Tool output from the scan can be found at " + outpath)
|
else:
|
||||||
else:
|
logger.warning("[!] There was a problem compressing tool output. Check " + outpath + " manually.")
|
||||||
logger.warning("[!] There was a problem compressing tool output. Check " + outpath + " manually.")
|
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
showScanSummary(results)
|
showScanSummary(results)
|
||||||
|
|
||||||
|
@ -210,17 +99,15 @@ def runVA(scan_with_tasks, outpath, compress_results):
|
||||||
def main():
|
def main():
|
||||||
|
|
||||||
scan_success = {
|
scan_success = {
|
||||||
'nmap': "NA",
|
'nmap': False,
|
||||||
'nessus': "NA",
|
'nessus': False,
|
||||||
'tlsobs': "NA",
|
'tlsobs': False,
|
||||||
'httpobs': "NA",
|
'httpobs': False,
|
||||||
'sshscan': "NA",
|
'sshscan': False,
|
||||||
'websearch': 'NA',
|
'websearch': False,
|
||||||
'dirbrute': "NA"
|
'dirbrute': False
|
||||||
}
|
}
|
||||||
compress_results = True
|
destination = sys.argv[1]
|
||||||
tool_arguments = parseCmdArgs()
|
|
||||||
destination = tool_arguments.target
|
|
||||||
output_path = "/app/results/" + destination + "/"
|
output_path = "/app/results/" + destination + "/"
|
||||||
va_target = target.Target(destination, scan_success)
|
va_target = target.Target(destination, scan_success)
|
||||||
|
|
||||||
|
@ -238,12 +125,10 @@ def main():
|
||||||
os.stat(output_path)
|
os.stat(output_path)
|
||||||
except Exception:
|
except Exception:
|
||||||
os.mkdir(output_path)
|
os.mkdir(output_path)
|
||||||
|
|
||||||
va_scan = setupVA(va_target, tool_arguments)
|
|
||||||
if not tool_arguments.all:
|
|
||||||
compress_results = False
|
|
||||||
runVA(va_scan, output_path, compress_results)
|
|
||||||
|
|
||||||
|
va_scan = setupVA(va_target)
|
||||||
|
runVA(va_scan, output_path)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
Загрузка…
Ссылка в новой задаче