コード例 #1
1
ファイル: qualys_web.py プロジェクト: xxoxx/VulnWhisperer
 def __init__(self, config=None):
     self.logger = logging.getLogger('qualysWhisperAPI')
     self.config = config
     try:
         self.qgc = qualysapi.connect(config, 'qualys_web')
         self.logger.info('Connected to Qualys at {}'.format(self.qgc.server))
     except Exception as e:
         self.logger.error('Could not connect to Qualys: {}'.format(str(e)))
     self.headers = {
         "content-type": "text/xml"}
     self.config_parse = qcconf.QualysConnectConfig(config)
     try:
         self.template_id = self.config_parse.get_template_id()
     except:
         self.logger.error('Could not retrieve template ID')
コード例 #2
0
def connect_api():
    if not os.path.isfile(os.getcwd() + '/.qcrc'):

        # create the qcrc, enter your qualys credentials
        print 'creating .qcrc in ' + folder + ', enter your qualysguard credentials below;'
        qgs = qualysapi.connect(remember_me=True)

    else:
        # connect using existing .qcrc
        qgs = qualysapi.connect()

    # connect to the API and list reports as an XML
    ret = qgs.request('/api/2.0/fo/report', {'action': 'list'})
    root = xmltodict.parse(ret)

    # iterate over available reports for your account, parse timestamps in epoch
    for x in root['REPORT_LIST_OUTPUT']['RESPONSE']['REPORT_LIST']['REPORT']:
        y1 = x['LAUNCH_DATETIME']
        y2 = datetime.datetime.strptime(str(y1),
                                        '%Y-%m-%dT%H:%M:%SZ').strftime('%s')

        z1 = x['EXPIRATION_DATETIME']
        z2 = datetime.datetime.strptime(str(z1),
                                        '%Y-%m-%dT%H:%M:%SZ').strftime('%s')

        a = x['ID'] + ',' + y1 + ',' + y2 + ',' + z1 + ',' + z2 + ',' + x[
            'USER_LOGIN'] + ',' + x['OUTPUT_FORMAT'] + ',' + x['SIZE']
        print a

        result.append(str(a) + '\n')
        resid.append(int(x['ID']))

    print ''

    # check for reports that arent downloaded yet, else skip
    tmp = []
    tmp.append(glob.glob(os.getcwd() + '/results/*csv'))

    for x in resid:
        found = False
        for y in tmp:
            if re.search(str(x), str(y)):
                found = True

        fname = str(x) + '_' + str(y2) + '.csv'

        if found == False:
            print 'downloading ' + fname
            download_report(x, fname)
        else:
            print 'skipping ' + fname

    # write an overview of report metadata to a csv
    f = open(os.getcwd() + '/reports.csv', 'wb')
    for x in result:
        f.write(x)
    f.close
コード例 #3
0
ファイル: qualys-get.py プロジェクト: marekq/qualys-reporter
def connect_api():
	if not os.path.isfile(os.getcwd()+'/.qcrc'):

		# create the qcrc, enter your qualys credentials
		print 'creating .qcrc in '+folder+', enter your qualysguard credentials below;'
		qgs	= qualysapi.connect(remember_me=True)

	else:
		# connect using existing .qcrc
		qgs	= qualysapi.connect()

	# connect to the API and list reports as an XML
	ret 	= qgs.request('/api/2.0/fo/report', {'action': 'list'})
	root	= xmltodict.parse(ret)

	# iterate over available reports for your account, parse timestamps in epoch
	for x in root['REPORT_LIST_OUTPUT']['RESPONSE']['REPORT_LIST']['REPORT']:
		y1	= x['LAUNCH_DATETIME']
		y2	= datetime.datetime.strptime(str(y1), '%Y-%m-%dT%H:%M:%SZ').strftime('%s')

		z1	= x['EXPIRATION_DATETIME']
		z2	= datetime.datetime.strptime(str(z1), '%Y-%m-%dT%H:%M:%SZ').strftime('%s')

		a	= x['ID']+','+y1+','+y2+','+z1+','+z2+','+x['USER_LOGIN']+','+x['OUTPUT_FORMAT']+','+x['SIZE']
		print a

		result.append(str(a)+'\n')
		resid.append(int(x['ID']))

	print ''

	# check for reports that arent downloaded yet, else skip
	tmp	= []
	tmp.append(glob.glob(os.getcwd()+'/results/*csv'))

	for x in resid:
		found	= False
		for y in tmp:
			if re.search(str(x), str(y)):
				found	= True

		fname	= str(x)+'_'+str(y2)+'.csv'

		if found == False:
			print 'downloading '+fname
			download_report(x, fname)
		else:
			print 'skipping '+fname
	
	# write an overview of report metadata to a csv
	f	= open(os.getcwd()+'/reports.csv', 'wb')
	for x in result:
		f.write(x)
	f.close
コード例 #4
0
ファイル: QualysAccess.py プロジェクト: Chambers82/Atriqualys
	def __init__(self, qsub='test'):
		self.filename = config_dict[qsub]
		try:
			self.api = qualysapi.connect(self.filename)
		except:
			print "Config file missing or connect failed."
			user = raw_input("Enter user: "******"Enter pass: "******"qualys.server.com")
			except:
				print "Could not connect.  Quitting..."
		print "Loading asset groups..."
		print "\nCVS-Qualys Instance Asset Groups as of " + str(datetime.now())
		self.update_asset_groups()
		self.build_asset_dict()
