def CDNMenu(): flag = True scripts.clear() while flag == True: scripts.clear() #Display menu options print(' ' + scripts.bcolors.BOLD + scripts.bcolors.UNDERLINE + scripts.bcolors.HEADER + 'CDN MENU' + scripts.bcolors.ENDC + scripts.bcolors.ENDC + scripts.bcolors.ENDC) print(scripts.bcolors.HEADER + '===========' + scripts.bcolors.ENDC) print('1: List Public IPs') print('2: Purge Options') print('3: Activate Service') print('B to go back') print(scripts.bcolors.HEADER + '===========' + scripts.bcolors.ENDC) print(' ') choice = input('Option: ') #get user's choice if choice == '1': scripts.clear() scripts.CDN.listPublicIPs() elif choice == '2': scripts.clear() scripts.CDN.purgeMenu() elif choice == '3': scripts.clear() scripts.CDN.activateService() elif choice == 'B' or choice == 'b': scripts.mainMenu() else: input('Not a valid choice. Hit enter to continue...')
def purgeURL(url): if scripts.checkAPINoPrint(): header = {"Accept": "application/json"} header.update({"Fastly-Key": scripts.getKeyFromConfig()}) header.update({"Fastly-Soft-Purge": "1"}) url = str(input("Purge URL: ")) while "Not a valid response.": reply = str(input("Correct URL [Y/n]: ")).lower().strip() if reply == 'y': break elif reply == 'n': scripts.clear() purgeMenu() break r = requests.request("PURGE", str(url), headers=header) if r.status_code == 401: input(scripts.bcolors.WARNING + "Error with request. Press ENTER to continue..." + scripts.bcolors.ENDC) elif r.status_code == 200: pprint.pprint(r.json()) input("Press ENTER to continue...") else: input(scripts.bcolors.WARNING + "Error with request. Press ENTER to continue..." + scripts.bcolors.ENDC) else: input( scripts.bcolors.WARNING + "Error with API Key, generate a new one. Press ENTER to continue..." + scripts.bcolors.ENDC)
def purgeServiceMenu(): df = scripts.listServicesNoPrint() print(df) try: sernumber = int(input("\n\nEnter index of service to purge: ")) print(str(df.iloc[sernumber])) except: e = input( "Not a valid number. Press enter to continue or E to exit...") if e.lower() == 'e': scripts.clear() purgeMenu() while "Not a valid response.": reply = str(input("Correct service [Y/n]: ")).lower().strip() if reply == 'y': service = str(df['ID'].iloc[sernumber]) purgeService(str(service)) break elif reply == 'n': scripts.clear() purgeKeyMenu() break
def enableWAF(): print( scripts.bcolors.WARNING + scripts.bcolors.UNDERLINE + "EMERGENCY ENABLE: THIS IS TO BE USED IN AN EMERGENCY ONLY (only works on emergency disabled WAF)\n(Requires Superuser permissions)" + scripts.bcolors.ENDC + scripts.bcolors.ENDC) if scripts.checkAPINoPrint(): dfObj = listWAFIDsNoPrompt() try: inVar = int(input("\n\nEnter index of WAF to display: ")) str(dfObj['WAF ID'].iloc[inVar]) except: e = input( "Not a valid number. Press enter to continue or E to exit...") if e.strip(' ').lower() == 'e': scripts.clear() scripts.WAFMenu() scripts.clear() enableWAF() header = {"Accept": "application/vnd.api+json"} header.update({"Content-Type": "application/vnd.api+json"}) header.update({"Fastly-Key": scripts.getKeyFromConfig()}) r = requests.patch("https://api.fastly.com/wafs/" + str(dfObj['WAF ID'].iloc[inVar]) + "/enable", headers=header) if r.status_code == 202: print(scripts.bcolors.OKGREEN + "Enabled WAF" + scripts.bcolors.ENDC) pprint.pprint(r.json()['data']) input("Press ENTER to return to menu...") else: input(scripts.bcolors.WARNING + "Error with request.\nStatus: " + str(r.status_code) + "\nPress ENTER to continue..." + scripts.bcolors.ENDC) else: input( scripts.bcolors.WARNING + "Error with API Key, generate a new one. Press ENTER to continue..." + scripts.bcolors.ENDC)
def disableWAF(): print( scripts.bcolors.FAIL + scripts.bcolors.UNDERLINE + "EMERGENCY DISABLE: THIS IS TO BE USED IN AN EMERGENCY ONLY\n(Requires Superuser permissions)" + scripts.bcolors.ENDC + scripts.bcolors.ENDC) if scripts.checkAPINoPrint(): dfObj = listWAFIDsNoPrompt() try: inVar = int( input("\n\nEnter index of WAF to display [Enter to exit]: ")) print(str(dfObj['WAF ID'].iloc[inVar])) except: e = input( "Not a valid number. Press enter to continue or E to exit...") if e.strip(' ').lower() == 'e': scripts.clear() scripts.WAFMenu() scripts.clear() disableWAF() print(scripts.bcolors.WARNING + scripts.bcolors.UNDERLINE + "EMERGENCY DISABLE: THIS IS TO BE USED IN AN EMERGENCY ONLY" + scripts.bcolors.ENDC + scripts.bcolors.ENDC) while "Not a valid response.": reply = str( input("Request: https://api.fastly.com/wafs/" + str(dfObj['WAF ID'].iloc[inVar]) + "/disable\nCorrect service " + str(dfObj['Name'].iloc[inVar]) + " [Y/n]: ")).lower().strip() if reply[0] == 'y': break if reply[0] == 'n': scripts.clear() disableWAF() break header = {"Accept": "application/vnd.api+json"} header.update({"Content-Type": "application/vnd.api+json"}) header.update({"Fastly-Key": scripts.getKeyFromConfig()}) r = requests.patch("https://api.fastly.com/wafs/" + str(dfObj['WAF ID'].iloc[inVar]) + "/disable", headers=header) if r.status_code == 202: print(scripts.bcolors.OKGREEN + "Disabled WAF" + scripts.bcolors.ENDC) pprint.pprint(r.json()['data']) input("Press ENTER to return to menu...") else: input(scripts.bcolors.WARNING + "Error with request.\nStatus: " + str(r.status_code) + "\nPress ENTER to continue..." + scripts.bcolors.ENDC) else: input( scripts.bcolors.WARNING + "Error with API Key, generate a new one. Press ENTER to continue..." + scripts.bcolors.ENDC)
def purgeKeyMenu(): df = scripts.listServicesNoPrint() print(df) try: sernumber = int(input("\n\nEnter index of service to purge: ")) except: e = input( "Not a valid number. Press enter to continue or E to exit...") if e.lower() == 'e': scripts.clear() purgeMenu() print(str(df.iloc[sernumber])) while "Not a valid response.": reply = str(input("Correct service [Y/n]: ")).lower().strip() if reply == 'y': service = str(df['ID'].iloc[sernumber]) break if reply == 'n': scripts.clear() purgeKeyMenu() break key = str(input("Enter key to purge: ")) print("Key: " + str(key)) while "Not a valid response.": reply = str(input("Correct key [Y/n]: ")).lower().strip() if reply[0] == 'y': break if reply[0] == 'n': scripts.clear() purgeKeyMenu() break while "Not a valid response.": reply = str(input("Soft purge [Y/n]: ")).lower().strip() if reply[0] == 'y': purgeKey(service, key, True) break if reply[0] == 'n': purgeKey(service, key, False) break
def modifyRules(): pandas.set_option('display.max_rows', 1000) if scripts.checkAPINoPrint(): dfObj = scripts.WAF.listWAFIDsNoPrompt() # print(dfObj) try: inVar = int(input("\n\nEnter index of WAF to modify: ")) except: e = input( "Not a valid number. Press enter to continue or E to exit...") if e.strip(' ').lower() == 'e': scripts.clear() scripts.WAFMenu() scripts.clear() modifyRules() ruleids = str( input( "Enter rule ID's to modify (Example: 1010010,931100,931110): ") ).lower().strip() action = str( input("Enter action to perform on rules (disabled, log, block):") ).lower().strip() ruleList = ruleids.split(",") body = {} datatemp = {} attributes = {} for rid in ruleList: print(str(rid)) wrid = str(dfObj['WAF ID'].iloc[inVar]) + "-" + str(rid) datatemp.update({"id": wrid}) datatemp.update({"type": "rule_status"}) attributes.update({"status": action}) datatemp.update({"attributes": attributes}) body.update({"data": datatemp}) #print(json.dumps(data)) header = {"Accept": "application/vnd.api+json"} header.update({"Fastly-Key": scripts.getKeyFromConfig()}) #r=requests.get("https://api.fastly.com/service/" + str(dfObj['Service ID'].iloc[inVar]) + "/wafs/" + str(dfObj['WAF ID'].iloc[inVar]) + "/rules/" + str(rid) + "/rule_status",headers=header) #pprint.pprint(r.json()['data']) header.update({"Content-Type": "application/vnd.api+json"}) #print(json.dumps(header)) #print(json.dumps(body)) #print("https://api.fastly.com/service/" + str(dfObj['Service ID'].iloc[inVar]) + "/wafs/" + str(dfObj['WAF ID'].iloc[inVar]) + "/rules/" + str(row['Num ID']) + "/rule_status") r = requests.patch("https://api.fastly.com/service/" + str(dfObj['Service ID'].iloc[inVar]) + "/wafs/" + str(dfObj['WAF ID'].iloc[inVar]) + "/rules/" + str(rid) + "/rule_status", data=str(json.dumps(body)), headers=header) if r.status_code == 200: pprint.pprint(r.json()['data']) else: print(scripts.bcolors.WARNING + "Error with services request.\nStatus: " + str(r.status_code) + scripts.bcolors.ENDC) while "Not a valid response.": reply = str(input("Modify another set [Y/n]: ")).lower().strip() if reply == 'y': modifyRules() if reply == 'n': scripts.WAFMenu() else: input( scripts.bcolors.WARNING + "Error with API Key, generate a new one. Press ENTER to continue..." + scripts.bcolors.ENDC)
def OWASP(): pandas.set_option('display.max_rows', 1000) if scripts.checkAPINoPrint(): dfObj = listWAFIDsNoPrompt() # print(dfObj) try: inVar = int(input("\n\nEnter index of WAF to display: ")) print("https://api.fastly.com/service/" + str(dfObj['Service ID'].iloc[inVar]) + "/wafs/" + str(dfObj['WAF ID'].iloc[inVar]) + "/owasp") except: e = input("Not a valid number. Press enter to continue or E to exit...") if e.lower() == 'e': return scripts.clear() OWASP() header={"Accept":"application/vnd.api+json"} header.update({"Fastly-Key":scripts.getKeyFromConfig()}) r=requests.get("https://api.fastly.com/service/" + str(dfObj['Service ID'].iloc[inVar]) + "/wafs/" + str(dfObj['WAF ID'].iloc[inVar]) + "/owasp",headers=header) # pprint.pprint(r.json()['data']) if r.status_code == 401: input(scripts.bcolors.WARNING + "Error with services request.\nStatus: " + str(r.status_code) + "\nPress ENTER to continue..." + scripts.bcolors.ENDC) elif r.status_code == 404: # * no waf for that service pass elif r.status_code == 200: with scripts.utils.DataFrameFromDict(r.json()['data']) as df: owaspid = str(df['id'].iloc[0]) df['Allowed HTTP Versions'] = df['attributes.allowed_http_versions'] df['Allowed Methods'] = df['attributes.allowed_methods'] df['Allowed Request Content Type'] = df['attributes.allowed_request_content_type'] df['Allowed Request Content Type Charset'] = df['attributes.allowed_request_content_type_charset'] df['Arg Length'] = df['attributes.arg_length'] df['Arg Namr Length'] = df['attributes.arg_name_length'] df['Combined File Sizes'] = df['attributes.combined_file_sizes'] df['Created At'] = df['attributes.created_at'] df['Critical Anomaly Score'] = df['attributes.critical_anomaly_score'] df['CRS Validate UTF8 Encoding'] = df['attributes.crs_validate_utf8_encoding'] df['Error Anomaly Score'] = df['attributes.error_anomaly_score'] df['High Risk Country Codes'] = df['attributes.high_risk_country_codes'] df['HTTP Violation Score Threshold'] = df['attributes.http_violation_score_threshold'] df['Inbound Anomaly Score Threshold'] = df['attributes.inbound_anomaly_score_threshold'] df['LFI Score Threshold'] = df['attributes.lfi_score_threshold'] df['Max File Size'] = df['attributes.max_file_size'] df['Max Num Args'] = df['attributes.max_num_args'] df['Notice Anomaly Score'] = df['attributes.notice_anomaly_score'] df['Paranoia Level'] = df['attributes.paranoia_level'] df['PHP Injection Score Threshold'] = df['attributes.php_injection_score_threshold'] df['RCE Score Threshold'] = df['attributes.rce_score_threshold'] df['Restricted Extensions'] = df['attributes.restricted_extensions'] df['Restricted Headers'] = df['attributes.restricted_headers'] df['RFI Score Threshold'] = df['attributes.rfi_score_threshold'] df['Session Fixation Score Threshold'] = df['attributes.session_fixation_score_threshold'] df['SQL Injection Score Threshold'] = df['attributes.sql_injection_score_threshold'] df['Total Arg Length'] = df['attributes.total_arg_length'] df['Updated At'] = df['attributes.updated_at'] df['Warning Anomaly Score'] = df['attributes.warning_anomaly_score'] df['XSS Score Threshold'] = df['attributes.xss_score_threshold'] # df.insert(2, 'Severity', None) # df.insert(3, 'Description', None) # if x == 0: # df_all_rows = df # for x in range(len(df.index)): # obj = getRuleByID(str(df['ID'].iloc[x])) # df.at[x,'Severity'] = obj['Severity'].iloc[0] # df.at[x,'Description'] = obj['Description'].iloc[0] # pandas.set_option('display.max_colwidth', -1) # df_all_rows = df_all_rows.append(df,ignore_index = True) print("\n\n" + scripts.bcolors.OKBLUE + scripts.bcolors.UNDERLINE + "OWASP CONFIG for " + owaspid + scripts.bcolors.ENDC + scripts.bcolors.ENDC) print(df.iloc[0]) input("Press ENTER to return to menu...") else: input(scripts.bcolors.WARNING + "Error with services request.\nStatus: " + str(r.status_code) + "\nPress ENTER to continue..." + scripts.bcolors.ENDC) else: input(scripts.bcolors.WARNING + "Error with API Key, generate a new one. Press ENTER to continue..." + scripts.bcolors.ENDC)
#definitions def handler(signum, frame): print('Signal interrupt detected with signal (Ctrl-C): ', signum) exit() #variables flag = True #loop control columns = shutil.get_terminal_size().columns signal.signal(signal.SIGINT, handler) pandas.set_option('display.max_colwidth', -1) pandas.set_option('display.max_rows', 1000) if __name__ == "__main__": scripts.clear() print((' ' + scripts.bcolors.BOLD + scripts.bcolors.UNDERLINE + scripts.bcolors.HEADER + 'WELCOME TO THE FASTLY CLI' \ + scripts.bcolors.ENDC + scripts.bcolors.ENDC + scripts.bcolors.ENDC).center(columns)) print((scripts.bcolors.OKGREEN + " ______ __ __ ________ ____ " + scripts.bcolors.ENDC).center(columns)) print((scripts.bcolors.OKGREEN + " / ____/___ ______/ /_/ /_ __ / ____/ / / _/ " + scripts.bcolors.ENDC).center(columns)) print((scripts.bcolors.OKGREEN + " / /_ / __ `/ ___/ __/ / / / / / / / / / / " + scripts.bcolors.ENDC).center(columns)) print((scripts.bcolors.OKGREEN + " / __/ / /_/ (__ ) /_/ / /_/ / / /___/ /____/ / " + scripts.bcolors.ENDC).center(columns)) print((scripts.bcolors.OKGREEN +
if ((len(sys.argv) > 2)): #Error Usage error() exit() elif (len(sys.argv) == 2): #jika Menggnuakan Argument pil3 = 'y' pers = str(sys.argv[1]) if ((sys.argv[1].find('x')) == -1): error() print('\nNo Variable or using other than x') exit() else: pil3 = 'n' clear() while (pil2 == 'y' or pil2 == 'Y'): if (pil3 == 'n' or pil3 == 'N'): print("ex. x^3 + 2*x^2 - 4*x - 4") pers = str(input("Masukkan Persamaan : ")) pers = pers.lower() print() #Pemilihan Metode Numerik method(pers) print() pil2 = input("Ulang ? (y/n) : ") if (pil2 == 'y' or pil2 == 'Y'): pil3 = input("Ulang dengan Persamaan yang sama ? (y/n) : ") clear()
def WAFMenu(): flag = True scripts.clear() while flag == True: scripts.clear() #Display menu options print(' ' + scripts.bcolors.BOLD + scripts.bcolors.UNDERLINE + scripts.bcolors.HEADER + 'WAF MENU' + scripts.bcolors.ENDC + scripts.bcolors.ENDC + scripts.bcolors.ENDC) print(scripts.bcolors.HEADER + '===========' + scripts.bcolors.ENDC) print('1: List/Search All WAF Rules') print('2: List WAF IDs') print('3: List/Modify WAF Config') print('4: List OWASP Config') print('5: Modify WAF Rules') print('911d: Disable WAF - EMERGENCY ONLY') print('911e: Enable WAF - EMERGENCY ONLY') print('B to go back') print(scripts.bcolors.HEADER + '===========' + scripts.bcolors.ENDC) print(' ') choice = input('Option: ') #get user's choice if choice == '1': scripts.clear() scripts.WAF.listWAFRules() elif choice == '2': scripts.clear() scripts.WAF.listWAFIDs() elif choice == '3': scripts.clear() scripts.WAF.getWAFRuleset() elif choice == '4': scripts.clear() scripts.WAF.OWASP() elif choice == '5': scripts.clear() scripts.WAF.modifyRules() elif choice == '911d': scripts.clear() scripts.WAF.disableWAF() elif choice == '911e': scripts.clear() scripts.WAF.enableWAF() elif choice == 'B' or choice == 'b': scripts.mainMenu() else: input('Not a valid choice. Hit enter to continue...')
def purgeMenu(): flag = True scripts.clear() while flag == True: scripts.clear() #Display menu options print(' ' + scripts.bcolors.BOLD + scripts.bcolors.UNDERLINE + scripts.bcolors.HEADER + 'PURGE MENU' + scripts.bcolors.ENDC + scripts.bcolors.ENDC + scripts.bcolors.ENDC) print(scripts.bcolors.HEADER + '===========' + scripts.bcolors.ENDC) print('1: Purge Key') print('2: Purge Service') print('3: Purge URL') print('B to go back') print(scripts.bcolors.HEADER + '===========' + scripts.bcolors.ENDC) print(' ') choice = input('Option: ').strip(' ') #get user's choice if choice == '1': scripts.clear() purgeKeyMenu() elif choice == '2': scripts.clear() purgeServiceMenu() elif choice == '3': scripts.clear() try: url = str(input("Enter URL to purge: ")) except: input("Error in input. Press Enter to continue...") scripts.clear() purgeMenu() purgeURL(url) elif choice.strip(' ') == 'B' or choice.strip(' ') == 'b': scripts.CDNMenu() else: input('Not a valid choice. Hit enter to continue...')
def mainMenu(): while True: scripts.clear() #Display menu options print(' ' + scripts.bcolors.BOLD + scripts.bcolors.UNDERLINE + scripts.bcolors.HEADER + 'MAIN MENU' + \ scripts.bcolors.ENDC + scripts.bcolors.ENDC + scripts.bcolors.ENDC) print(scripts.bcolors.HEADER + '===========' + scripts.bcolors.ENDC) print('1: WAF') print('2: CDN') print('3: List Services') print('4: Check API Key') print('5: Generate API Key') print('6: List API Keys') print('0: Revoke API Key') print('Q to quit') print(scripts.bcolors.HEADER + '===========' + scripts.bcolors.ENDC) print(' ') choice = input('Option: ').strip(' ') #get user's choice if choice == '1': scripts.clear() scripts.WAFMenu() elif choice == '2': scripts.clear() scripts.CDNMenu() elif choice == '3': scripts.clear() scripts.listServices() elif choice == '4': scripts.clear() scripts.checkAPI() elif choice == '5': scripts.clear() scripts.generateKey() elif choice == '6': scripts.clear() scripts.getAllTokens() elif choice == '0': scripts.clear() scripts.revokeKey() elif choice == 'Q' or choice == 'q': exit() else: input('Not a valid choice. Hit enter to continue...')