def handler_scenario(scenario): """ Execute scenarios from the scenario pool :param scenario: A list containing a scenario :return: none """ global attack_duration, protocol, host, port, payloads, user_agents, start_time, max_request_multiplier, min_request_multiplier,dataset_path up_time = datetime.now() - start_time if up_time.seconds < attack_duration: context = scenario[1] version = scenario[2] resource_path = scenario[3] token = scenario[4] method = scenario[5] request_target = scenario[0] * random.randint(min_request_multiplier, max_request_multiplier) current_requests = 0 ip = scenario[6] cookie = scenario[7] request_path = "{}://{}:{}/{}/{}/{}".format(protocol, host, port, context, version, resource_path) random_user_agent = random.choice(user_agents) random_payload = random.choice(payloads) for i in range(request_target): up_time = datetime.now() - start_time if up_time.seconds >= attack_duration: break response = util_methods.send_simple_request(request_path, method, token, ip, cookie, random_user_agent, payload=random_payload) request_string = "{},{},{},{},{},{},{}".format(datetime.now(), request_path, method, token, ip, cookie, response.status_code) util_methods.log(dataset_path, request_string, "a") time.sleep(generate_biased_random(0, 3, 2)) current_requests += 1
def request_handler(i): """ Handle the requests :return: None """ global attack_duration, protocol, host, port, payloads, user_agents, api_list, dataset_path up_time = datetime.now() - start_time if up_time.seconds < attack_duration: api = random.choice(api_list) context = api.context version = api.version resource_path = random.choice(api.resources['DELETE']) # random_user = random.choice(api.users) random_user = api.single_user method = "DELETE" accept = content_type = "application/json" # sleep the process for a random period of time time.sleep(abs(int(np.random.normal() * 10))) request_path = "{}://{}:{}/{}/{}/{}".format(protocol, host, port, context, version, resource_path) random_user_agent = random.choice(user_agents) token = random_user[0] ip = random_user[2] cookie = random_user[3] path_param = generate_random_string(10) try: response = util_methods.send_simple_request(request_path, method, token, ip, cookie, accept, content_type, random_user_agent, path_params=path_param) request_info = "{},{},{},{},{}/{},{},{},{},{},\"{}\",{}".format( datetime.now(), ip, token, method, request_path, path_param, cookie, accept, content_type, ip, random_user_agent, response.status_code, ) util_methods.log(dataset_path, request_info, "a") except requests.exceptions.RequestException: msg_string = "[Error] {} - Request Failure\n\t {}".format( datetime.now(), str(ex)) print(msg_string) util_methods.log(attack_tool_log_path, msg_string, "a")
def simulate_user(user_data): """ Simulate the behaviour of a user during the attack duration. :param user_data: A dictionary containing the user data :return: None """ global attack_duration, protocol, host, port, payloads, user_agents, start_time, dataset_path, invoke_patterns, max_request_multiplier, min_request_multiplier up_time = datetime.now() - start_time if up_time.seconds < attack_duration: for app_name, app in user_data.items(): sleep_pattern = invoke_patterns[random.choice(list(invoke_patterns.keys()))] for scenario in app: scenario[0] *= random.randint(min_request_multiplier, max_request_multiplier) invoke_pattern_indices = util_methods.generate_method_invoke_pattern(app) for i in invoke_pattern_indices: up_time = datetime.now() - start_time if up_time.seconds >= attack_duration: break sleep_time = np.absolute(np.random.normal(sleep_pattern['mean'], sleep_pattern['std'])) time.sleep(sleep_time) scenario = app[i] path = scenario[2] token = scenario[3] method = scenario[4] request_path = "{}://{}:{}/{}".format(protocol, host, port, path) random_user_agent = scenario[7] ip = scenario[5] cookie = scenario[6] random_payload = random.choice(payloads) accept = content_type = "application/json" try: response = util_methods.send_simple_request(request_path, method, token, ip, cookie, accept, content_type, random_user_agent, payload=random_payload) request_info = "{},{},{},{},{},{},{},{},{},\"{}\",{}".format(datetime.now(), ip, token, method, request_path, cookie, accept, content_type, ip, random_user_agent, response.status_code, ) util_methods.log(dataset_path, request_info, "a") except requests.exceptions.RequestException: msg_string = "[Error] {} - Request Failure\n\t {}".format(datetime.now(), str(ex)) print(msg_string) util_methods.log(attack_tool_log_path, msg_string, "a")
def execute_scenario(scenario): """ Execute scenarios from the scenario pool to simulate abnormal token usage :param scenario: A list containing a scenario :return: none """ global attack_duration, protocol, host, port, payloads, user_agents, start_time, max_request_multiplier, min_request_multiplier, dataset_path up_time = datetime.now() - start_time if up_time.seconds < attack_duration: # multiply normal request count by a random value between user defined min and max value request_target = scenario[0] * random.randint(min_request_multiplier, max_request_multiplier) context = scenario[1] version = scenario[2] resource_path = scenario[3] token = scenario[4] method = scenario[5] ip = scenario[6] cookie = scenario[7] user_agent = scenario[10] request_path = "{}://{}:{}/{}/{}/{}".format(protocol, host, port, context, version, resource_path) random_payload = random.choice(payloads) # sending requests until the request target achieved or attack duration elapses for i in range(request_target): up_time = datetime.now() - start_time if up_time.seconds >= attack_duration: break response = util_methods.send_simple_request(request_path, method, token, ip, cookie, user_agent, payload=random_payload) request_info = "{},{},{},{},{},{},{},\"{}\"".format( datetime.now(), request_path, method, token, ip, cookie, response.status_code, user_agent) util_methods.log(dataset_path, request_info, "a") # sleep the process for a random period of time between 0 and 3 seconds but biased to 0 time.sleep(generate_biased_random(0, 3, 2))
def request_handler(i): """ Handle the requests :return: None """ global attack_duration, protocol, host, port, payloads, user_agents, api_list, dataset_path up_time = datetime.now() - start_time if up_time.seconds < attack_duration: api = random.choice(api_list) context = api.context version = api.version resource_path = random.choice(api.resources['DELETE']) random_user = random.choice(api.users) token = random_user[0] method = "DELETE" # time.sleep(generate_biased_random(0, 10, 2)) time.sleep(random.randint(0, 10)) request_path = "{}://{}:{}/{}/{}/{}".format(protocol, host, port, context, version, resource_path) random_user_agent = random.choice(user_agents) ip = random_user[2] cookie = random_user[3] path_param = generate_random_string(10) response = util_methods.send_simple_request(request_path, method, token, ip, cookie, random_user_agent, path_params=path_param) request_info = "{},{},{},{},{},{},{},\"{}\"".format( datetime.now(), request_path, method, token, ip, cookie, response.status_code, random_user_agent) util_methods.log(dataset_path, request_info, "a") print("Request sent with token: %s" % token, flush=True)
def removeUserSOAP(gateway_protocol, gateway_host, gateway_port, soap_endpoint, username, admin_b64): """ This function will remove a given user account from carbon (Uses SOAP endpoint) :param gateway_protocol: Running protocol of the gateway :param gateway_host: Host IP address of the gateway :param gateway_port: Port :param soap_endpoint: SOAP Endpoint :param username: Username of the user/ account :param admin_b64: Base64 encrypted username:password of the tenant admin :return: True if the user account removed. False otherwise """ url = "{}://{}:{}{}".format(gateway_protocol, gateway_host, gateway_port, soap_endpoint) headers = { "Authorization": "Basic {}".format(admin_b64), "Content-Type": "text/xml", "SOAPAction": "urn:deleteUser" } data = """ <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://service.ws.um.carbon.wso2.org"> <soapenv:Header/> <soapenv:Body> <ser:deleteUser> <!--Optional:--> <ser:userName>{}</ser:userName> </ser:deleteUser> </soapenv:Body> </soapenv:Envelope>""".format(username) try: response = requests.post(url=url, headers=headers, data=data, verify=False) code = response.status_code res_txt = response.text log_txt = "removeUserSOAP(). responseCode: " + str( code) + ", responseMessage: " + str( res_txt ) + ", method: POST" + ", url: " + url + ", username: "******"SUCCESS", log_txt) return True else: util_methods.log('traffic-requests.log', "FAILED", log_txt) return False except Exception as err: code = 521 log_txt = "removeUserSOAP(). responseCode: " + str( code) + ", errorLog: " + str( err) + ", method: POST" + ", url: " + url + ", body: " + str( data) util_methods.log('traffic-requests.log', "ERROR", log_txt) return False
def getAccessToken(gateway_protocol, gateway_host, gateway_port, endpoint, b64_encoded_value, scope, admin_username, admin_password): """ This function will obtain an access token for a given scope. :param gateway_protocol: Running protocol of the gateway :param gateway_host: Host IP address of the gateway :param gateway_port: Port to obtain access token :param endpoint: Endpoint to obtain access token :param b64_encoded_value: Base64 encrypted value of client_id:client_secret :param scope: Scope of the token :param admin_username: Username of the tenant admin :param admin_password: Password of the tenant admin :return: Access token and refresh token """ url = "{}://{}:{}{}".format(gateway_protocol, gateway_host, gateway_port, endpoint) headers = { "Authorization": "Basic {}".format(b64_encoded_value), "Content-Type": "application/x-www-form-urlencoded" } data = { 'grant_type': 'password', 'username': admin_username, 'password': admin_password, 'scope': scope } try: response = requests.post(url=url, headers=headers, data=data, verify=False) code = response.status_code res_txt = response.text response = json.loads(res_txt) log_txt = "getAccessToken(). responseCode: " + str( code) + ", responseMessage: " + str( res_txt) + ", method: POST" + ", url: " + url if code == 200: util_methods.log('traffic-requests.log', "SUCCESS", log_txt) return response['access_token'], response['refresh_token'] else: util_methods.log('traffic-requests.log', "FAILED", log_txt) return None, None except Exception as err: code = 521 log_txt = "getAccessToken(). responseCode: " + str( code) + ", errorLog: " + str( err) + ", method: POST" + ", url: " + url + ", body: " + str( data) util_methods.log('traffic-requests.log', "ERROR", log_txt) return None, None
def execute_scenario(scenario): """ Execute a scenario from the scenario pool to simulate the usage of a stolen token :param scenario: A list containing a scenario :return: none """ global attack_duration, protocol, host, port, payloads, user_agents, start_time, dataset_path up_time = datetime.now() - start_time if up_time.seconds < attack_duration: request_target = scenario[0] context = scenario[1] version = scenario[2] resource_path = scenario[3] token = scenario[4] method = scenario[5] request_path = "{}://{}:{}/{}/{}/{}".format(protocol, host, port, context, version, resource_path) random_user_agent = random.choice(user_agents) random_ip = generate_unique_ip() random_cookie = generate_cookie() random_payload = random.choice(payloads) for i in range(request_target): up_time = datetime.now() - start_time if up_time.seconds >= attack_duration: break response = util_methods.send_simple_request(request_path, method, token, random_ip, random_cookie, random_user_agent, payload=random_payload) request_info = "{},{},{},{},{},{},{},\"{}\"".format(datetime.now(), request_path, method, token, random_ip, random_cookie, response.status_code, random_user_agent) util_methods.log(dataset_path, request_info, "a") # print("Request sent with token: %s" % token, flush=True) # sleep the process for a random period of time between 0 and 5 seconds but biased to 0 time.sleep(generate_biased_random(0, 5, 2))
def getIDSecret(gateway_protocol, gateway_host, gateway_port, endpoint, admin_username, admin_b64): """ This function will send http request to obtain client id, client secret. :param gateway_protocol: Running protocol of the gateway :param gateway_host: Host IP address of the gateway :param gateway_port: Port to obtain key, secret :param endpoint: Endpoint to obtain key, secret :param admin_username: Username of the tenant admin :param admin_b64: Base64 encrypted username:password of the tenant admin :return: Client ID and client secret """ url = "{}://{}:{}{}".format(gateway_protocol, gateway_host, gateway_port, endpoint) headers = { "Authorization": "Basic {}".format(admin_b64), "Content-Type": "application/json" } data = { "callbackUrl": "www.google.lk", "clientName": "rest_api_publisher", "owner": admin_username, "grantType": "password refresh_token", "saasApp": "true" } data = json.dumps(data) try: response = requests.post(url=url, headers=headers, data=data, verify=False) code = response.status_code res_txt = response.text response = json.loads(res_txt) log_txt = "getIDSecret(). responseCode: " + str( code) + ", responseMessage: " + str( res_txt) + ", method: POST" + ", url: " + url if code == 200: util_methods.log('traffic-requests.log', "SUCCESS", log_txt) return response['clientId'], response['clientSecret'] else: util_methods.log('traffic-requests.log', "FAILED", log_txt) return None, None except Exception as err: code = 521 log_txt = "getIDSecret(). responseCode: " + str( code) + ", errorLog: " + str( err) + ", method: POST" + ", url: " + url + ", body: " + str( data) util_methods.log('traffic-requests.log', "ERROR", log_txt) return None, None
def subscribe(gateway_protocol, gateway_host, gateway_port, endpoint, subs_token, subs_tier, api_id, app_id): """ This function will subscribe given app to given API :param gateway_protocol: Running protocol of the gateway :param gateway_host: Host IP address of the gateway :param gateway_port: Port :param endpoint: Endpoint :param subs_token: API subscription token :param subs_tier: Subscription tier :param api_id: ID of the API :param app_id: ID of the app :return: True if subscription successful. False otherwise """ url = "{}://{}:{}{}".format(gateway_protocol, gateway_host, gateway_port, endpoint) headers = { "Authorization": "Bearer {}".format(subs_token), "Content-Type": "application/json" } data = { "tier": subs_tier, "apiIdentifier": api_id, "applicationId": app_id } data = json.dumps(data) try: response = requests.post(url=url, headers=headers, data=data, verify=False) code = response.status_code res_txt = response.text response = json.loads(res_txt) log_txt = "subscribe(). responseCode: " + str( code) + ", responseMessage: " + str( res_txt) + ", method: POST" + ", url: " + url if code == 201: util_methods.log('traffic-requests.log', "SUCCESS", log_txt) return True else: util_methods.log('traffic-requests.log', "FAILED", log_txt) return False except Exception as err: code = 521 log_txt = "subscribe(). responseCode: " + str( code) + ", errorLog: " + str( err) + ", method: POST" + ", url: " + url + ", body: " + str( data) util_methods.log('traffic-requests.log', "ERROR", log_txt) return False
def selfSignupStoreAPI(gateway_protocol, gateway_host, gateway_port, endpoint, username, password, all_fields): """ This function will self signup users through store API (deprecated in version 3.0.0 onwards) :param gateway_protocol: Running protocol of the gateway :param gateway_host: Host IP address of the gateway :param gateway_port: Port :param endpoint: Endpoint :param username: Username :param password: Password :param all_fields: Remaining fields seperated by '|' in a string :return: True if user signup successful. False otherwise """ url = "{}://{}:{}{}".format(gateway_protocol, gateway_host, gateway_port, endpoint) headers = { "Content-Type": "application/x-www-form-urlencoded", "Accept": "application/json" } data = { 'action': 'addUser', 'username': username, 'password': password, 'allFieldsValues': all_fields } try: response = requests.post(url=url, headers=headers, data=data, verify=False) code = response.status_code res_txt = response.text log_txt = "selfSignupStoreAPI(). responseCode: " + str( code) + ", responseMessage: " + str( res_txt ) + ", method: POST" + ", url: " + url + ", username: "******"SUCCESS", log_txt) return True else: util_methods.log('traffic-requests.log', "FAILED", log_txt) return False except Exception as err: code = 521 log_txt = "selfSignupStoreAPI(). responseCode: " + str( code) + ", errorLog: " + str( err) + ", method: POST" + ", url: " + url + ", body: " + str( data) util_methods.log('traffic-requests.log', "ERROR", log_txt) return False
def publishAPI(gateway_protocol, gateway_host, gateway_port, endpoint, publish_token, api_id): """ This function will publish an API :param gateway_protocol: Running protocol of the gateway :param gateway_host: Host IP address of the gateway :param gateway_port: Port :param endpoint: Endpoint :param publish_token: Token to publish :param api_id: ID of the API :return: True if API published successfully. False otherwise """ url = "{}://{}:{}{}/change-lifecycle?apiId={}&action=Publish".format( gateway_protocol, gateway_host, gateway_port, endpoint, api_id) headers = { "Authorization": "Bearer {}".format(publish_token), "Content-Type": "application/json" } data = {} try: response = requests.post(url=url, headers=headers, data=data, verify=False) code = response.status_code res_txt = response.text log_txt = "publishAPI(). responseCode: " + str( code) + ", responseMessage: " + str( res_txt) + ", method: POST" + ", url: " + url if code == 200: util_methods.log('traffic-requests.log', "SUCCESS", log_txt) return True else: util_methods.log('traffic-requests.log', "FAILED", log_txt) return False except Exception as err: code = 521 log_txt = "publishAPI(). responseCode: " + str( code) + ", errorLog: " + str( err) + ", method: POST" + ", url: " + url + ", body: " + str( data) util_methods.log('traffic-requests.log', "ERROR", log_txt) return False
def deleteAppAPI(gateway_protocol, gateway_host, gateway_port, endpoint, access_token, id): """ This function will delete a given API or application :param gateway_protocol: Running protocol of the gateway :param gateway_host: Host IP address of the gateway :param gateway_port: Port :param endpoint: Endpoint :param access_token: Access token to delete :param id: ID of the API or application :return: True if the deletion successful. False otherwise """ url = "{}://{}:{}{}/{}".format(gateway_protocol, gateway_host, gateway_port, endpoint, id) headers = { "Authorization": "Bearer {}".format(access_token), "Content-Type": "application/json" } try: response = requests.delete(url=url, headers=headers, verify=False) code = response.status_code res_txt = response.text log_txt = "deleteAppAPI(). responseCode: " + str( code) + ", responseMessage: " + str( res_txt) + ", method: DELETE" + ", url: " + url if code == 200: util_methods.log('traffic-requests.log', "SUCCESS", log_txt) return True else: util_methods.log('traffic-requests.log', "FAILED", log_txt) return False except Exception as err: code = 521 log_txt = "deleteAppAPI(). responseCode: " + str( code) + ", errorLog: " + str( err) + ", method: DELETE" + ", url: " + url util_methods.log('traffic-requests.log', "ERROR", log_txt) return False
def generateInvokeToken(gateway_protocol, gateway_host, gateway_port, endpoint, b64_key_secret, username, password, scope): """ This function will generate API invoke tokens in password grant type for a given user :param gateway_protocol: Running protocol of the gateway :param gateway_host: Host IP address of the gateway :param gateway_port: Port :param endpoint: Endpoint :param b64_key_secret: Base64 encrypted value of consumer_key:consumer_secret :param username: Username of the user :param password: Password of the user :param scope: Scope to generate tokens :return: Access token and refresh token """ url = "{}://{}:{}{}".format(gateway_protocol, gateway_host, gateway_port, endpoint) headers = { "Authorization": "Basic {}".format(b64_key_secret), "Content-Type": "application/x-www-form-urlencoded" } data = { "grant_type": "password", "username": username, "password": password, "scope": scope } try: response = requests.post(url=url, headers=headers, data=data, verify=False) code = response.status_code res_txt = response.text response = json.loads(res_txt) expires_in = response['expires_in'] if int(expires_in) <= 4800: util_methods.log( 'traffic-tool.log', "WARN", "Your token expiration time is {}. It is recommended to increase expiration time to prevent unnecessary token expirations!" .format(str(expires_in))) log_txt = "generateInvokeToken(). responseCode: " + str( code) + ", responseMessage: " + str( res_txt) + ", method: POST" + ", url: " + url if code == 200: util_methods.log('traffic-requests.log', "SUCCESS", log_txt) return response['access_token'], response['refresh_token'] else: util_methods.log('traffic-requests.log', "FAILED", log_txt) return None, None except Exception as err: code = 521 log_txt = "generateInvokeToken(). responseCode: " + str( code) + ", errorLog: " + str( err) + ", method: POST" + ", url: " + url + ", body: " + str( data) util_methods.log('traffic-requests.log', "ERROR", log_txt) return None, None
os.path.join(__file__, "../../../../../config/apim.yaml")), "r") as config_file: config = yaml.load(config_file, Loader=yaml.FullLoader) with open( os.path.abspath( os.path.join(__file__, "../../../../../config/attack-tool.yaml")), "r") as attack_config_file: attack_config = yaml.load(attack_config_file, Loader=yaml.FullLoader) except FileNotFoundError as ex: error_string = "[ERROR] {} - {}: \'{}\'".format( datetime.now(), ex.strerror, ex.filename) print(error_string) util_methods.log(attack_tool_log_path, error_string, "a") sys.exit() # reading configurations from attack-tool.yaml protocol = attack_config['general_config']['api_host']['protocol'] host = attack_config['general_config']['api_host']['ip'] port = attack_config['general_config']['api_host']['port'] attack_duration = attack_config['general_config']['attack_duration'] scenario_name = attack_config['general_config']['scenario'] payloads = attack_config['general_config']['payloads'] user_agents = attack_config['general_config']['user_agents'] process_count = attack_config['general_config']['number_of_processes'] # reading api configuration from apim.yaml apis = config['apis']
)), "rb") as scenario_file: scenario_pool = pickle.load(scenario_file, ) with open( os.path.abspath( os.path.join(__file__, "../../../../../config/attack-tool.yaml")), "r") as attack_config_file: attack_config = yaml.load(attack_config_file, Loader=yaml.FullLoader) except FileNotFoundError as ex: error_string = "[ERROR] {} - {}: \'{}\'".format( datetime.now(), ex.strerror, ex.filename) print(error_string) util_methods.log(attack_tool_log_path, error_string, "a") sys.exit() # Reading configurations from attack-tool.yaml protocol = attack_config[GENERAL_CONFIG][API_HOST][PROTOCOL] host = attack_config[GENERAL_CONFIG][API_HOST][IP] port = attack_config[GENERAL_CONFIG][API_HOST][PORT] attack_duration = attack_config[GENERAL_CONFIG][ATTACK_DURATION] payloads = attack_config[GENERAL_CONFIG][PAYLOADS] user_agents = attack_config[GENERAL_CONFIG][USER_AGENTS] process_count = attack_config[GENERAL_CONFIG][NUMBER_OF_PROCESSES] compromised_user_count = attack_config[ATTACKS][STOLEN_TOKEN][ COMPROMISED_USER_COUNT] invoke_patterns = util_methods.process_time_patterns( attack_config[GENERAL_CONFIG][TIME_PATTERNS])
def sendRequest(url_protocol, url_ip, url_port, path, access_token, method, user_ip, cookie, user_agent): """ This function will send http requests to the given address :param url_protocol: Protocol of the URL :param url_ip: IP of the URL :param url_port: Port of the URL :param path: Invoke path for the request :param access_token: Access token for the request :param method: HTTP method of the request :param user_ip: IP of the user :param cookie: Cookie of the user :param user_agent: User agent for the user :return: Response code and response text """ global post_data, delete_data url = "{}://{}:{}/{}".format(url_protocol, url_ip, url_port, path) accept = 'application/json' content_type = 'application/json' headers = { 'accept': '{}'.format(accept), 'Content-Type': '{}'.format(content_type), 'Authorization': 'Bearer {}'.format(access_token), 'client-ip': '{}'.format(user_ip), 'x-forwarded-for': '{}'.format(user_ip), 'cookie': '{}'.format(cookie), 'User-Agent': '{}'.format(user_agent) } res_txt = "" try: if method == "GET": response = requests.get(url=url, headers=headers, verify=False) code = response.status_code res_txt = response.text elif method == "POST": data = json.dumps(random.choice(post_data)) response = requests.post(url=url, headers=headers, data=data, verify=False) code = response.status_code res_txt = response.text elif method == "DELETE": if delete_data is not None: data = json.dumps(random.choice(delete_data)) response = requests.delete(url=url, headers=headers, data=data, verify=False) code = response.status_code res_txt = response.text else: url = url + '/' + str(random.randint(0, 1000)) response = requests.delete(url=url, headers=headers, verify=False) code = response.status_code res_txt = response.text elif method == "PUT": response = requests.put(url=url, headers=headers, verify=False) code = response.status_code res_txt = response.text elif method == "PATCH": response = requests.patch(url=url, headers=headers, verify=False) code = response.status_code res_txt = response.text else: code = '400' res_txt = 'Invalid type' except Exception as err: code = '521' log_txt = "sendRequest(). responseCode: " + str(code) + ", errorLog: " + str(err) + ", method: " + method + ", url: " + url util_methods.log('traffic-requests.log', 'ERROR', log_txt) util_methods.log('traffic-tool.log', 'ERROR', str(err)) # user agent is wrapped around quotes because there are commas in the user agent and they clash with the commas in csv file write_string = str( datetime.now()) + "," + user_ip + "," + access_token + "," + method + "," + path + "," + cookie + "," + accept + "," + content_type + "," + user_ip + ",\"" + user_agent + "\"," + str( code) + "\n" with open(abs_path + '/../../../../dataset/traffic/{}'.format(filename), 'a+') as dataset_file: dataset_file.write(write_string) return code, res_txt
def runInvoker(user_scenario, connection_refuse_count): """ This function will take a given invoke scenario and execute it. Supposed to be executed from a process. :param user_scenario: User scenario data :param connection_refuse_count: Current connection refuse count :return: None """ global script_start_time, script_runtime appNames = list(user_scenario.keys()) while True: app_name = appNames[random.randint(0, len(appNames) - 1)] app_scenario_list = user_scenario.get(app_name) time_pattern = None iterations = 0 probability_list = [] # prepare probabilities for the scenario for scenario in app_scenario_list: iterations += scenario[0] probability_list.append(scenario[0]) if iterations == 0: continue for i in range(len(probability_list)): probability_list[i] = probability_list[i] / iterations # increase probabilities if it's too small compared to max value for i in range(len(probability_list)): max_pro = max(probability_list) if max_pro - probability_list[i] >= 0.5: probability_list[i] = probability_list[i] + 0.075 probability_list[probability_list.index(max_pro)] = max_pro - 0.075 # prepare request pattern from list indices invoke_pattern_indices = np.random.choice(len(app_scenario_list), size=iterations, p=probability_list) for i in invoke_pattern_indices: up_time = datetime.now() - script_start_time if up_time.seconds >= script_runtime: break scenario = app_scenario_list[i] path = scenario[2] access_token = scenario[3] method = scenario[4] user_ip = scenario[5] cookie = scenario[6] user_agent = scenario[7] # set time pattern if not set if time_pattern is None: time_pattern = scenario[8] time_pattern = time_patterns.get(time_pattern) # send the request try: if heavy_traffic != 'true': sleep_time = np.absolute(np.random.normal(time_pattern['mean'], time_pattern['std'])) time.sleep(sleep_time) res_code = sendRequest(host_protocol, host_ip, host_port, path, access_token, method, user_ip, cookie, user_agent)[0] if res_code == '521': connection_refuse_count.value += 1 except Exception as err: util_methods.log('traffic-tool.log', 'ERROR', str(err)) connection_refuse_count.value += 1 up_time = datetime.now() - script_start_time if up_time.seconds >= script_runtime: break else: time.sleep(abs(int(np.random.normal() * 10)))
def selfSignupIS(gateway_protocol, gateway_host, gateway_port, endpoint, admin_b64, username, password, firstname, lastname, email, country, organization, land_no, mobile_no, IM, user_url): """ This function will self signup users through WSO2 Identity server :param gateway_protocol: Running protocol of the gateway :param gateway_host: Host IP address of the gateway :param gateway_port: Port :param endpoint: Endpoint :param admin_b64: Base64 encrypted username:password of the tenant admin :param username: Username :param password: Password :param firstname: First name of the user :param lastname: Last name of the user :param email: Email address of the user :param country: Country of the user :param organization: Organization of the user :param land_no: Land phone number of the user :param mobile_no: Mobile phone number of the user :param IM: IM of the user :param user_url: Url of the user :return: True if user signup successful. False otherwise """ url = "{}://{}:{}{}".format(gateway_protocol, gateway_host, gateway_port, endpoint) headers = { "Authorization": "Basic {}".format(admin_b64), "Content-Type": "application/json", } data = { "user": { "username": username, "realm": "PRIMARY", "password": password, "claims": [{ "uri": "http://wso2.org/claims/givenname", "value": firstname }, { "uri": "http://wso2.org/claims/emailaddress", "value": email }, { "uri": "http://wso2.org/claims/lastname", "value": lastname }, { "uri": "http://wso2.org/claims/mobile", "value": mobile_no }, { "uri": "http://wso2.org/claims/organization", "value": organization }, { "uri": "http://wso2.org/claims/telephone", "value": land_no }, { "uri": "http://wso2.org/claims/country", "value": country }, { "uri": "http://wso2.org/claims/url", "value": user_url }, { "uri": "http://wso2.org/claims/im", "value": IM }] }, "properties": [] } data = json.dumps(data) try: response = requests.post(url=url, headers=headers, data=data, verify=False) code = response.status_code res_txt = response.text log_txt = "selfSignupIS(). responseCode: " + str( code) + ", responseMessage: " + str( res_txt ) + ", method: POST" + ", url: " + url + ", username: "******"SUCCESS", log_txt) return True else: util_methods.log('traffic-requests.log', "FAILED", log_txt) return False except Exception as err: code = 521 log_txt = "selfSignupIS(). responseCode: " + str( code) + ", errorLog: " + str( err) + ", method: POST" + ", url: " + url + ", body: " + str( data) util_methods.log('traffic-requests.log', "ERROR", log_txt) return False
def createAPI(gateway_protocol, gateway_host, gateway_port, endpoint, create_token, name, desc, path, version, swagger, tags, throttling_tier, visibility, production_endpoint, sandbox_endpoint, admin_username): """ This function will create a given API in WSO2 API Manager :param gateway_protocol: Running protocol of the gateway :param gateway_host: Host IP address of the gateway :param gateway_port: Port :param endpoint: Endpoint :param create_token: API creation token :param name: API name :param desc: API description :param path: API path :param version: API version :param swagger: Swagger definition (swagger string) :param tags: API tag list :param throttling_tier: Throttling tier of the API :param visibility: Visibility of the API :param production_endpoint: Production endpoint :param sandbox_endpoint: Sandbox endpoint :param admin_username: Username of the tenant admin :return: ID of the create API """ url = "{}://{}:{}{}".format(gateway_protocol, gateway_host, gateway_port, endpoint) headers = { "Authorization": "Bearer {}".format(create_token), "Content-Type": "application/json" } data = { "name": name, "description": desc, "context": path, "version": version, "provider": admin_username, "apiDefinition": str(swagger), "wsdlUri": None, "responseCaching": "Disabled", "cacheTimeout": 300, "destinationStatsEnabled": "false", "isDefaultVersion": "false", "type": "HTTP", "transport": ["http", "https"], "tags": tags, "tiers": [throttling_tier], "maxTps": None, "visibility": visibility, "visibleRoles": [], "endpointConfig": "{\"production_endpoints\":{\"url\":\"%s\",\"config\":null},\"sandbox_endpoints\":{\"url\":\"%s\",\"config\":null},\"endpoint_type\":\"http\"}" % (production_endpoint, sandbox_endpoint), "endpointSecurity": { "username": "******", "type": "basic", "password": "******" }, "gatewayEnvironments": "Default", "sequences": [], "subscriptionAvailability": None, "subscriptionAvailableTenants": [], "businessInformation": { "businessOwnerEmail": None, "technicalOwnerEmail": None, "technicalOwner": None, "businessOwner": None }, "corsConfiguration": { "accessControlAllowOrigins": ["*"], "accessControlAllowHeaders": [ "authorization", "Access-Control-Allow-Origin", "Content-Type", "SOAPAction" ], "accessControlAllowMethods": ["GET", "PUT", "POST", "DELETE", "PATCH", "OPTIONS"], "accessControlAllowCredentials": "false", "corsConfigurationEnabled": "false" } } data = json.dumps(data).replace('\\\\\\', '\\') try: response = requests.post(url=url, headers=headers, data=data, verify=False) code = response.status_code res_txt = response.text response = json.loads(res_txt) log_txt = "createAPI(). responseCode: " + str( code) + ", responseMessage: " + str( res_txt) + ", method: POST" + ", url: " + url if code == 201: util_methods.log('traffic-requests.log', "SUCCESS", log_txt) api_id = response['id'] with open(abs_path + '/../../../data/runtime_data/api_ids.csv', 'a+') as file: file.write(api_id + '\n') return api_id else: util_methods.log('traffic-requests.log', "FAILED", log_txt) return None except Exception as err: code = 521 log_txt = "createAPI(). responseCode: " + str( code) + ", errorLog: " + str( err) + ", method: POST" + ", url: " + url + ", body: " + str( data) util_methods.log('traffic-requests.log', "ERROR", log_txt) return None
def genProductionKey(gateway_protocol, gateway_host, gateway_port, endpoint, subs_token, token_validity_period): """ This function will generate production keys :param gateway_protocol: Running protocol of the gateway :param gateway_host: Host IP address of the gateway :param gateway_port: Port :param endpoint: Endpoint :param subs_token: Token in subscribe scope :param token_validity_period: Access token validity period :return: Consumer key and consumer secret """ url = "{}://{}:{}{}".format(gateway_protocol, gateway_host, gateway_port, endpoint) headers = { "Authorization": "Bearer {}".format(subs_token), "Content-Type": "application/json" } data = { "validityTime": token_validity_period, "keyType": "PRODUCTION", "accessAllowDomains": ["ALL"], "scopes": ["am_application_scope", "default"], "supportedGrantTypes": [ "urn:ietf:params:oauth:grant-type:saml2-bearer", "iwa:ntlm", "refresh_token", "client_credentials", "password" ] } data = json.dumps(data) try: response = requests.post(url=url, headers=headers, data=data, verify=False) code = response.status_code res_txt = response.text response = json.loads(res_txt) log_txt = "genProductionKey(). responseCode: " + str( code) + ", responseMessage: " + str( res_txt) + ", method: POST" + ", url: " + url if code == 200: util_methods.log('traffic-requests.log', "SUCCESS", log_txt) return response['consumerKey'], response['consumerSecret'] else: util_methods.log('traffic-requests.log', "FAILED", log_txt) return None, None except Exception as err: code = 521 log_txt = "genProductionKey(). responseCode: " + str( code) + ", errorLog: " + str( err) + ", method: POST" + ", url: " + url + ", body: " + str( data) util_methods.log('traffic-requests.log', "ERROR", log_txt) return None, None
def createApplication(gateway_protocol, gateway_host, gateway_port, endpoint, subs_token, name, desc, throttling_tier): """ This function will create a given application :param gateway_protocol: Running protocol of the gateway :param gateway_host: Host IP address of the gateway :param gateway_port: Port :param endpoint: Endpoint :param subs_token: Subscribe access token :param name: App name :param desc: App description :param throttling_tier: Throttling tier of the app :return: ID of the created app """ url = "{}://{}:{}{}".format(gateway_protocol, gateway_host, gateway_port, endpoint) headers = { "Authorization": "Bearer {}".format(subs_token), "Content-Type": "application/json" } data = { "throttlingTier": throttling_tier, "description": desc, "name": name, "callbackUrl": "http://my.server.com/callback" } data = json.dumps(data) try: response = requests.post(url=url, headers=headers, data=data, verify=False) code = response.status_code res_txt = response.text response = json.loads(res_txt) log_txt = "createApplication(). responseCode: " + str( code) + ", responseMessage: " + str( res_txt) + ", method: POST" + ", url: " + url if code == 201: util_methods.log('traffic-requests.log', "SUCCESS", log_txt) app_id = response['applicationId'] with open(abs_path + '/../../../data/runtime_data/app_ids.csv', 'a+') as file: file.write(app_id + '\n') return app_id else: util_methods.log('traffic-requests.log', "FAILED", log_txt) return None except Exception as err: code = 521 log_txt = "createApplication(). responseCode: " + str( code) + ", errorLog: " + str( err) + ", method: POST" + ", url: " + url + ", body: " + str( data) util_methods.log('traffic-requests.log', "ERROR", log_txt) return None