def add_user(self, access_req): self.url = self.qualys_host + "/msp/user.php" usrLst = access_req['userList'] for user in usrLst: userinfo = user.split(',') # uname,name,email pswd = userinfo[0] + '!vul5c4p1' parms = {'action': 'add', 'user_role': 'scanner', 'business_unit': 'Unassigned', 'asset_groups': access_req['site_name'], 'first_name': userinfo[1].split(' ')[0], 'last_name': userinfo[1].split(' ')[1], 'title': 'Scanner User', 'phone': '0000000000', 'email': userinfo[2], 'address1': '3401 Hillview Ave', 'city': 'Palo Alto', 'country': 'United States of America', 'state': 'California', 'zip_code': '94304', 'send_email': '1'} response_user_add = self.makeRequest(parms) # print(response_user_add.content) responseXML = response_user_add.content tree = ElementTree(fromstring(responseXML)) root = tree.getroot() asset_response = root.find('RETURN') user_add_status = asset_response.get('status') user_add_status_msg = asset_response.find('MESSAGE').text # print(user_add_status + user_add_status_msg) if user_add_status == "SUCCESS": Utilities.printSuccess( user_add_status_msg +" for " + userinfo[1]) return True else: Utilities.printError("User addition Failure: " + user_add_status_msg) return False
def add_asset(self, access_req): self.url = self.qualys_host + "/api/2.0/fo/asset/ip/" params = {'action': 'add', 'ips': access_req['ip'], 'enable_vm': '1'} max_login_try_limit = 2 while True: # Login check done here, if it fails here then rest all task is skipped if (self.login_try > 0) and (self.login_try < max_login_try_limit): self.uname = input("Please enter your username for " + " Qualys" + ": ") self.passwd = input("Please enter your password for " + " Qualys" + ": ") elif self.login_try >= max_login_try_limit: Utilities.printError("Qualys login attemts exceded maximum limit, skipping Qualys tasks..") return False response_aasset_add = self.makeRequest(params) # print(response_aasset_add.content) responseXML = response_aasset_add.content tree = ElementTree(fromstring(responseXML)) root = tree.getroot() asset_response = root.find('RESPONSE') asset_status = asset_response.find('TEXT').text if asset_status == "IPs successfully added to Vulnerability Management": Utilities.printSuccess("Asset added to Qualys Scanner") return True elif asset_status == "Bad Login/Password": Utilities.printError("Qualys login failed..") self.login_try += 1 else: Utilities.printError("Asset adition Failure: " + asset_status) Utilities.printLog("Skipping remaning Qualys tasks..") return False
def create_user(self, access_req): try: # Create User create_user_URL = self.nessus_host + "/users" usrLst = access_req['userList'] for user in usrLst: userinfo = user.split(',') # uname,name,email pswd = Utilities.gen_code() payload = {'username': userinfo[0], 'password': pswd, 'permissions': '32', 'name': userinfo[1], 'email': userinfo[2], 'type': 'local'} response = self.makeRequest(create_user_URL, json.dumps(payload), self.headers) json_rep = json.loads(response.decode("utf-8")) # print(json_rep) if self.status_code == 200: Utilities.printSuccess("Created user: "******"Nessus\nUsername:"******"\nPassword:"******"User creation Failure: Invalid field request") return False if self.status_code == 403: Utilities.printError("User creation Failure: No permission to create a user") return False if self.status_code == 409: Utilities.printError("User creation Failure: Duplicate username") return False except Exception as e: Utilities.printException(str(e))
def login_nessus(self, scanner_info): sessionreqURL = self.nessus_host + "/session" max_login_try_limit = 2 while True: if self.login_try == 0: payload = {'username': scanner_info['uname'], 'password': scanner_info['passwd']} elif self.login_try > 0 and self.login_try < max_login_try_limit: usr_name = input("Please enter your username for " + " Nessus" + ": ") usr_passwd = input("Please enter your password for " + " Nessus" + ": ") payload = {'username': usr_name, 'password': usr_passwd} else: Utilities.printError("Nessus login attemts exceded maximum limit, skipping Nessus tasks..") return False response = self.makeRequest(sessionreqURL, json.dumps(payload), self.headers) json_rep = json.loads(response.decode("utf-8")) # convert to string then convert to json # print(json_rep) if self.status_code == 200: self.session_token = json_rep['token'] self.headers.update({'X-Cookie': 'token=' + self.session_token}) # session token added to HTTP header # print(self.headers) Utilities.printSuccess("Logged in to Nessus Scanner") return True elif self.status_code == 400: Utilities.printError("Login Failure: username format is not valid") self.login_try += 1 elif self.status_code == 401: Utilities.printError("Login Failure: username or password is invalid") self.login_try += 1 elif self.status_code == 500: Utilities.printError("Login Failure: too many users are connected") self.login_try += 1
def addSite(self, access_req): # print("TestModule:SiteManagement") siteSaveRequest = Element('SiteSaveRequest', attrib={'session-id': self.session_id}) # print(access_req['site_name']) # Site element have 'S' in caps !!--lost a day on this !! site_elem = SubElement(siteSaveRequest, 'Site', attrib={'name': access_req['site_name'], 'id': '-1'}) host_elem = SubElement(site_elem, 'Hosts') for ip in access_req['ip'].split(','): range_elem = SubElement(host_elem, 'range', attrib={'from': ip, 'to': ''}) scanConfig_elem = SubElement(site_elem, 'ScanConfig', attrib={'name': 'Full audit', 'templateID': 'full-audit'}) xmlTree = ElementTree(siteSaveRequest) f = BytesIO() xmlTree.write(f, encoding='utf-8', xml_declaration=True) # required so that xml declarations will come up in generated XML saveSiteReqXML = f.getvalue().decode("utf-8") # converts bytes to string # print(saveSiteReqXML) responseXML = self.makeRequest(self.reqURL, saveSiteReqXML, self.headers) tree = ElementTree(fromstring(responseXML)) root = tree.getroot() addSiteResponse = root.get('success') if (addSiteResponse == "1"): self.site_id = root.get('site-id') Utilities.printSuccess("Created site with site-id: " + self.site_id) return True else: fa = root.find('Failure') ex = fa.find('Exception') msg = ex.find('message').text Utilities.printError("Site creation failed: " + msg) return False
def login_nexpose(self, scanner_info): # API v1.1 Login and get the session here max_login_try_limit = 2 while True: if self.login_try == 0: xmlReq = Element('LoginRequest', attrib={'user-id': scanner_info['uname'], 'password': scanner_info['passwd']}) elif self.login_try > 0 and self.login_try < max_login_try_limit: usr_name = input("Please enter your username for " + " Nexpose" + ": ") usr_passwd = input("Please enter your password for " + " Nexpose" + ": ") xmlReq = Element('LoginRequest', attrib={'user-id': usr_name, 'password': usr_passwd}) else: Utilities.printError("Nexpose login attemts exceded maximum limit, skipping Nexpose tasks..") return False xmlReq = Element('LoginRequest', attrib={'user-id': scanner_info['uname'], 'password': scanner_info['passwd']}) xmlTree = ElementTree(xmlReq) f = BytesIO() xmlTree.write(f, encoding='utf-8', xml_declaration=True) # required so that xml declarations will come up in generated XML loginReqXML = f.getvalue().decode("utf-8") # converts bytes to string # print(self.loginReqXML) responseXML = self.makeRequest(self.reqURL, loginReqXML, self.headers) tree = ElementTree(fromstring(responseXML)) root = tree.getroot() loginResponse = root.get('success') if (loginResponse == "1"): self.session_id = root.get('session-id') Utilities.printSuccess("Logged in to Nexpose Scanner") return True else: fa = root.find('Failure') ex = fa.find('Exception') msg = ex.find('message').text Utilities.printError("Login Failure: " + msg) self.login_try += 1
def addUser(self, access_req): # print("addUser Module") usrLst = access_req['userList'] for user in usrLst: usrSaveRequest = Element('UserSaveRequest', attrib={'session-id': self.session_id}) userinfo = user.split(',') # uname,name,email pswd = Utilities.gen_code() usrConfig_elem = SubElement(usrSaveRequest, 'UserConfig', attrib={'id': '-1', 'role-name': 'user', 'authsrcid': '-1', 'enabled': '1', 'name': userinfo[0], 'fullname': userinfo[1], 'email': userinfo[2], 'password': pswd}) sites_elem = SubElement(usrConfig_elem, 'UserSite') site_elem = SubElement(sites_elem, 'site', attrib={'id': self.site_id}) site_elem.text = access_req['site_name'] xmlTree = ElementTree(usrSaveRequest) f = BytesIO() xmlTree.write(f, encoding='utf-8', xml_declaration=True) # required so that xml declarations will come up in generated XML usrSaveReqXML = f.getvalue().decode("utf-8") # converts bytes to string # print(usrSaveReqXML) responseXML = self.makeRequest(self.reqURL, usrSaveReqXML, self.headers) # print(responseXML) tree = ElementTree(fromstring(responseXML)) root = tree.getroot() addUserReq = root.get('success') if (addUserReq == "1"): Utilities.printSuccess("Created user: "******"Nexpose\nUsername:"******"\nPassword:"******"User creation failed: " + msg) return False
def logout_user(self): try: # destroy the user session logoutURL = self.nessus_host + "/session" response = self.makeRequest(logoutURL, {}, self.headers, "DELETE") if self.status_code == 200: Utilities.printSuccess("Logged out of Nessus Scanner") if self.status_code == 401: Utilities.printSuccess("Logged out failure: No session exists") except Exception as e: Utilities.printException(str(e))
def add_IP(self, s, target_IP): #set up host authentication payload = { 'action':'add', 'ips':target_IP, 'enable_vm':1, 'enable_pc':0, } r = s.post('https://qualysapi.qualys.com/api/2.0/fo/asset/ip/', data=payload) xmlreturn = ET.fromstring(r.text) for elem in xmlreturn.findall('.//TEXT'): if "action has invalid value" in elem.text: Utilities.printError("You do not have permissions do add IP(s)") else: Utilities.printSuccess(elem.text)
def setup_auth(self, s, target_IP, username, password, title): #set up host authentication status = "Success" payload = { 'action':'create', 'title':title+'_'+target_IP, 'ips':target_IP, 'username':username, 'password':password, } r = s.post('https://qualysapi.qualys.com/api/2.0/fo/auth/unix/', data=payload) xmlreturn = ET.fromstring(r.text) for elem in xmlreturn.findall('.//TEXT'): if "action has invalid value" in elem.text: Utilities.printError("You do not have permissions do add authentication records") else: Utilities.printSuccess("Authentication Record " + elem.text) if "existing scan auth record has the specified title" in elem.text: #delete the auth record payload = { 'action':'list', 'title':target_IP } r = s.post('https://qualysapi.qualys.com/api/2.0/fo/auth/unix/', data=payload) xmlreturn = ET.fromstring(r.text) for elem in xmlreturn.findall('.//AUTH_UNIX'): title_id = elem[0].text payload = { 'action':'delete', 'ids':title_id, } r = s.post('https://qualysapi.qualys.com/api/2.0/fo/auth/unix/', data=payload) xmlreturn = ET.fromstring(r.text) for elem in xmlreturn.findall('.//TEXT'): status = elem.text Utilities.printLog("Authentication Record " + status) self.setup_auth(s, target_IP, username, password, title) elif "one or more of the specified IPs" in elem.text: #delete the auth record status = "Failure" Utilities.printError("---\nPlease note:\nIP exists in another authentication record\nQualys doesn't support multiple authentication record of same type for any IP\nPlease delete the existing authentication record manually to proceed.\n---") return status
def logoutOperation(self): xmlReq = Element('LogoutRequest', attrib={'session-id': self.session_id}) xmlTree = ElementTree(xmlReq) f = BytesIO() xmlTree.write(f, encoding='utf-8', xml_declaration=True) # required so that xml declarations will come up in generated XML logoutReqXML = f.getvalue().decode("utf-8") # converts bytes to string # print(logoutReqXML) responseXML = self.makeRequest(self.reqURL, logoutReqXML, self.headers) tree = ElementTree(fromstring(responseXML)) root = tree.getroot() logoutResponse = root.get('success') if (logoutResponse == "1"): self.session_id = root.get('session-id') Utilities.printSuccess("Logged out of Nexpose Scanner") else: fa = root.find('Failure') ex = fa.find('Exception') msg = ex.find('message').text Utilities.printError("Logout Failure: " + msg)
def add_asset_grp(self, access_req): scanner_id = self.get_scanners() self.url = self.qualys_host + "/api/2.0/fo/asset/group/" if scanner_id is not None: params = {'action': 'add', 'ips': access_req['ip'], 'title': access_req['site_name'], 'appliance_ids':scanner_id} # print(self.url) response_asset_grp_add = self.makeRequest(params) # print(response_asset_grp_add.content) responseXML = response_asset_grp_add.content tree = ElementTree(fromstring(responseXML)) root = tree.getroot() asset_response = root.find('RESPONSE') asset_status = asset_response.find('TEXT').text if asset_status == "Asset Group successfully added.": Utilities.printSuccess("Asset group added to Qualys Scanner") return True else: Utilities.printError("Asset group addition Failure: " + asset_status) Utilities.printLog("Skipping remaning Qualys tasks..") return False else: Utilities.printError("Asset Group adition Failure: Scanner id not found") return False