import os.path import argparse import subprocess import sys import os import time import errno import array import re # # Author: Andy Marks # # Date: 07/19/15 # # Description: This is a simple program to kick off Openvas # scans for each IP address in a particular file. This script # may greatly increase efficiency of penetration testing when # very large numbers of hosts are involved. # # At this time, 3 concurrent scans are allowed by default. # Use an argument to change the concurrency setting. # # Type the following to see command line option: # # python openvasrun.py -h # # Requirements: Linux OS / Python / Openvas # # Instructions: # # 0. Ensure you have Openvas running. It is necessary to # create a file called omp.config in your home directory # with omp (Openvas Management Service) settings, such as # # # [Connection] # host=127.0.0.1 # port=9390 # username=uuuuuu # password=pppppp # # where uuuuu is a valid Openvas user (one that can log into # Greenbone, for example), and pppppp is it's password. # # It is not likely this program will work without that file # set up. # # 1. Create a directory. # 2. Download openvasrun.py to the directory. # 3. Create a text file called target_addresses.txt containing # the IP addresses to be scanned, one IP per line. It should # be in the same directory as nmapformat.py. The IP addresses # should be unique. It is unknown what will occur if there # are duplicates. # 4. Ensure the current directory is this newly created # directory by typing pwd. # 5. Run the following command: sudo python openvasrun.py . # # Please email me with recommendations for improvements. I # tailored this program to my specific needs but want to # eventually make it as widely useful as possible. # # Feel free to modify the source code on your system, such as # adding and removing flags from the nmap system call. # def is_valid_file(parser, arg): if not os.path.exists(arg): parser.error("The file %s does not exist!" % arg) else: return open(arg, 'r') # return an open file handle def start_process(ip_address): # # The following code creates the target and task records and then kicks off the task for a single IP # # The test IP address here to be changed to the variable: command_line = " omp --xml=\"" + ip_address + "" + ip_address + "Consider Alive\"" if debugf == 'yes': print command_line p = subprocess.Popen([command_line], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) lines_iterator = iter(p.stdout.readline, b"") already_exists = 'No' for line in lines_iterator: if line.find('status="400"') > 0: already_exists = 'Yes' p = subprocess.Popen(['omp --get-targets'], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) lines_iterator = iter(p.stdout.readline, b"") for line in lines_iterator: if line.find(ip_address) > 0: # The test IP address here to be changed to the variable. # # Attempt to create target failed: already exists: Now, grab the ID here from a list of all target records. # target_id = line[0:36] else: # # Target record create successful: Grab the ID from the command line output: # target_id = line[28:64] # # Create task here: # command_line = " omp --xml=\"" + ip_address + "\"" if debugf == 'yes': print command_line p = subprocess.Popen([command_line], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) lines_iterator = iter(p.stdout.readline, b"") for line in lines_iterator: if debugf == 'yes': print line if line.find('create_task') > 0: task_id = line[26:62] if debugf == 'yes': print task_id # Sample Output: # # # Kick off task here: # command_line = " omp --xml=\"\"" if debugf == 'yes': print command_line p = subprocess.Popen([command_line], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) lines_iterator = iter(p.stdout.readline, b"") already_exists = 'No' for line in lines_iterator: if debugf == 'yes': print line # # End End End ---->>> start_process <<<----- # ############################################################### # # def get_running_processes(): # # Compute the number of running tasks and the number of tasks # to be started. # command_line = "omp --get-tasks" if debugf == 'yes': print command_line p = subprocess.Popen([command_line], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) lines_iterator = iter(p.stdout.readline, b"") scans_running = 0 for line in lines_iterator: if debugf == 'yes': print line if line.find('Running') > 0 or line.find('Requested') > 0: scans_running += 1 return scans_running # # End End End ---->>> get_running_processes <<<----- # ############################################################### # # Begin ---->>> Main program <<<----- # # The debugf flag essentially displays trace messages to aid in # troubleshooting. It must be 'yes' to show the messages. # parser = argparse.ArgumentParser() parser.add_argument("-i", "--inputfile", dest="filename", # required=True, help="Input file with IP addresses, one per line. Default name is target_addresses.txt", metavar="FILE", type=lambda x: is_valid_file(parser, x), default='target_addresses.txt') parser.add_argument("-s", "--sleep", help="Amount of time in seconds to sleep between status checks", nargs='?', const=10, type=int, default=10) parser.add_argument("-c", "--concurrent", help="Maximum number of concurrent processes allowed", nargs='?', const=3, type=int, default=3) parser.add_argument("-d", "--debug", help="Show debug messages",action="store_true") args = parser.parse_args() max_concurrent_scans = args.concurrent sleep_seconds = args.sleep file = args.filename if args.debug: debugf = 'yes' else: debugf = 'no' if debugf == 'yes': print 'File: '+str(args.filename) print 'Print debug messages: '+debugf print 'Sleep '+str(sleep_seconds)+' seconds between status checks.' print 'Maximum concurrent scans: '+str(max_concurrent_scans) # All processes are stored in process_array just after they are started. # This allows for checking if it is still running. We count the number # of processes in the following variable. # ip_array = [] for line in file: ip_array.append([str(line).rstrip()]) #if debugf == 'yes': # print ip_array if max_concurrent_scans > len(ip_array): max_concurrent_scans = len(ip_array) running_scans = 0 while running_scans > 0 or len(ip_array) > 0: if running_scans < max_concurrent_scans: number_to_kickoff = max_concurrent_scans - running_scans if debugf == 'yes': print number_to_kickoff if len(ip_array) > 0: for startloop in range(0,number_to_kickoff): ip_address = ip_array[0] if debugf == 'yes': print ip_array[0] del ip_array[0] start_process((ip_address)[0]) running_scans = get_running_processes() print 'Running scans: '+str(running_scans) # Sleep for awhile so as not to waste too much system resources rechecking. time.sleep(sleep_seconds) print 'All scans complete.'