コード例 #5
0
ファイル: QualysAccess.py プロジェクト: Chambers82/Atriqualys
	def __init__(self, qsub='test'):
		self.filename = self.config_dict[qsub]
		self.fullpath = os.getcwd()
		#full_config_filepath = self.fullpath.replace("\\", "\\\\") + "\\\\" + self.filename
		#print self.filename
		try:
			self.api = qualysapi.connect(self.filename)  	# Full path names and the config file?  WTF yo
			self.qsub_v = qsub
		except:
			print "\n[!] Please Authenticate: "
			#user = raw_input("Enter user: "******"Enter pass: "******"qualys.server.com")
			except:
				print "Could not connect.  Quitting..."
コード例 #6
0
ファイル: sheachanddelete.py プロジェクト: SBB-Mx/Qualys
 def add_ip(self):
     a = qualysapi.connect('config.ini')  #conexion a la API de Qualys
     reportScans = a.request('/api/2.0/fo/asset/ip/', {
         'action': 'add',
         'details': 'All',
         'ips': (self.ip),
         'enable_vm': '1'
     })
コード例 #7
0
ファイル: qualys.py プロジェクト: Yikez978/VulnWhisperer
 def __init__(self, config=None):
     self.config = config
     try:
         self.qgc = qualysapi.connect(config)
         print('[SUCCESS] - Connected to Qualys at %s' % self.qgc.server)
     except Exception as e:
         print('[ERROR] Could not connect to Qualys - %s' % e)
     self.headers = {"content-type": "text/xml"}
コード例 #8
0
ファイル: qualys-get.py プロジェクト: marekq/qualys-reporter
def download_report(rid, fname):
	qgs	= qualysapi.connect()
	ret 	= qgs.request('/api/2.0/fo/report', {'action': 'fetch', 'id': rid})
	
	# write the report  as csv to disk with the id and timestamp in fname
	f	= open(str(folder+fname), 'wb')
	f.write(ret)
	f.close
コード例 #9
0
def download_report(rid, fname):
    qgs = qualysapi.connect()
    ret = qgs.request('/api/2.0/fo/report', {'action': 'fetch', 'id': rid})

    # write the report  as csv to disk with the id and timestamp in fname
    f = open(str(folder + fname), 'wb')
    f.write(ret)
    f.close
コード例 #10
0
def main(args):

    # Setup connection to QualysGuard API.
    qgc = qualysapi.connect(args.qualys_config)
    current_time = datetime.datetime.now().strftime("%Y%m%d%H%M")
    logger.debug('Current Time: %s', current_time)

    webapp_id = update_scan_url(qgc, current_time, args)
    scan_id = scan_report(qgc, current_time, args, webapp_id)
    generate_report(qgc, args, scan_id)
コード例 #11
0
 def __init__(self, config=None):
     self.config = config
     try:
         self.qgc = qualysapi.connect(config)
         # Fail early if we can't make a request or auth is incorrect
         self.qgc.request('about.php')
         print('[SUCCESS] - Connected to Qualys at %s' % self.qgc.server)
     except Exception as e:
         print('[ERROR] Could not connect to Qualys - %s' % e)
         exit(1)
コード例 #12
0
 def __init__(self, config=None):
     self.logger = logging.getLogger('qualysWhisperAPI')
     self.config = config
     try:
         self.qgc = qualysapi.connect(config, 'qualys_vuln')
         # Fail early if we can't make a request or auth is incorrect
         self.qgc.request('about.php')
         self.logger.info('Connected to Qualys at {}'.format(self.qgc.server))
     except Exception as e:
         self.logger.error('Could not connect to Qualys: {}'.format(str(e)))
         # FIXME: exit(1) does not exist: either it's exit() or sys.exit(CODE)
         exit(1)
コード例 #13
0
 def __init__(self, config=None):
     self.config = config
     try:
         self.qgc = qualysapi.connect(config)
         print('[SUCCESS] - Connected to Qualys at %s' % self.qgc.server)
     except Exception as e:
         print('[ERROR] Could not connect to Qualys - %s' % e)
     self.headers = {"content-type": "text/xml"}
     self.config_parse = qcconf.QualysConnectConfig(config)
     try:
         self.template_id = self.config_parse.get_template_id()
     except:
         print('ERROR - Could not retrieve template ID')
コード例 #14
0
def query(url=None,
          params=None,
          username=None,
          password=None,
          remember_me=False,
          max_retries=_max_retries):

    _pc_scans_suffix = '/api/2.0/fo/scan/compliance'
    _pc_scans_list_dtd = ''

    if url is None or '':
        return False
    if params is None or '':
        return False
    if username is None or '':
        return False
    if password is None or '':
        return False
    else:
        _username = str(username)
        _password = str(password)

    try:
        ''' Create the API request if _suffix is valid based on API type'''
        with api.connect(hostname=url,
                         username=_username,
                         password=_password,
                         remember_me=remember_me,
                         max_retries=max_retries) as cnn:
            try:
                ''' Send the crafted API request '''
                with cnn.request(api_call=url,
                                 data=params,
                                 api_version='2.0',
                                 http_method='post') as response:
                    # TODO: Validate XML Reponse with DTD here
                    # If ok, pass response, response.status
                    return etree.fromstring(response.encode('utf-8')), \
                           response.status

            except Exception as ex:
                log.exception(f'Could not submit request to the Qualys API: '
                              f'{str(ex)}')
                return False

    except Exception as ex:
        log.exception(f'Could not use qualysapi to connect to Qualys API: '
                      f'{str(ex)}')
        return False
