def fetch_logintoken(self, url, method, headers, body=None, relogin=None): if method.upper() == "GET": login_request = requests.get(url, headers=headers) elif method.upper() == "POST": #print headers,body login_request = requests.post(url, headers=headers, json=body) #debugging logs.logging.info("HTTP response of login API : %s %s %s", login_request.status_code, headers, body) else: print "[-]Invalid request" sys.exit(1) try: cookie = {'cookie': login_request.headers['Set-Cookie']} print "Login successful" update_value('login', 'auth', cookie) update_value('login', 'auth_type', 'cookie') return True except: if relogin is not None: print "Session fixation attack won't be tested since it failed to re-login." return login_response = raw_input( "Failed to fetch cookie. Do you want to continue scanning without cookie(y/n)," + self.api_logger.G + url + ': ' + self.api_logger.W) if login_response == 'Y' or login_response == 'y': return elif login_response == 'n' or login_response == 'N': sys.exit(1)
def main(): (collection_type, collection_name, url, headers, method, body, loginurl, loginheaders, logindata) = get_arg(sys.argv[1:]) if loginheaders is None: loginheaders = {'Content-Type': 'application/json'} if (collection_type and collection_name and loginurl and loginmethod and logindata): # Login data is given as an input. api_login.fetch_logintoken(loginurl, loginmethod, loginheaders, logindata) login_require = False elif collection_type and collection_name and loginurl: parse_collection(collection_name, collection_type) try: (loginurl, lognheaders, loginmethod, logidata) = api_login.parse_logindata(loginurl) except: print "[-]%s Failed to detect login API from collection %s " % ( api_logger.R, api_logger.W) sys.exit(1) api_login.fetch_logintoken(loginurl, loginmethod, loginheaders, logindata) login_require = False elif loginurl and loginmethod: api_login.fetch_logintoken(loginurl, loginmethod, loginheaders, logindata) login_require = False elif collection_type and collection_name and headers: # Custom headers update_value('login', 'header', headers) login_require = False elif url and collection_name and headers: # Custom headers update_value('login', 'header', headers) login_require = False elif url: if headers is None: headers = {'Content-Type': 'application/json'} if method is None: method = "GET" login_require = False else: login_require = True if body: body = ast.literal_eval(body) # Configuring ZAP before starting a scan get_auth = get_value('config.property', 'login', 'auth_type') if collection_type and collection_name is not None: scan_core(collection_type, collection_name, url, headers, method, body, loginurl, loginheaders, logindata, login_require) else: scanid = generate_scanid() scan_single_api(url, method, headers, body, "F", scanid) scan_complete()
def fetch_logintoken(self, url, method, headers, body=None, relogin=None): if method.upper() == "GET": login_request = requests.get(url, headers=headers) elif method.upper() == "POST": login_request = requests.post(url, headers=headers, json=body) logs.logging.info("HTTP response of login API : %s %s %s", login_request.status_code, headers, body) else: print "[-]Invalid request" sys.exit(1) try: login_response = json.loads(login_request.text) except: pass if relogin is not None: print "Session fixation attack won't be tested since it failed to re-login." return auth_names = get_value('config.property', 'login', 'auth_names') auth_type = get_value('config.property', 'login', 'auth_type') auth_names = auth_names.split(',') #auth_header = get_value('config.property','login','auth_header') # Auth types: # 1. Cookie # 2. Basic # 3. Oauth auth_status = False if auth_type == 'cookie': if login_request.headers['Set-Cookie']: auth_cookie = {'cookie': login_request.headers['Set-Cookie']} print "[+]Login successful" update_value('login', 'auth_success', 'Y') update_value('login', 'cookie', auth_cookie) auth_status = True # Basic and oauth auth type code will come here(yet to develop). else: for auth_name in auth_names: if auth_name in login_response: auth_success_token = login_response[auth_name] print "[+]Login successful" update_value('login', 'auth_success', 'Y') update_value('login', 'auth_success_param', auth_name) update_value('login', 'auth_success_token', auth_success_token) auth_status = True break if not auth_status: login_response = raw_input( "Failed to login. Do you want to continue scanning without cookie(y/n)," + self.api_logger.G + url + ': ' + self.api_logger.W) if login_response == 'Y' or login_response == 'y': return elif login_response == 'n' or login_response == 'N': sys.exit(1)
def verify_login(self, collection_data): api_url, api_type = self.auth_verify(collection_data, 'login') logs.logging.info("API URL for login is : %s", api_url) if api_url is None: auth_response = raw_input( self.api_logger.Y + "[-]Failed to detect login url. Do you want to contiune without authentication?(y/n):" + self.api_logger.W) if auth_response == 'y' or auth_response == 'Y': return else: sys.exit(1) for data in collection_data: if data['url'] == api_url: url, method, headers, body = data['url'], data['method'], data[ 'headers'], data['body'] if api_type == 'login': if body: body = json.loads(base64.b64decode(body)) login_token = self.fetch_logintoken( url, method, headers, body) else: login_token = self.fetch_logintoken( url, method, headers) if login_token == True: logs.logging.info("Login successfully : %s", url) # calling auth_verify function to fetch logout request logout_url, api_type = self.auth_verify( collection_data, "logout") self.verify_logout(collection_data, logout_url) auth_data = { 'loginurl': url, 'loginmethod': method, 'loginheaders': headers, 'loginbody': body, 'loginresult': 'Y' } for key, value in auth_data.items(): update_value("login", key, value) return
def verify_logout(self, collection_data, api_url): if api_url is not None: for data in collection_data: if data['url'] == api_url: url, method, headers, body = data['url'], data[ 'method'], data['headers'], data['body'] logout_data = { 'logouturl': url, 'logoutmethod': method, 'logoutheaders': headers, 'logoutbody': body, 'logoutresult': 'Y' } break for key, value in logout_data.items(): update_value("logout", key, value) return else: print "Failed"