From d3663421a76fe2cae511bdcb4c59efb2723d4407 Mon Sep 17 00:00:00 2001 From: mahajanhrishikesh Date: Mon, 21 Nov 2022 18:00:14 -0500 Subject: [PATCH 1/3] Removed the local import issue --- Reconnoitre/reconnoitre.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Reconnoitre/reconnoitre.py b/Reconnoitre/reconnoitre.py index 6d3d6df..f825886 100644 --- a/Reconnoitre/reconnoitre.py +++ b/Reconnoitre/reconnoitre.py @@ -4,14 +4,13 @@ import signal import sys -from .lib.core.input import CliArgumentParser -from .lib.find_dns import find_dns -from .lib.hostname_scan import hostname_scan -from .lib.ping_sweeper import ping_sweeper -from .lib.service_scan import service_scan -from .lib.snmp_walk import snmp_walk -from .lib.virtual_host_scanner import VirtualHostScanner - +from lib.core.input import CliArgumentParser +from lib.find_dns import find_dns +from lib.hostname_scan import hostname_scan +from lib.ping_sweeper import ping_sweeper +from lib.service_scan import service_scan +from lib.snmp_walk import snmp_walk +from lib.virtual_host_scanner import VirtualHostScanner def print_banner(): print(" __") From 7e226557e56d83ada3ba4480bd35b3919d5ea2ed Mon Sep 17 00:00:00 2001 From: mahajanhrishikesh Date: Tue, 22 Nov 2022 19:53:29 -0500 Subject: [PATCH 2/3] Re-added the dots in reco main file --- .DS_Store | Bin 0 -> 6148 bytes Reconnoitre/reconnoitre.py | 14 +++++++------- 2 files changed, 7 insertions(+), 7 deletions(-) create mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..c092f7b7a2c50d043442ea939caafd3894ff3422 GIT binary patch literal 6148 zcmeHKJxc>Y5S=yA1XGy8LJQ$4OCkT@3>R$0*w|@4NQA@-Ch6}d*eDhj)`HlHh=qj+ z{sDiFZ+6#YHbO-QDicu=jWNHBZjP~^Tgn#f%qmdv z8of@X-i-T$RHRIZ0;0fQRDj>zJZ({jj%nn*zlG?^_4VT@YV_g;=878!?@yN(FWbJq z^`(E%b-oS7Go(`Cb6@Jxm>S;hlzU4@xE!8$t{*LjnRWW{lu34!$A<#uvqVQU#MPz| z4ShDX{aL@u<>7w9#aqK=k`?3g*kv9i+5?9s#dLxz<|jj^)b<(O++|0)+%|6~+%nd6 zS$-ew@l_%7T?D^2bW5qWvhI6bUgxh9UQWKtWqyRWzj%|VBLFauX>AzuS%Px{i=oBDAUrT-Qh_E_*&~KB>6i~}Txc;d zXwpg9!-ujvD|%8aEK1w?_V0y#4*bN#PnpZ})`G7<$ufq$of%18C6 zirccaHFbkrYXh`HG&YV)4C)kgwjApLm*O=vZSVy=0EQM5gP4KIkARjzI#J+P75D(z CowSMo literal 0 HcmV?d00001 diff --git a/Reconnoitre/reconnoitre.py b/Reconnoitre/reconnoitre.py index f825886..ccfd8d1 100644 --- a/Reconnoitre/reconnoitre.py +++ b/Reconnoitre/reconnoitre.py @@ -4,13 +4,13 @@ import signal import sys -from lib.core.input import CliArgumentParser -from lib.find_dns import find_dns -from lib.hostname_scan import hostname_scan -from lib.ping_sweeper import ping_sweeper -from lib.service_scan import service_scan -from lib.snmp_walk import snmp_walk -from lib.virtual_host_scanner import VirtualHostScanner +from .lib.core.input import CliArgumentParser +from .lib.find_dns import find_dns +from .lib.hostname_scan import hostname_scan +from .lib.ping_sweeper import ping_sweeper +from .lib.service_scan import service_scan +from .lib.snmp_walk import snmp_walk +from .lib.virtual_host_scanner import VirtualHostScanner def print_banner(): print(" __") From 08b726ece52cfa726b422f821d9abec2a23ec154 Mon Sep 17 00:00:00 2001 From: mahajanhrishikesh Date: Sun, 11 Dec 2022 11:32:53 -0500 Subject: [PATCH 3/3] Refactored and Tested --- Reconnoitre/lib/.DS_Store | Bin 0 -> 6148 bytes Reconnoitre/lib/file_helper.py | 169 ------------------ Reconnoitre/lib/find_dns.py | 109 ++++++------ Reconnoitre/lib/hostname_scan.py | 73 ++++---- Reconnoitre/lib/ping_sweeper.py | 62 +++---- Reconnoitre/lib/service_scan.py | 252 ++++++++++----------------- Reconnoitre/lib/snmp_walk.py | 113 ++++++------ Reconnoitre/lib/subprocess_helper.py | 8 - Reconnoitre/lib/utility.py | 188 ++++++++++++++++++++ Reconnoitre/reconnoitre.py | 30 ++-- 10 files changed, 479 insertions(+), 525 deletions(-) create mode 100644 Reconnoitre/lib/.DS_Store delete mode 100644 Reconnoitre/lib/file_helper.py delete mode 100644 Reconnoitre/lib/subprocess_helper.py create mode 100644 Reconnoitre/lib/utility.py diff --git a/Reconnoitre/lib/.DS_Store b/Reconnoitre/lib/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..7c4f6b8bc9bda61b68b39a8a89cd06d256f88f6c GIT binary patch literal 6148 zcmeHKu};H44E2=^L0vi`ruzVv{z0h1z}$@`rD;WnMv0IZV9F=(1qgNIBbZ=f;xqUQ zp3hdAC@m5TLX|D~-oB_j?v)n$Fkd93JuJ?CarW^LGA| z_u?1c)vBGvBPSCf&ysFw+0D>Dx7XS^y`H{*Ts?)Hn%JV;X0dC%d+rQdn-~MefH80| z44`JS#6v+FjR9l87-$&a?}LXjCW^IS_;g?hEdVfrISA(5OK^-=OcZNDtU#QE0wvUG zi{T_3cCUVkVl61)z$Txc*=4@Bh0&_GAng z0|&)`i_&R2!7FKP?Y$h=S`VE;S=g@@Y(g*zr5L_kicg?HVD~%$CW^HnED-w<2sGGW I4E!kr-`Gl0AOHXW literal 0 HcmV?d00001 diff --git a/Reconnoitre/lib/file_helper.py b/Reconnoitre/lib/file_helper.py deleted file mode 100644 index 93068d9..0000000 --- a/Reconnoitre/lib/file_helper.py +++ /dev/null @@ -1,169 +0,0 @@ -import os -import json - - -def check_directory(output_directory): - try: - os.stat(output_directory) - except Exception: - os.mkdir(output_directory) - print("[!] %s didn't exist and has been created." % output_directory) - - -def load_targets(target_hosts, output_directory, quiet): - if (os.path.isdir(target_hosts) or os.path.isfile(target_hosts)): - return target_hosts - elif "-" in target_hosts: - expand_targets(target_hosts, output_directory) - return output_directory + "/targets.txt" - else: - return output_directory + "/targets.txt" - - -def expand_targets(target_hosts, output_directory): - parts = target_hosts.split(".") - target_list = [] - for part in parts: - if "-" in part: - iprange = part.split("-") - for i in range(int(iprange[0]), int(iprange[1])): - target_list.append( - parts[0] + - "." + - parts[1] + - "." + - parts[2] + - "." + - str(i)) - with open(output_directory + "/targets.txt", "w") as targets: - for target in target_list: - targets.write("%s\n" % target) - - -def create_dir_structure(ip_address, output_directory): - print("[+] Creating directory structure for " + ip_address) - - hostdir = output_directory + "/" + ip_address - try: - os.stat(hostdir) - except Exception: - os.mkdir(hostdir) - - nmapdir = hostdir + "/scans" - print(" [>] Creating scans directory at: %s" % nmapdir) - try: - os.stat(nmapdir) - except Exception: - os.mkdir(nmapdir) - - exploitdir = hostdir + "/exploit" - print(" [>] Creating exploit directory at: %s" % exploitdir) - try: - os.stat(exploitdir) - except Exception: - os.mkdir(exploitdir) - - lootdir = hostdir + "/loot" - print(" [>] Creating loot directory at: %s" % lootdir) - try: - os.stat(lootdir) - except Exception: - os.mkdir(lootdir) - - prooffile = hostdir + "/proof.txt" - print(" [>] Creating proof file at: %s" % prooffile) - open(prooffile, 'a').close() - - -def write_recommendations(results, ip_address, outputdir): - recommendations_file = outputdir + "/" + ip_address + "_findings.txt" - serv_dict = {} - lines = results.split("\n") - for line in lines: - ports = [] - line = line.strip() - if ("tcp" in line) and ("open" in line) and not ("Discovered" in line): - while " " in line: - line = line.replace(" ", " ") - service = line.split(" ")[2] - port = line.split(" ")[0] - - if service in serv_dict: - ports = serv_dict[service] - - ports.append(port) - serv_dict[service] = ports - - print("[+] Writing findings for %s" % (ip_address)) - - __location__ = os.path.realpath( - os.path.join( - os.getcwd(), - os.path.dirname(__file__))) - with open(os.path.join(__location__, "config.json"), "r") as config: - c = config.read() - j = json.loads( - c.replace( - "$ip", - "%(ip)s").replace( - "$port", - "%(port)s").replace( - "$outputdir", - "%(outputdir)s")) - - f = open(recommendations_file, 'w') - for serv in serv_dict: - ports = serv_dict[serv] - - for service in j["services"]: - if (serv in j["services"][service] - ["nmap-service-names"]) or (service in serv): - for port in ports: - port = port.split("/")[0] - - description = ("[*] " - + j["services"][service]["description"]) - print(description % {"ip": ip_address, "port": port}) - f.write((description + "\n") % - {"ip": ip_address, "port": port}) - - for entry in j["services"][service]["output"]: - f.write(" [*] " + entry["description"] + "\n") - - for cmd in entry["commands"]: - f.write((" [=] " + cmd + "\n") % - {"ip": ip_address, - "port": port, - "outputdir": outputdir}) - - f.write("\n") - - f.write( - "\n\n[*] Always remember to manually go over the" - " portscan report and carefully read between the lines ;)") - f.close() - - -def get_config_options(key, *args): - __location__ = os.path.realpath( - os.path.join( - os.getcwd(), - os.path.dirname(__file__))) - with open(os.path.join(__location__, "config.json"), "r") as config: - c = config.read() - j = json.loads( - c.replace( - "$ip", - "%(ip)s").replace( - "$port", - "%(port)s").replace( - "$outputdir", - "%(outputdir)s")) - - res = j.get(key, None) - for arg in args: - res = res.get(arg, None) - if res is None: - raise KeyError - - return res diff --git a/Reconnoitre/lib/find_dns.py b/Reconnoitre/lib/find_dns.py index fb6ec90..15eb00a 100644 --- a/Reconnoitre/lib/find_dns.py +++ b/Reconnoitre/lib/find_dns.py @@ -1,51 +1,58 @@ -from Reconnoitre.lib.file_helper import check_directory -from Reconnoitre.lib.file_helper import load_targets -from Reconnoitre.lib.subprocess_helper import run_scan - - -def find_dns(target_hosts, output_directory, quiet): - check_directory(output_directory) - dns_server_list = [] - results = 0 - hostcount = 0 - dnscount = 0 - - output_file = open(output_directory + "/DNS-Detailed.txt", 'w') - output_targets = open(output_directory + "/DNS-targets.txt", 'w') - - targets = load_targets(target_hosts, output_directory, quiet) - target_file = open(targets, 'r') - - print("[*] Loaded targets from: %s" % targets) - print("[+] Enumerating TCP port 53 over targets to find dns servers") - - for ip_address in target_file: - hostcount += 1 - ip_address = ip_address.strip() - ip_address = ip_address.rstrip() - - print(" [>] Testing %s for DNS" % ip_address) - DNSSCAN = "nmap -n -sV -Pn -vv -p53 %s" % (ip_address) - results = run_scan(DNSSCAN) - lines = results.split("\n") - - for line in lines: - line = line.strip() - line = line.rstrip() - if (("53/tcp" in line) and ("open" in line) - and ("Discovered" not in line)): - print( - " [=] Found DNS service running on: %s" % - (ip_address)) - output_file.write( - "[*] Found DNS service running on: %s\n" % - (ip_address)) - output_file.write(" [>] %s\n" % (line)) - output_targets.write("%s\n" % (ip_address)) - dns_server_list.append(ip_address) - dnscount += 1 - print("[*] Found %s DNS servers within %s hosts" % - (str(dnscount), str(hostcount))) - output_file.close() - output_targets.close() - return '' if len(dns_server_list) == 0 else ','.join(dns_server_list) +from lib.utility import Utility + +class FindDNS: + def __init__(self, target_hosts, output_directory, quiet) -> None: + # Function args + self.target_hosts = target_hosts + self.output_directory = output_directory + self.quiet = quiet + # Algorithm setup + self.output_file = "{}/DNS-Detailed.txt".format(self.output_directory) + self.output_targets = "{}/DNS-targets.txt".format(self.output_directory) + self.dns_server_list = [] + self.results = 0 + self.hostcount = 0 + self.dnscount = 0 + + def find_dns(self): + Utility.check_directory(self.output_directory) + + output_file = open(self.output_directory + "/DNS-Detailed.txt", 'w') + output_targets = open(self.output_directory + "/DNS-targets.txt", 'w') + + targets = Utility.load_targets(self.target_hosts, self.output_directory, self.quiet) + target_file = open(targets, 'r') + + print("[*] Loaded targets from: %s" % targets) + print("[+] Enumerating TCP port 53 over targets to find dns servers") + + for ip_address in target_file: + self.hostcount += 1 + ip_address = ip_address.strip() + ip_address = ip_address.rstrip() + + print(" [>] Testing %s for DNS" % ip_address) + DNSSCAN = "nmap -n -sV -Pn -vv -p53 %s" % (ip_address) + results = Utility.run_scan(DNSSCAN) + lines = results.split("\n") + + for line in lines: + line = line.strip() + line = line.rstrip() + if (("53/tcp" in line) and ("open" in line) + and ("Discovered" not in line)): + print( + " [=] Found DNS service running on: %s" % + (ip_address)) + output_file.write( + "[*] Found DNS service running on: %s\n" % + (ip_address)) + output_file.write(" [>] %s\n" % (line)) + output_targets.write("%s\n" % (ip_address)) + self.dns_server_list.append(ip_address) + self.dnscount += 1 + print("[*] Found %s DNS servers within %s hosts" % + (str(self.dnscount), str(self.hostcount))) + output_file.close() + output_targets.close() + return '' if len(self.dns_server_list) == 0 else ','.join(self.dns_server_list) diff --git a/Reconnoitre/lib/hostname_scan.py b/Reconnoitre/lib/hostname_scan.py index 09e985e..756234d 100644 --- a/Reconnoitre/lib/hostname_scan.py +++ b/Reconnoitre/lib/hostname_scan.py @@ -1,48 +1,51 @@ import os +from lib.utility import Utility -from Reconnoitre.lib.file_helper import check_directory -from Reconnoitre.lib.subprocess_helper import run_scan +class HostNameScan(): + def __init__(self, target_hosts, output_directory, quiet): + self.target_hosts = target_hosts + self.output_directory = output_directory + self.quiet = quiet + self.hostnames = 0 + self.output_file = "{}/hostnames.txt".format(self.output_directory) + def hostname_scan(self, target_hosts, output_directory, quiet): + Utility.check_directory(output_directory) + f = open(self.output_file, 'w') + print("[+] Writing hostnames to: %s" % self.output_file) -def hostname_scan(target_hosts, output_directory, quiet): - check_directory(output_directory) - output_file = output_directory + "/hostnames.txt" - f = open(output_file, 'w') - print("[+] Writing hostnames to: %s" % output_file) + SWEEP = '' - hostnames = 0 - SWEEP = '' + if (os.path.isfile(target_hosts)): + SWEEP = "nbtscan -q -f %s" % (target_hosts) + else: + SWEEP = "nbtscan -q %s" % (target_hosts) - if (os.path.isfile(target_hosts)): - SWEEP = "nbtscan -q -f %s" % (target_hosts) - else: - SWEEP = "nbtscan -q %s" % (target_hosts) + results = Utility.run_scan(SWEEP) + lines = results.split("\n") - results = run_scan(SWEEP) - lines = results.split("\n") + for line in lines: + line = line.strip() + line = line.rstrip() - for line in lines: - line = line.strip() - line = line.rstrip() + # Final line is blank which causes list index issues if we don't + # continue past it. + if " " not in line: + continue - # Final line is blank which causes list index issues if we don't - # continue past it. - if " " not in line: - continue + while " " in line: + line = line.replace(" ", " ") - while " " in line: - line = line.replace(" ", " ") + ip_address = line.split(" ")[0] + host = line.split(" ")[1] - ip_address = line.split(" ")[0] - host = line.split(" ")[1] + if (self.hostnames > 0): + f.write('\n') - if (hostnames > 0): - f.write('\n') + print(" [>] Discovered hostname: %s (%s)" % (host, ip_address)) + f.write("%s - %s" % (host, ip_address)) + self.hostnames += 1 - print(" [>] Discovered hostname: %s (%s)" % (host, ip_address)) - f.write("%s - %s" % (host, ip_address)) - hostnames += 1 - - print("[*] Found %s hostnames." % (hostnames)) - print("[*] Created hostname list %s" % (output_file)) - f.close() + print("[*] Found %s hostnames." % (self.hostnames)) + print("[*] Created hostname list %s" % (self.output_file)) + f.close() diff --git a/Reconnoitre/lib/ping_sweeper.py b/Reconnoitre/lib/ping_sweeper.py index 6d2c660..fe76876 100644 --- a/Reconnoitre/lib/ping_sweeper.py +++ b/Reconnoitre/lib/ping_sweeper.py @@ -1,44 +1,44 @@ -from Reconnoitre.lib.file_helper import check_directory -from Reconnoitre.lib.subprocess_helper import run_scan +from lib.utility import Utility +class PingSweeper: -def ping_sweeper(target_hosts, output_directory, quiet): - check_directory(output_directory) - output_file = output_directory + "/targets.txt" + def __init__(self, target_hosts, output_directory, quiet) -> None: + self.target_hosts = target_hosts + self.output_directory = output_directory + self.quiet = quiet + self.output_file = "{}/targets.txt".format(self.output_directory) + self.live_hosts = [] + self.nmap_output = None - print("[+] Performing ping sweep over %s" % target_hosts) + def ping_sweeper(self): + Utility.check_directory(self.output_directory) - lines = call_nmap_sweep(target_hosts) - live_hosts = parse_nmap_output_for_live_hosts(lines) - write_live_hosts_list_to_file(output_file, live_hosts) + print("[+] Performing ping sweep over %s" % self.target_hosts) - for ip_address in live_hosts: - print(" [>] Discovered host: %s" % (ip_address)) + self.call_nmap_sweep() + self.parse_nmap_output_for_live_hosts() + self.write_live_hosts_list_to_file() - print("[*] Found %s live hosts" % (len(live_hosts))) - print("[*] Created target list %s" % (output_file)) + for ip_address in self.live_hosts: + print(" [>] Discovered host: %s" % (ip_address)) + print("[*] Found %s live hosts" % (len(self.live_hosts))) + print("[*] Created target list %s" % (self.output_file)) -def call_nmap_sweep(target_hosts): - SWEEP = "nmap -n -sP %s" % (target_hosts) - results = run_scan(SWEEP) - lines = str(results).split("\n") - return lines + def call_nmap_sweep(self): + SWEEP = "nmap -n -sP %s" % (self.target_hosts) + results = Utility.run_scan(SWEEP) + self.nmap_output = str(results).split("\n") -def parse_nmap_output_for_live_hosts(lines): - def get_ip_from_nmap_line(line): - return line.split()[4] + def parse_nmap_output_for_live_hosts(self): + self.live_hosts = [line.split()[4] + for line in self.nmap_output + if "Nmap scan report for" in line] - live_hosts = [get_ip_from_nmap_line(line) - for line in lines - if "Nmap scan report for" in line] - return live_hosts - - -def write_live_hosts_list_to_file(output_file, live_hosts): - print("[+] Writing discovered targets to: %s" % output_file) - with open(output_file, 'w') as f: - f.write("\n".join(live_hosts)) + def write_live_hosts_list_to_file(self): + print("[+] Writing discovered targets to: %s" % self.output_file) + with open(self.output_file, 'w') as f: + f.write("\n".join(self.live_hosts)) diff --git a/Reconnoitre/lib/service_scan.py b/Reconnoitre/lib/service_scan.py index d530bc0..beed65d 100644 --- a/Reconnoitre/lib/service_scan.py +++ b/Reconnoitre/lib/service_scan.py @@ -1,163 +1,101 @@ import multiprocessing -import socket - -from Reconnoitre.lib.file_helper import check_directory -from Reconnoitre.lib.file_helper import create_dir_structure -from Reconnoitre.lib.file_helper import get_config_options -from Reconnoitre.lib.file_helper import load_targets -from Reconnoitre.lib.file_helper import write_recommendations -from Reconnoitre.lib.subprocess_helper import run_scan - - -def nmap_scan( - ip_address, - output_directory, - dns_server, - quick, - no_udp_service_scan): - ip_address = ip_address.strip() - - print("[+] Starting quick nmap scan for %s" % (ip_address)) - flags = get_config_options('nmap', 'quickscan') - QUICKSCAN = f"nmap {flags} {ip_address} -oA '{output_directory}/{ip_address}.quick'" - quickresults = run_scan(QUICKSCAN) - - write_recommendations(quickresults, ip_address, output_directory) - print("[*] TCP quick scans completed for %s" % ip_address) - - if (quick): - return - - if dns_server: - print( - "[+] Starting detailed TCP%s nmap scans for " - "%s using DNS Server %s" % - (("" if no_udp_service_scan is True else "/UDP"), - ip_address, - dns_server)) - print("[+] Using DNS server %s" % (dns_server)) - flags = get_config_options("nmap", "tcpscan") - TCPSCAN = f"nmap {flags} --dns-servers {dns_server} -oN\ - '{output_directory}/{ip_address}.nmap' -oX\ - '{output_directory}/{ip_address}_nmap_scan_import.xml' {ip_address}" - - flags = get_config_options("nmap", "dnsudpscan") - UDPSCAN = f"nmap {flags} \ - --dns-servers {dns_server} -oN '{output_directory}/{ip_address}U.nmap' \ - -oX '{output_directory}/{ip_address}U_nmap_scan_import.xml' {ip_address}" - - else: - print("[+] Starting detailed TCP%s nmap scans for %s" % ( - ("" if no_udp_service_scan is True else "/UDP"), ip_address)) - flags = get_config_options("nmap", "tcpscan") - TCPSCAN = f"nmap {flags} -oN\ - '{output_directory}/{ip_address}.nmap' -oX\ - '{output_directory}/{ip_address}_nmap_scan_import.xml' {ip_address}" - - flags = get_config_options("nmap", "udpscan") - UDPSCAN = f"nmap {flags} {ip_address} -oA '{output_directory}/{ip_address}-udp'" - - udpresult = "" if no_udp_service_scan is True else run_scan(UDPSCAN) - tcpresults = run_scan(TCPSCAN) - - write_recommendations(tcpresults + udpresult, ip_address, output_directory) - print("[*] TCP%s scans completed for %s" % - (("" if no_udp_service_scan is True else "/UDP"), ip_address)) - - -def valid_ip(address): - try: - socket.inet_aton(address) - return True - except socket.error: - return False - - -def target_file( - target_hosts, - output_directory, - dns_server, - quiet, - quick, - no_udp_service_scan): - targets = load_targets(target_hosts, output_directory, quiet) - target_file = open(targets, 'r') - try: - target_file = open(targets, 'r') - print("[*] Loaded targets from: %s" % targets) - except Exception: - print("[!] Unable to load: %s" % targets) - - for ip_address in target_file: - ip_address = ip_address.strip() - create_dir_structure(ip_address, output_directory) - host_directory = output_directory + "/" + ip_address - nmap_directory = host_directory + "/scans" +from lib.utility import Utility + +class ServiceScan: + + def __init__(self, target_hosts, output_directory, dns_server, quiet, quick, no_udp_service_scan): + self.target_hosts = target_hosts + self.output_directory = output_directory + self.dns_server = dns_server + self.quiet = quiet + self.quick = quick + self.no_udp_service_scan = no_udp_service_scan + Utility.create_dir_structure(self.target_hosts, self.output_directory) + + def nmap_scan(self, ip_address): + print("[+] Starting quick nmap scan for %s" % (self.target_hosts)) + flags = Utility.get_config_options('nmap', 'quickscan') + hostDirectory = self.output_directory+"/"+ip_address + scanDirectory = hostDirectory + "/scans" + QUICKSCAN = f"nmap {flags} {ip_address} -oA '{scanDirectory}/{ip_address}.quick'" + quickresults = Utility.run_scan(QUICKSCAN) + Utility.write_recommendations(quickresults, ip_address, scanDirectory) + print("[*] TCP quick scans completed for %s" % self.target_hosts) + + if (self.quick): + return + + if self.dns_server: + print( + "[+] Starting detailed TCP%s nmap scans for " + "%s using DNS Server %s" % + (("" if self.no_udp_service_scan is True else "/UDP"), + ip_address, + self.dns_server)) + print("[+] Using DNS server %s" % (self.dns_server)) + flags = Utility.get_config_options("nmap", "tcpscan") + TCPSCAN = f"nmap {flags} --dns-servers {self.dns_server} -oN\ + '{scanDirectory}/{ip_address}.nmap' -oX\ + '{scanDirectory}/{ip_address}_nmap_scan_import.xml' {ip_address}" + + flags = Utility.get_config_options("nmap", "dnsudpscan") + UDPSCAN = f"nmap {flags} \ + --dns-servers {self.dns_server} -oN '{scanDirectory}/{ip_address}U.nmap' \ + -oX '{scanDirectory}/{ip_address}U_nmap_scan_import.xml' {ip_address}" + + else: + print("[+] Starting detailed TCP%s nmap scans for %s" % ( + ("" if self.no_udp_service_scan is True else "/UDP"), ip_address)) + flags = Utility.get_config_options("nmap", "tcpscan") + TCPSCAN = f"nmap {flags} -oN\ + '{scanDirectory}/{ip_address}.nmap' -oX\ + '{scanDirectory}/{ip_address}_nmap_scan_import.xml' {ip_address}" + + flags = Utility.get_config_options("nmap", "udpscan") + UDPSCAN = f"nmap {flags} {ip_address} -oA '{scanDirectory}/{ip_address}-udp'" + + udpresult = "" if self.no_udp_service_scan is True else Utility.run_scan(UDPSCAN) + tcpresults = Utility.run_scan(TCPSCAN) + + Utility.write_recommendations(tcpresults + udpresult, ip_address, scanDirectory) + print("[*] TCP%s scans completed for %s" % + (("" if self.no_udp_service_scan is True else "/UDP"), ip_address)) + + def target_file(self): + targets = Utility.load_targets(self.target_hosts, self.output_directory, self.quiet) + target_file = open(targets, 'r') + try: + target_file = open(targets, 'r') + print("[*] Loaded targets from: %s" % targets) + except Exception: + print("[!] Unable to load: %s" % targets) + + for ip_address in target_file: + ip_address = ip_address.strip() + Utility.create_dir_structure(ip_address, self.output_directory) + jobs = [] + p = multiprocessing.Process(target=self.nmap_scan, args=[ip_address]) + jobs.append(p) + p.start() + target_file.close() + + + def target_ip(self, ip_address): + print("[*] Loaded single target: %s" % ip_address) + target_hosts = ip_address.strip() + Utility.create_dir_structure(target_hosts, self.output_directory) jobs = [] - p = multiprocessing.Process( - target=nmap_scan, - args=( - ip_address, - nmap_directory, - dns_server, - quick, - no_udp_service_scan)) + p = multiprocessing.Process(target=self.nmap_scan, args=[ip_address]) jobs.append(p) p.start() - target_file.close() - - -def target_ip( - target_hosts, - output_directory, - dns_server, - quiet, - quick, - no_udp_service_scan): - print("[*] Loaded single target: %s" % target_hosts) - target_hosts = target_hosts.strip() - create_dir_structure(target_hosts, output_directory) - - host_directory = output_directory + "/" + target_hosts - nmap_directory = host_directory + "/scans" - - jobs = [] - p = multiprocessing.Process( - target=nmap_scan, - args=( - target_hosts, - nmap_directory, - dns_server, - quick, - no_udp_service_scan)) - jobs.append(p) - p.start() - - -def service_scan( - target_hosts, - output_directory, - dns_server, - quiet, - quick, - no_udp_service_scan): - check_directory(output_directory) - - if (valid_ip(target_hosts)): - target_ip( - target_hosts, - output_directory, - dns_server, - quiet, - quick, - no_udp_service_scan) - else: - target_file( - target_hosts, - output_directory, - dns_server, - quiet, - quick, - no_udp_service_scan) + + + def service_scan(self): + Utility.check_directory(self.output_directory) + + if (Utility.valid_ip(self.target_hosts)): + self.target_ip(self.target_hosts) + else: + self.target_file() diff --git a/Reconnoitre/lib/snmp_walk.py b/Reconnoitre/lib/snmp_walk.py index 21b8a99..9b1745a 100644 --- a/Reconnoitre/lib/snmp_walk.py +++ b/Reconnoitre/lib/snmp_walk.py @@ -1,83 +1,72 @@ import multiprocessing -import socket import subprocess +from lib.utility import Utility -from Reconnoitre.lib.file_helper import check_directory, load_targets -from Reconnoitre.lib.subprocess_helper import run_scan +class SnmpWalk: + def __init__(self, target_hosts, output_directory, quiet): + self.target_hosts = target_hosts + self.output_directory = output_directory + self.quiet = quiet -def valid_ip(address): - try: - socket.inet_aton(address) - return True - except socket.error: - return False + def target_file(self): + targets = Utility.load_targets(self.target_hosts, self.output_directory, self.quiet) + target_file = open(targets, 'r') + try: + target_file = open(targets, 'r') + print("[*] Loaded targets from: %s" % targets) + except Exception: + print("[!] Unable to load: %s" % targets) + for ip_address in target_file: + ip_address = ip_address.strip() + jobs = [] + p = multiprocessing.Process(target=self.snmp_scans, args=(ip_address)) + jobs.append(p) + p.start() + target_file.close() -def target_file(target_hosts, output_directory, quiet): - targets = load_targets(target_hosts, output_directory, quiet) - target_file = open(targets, 'r') - try: - target_file = open(targets, 'r') - print("[*] Loaded targets from: %s" % targets) - except Exception: - print("[!] Unable to load: %s" % targets) - for ip_address in target_file: - ip_address = ip_address.strip() + def target_ip(self, ip_address): + print("[*] Loaded single target: %s" % self.target_hosts) + target_hosts = target_hosts.strip() - snmp_directory = output_directory + '/' + ip_address + '/scans/snmp/' - check_directory(snmp_directory) + snmp_directory = self.output_directory + '/' + target_hosts + '/scans/snmp/' + Utility.check_directory(snmp_directory) jobs = [] p = multiprocessing.Process( - target=snmp_scans, args=( - ip_address, snmp_directory)) + target=self.snmp_scans, args=(ip_address)) jobs.append(p) p.start() - target_file.close() - - -def target_ip(target_hosts, output_directory, quiet): - print("[*] Loaded single target: %s" % target_hosts) - target_hosts = target_hosts.strip() - - snmp_directory = output_directory + '/' + target_hosts + '/scans/snmp/' - check_directory(snmp_directory) - - jobs = [] - p = multiprocessing.Process( - target=snmp_scans, args=( - target_hosts, snmp_directory)) - jobs.append(p) - p.start() -def snmp_walk(target_hosts, output_directory, quiet): - check_directory(output_directory) + def snmp_walk(self): + Utility.check_directory(self.output_directory) - if (valid_ip(target_hosts)): - target_ip(target_hosts, output_directory, quiet) - else: - target_file(target_hosts, output_directory, quiet) + if (Utility.valid_ip(self.target_hosts)): + self.target_ip(self.target_hosts) + else: + self.target_file() -def snmp_scans(ip_address, output_directory): - print("[+] Performing SNMP scans for %s to %s" % - (ip_address, output_directory)) - print( - " [>] Performing snmpwalk on public tree for:" - " %s - Checking for System Processes" % - (ip_address)) - SCAN = ("snmpwalk -c public -v1 %s " - "1.3.6.1.2.1.25.1.6.0 > '%s%s-systemprocesses.txt'" % ( - ip_address, output_directory, ip_address)) + def snmp_scans(self, ip_address): + ipDir = self.output_directory+'/'+ip_address+'/scans/snmp' + print("[+] Performing SNMP scans for %s to %s" % + (ip_address, ipDir)) + print( + " [>] Performing snmpwalk on public tree for:" + " %s - Checking for System Processes" % + (ip_address)) + SCAN = ("snmpwalk -c public -v1 %s " + "1.3.6.1.2.1.25.1.6.0 > '%s%s-systemprocesses.txt'" % ( + ip_address, ipDir, ip_address)) - try: - run_scan(SCAN, stderr=subprocess.STDOUT) - except Exception: - print("[+] No Response from %s" % ip_address) - except subprocess.CalledProcessError: - print("[+] Subprocess failure during scan of %s" % ip_address) + try: + Utility.run_scan(SCAN, stderr=subprocess.STDOUT) + except Exception: + print("[+] No Response from %s" % ip_address) + except subprocess.CalledProcessError: + print("[+] Subprocess failure during scan of %s" % self.target_hosts) - print("[+] Completed SNMP scans for %s" % (ip_address)) + print("[+] Completed SNMP scans for %s" % (ip_address)) diff --git a/Reconnoitre/lib/subprocess_helper.py b/Reconnoitre/lib/subprocess_helper.py deleted file mode 100644 index 992cab0..0000000 --- a/Reconnoitre/lib/subprocess_helper.py +++ /dev/null @@ -1,8 +0,0 @@ -import subprocess - - -def run_scan(scan, stderr=None): - """Helper method to perform a scan using a subprocess and return results. - We use the same configuration options for each call to check_output, this - can be bunched into one helper function to keep config constant.""" - return subprocess.check_output(scan, shell=True, stderr=stderr, universal_newlines=True) diff --git a/Reconnoitre/lib/utility.py b/Reconnoitre/lib/utility.py new file mode 100644 index 0000000..935b802 --- /dev/null +++ b/Reconnoitre/lib/utility.py @@ -0,0 +1,188 @@ +import os +import json +import subprocess +import socket + +class Utility: + + @staticmethod + def check_directory(output_directory): + try: + os.stat(output_directory) + except Exception: + os.mkdir(output_directory) + print("[!] %s didn't exist and has been created." % output_directory) + + @staticmethod + def load_targets(target_hosts, output_directory, quiet): + if (os.path.isdir(target_hosts) or os.path.isfile(target_hosts)): + return target_hosts + elif "-" in target_hosts: + Utility.expand_targets(target_hosts, output_directory) + return output_directory + "/targets.txt" + else: + return output_directory + "/targets.txt" + + @staticmethod + def expand_targets(target_hosts, output_directory): + parts = target_hosts.split(".") + target_list = [] + for part in parts: + if "-" in part: + iprange = part.split("-") + for i in range(int(iprange[0]), int(iprange[1])): + target_list.append( + parts[0] + + "." + + parts[1] + + "." + + parts[2] + + "." + + str(i)) + with open(output_directory + "/targets.txt", "w") as targets: + for target in target_list: + targets.write("%s\n" % target) + + @staticmethod + def create_dir_structure(ip_address, output_directory): + print("[+] Creating directory structure for " + ip_address) + + hostdir = output_directory + "/" + ip_address + try: + os.stat(hostdir) + except Exception: + os.makedirs(hostdir) + + nmapdir = hostdir + "/scans" + print(" [>] Creating scans directory at: %s" % nmapdir) + try: + os.stat(nmapdir) + except Exception: + os.makedirs(nmapdir) + + exploitdir = hostdir + "/exploit" + print(" [>] Creating exploit directory at: %s" % exploitdir) + try: + os.stat(exploitdir) + except Exception: + os.makedirs(exploitdir) + + lootdir = hostdir + "/loot" + print(" [>] Creating loot directory at: %s" % lootdir) + try: + os.stat(lootdir) + except Exception: + os.makedirs(lootdir) + + prooffile = hostdir + "/proof.txt" + print(" [>] Creating proof file at: %s" % prooffile) + open(prooffile, 'a').close() + + @staticmethod + def write_recommendations(results, ip_address, outputdir): + recommendations_file = outputdir + "/" + ip_address + "_findings.txt" + serv_dict = {} + lines = results.split("\n") + for line in lines: + ports = [] + line = line.strip() + if ("tcp" in line) and ("open" in line) and not ("Discovered" in line): + while " " in line: + line = line.replace(" ", " ") + service = line.split(" ")[2] + port = line.split(" ")[0] + + if service in serv_dict: + ports = serv_dict[service] + + ports.append(port) + serv_dict[service] = ports + + print("[+] Writing findings for %s" % (ip_address)) + + __location__ = os.path.realpath( + os.path.join( + os.getcwd(), + os.path.dirname(__file__))) + with open(os.path.join(__location__, "config.json"), "r") as config: + c = config.read() + j = json.loads( + c.replace( + "$ip", + "%(ip)s").replace( + "$port", + "%(port)s").replace( + "$outputdir", + "%(outputdir)s")) + + f = open(recommendations_file, 'w') + for serv in serv_dict: + ports = serv_dict[serv] + + for service in j["services"]: + if (serv in j["services"][service] + ["nmap-service-names"]) or (service in serv): + for port in ports: + port = port.split("/")[0] + + description = ("[*] " + + j["services"][service]["description"]) + print(description % {"ip": ip_address, "port": port}) + f.write((description + "\n") % + {"ip": ip_address, "port": port}) + + for entry in j["services"][service]["output"]: + f.write(" [*] " + entry["description"] + "\n") + + for cmd in entry["commands"]: + f.write((" [=] " + cmd + "\n") % + {"ip": ip_address, + "port": port, + "outputdir": outputdir}) + + f.write("\n") + + f.write( + "\n\n[*] Always remember to manually go over the" + " portscan report and carefully read between the lines ;)") + f.close() + + @staticmethod + def get_config_options(key, *args): + __location__ = os.path.realpath( + os.path.join( + os.getcwd(), + os.path.dirname(__file__))) + with open(os.path.join(__location__, "config.json"), "r") as config: + c = config.read() + j = json.loads( + c.replace( + "$ip", + "%(ip)s").replace( + "$port", + "%(port)s").replace( + "$outputdir", + "%(outputdir)s")) + + res = j.get(key, None) + for arg in args: + res = res.get(arg, None) + if res is None: + raise KeyError + + return res + + @staticmethod + def run_scan(scan, stderr=None): + """Helper method to perform a scan using a subprocess and return results. + We use the same configuration options for each call to check_output, this + can be bunched into one helper function to keep config constant.""" + return subprocess.check_output(scan, shell=True, stderr=stderr, universal_newlines=True) + + @staticmethod + def valid_ip(address): + try: + socket.inet_aton(address) + return True + except socket.error: + return False \ No newline at end of file diff --git a/Reconnoitre/reconnoitre.py b/Reconnoitre/reconnoitre.py index ccfd8d1..bd612ed 100644 --- a/Reconnoitre/reconnoitre.py +++ b/Reconnoitre/reconnoitre.py @@ -4,13 +4,13 @@ import signal import sys -from .lib.core.input import CliArgumentParser -from .lib.find_dns import find_dns -from .lib.hostname_scan import hostname_scan -from .lib.ping_sweeper import ping_sweeper -from .lib.service_scan import service_scan -from .lib.snmp_walk import snmp_walk -from .lib.virtual_host_scanner import VirtualHostScanner +from lib.core.input import CliArgumentParser +from lib.find_dns import FindDNS +from lib.hostname_scan import HostNameScan +from lib.ping_sweeper import PingSweeper +from lib.service_scan import ServiceScan +from lib.snmp_walk import SnmpWalk +from lib.virtual_host_scanner import VirtualHostScanner def print_banner(): print(" __") @@ -83,41 +83,47 @@ def main(): if arguments.ping_sweep is True: print("[#] Performing ping sweep") - ping_sweeper( + driver = PingSweeper( arguments.target_hosts, arguments.output_directory, arguments.quiet) + driver.ping_sweeper() if arguments.hostname_scan is True: print("[#] Identifying hostnames") - hostname_scan( + driver = HostNameScan( arguments.target_hosts, arguments.output_directory, arguments.quiet) + driver.hostname_scan() if arguments.find_dns_servers is True: print("[#] Identifying DNS Servers") - dns_servers = find_dns( + driver = FindDNS( arguments.target_hosts, arguments.output_directory, arguments.quiet) + dns_servers = driver.find_dns() + if arguments.perform_service_scan is True: print("[#] Performing service scans") - service_scan( + driver = ServiceScan( arguments.target_hosts, arguments.output_directory, dns_servers, arguments.quiet, arguments.quick, arguments.no_udp_service_scan) + driver.service_scan() if arguments.perform_snmp_walk is True: print("[#] Performing SNMP walks") - snmp_walk( + driver = SnmpWalk( arguments.target_hosts, arguments.output_directory, arguments.quiet) + driver.snmp_walk() if arguments.virtualhosts is True: print("[#] Performing Virtual host scans")