コード例 #15
0
def handle_command(command, channel):
    """
        Executes bot command if the command is known
    """
    # Default response is help text for the user
    default_response = "Not sure what you mean. Try *{}*.".format(
        EXAMPLE_COMMAND)

    # Finds and executes the given command, filling in response
    response = None
    # This is where you start to implement more commands!
    if command.startswith(EXAMPLE_COMMAND):
        q = qualysapi.connect()
        r = q.request('/api/2.0/fo/scan/', {
            'action': 'list',
            'state': 'Running'
        })
        root = objectify.fromstring(bytes(r, encoding='utf-8'))
        try:
            # Iterate scans and store scan references.
            for scan in root.RESPONSE.SCAN_LIST.SCAN:
                response = f'Canceling {scan.TITLE.text}: {scan.REF.text}...'
                # Sends the response back to the channel
                slack_client.api_call("chat.postMessage",
                                      channel=channel,
                                      text=response or default_response)
                r = q.request('/api/2.0/fo/scan/', {
                    'action': 'cancel',
                    'scan_ref': scan.REF.text
                })
                response = 'Failed to cancel scan, or scan has already been canceled.'
                if '<TEXT>Canceling scan</TEXT>' in r:
                    response = 'Successfully canceled scan.'
                slack_client.api_call("chat.postMessage",
                                      channel=channel,
                                      text=response or default_response)
        except AttributeError:
            response = 'No scans running.'
            slack_client.api_call("chat.postMessage",
                                  channel=channel,
                                  text=response or default_response)
コード例 #16
0
ファイル: sheachanddelete.py プロジェクト: SBB-Mx/Qualys
 def delete_ip(self):
     try:
         a = qualysapi.connect('config.ini')  #conexion a la API de Qualys
         #reportScans = a.request('/api/2.0/fo/asset/host/',{'action':'purge','echo_request':'1','ips':(self.ip)})
         reportScans = a.request('/api/2.0/fo/asset/host/', {
             'action': 'purge',
             'ips': (self.ip)
         })
         ### solo para debuging
         #print (reportScans)
         root = objectify.fromstring(reportScans.encode('utf-8'))
         print(root.RESPONSE.BATCH_LIST.BATCH.ID_SET.ID)
     except AttributeError:
         print("++++++++++++++++++++++++++++++++++++++++" '\n')
         print("Error Code " + root.RESPONSE.BATCH_LIST.BATCH.CODE.text)
         print("Description " + root.RESPONSE.BATCH_LIST.BATCH.TEXT.text +
               '\n')
         print("++++++++++++++++++++++++++++++++++++++++")
     else:
         for host in root.RESPONSE.BATCH_LIST.BATCH:
             print(host.TEXT.text)
             print(host.ID_SET.ID.text)
コード例 #17
0
ファイル: sheachanddelete.py プロジェクト: SBB-Mx/Qualys
 def search_ip(self):
     try:
         a = qualysapi.connect('config.ini')  #conexion a la API de Qualys
         reportScans = a.request('/api/2.0/fo/asset/host/', {
             'action': 'list',
             'details': 'All',
             'ips': (self.ip)
         })
         #print (reportScans)# Activar solo para troubleshoting
         root = objectify.fromstring(reportScans.encode('utf-8'))
         print(root.RESPONSE.HOST_LIST.HOST)
     except AttributeError:
         print('\n' "++++++++++++++++++++++++++++++++++++++++" '\n')
         print("host " + self.ip + " is not on Qualys")
         print('\n' "++++++++++++++++++++++++++++++++++++++++" '\n')
     else:
         for host in root.RESPONSE.HOST_LIST.HOST:
             print("++++++++++++++++++++++++++++++++++++++++" '\n')
             print("Server Information " '\n')
             print("----------------------------------------")
             print("IP: " + host.IP.text)
             try:  # Validar DNS
                 print("DNS: " + host.DNS.text)
             except AttributeError:
                 print("No DNS")
             print("OS: " + host.OS.text)
             try:  # Validar hostname
                 print("NETBIOS: " + host.NETBIOS.text)
             except AttributeError:
                 print("No Netbios")
             print("ID: " + host.ID.text)
             try:  # validad ultimo scan
                 print("LAST VULN SCAN: " +
                       host.LAST_VULN_SCAN_DATETIME.text)
             except AttributeError:
                 print("No last vuln info")
             print("----------------------------------------")
             print('\n' "++++++++++++++++++++++++++++++++++++++++" '\n')
