Added --single-target and --only-scans-dir options.
This commit is contained in:
parent
d7058848a5
commit
4d79a9e340
83
autorecon.py
83
autorecon.py
|
@ -17,6 +17,7 @@ import re
|
|||
import socket
|
||||
import string
|
||||
import sys
|
||||
import time
|
||||
import toml
|
||||
|
||||
verbose = 0
|
||||
|
@ -33,6 +34,9 @@ password_wordlist = '/usr/share/seclists/Passwords/darkweb2017-top100.txt'
|
|||
|
||||
rootdir = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__)))
|
||||
|
||||
single_target = False
|
||||
only_scans_dir = False
|
||||
|
||||
def e(*args, frame_index=1, **kvargs):
|
||||
frame = sys._getframe(frame_index)
|
||||
|
||||
|
@ -104,22 +108,61 @@ def fail(*args, sep=' ', end='\n', file=sys.stderr, **kvargs):
|
|||
cprint(*args, color=Fore.RED, char='!', sep=sep, end=end, file=file, frame_index=2, **kvargs)
|
||||
exit(-1)
|
||||
|
||||
def merge_toml(a, b, path=None):
|
||||
if path is None: path = []
|
||||
for key in b:
|
||||
if key in a:
|
||||
if isinstance(a[key], dict) and isinstance(b[key], dict):
|
||||
merge_toml(a[key], b[key], path + [str(key)])
|
||||
elif a[key] == b[key]:
|
||||
pass
|
||||
else:
|
||||
a[key] = b[key]
|
||||
else:
|
||||
a[key] = b[key]
|
||||
return a
|
||||
|
||||
port_scan_profiles_config_file = 'port-scan-profiles.toml'
|
||||
with open(os.path.join(rootdir, 'config', port_scan_profiles_config_file), 'r') as p:
|
||||
try:
|
||||
with open(os.path.join(rootdir, 'config', port_scan_profiles_config_file), 'r') as p:
|
||||
try:
|
||||
port_scan_profiles_config = toml.load(p)
|
||||
|
||||
custom_port_scan_profiles_config_file = os.path.join(rootdir, 'config', 'custom-port-scan-profiles.toml')
|
||||
if os.path.isfile(custom_port_scan_profiles_config_file):
|
||||
try:
|
||||
with open(custom_port_scan_profiles_config_file, 'r') as c:
|
||||
custom_port_scan_profiles_config = toml.load(c)
|
||||
merge_toml(port_scan_profiles_config, custom_port_scan_profiles_config)
|
||||
except IOError:
|
||||
fail('Error: Couldn\'t load custom-port-scan-profiles.toml config file. Check the file exists and has the correct permissions.')
|
||||
|
||||
if len(port_scan_profiles_config) == 0:
|
||||
fail('There do not appear to be any port scan profiles configured in the {port_scan_profiles_config_file} config file.')
|
||||
|
||||
except toml.decoder.TomlDecodeError as e:
|
||||
fail('Error: Couldn\'t parse {port_scan_profiles_config_file} config file. Check syntax and duplicate tags.')
|
||||
fail('Error: Couldn\'t parse {port_scan_profiles_config_file} or custom-port-scan-profiles.toml config file. Check syntax and duplicate tags.')
|
||||
except IOError:
|
||||
fail('Error: Couldn\'t load {port_scan_profiles_config_file} config file. Check the file exists and has the correct permissions.')
|
||||
|
||||
with open(os.path.join(rootdir, 'config', 'service-scans.toml'), 'r') as c:
|
||||
try:
|
||||
with open(os.path.join(rootdir, 'config', 'service-scans.toml'), 'r') as s:
|
||||
try:
|
||||
service_scans_config = toml.load(c)
|
||||
service_scans_config = toml.load(s)
|
||||
|
||||
custom_service_scans_config_file = os.path.join(rootdir, 'config', 'custom-service-scans.toml')
|
||||
if os.path.isfile(custom_service_scans_config_file):
|
||||
try:
|
||||
with open(custom_service_scans_config_file, 'r') as c:
|
||||
custom_service_scans_config = toml.load(c)
|
||||
merge_toml(service_scans_config, custom_service_scans_config)
|
||||
except IOError:
|
||||
fail('Error: Couldn\'t load custom-service-scans.toml config file. Check the file exists and has the correct permissions.')
|
||||
|
||||
except toml.decoder.TomlDecodeError as e:
|
||||
fail('Error: Couldn\'t parse service-scans.toml config file. Check syntax and duplicate tags.')
|
||||
fail('Error: Couldn\'t parse service-scans.toml or custom-service-scans.toml config file. Check syntax and duplicate tags.')
|
||||
except IOError:
|
||||
fail('Error: Couldn\'t load service-scans.toml config file. Check the file exists and has the correct permissions.')
|
||||
|
||||
with open(os.path.join(rootdir, 'config', 'global-patterns.toml'), 'r') as p:
|
||||
try:
|
||||
|
@ -401,6 +444,7 @@ async def scan_services(loop, semaphore, target):
|
|||
|
||||
info('Found {bmagenta}{service}{rst} on {bmagenta}{protocol}/{port}{rst} on target {byellow}{address}{rst}')
|
||||
|
||||
if not only_scans_dir:
|
||||
with open(os.path.join(target.reportdir, 'notes.txt'), 'a') as file:
|
||||
file.writelines(e('[*] {service} found on {protocol}/{port}.\n\n\n\n'))
|
||||
|
||||
|
@ -514,12 +558,17 @@ async def scan_services(loop, semaphore, target):
|
|||
pending.add(asyncio.ensure_future(run_cmd(semaphore, e(command), target, tag=tag, patterns=patterns)))
|
||||
|
||||
def scan_host(target, concurrent_scans):
|
||||
start_time = time.time()
|
||||
info('Scanning target {byellow}{target.address}{rst}')
|
||||
|
||||
if single_target:
|
||||
basedir = os.path.abspath(outdir)
|
||||
else:
|
||||
basedir = os.path.abspath(os.path.join(outdir, target.address + srvname))
|
||||
target.basedir = basedir
|
||||
os.makedirs(basedir, exist_ok=True)
|
||||
|
||||
if not only_scans_dir:
|
||||
exploitdir = os.path.abspath(os.path.join(basedir, 'exploit'))
|
||||
os.makedirs(exploitdir, exist_ok=True)
|
||||
|
||||
|
@ -530,6 +579,9 @@ def scan_host(target, concurrent_scans):
|
|||
target.reportdir = reportdir
|
||||
os.makedirs(reportdir, exist_ok=True)
|
||||
|
||||
open(os.path.abspath(os.path.join(reportdir, 'local.txt')), 'a').close()
|
||||
open(os.path.abspath(os.path.join(reportdir, 'proof.txt')), 'a').close()
|
||||
|
||||
screenshotdir = os.path.abspath(os.path.join(reportdir, 'screenshots'))
|
||||
os.makedirs(screenshotdir, exist_ok=True)
|
||||
|
||||
|
@ -539,9 +591,6 @@ def scan_host(target, concurrent_scans):
|
|||
|
||||
os.makedirs(os.path.abspath(os.path.join(scandir, 'xml')), exist_ok=True)
|
||||
|
||||
open(os.path.abspath(os.path.join(reportdir, 'local.txt')), 'a').close()
|
||||
open(os.path.abspath(os.path.join(reportdir, 'proof.txt')), 'a').close()
|
||||
|
||||
# Use a lock when writing to specific files that may be written to by other asynchronous functions.
|
||||
target.lock = asyncio.Lock()
|
||||
|
||||
|
@ -553,6 +602,15 @@ def scan_host(target, concurrent_scans):
|
|||
|
||||
try:
|
||||
loop.run_until_complete(scan_services(loop, semaphore, target))
|
||||
elapsed_seconds = time.time() - start_time
|
||||
|
||||
m, s = divmod(elapsed_seconds, 60)
|
||||
h, m = divmod(m, 60)
|
||||
|
||||
elapsed_time = ''
|
||||
if h > 0:
|
||||
elapsed_time += h + ' hour'
|
||||
|
||||
info('Finished scanning target {byellow}{target.address}{rst}')
|
||||
except KeyboardInterrupt:
|
||||
sys.exit(1)
|
||||
|
@ -575,6 +633,8 @@ if __name__ == '__main__':
|
|||
parser.add_argument('--profile', action='store', default='default', help='The port scanning profile to use (defined in port-scan-profiles.toml). Default: %(default)s')
|
||||
parser.add_argument('-o', '--output', action='store', default='results', help='The output directory for results. Default: %(default)s')
|
||||
nmap_group = parser.add_mutually_exclusive_group()
|
||||
parser.add_argument('--single-target', action='store_true', default=False, help='Only scan a single target. A directory named after the target will not be created. Instead, the directory structure will be created within the output directory. Default: false')
|
||||
parser.add_argument('--only-scans-dir', action='store_true', default=False, help='Only create the "scans" directory for results. Other directories (e.g. exploit, loot, report) will not be created.')
|
||||
nmap_group.add_argument('--nmap', action='store', default='-vv --reason -Pn', help='Override the {nmap_extra} variable in scans. Default: %(default)s')
|
||||
nmap_group.add_argument('--nmap-append', action='store', default='', help='Append to the default {nmap_extra} variable in scans.')
|
||||
parser.add_argument('-v', '--verbose', action='count', default=0, help='Enable verbose output. Repeat for more verbosity.')
|
||||
|
@ -582,6 +642,9 @@ if __name__ == '__main__':
|
|||
parser.error = lambda s: fail(s[0].upper() + s[1:])
|
||||
args = parser.parse_args()
|
||||
|
||||
single_target = args.single_target
|
||||
only_scans_dir = args.only_scans_dir
|
||||
|
||||
errors = False
|
||||
|
||||
if args.concurrent_targets <= 0:
|
||||
|
@ -651,6 +714,10 @@ if __name__ == '__main__':
|
|||
error('You must specify at least one target to scan!')
|
||||
errors = True
|
||||
|
||||
if single_target and len(args.targets) != 1:
|
||||
error('You cannot provide more than one target when scanning in single-target mode.')
|
||||
sys.exit(1)
|
||||
|
||||
targets = []
|
||||
|
||||
for target in args.targets:
|
||||
|
|
Loading…
Reference in New Issue