コード例 #18
0
def purge(days):
	try:
		a = qualysapi.connect('config.ini')
		assets = a.request('/api/2.0/fo/asset/host/',{'action':'list','details':'All/AGs','no_vm_scan_since':days})
		#print(assets)
		root = objectify.fromstring(assets.encode('utf-8'))
		file = open("ips.csv","w+")
		file.write ("******************************************************"+'\n')
		file.write ("		 				  "+'\n')
		file.write ("		Vulnerabilty Management Team				  "+'\n')
		file.write ("		 				  "+'\n')
		file.write ("******************************************************"'\n')
		file.write("IP , NETBIOS ,Last vuln scan"'\n')
		for host in root.RESPONSE.HOST_LIST.HOST:
			#ipList = (host.DNS.text+host.IP.text+","+host.LAST_VULN_SCAN_DATETIME.text+'\n')
			print ('\n'"++++++++++++++++++++++++++++++++++++++++"'\n')
			print ("ID: "+host.ID.text)
			print ("IP: "+host.IP.text)
			file.write(host.IP.text+",")
			try: 
				print ("DNS: "+host.DNS.text)
				file.write(host.DNS.text+",")
			except AttributeError:
				print ("NO DNS ")
				file.write("NO HOSTNAME"+",")
			try: print ("OS: "+host.OS.text)
			except AttributeError:
				print ("No OS")
			print ("Last day scanned: "+host.LAST_VULN_SCAN_DATETIME.text)
			file.write(host.LAST_VULN_SCAN_DATETIME.text+'\n')
			try: 
				print ("Asset group: "+host.ASSET_GROUP_IDS.text)
			except AttributeError: 
				print ("No Asset group")
			print ('\n'"++++++++++++++++++++++++++++++++++++++++"'\n')
		file.close()
	except AttributeError:
		print("error", "I don't find data for host not scanned sice "+ days)	
            netbios = str(host.NETBIOS)
        except AttributeError, e:
            logging.debug("%s: No NetBIOS." % (ip, str(e)))
        # Grab OS.
        os = ""
        try:
            os = str(host.OS)
        except AttributeError, e:
            logging.debug("%s: No OS." % (ip, str(e)))
        # Write to CSV.
        csvwriter.writerow([ip, hostname, netbios, os])
        # Increment number of hosts found.
        count += 1
        # Store ip in set.
        subscribe_me.add(ip)
# All data stored. Print out to files.
print "Number of live, not scannable hosts found: %s" % str(count)
print "Host details successfully written to %s." % args.file_ip_list
# Subscribe IPs, if requested.
if not args.subscribe:
    exit()
if c_args.config:
    qgc = qualysapi.connect(c_args.config)
else:
    qgc = qualysapi.connect()
# Combine IPs to comma-delimited string.
formatted_ips_to_subscribe = ",".join(subscribe_me)
# Subscribe IPs.
qgc = qualysapi.connect("asset_ip.php", {"action": "add", "host_ips": formatted_ips_to_subscribe})
exit()
コード例 #20
0
import qualysapi
from lxml import objectify

q = qualysapi.connect()
response = q.request('/api/2.0/fo/scan/', {
    'action': 'list',
    'state': 'Running'
})
root = objectify.fromstring(bytes(response, encoding='utf-8'))
# Iterate scans and store scan references.
try:
    for scan in root.RESPONSE.SCAN_LIST.SCAN:
        print(f'Canceling {scan.TITLE.text}: {scan.REF.text}...')
        response = q.request('/api/2.0/fo/scan/', {
            'action': 'cancel',
            'scan_ref': scan.REF.text
        })
        if '<TEXT>Canceling scan</TEXT>' in response:
            print('Successfully canceled scan.')
except AttributeError:
    print('No scans running.')
コード例 #21
0
#!/usr/bin/env python
import logging

import qualysapi

if __name__ == '__main__':
    # Basic command line processing.
    # Set the MAXIMUM level of log messages displayed @ runtime.
    logging.basicConfig(level=logging.DEBUG)

    # Call helper that creates a connection w/ HTTP-Basic to QualysGuard v1 API
    qgs = qualysapi.connect('qualys.ini')

    # Logging must be set after instanciation of connector class.
    logger = logging.getLogger('qualysapi.connector')
    logger.setLevel(logging.DEBUG)

    # Log to sys.out.
    logger_console = logging.StreamHandler()
    logger_console.setLevel(logging.DEBUG)
    formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
    logging.getLogger(__name__).addHandler(logger)

    # Formulate a request to the QualysGuard V1 API
    #  docs @
    #  https://community.qualys.com/docs/DOC-1324
    #  http://www.qualys.com/docs/QualysGuard_API_User_Guide.pdf
    #
    # ret = qgs.request('/api/2.0/fo/asset/vhost/', {'action':'list'})
    ret = qgs.listVirtualHosts()
    for vhost in ret:
if c_args.debug:
    # Enable debug level of logging.
    print "Logging level set to debug."
    logging.basicConfig(filename = LOG_FILENAME, format = '%(asctime)s %(message)s',
                        level = logging.DEBUG)
else:
    logging.basicConfig(filename = LOG_FILENAME, format = '%(asctime)s %(message)s',
                        level = logging.INFO)
# Validate arguments.
if not ((c_args.all_apps or c_args.tag or c_args.Tags_file)):
    parser.print_help()
    logging.error('Invalid run parameters.')
    exit(1)
# Configure Qualys API connector.
if c_args.config:
    qgc = qualysapi.connect(c_args.config)
else:
    qgc = qualysapi.connect()
# There may be more than 1000 apps so start with first possible record, # 0.
last_record = '0'
apps_to_update = []
print 'Downloading list of applications.'
while True:
    # Get list of web apps.
    query_uri = '/search/was/webapp'
    if c_args.all_apps:
        data = '''
        <ServiceRequest>
            <filters>
                <Criteria field="createdDate" operator="GREATER">2000-02-21T00:00:00Z</Criteria>
                <Criteria field="id" operator="GREATER">%s</Criteria>
コード例 #23
0
def run(job, logger, **kwargs):

    start = time.time()
    state = 'success'
    scan_type = '{{Scan_Type}}'
    template_id = scan_type
    requestor_email = job.owner.user.email
    # Allow the user to have the PDF report sent to additional email addresses
    cc_list = '{{Email_List}}'
    # Allow the user to add custom text to the bottom of the email
    extra_body = '{{Email_Extra_Body}}'
    # Verify Cloudbolt know the email address of the requestor
    if requestor_email is None or requestor_email == '':
        return "FAILURE", "Please update your email in your user profile.", ""
    server = job.server_set.first()
    job_id = job.id
    session = qualysapi.connect()
    call = 'scan.php'
    ipaddr = ''
    error_code = ''
    # Build an array to capture a dictionary of Qualys Scanner, Server names and IPs
    # And Build and array of the scanners
    svr_info = []
    scanner_list = []
    for server in job.server_set.all():
        if str(server.status) == 'ACTIVE':
            svrinfo = {
                'scanner': str(server.environment.qualys_scanner),
                'ipaddress': str(server.ip),
                'name': str(server)
            }
            svr_info.append(svrinfo)
            scanner_list.append(str(server.environment.qualys_scanner))

    # Find the unique scanners
    scanners = set(scanner_list)
    for scanner in scanners:
        # build the list of IPs for this scanner
        ipaddr = ''
        svr_string = ''
        for svr in svr_info:
            if svr['scanner'] == scanner:
                svr_string = svr_string + svr['name'] + ' : ' + svr[
                    'ipaddress'] + '\n'
                if ipaddr == '':
                    ipaddr = svr['ipaddress']
                else:
                    ipaddr = ipaddr + ',' + svr['ipaddress']

        parameters = {
            'scan_title':
            'Scan of ' + str(ipaddr) + ': Initiated via Cloudbolt job ' +
            str(job.id) + ' on Scanner ' + scanner,
            'iscanner_name':
            scanner,
            'ip':
            str(ipaddr),
            'option':
            "!IHG - Internal - Authenticated Scan - Full TCP",
            'save_report':
            'yes'
        }
        logger.debug('Request parameters: ' + str(parameters))
        set_progress("- Running Qualys Scan...")
        xml_output = session.request(call,
                                     parameters,
                                     concurrent_scans_retries=2,
                                     concurrent_scans_retry_delay=300)
        root = objectify.fromstring(xml_output)
        if hasattr(root, 'IP'):
            logger.debug('Root Attrib: ' + str(root.attrib))

            gen_pdf_report = session.request(
                '/api/2.0/fo/report', {
                    'action': 'launch',
                    'template_id': template_id,
                    'report_title': 'Cloudbolt report for job ' + str(job.id),
                    'report_type': 'Scan',
                    'output_format': 'pdf',
                    'report_refs': root.attrib['value']
                })
            gen_pdf = objectify.fromstring(gen_pdf_report)
            pdf_report_id = gen_pdf.RESPONSE.ITEM_LIST.ITEM['VALUE']

            gen_xml_report = session.request(
                '/api/2.0/fo/report', {
                    'action': 'launch',
                    'template_id': template_id,
                    'report_title': 'Cloudbolt report for job ' + str(job.id),
                    'report_type': 'Scan',
                    'output_format': 'xml',
                    'report_refs': root.attrib['value']
                })
            gen_xml = objectify.fromstring(gen_xml_report)
            xml_report_id = gen_xml.RESPONSE.ITEM_LIST.ITEM['VALUE']

            logger.debug('Waiting for XML Report to be Generated')
            retries = 40
            sleepseconds = 15
            count = 1
            while count <= retries:
                time.sleep(sleepseconds)
                xml_status_request = session.request('/api/2.0/fo/report', {
                    'action': 'list',
                    'id': xml_report_id
                })
                xml_status = objectify.fromstring(xml_status_request)
                logger.debug(xml_status)
                if hasattr(xml_status.RESPONSE,
                           'REPORT_LIST') and xml_status.RESPONSE.REPORT_LIST[
                               0].REPORT.STATUS['STATE'] == 'Finished':
                    count = retries * 2 + 10
                count += 1
            xml_report = session.request('/api/2.0/fo/report', {
                'action': 'fetch',
                'id': xml_report_id
            })

            report = objectify.fromstring(xml_report)
            sum_vuls = 0
            sev1 = 0
            sev2 = 0
            sev3 = 0
            sev4 = 0
            sev5 = 0
            if hasattr(report, 'IP'):
                logger.debug('report Attrib: ' + str(report.attrib))
                for svrip in report.IP:
                    svrname = svrip.attrib['name']
                    if hasattr(svrip, 'VULNS'):
                        for x in svrip.VULNS.CAT:
                            sum_vuls += len(x.VULN)
                            for vul in x.VULN:
                                set_progress('Server: ' + svrname +
                                             ' , Severity: ' +
                                             vul.attrib['severity'] +
                                             ' , QID: ' +
                                             vul.attrib['number'] +
                                             ' , VULNERBILITY: ' + vul.TITLE)
                                if vul.attrib['severity'] == '1': sev1 += 1
                                if vul.attrib['severity'] == '2': sev2 += 1
                                if vul.attrib['severity'] == '3': sev3 += 1
                                if vul.attrib['severity'] == '4': sev4 += 1
                                if vul.attrib['severity'] == '5': sev5 += 1
                    else:
                        logger.debug('NO Vulnerabilites found for ' +
                                     str(svrname))

            sum_3_5 = sev3 + sev4 + sev5
            sum_1_2 = sev1 + sev2
            set_progress(
                str(sum_3_5) + ' Critical Vunerabilites Found. Sev 5: ' +
                str(sev5) + ', Sev 4: ' + str(sev4) + ', Sev 3: ' + str(sev3))
            if sum_1_2 > 0:
                set_progress(
                    str(sum_1_2) +
                    ' Non-Critical Vunerabilites Found.  Sev 2: ' + str(sev2) +
                    ', Sev 1: ' + str(sev1))
            if sum_3_5 > 0: state = 'warning'
            del_xml = session.request('/api/2.0/fo/report', {
                'action': 'delete',
                'id': xml_report_id
            })

            logger.debug('Waiting for PDF Report to be Generated')
            count = 1
            while count <= retries:
                time.sleep(sleepseconds)
                pdf_status_request = session.request('/api/2.0/fo/report', {
                    'action': 'list',
                    'id': pdf_report_id
                })
                pdf_status = objectify.fromstring(pdf_status_request)
                if pdf_status.RESPONSE.REPORT_LIST[0].REPORT.STATUS[
                        'STATE'] == 'Finished':
                    count = retries * 2 + 10
                count += 1

            pdf_report = session.request('/api/2.0/fo/report', {
                'action': 'fetch',
                'id': pdf_report_id
            })
            filename = '/tmp/' + str(job.id) + '.pdf'
            with open(filename, 'wb') as f:
                f.write(pdf_report)
            f.close
            subject = 'Qualys Report for Cloudbolt job ' + str(job.id)

            if extra_body and extra_body != '':
                body = subject + '\n\nScanned Servers\n' + svr_string + extra_body
            else:
                body = subject + '\n\nScanned Servers\n' + svr_string
            sender = requestor_email
            recipient = [requestor_email]
            if cc_list and cc_list != '':
                ccs = cc_list.split(',')
                recipient.extend(ccs)
            attach = [(filename, 'application/pdf')]
            mail.send_mail(subject,
                           body,
                           sender,
                           recipient,
                           attachments=attach,
                           filter_recipients=False)
            os.remove(filename)

        else:
            logger.debug('Error Code: ' + str(root.ERROR.attrib['number']))
            state = 'fail'
            error_code = root.ERROR.attrib['number']

    done = time.time()
    restoreduration = "%.2f" % (done - start)
    logger.debug("Qualys Scan duration(secs): " + restoreduration)

    if state == 'success':
        return "SUCCESS", "Qualys Scan successfully completed. Check your email for PDF reports", ""
    elif state == 'warning':
        return "WARNING", "Qualys Scan found vulneribilities", ""
    else:
        if error_code == '3007':
            return "FAILURE", "Too many concurrent scans running at this time. Please try again later.", ""
        elif error_code == '3003':
            return "FAILURE", "Not Allowed to scan these IPs.", ""
        else:
            logger.debug('xml return from Qualys: ' + xml_output)
            return "FAILURE", "Qualys Scan request failed with unknown error", ""
コード例 #24
0
#! /usr/bin/python

"""
Licence : BeerWare
"""

import sys, qualysapi

login = qualysapi.connect(remember_me_always=True)
コード例 #25
0
import qualysapi

# Questions?  See:
#  https://bitbucket.org/uWaterloo_IST_ISS/python-qualysconnect

if __name__ == '__main__':
    # Basic command line processing.
    if len(sys.argv) != 2:
        print 'A single IPv4 address is expected as the only argument'
        sys.exit(2)
    
    # Set the MAXIMUM level of log messages displayed @ runtime. 
    logging.basicConfig(level=logging.INFO)
    
    # Call helper that creates a connection w/ HTTP-Basic to QualysGuard API.
    qgs=qualysapi.connect()

    # Logging must be set after instanciation of connector class.
    logger = logging.getLogger('qualysapi.connector')
    logger.setLevel(logging.DEBUG)

    # Log to sys.out.
    logger_console = logging.StreamHandler()
    logger_console.setLevel(logging.DEBUG)
    formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
    logging.getLogger(__name__).addHandler(logger)

    # Formulate a request to the QualysGuard V1 API.
    #  docs @
    #  https://community.qualys.com/docs/DOC-1324
    #  http://www.qualys.com/docs/QualysGuard_API_User_Guide.pdf
コード例 #26
0
from defusedxml.ElementTree import fromstring
from qualysapi import connect

# API url to pull data from. See qualys docs for a list of APIs
api_url = "/api/2.0/fo/asset/host/"

# Options for API request. See qualys docs for a list of all options
params = {
    'action': 'list',
    'truncation_limit': '10',
}

# Create a connection object used to pull data from Qualys
conn = connect(
    username="******",  # Qualys Username
    password="******",  # Qualys Password
    hostname="<hostname>",  # Optional api host url
    max_retries="<#>",  # Optional # of retries
)

# Perform API request
resp = conn.request(api_url, params)
print(resp)  # Raw text response from Qualys

# Parse the response string and convert to an xml object
xml = fromstring(resp.encode('utf-8'))
for host in xml.iter(tag='HOST'):
    id = host.find('./ID').text
    ip = host.find('./DNS').text
    print(id + ": " + ip)
コード例 #27
0
ファイル: qualysapi-example.py プロジェクト: uovobw/qualysapi
__author__ = 'Parag Baxi <*****@*****.**>'
__license__ = 'Apache License 2.0'

import qualysapi
from lxml import objectify
from lxml.builder import E

# Setup connection to QualysGuard API.
qgc = qualysapi.connect('config.txt')
#
# API v1 call: Scan the New York & Las Vegas asset groups
# The call is our request's first parameter.
call = 'scan.php'
# The parameters to append to the url is our request's second parameter.
parameters = {
    'scan_title': 'Go big or go home',
    'asset_groups': 'New York&Las Vegas',
    'option': 'Initial+Options'
}
# Note qualysapi will automatically convert spaces into plus signs for API v1 & v2.
# Let's call the API and store the result in xml_output.
xml_output = qgc.request(call,
                         parameters,
                         concurrent_scans_retries=2,
                         concurrent_scans_retry_delay=600)
# concurrent_retries: Retry the call this many times if your subscription hits the concurrent scans limit.
# concurrent_retries: Delay in seconds between retrying when subscription hits the concurrent scans limit.
# Example XML response when this happens below:
#     <?xml version="1.0" encoding="UTF-8"?>
#     <ServiceResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://localhost:50205/qps/rest/app//xsd/3.0/was/wasscan.xsd">
#       <responseCode>INVALID_REQUEST</responseCode>
コード例 #28
0
__author__ = 'Parag Baxi <*****@*****.**>'
__license__ = 'Apache License 2.0'

import qualysapi
from lxml import objectify
from lxml.builder import E

# Setup connection to QualysGuard API.
qgc = qualysapi.connect('config.txt', 'qualys_vuln')
#
# API v1 call: Scan the New York & Las Vegas asset groups
# The call is our request's first parameter.
call = 'scan.php'
# The parameters to append to the url is our request's second parameter.
parameters = {
    'scan_title': 'Go big or go home',
    'asset_groups': 'New York&Las Vegas',
    'option': 'Initial+Options'
}
# Note qualysapi will automatically convert spaces into plus signs for API v1 & v2.
# Let's call the API and store the result in xml_output.
xml_output = qgc.request(call,
                         parameters,
                         concurrent_scans_retries=2,
                         concurrent_scans_retry_delay=600)
# concurrent_retries: Retry the call this many times if your subscription hits the concurrent scans limit.
# concurrent_retries: Delay in seconds between retrying when subscription hits the concurrent scans limit.
# Example XML response when this happens below:
#     <?xml version="1.0" encoding="UTF-8"?>
#     <ServiceResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://localhost:50205/qps/rest/app//xsd/3.0/was/wasscan.xsd">
#       <responseCode>INVALID_REQUEST</responseCode>
コード例 #29
0
# logger_qc.addHandler(logger_file)
# logger_qc.addHandler(logger_console)
# Validate arguments.
if (not (c_args.all_vulns_template_id or c_args.all_vulns_xml)
        and (c_args.exclude_non_running_kernel_vulns_report_template_id
             or c_args.exclude_non_running_kernel_vulns_xml)):
    # if (not (c_args.all_vulns_xml and c_args.exclude_non_running_kernel_vulns_xml)):
    print 'One of each report is required.'
    parser.print_help()
    exit(1)
# Configure Qualys API connector.
if (c_args.mark_remediation_tickets_resolved_ignore
        or c_args.all_vulns_template_id
        or c_args.exclude_non_running_kernel_vulns_report_template_id):
    if c_args.config:
        qgc = qualysapi.connect(c_args.config)
    else:
        qgc = qualysapi.connect()
#
# Read in XML report including non-running kernels.
if c_args.all_vulns_xml:
    # Read in XML file.
    tree = etree.parse(c_args.all_vulns_xml)
else:
    # Grab XML from QualysGuard.
    tree = etree.parse(load_scan(c_args.all_vulns_template_id, c_args.title))
# Find all TICKET_NUMBER elements that contain associated remediation ticket numbers.
all_vulns = tree.findall(".//TICKET_NUMBER")
# Read in XML report excluding non-running kernels.
if c_args.exclude_non_running_kernel_vulns_xml:
    # Read in XML file.
コード例 #30
0
        try:
            netbios = str(host.NETBIOS)
        except AttributeError, e:
            logging.debug('%s: No NetBIOS.' % (ip, str(e)))
        # Grab OS.
        os = ''
        try:
            os = str(host.OS)
        except AttributeError, e:
            logging.debug('%s: No OS.' % (ip, str(e)))
        # Write to CSV.
        csvwriter.writerow([ip, hostname, netbios, os])
        # Increment number of hosts found.
        count += 1
        # Store ip in set.
        subscribe_me.add(ip)
# All data stored. Print out to files.
print 'Number of live, not scannable hosts found: %s' % str(count)
print 'Host details successfully written to %s.' % args.file_ip_list
# Subscribe IPs, if requested.
if not args.subscribe:
    exit()
if c_args.config:
    qgc = qualysapi.connect(c_args.config)
else:
    qgc = qualysapi.connect()
# Combine IPs to comma-delimited string.
formatted_ips_to_subscribe = ','.join(subscribe_me)
# Subscribe IPs.
qgc = qualysapi.connect('asset_ip.php',{'action': 'add', 'host_ips': formatted_ips_to_subscribe})
exit()
コード例 #31
0
__author__ = 'Parag Baxi <*****@*****.**>'
__license__ = 'Apache License 2.0'

import qualysapi
from lxml import objectify
from lxml.builder import E

# Setup connection to QualysGuard API.
qgc = qualysapi.connect('config.txt', 'qualys_vuln')
#
# API v1 call: Scan the New York & Las Vegas asset groups
# The call is our request's first parameter.
call = 'scan.php'
# The parameters to append to the url is our request's second parameter.
parameters = {'scan_title': 'Go big or go home', 'asset_groups': 'New York&Las Vegas', 'option': 'Initial+Options'}
# Note qualysapi will automatically convert spaces into plus signs for API v1 & v2.
# Let's call the API and store the result in xml_output.
xml_output = qgc.request(call, parameters, concurrent_scans_retries=2, concurrent_scans_retry_delay=600)
# concurrent_retries: Retry the call this many times if your subscription hits the concurrent scans limit.
# concurrent_retries: Delay in seconds between retrying when subscription hits the concurrent scans limit.
# Example XML response when this happens below:
#     <?xml version="1.0" encoding="UTF-8"?>
#     <ServiceResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://localhost:50205/qps/rest/app//xsd/3.0/was/wasscan.xsd">
#       <responseCode>INVALID_REQUEST</responseCode>
#       <responseErrorDetails>
#         <errorMessage>You have reached the maximum number of concurrent running scans (10) for your account</errorMessage>
#         <errorResolution>Please wait until your previous scans have completed</errorResolution>
#       </responseErrorDetails>
#
print(xml_output)
#
__author__ = 'pbaxi'

import csv
import qualysapi
from lxml import objectify, etree
from collections import defaultdict

# Connect to QualysGuard API.
qgc = qualysapi.connect()
# Create request and download XML.
request = '/msp/scheduled_scans.php'
parameters = {'list': 'all'}
print 'Downloading list of scheduled scans...'
xml_output = qgc.request(request, parameters)
# Process XML.
root = objectify.fromstring(xml_output)
# Combine IPs being scanned.
# Combine asset groups
max_number_of_scanners = 0
max_number_of_asset_groups = 0
orphan_scanners = []
asset_groups = defaultdict(list)
scanners = defaultdict(list)
# Parse XML.
list_of_scanners = []
for appliance in root.RESPONSE.APPLIANCE_LIST.APPLIANCE:
    try:
        for asset_group in appliance.ASSET_GROUP_LIST.ASSET_GROUP:
            # For sorted by scanners.
            asset_groups[asset_group.NAME.text].append(appliance.NAME.text)
            max_number_of_scanners = max(len(asset_groups[asset_group.NAME.text])+1, max_number_of_scanners)
コード例 #33
0
ファイル: main.py プロジェクト: shivaneej/Qualys
from qualysapi import connect
from lxml import objectify, etree
from file_integrity_monitor import *
import sys
from port_scanning import *


def get_number(call):
    xml = qualysConnection.request(call)
    xml = xml.encode('UTF-8')
    doc = etree.XML(xml)
    return doc.find('count').text


try:
    qualysConnection = qualysapi.connect('config.ini')
    while (True):
        choice = int(
            input(
                "1. File Integrity Monitoring 2. Scan Ports 3. Show number of webapps hosted 4. Show number of scans scheduled 5. Show number of reports generated 6. Show number of times scanned 7. Stop\nEnter choice: "
            ))
        if choice == 1:
            fim()
        elif choice == 2:
            target_host = input("Enter the hostname to be scanned: ")
            scanPorts(target_host)
        elif choice == 3:
            print("Number of webapps:", get_number('/count/was/webapp'), '\n')
        elif choice == 4:
            print("Number of scan scheduled:",
                  get_number('/count/was/wasscanschedule'), '\n')
コード例 #34
0
__author__ = 'Parag Baxi <*****@*****.**>'
__license__ = 'Apache License 2.0'

import qualysapi
from lxml import objectify
from lxml.builder import E

# Setup connection to QualysGuard API.
qgc = qualysapi.connect('config.txt')
#
# API v1 call: Scan the New York & Las Vegas asset groups
# The call is our request's first parameter.
call = 'scan.php'
# The parameters to append to the url is our request's second parameter.
parameters = {'scan_title': 'Go big or go home', 'asset_groups': 'New York&Las Vegas', 'option': 'Initial+Options'}
# Note qualysapi will automatically convert spaces into plus signs for API v1 & v2.
# Let's call the API and store the result in xml_output.
xml_output = qgc.request(call, parameters, concurrent_scans_retries=2, concurrent_scans_retry_delay=600)
# concurrent_retries: Retry the call this many times if your subscription hits the concurrent scans limit.
# concurrent_retries: Delay in seconds between retrying when subscription hits the concurrent scans limit.
# Example XML response when this happens below:
#     <?xml version="1.0" encoding="UTF-8"?>
#     <ServiceResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://localhost:50205/qps/rest/app//xsd/3.0/was/wasscan.xsd">
#       <responseCode>INVALID_REQUEST</responseCode>
#       <responseErrorDetails>
#         <errorMessage>You have reached the maximum number of concurrent running scans (10) for your account</errorMessage>
#         <errorResolution>Please wait until your previous scans have completed</errorResolution>
#       </responseErrorDetails>
#
print xml_output
#
コード例 #35
0
#!/usr/bin/env python3

# Use the defusedxml package for all xml parsing. See bandit docs: 
# https://bandit.readthedocs.io/en/latest/blacklists/blacklist_imports.html#b405-import-xml-etree
from defusedxml.ElementTree import fromstring
from qualysapi import connect

# Config settings
delimiter = "|"
api_url = "/api/2.0/fo/asset/group"
out_file = "out-asset-groups-list.csv"

# Connect to Qualys API
conn = connect()

# Options for API request. See qualys docs for a list of all options
params = {'action': 'list',
          'truncation_limit': '0'}

# Perform API request
resp = conn.request(api_url, params)

# Parse the response string and convert to an xml object
xml = fromstring(resp.encode('utf-8'))
ags = {}
with open(out_file, "w+") as f:
    f.write('id' + delimiter + 'title' + delimiter + 'network_id' + delimiter + \
            'ip_ranges' + '\n')
    for ag in xml.iter(tag='ASSET_GROUP'):

        # Get the ID for the asset group