├── LICENSE ├── README.md ├── hydra_export.py ├── hydra_export_py3.py ├── register_all_targets.py └── scope_download.py /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Ozgur Alp 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Synack Platform API Scripts 2 | Custom created scripts for a better/faster experience at Synack Bug Bounty Platform. 3 | 4 | **Note from 2024:** Most of the functionality is outdated and probably not working at the moment, but repository is still keeped for legacy. 5 | 6 | ***Scripts:*** 7 | - Hydra open ports export: `hydra_export.py` (Use `hydra_export_py3.py` if you are using python3) 8 | - Download all in-scope IP's for host targets: `scope_download.py` 9 | - Register for all targets at once: `register_all_targets.py` 10 | 11 | ***Usages:*** 12 | - Do not forgot to supply authorization headers for your user and target codename you want to process correctly while asked from command line. 13 | - Auth headers can be easily gathered from the web browser console with the command: `sessionStorage.getItem('shared-session-com.synack.accessToken');` while logged in. 14 | - Target codenames can also be easily gathered from URL, after clicking the target as: `https://platform.synack.com/targets//scope` 15 | - For `register_all_targets.py` script, make sure that edit `passed_assessments` array within your own passed assessments from platform. 16 | 17 | ***Credits:*** 18 | - Thanks [Rezn0k](https://twitter.com/Rezn0k) for his contributions on Hydra export script! 19 | -------------------------------------------------------------------------------- /hydra_export.py: -------------------------------------------------------------------------------- 1 | import json 2 | import requests 3 | 4 | requests.adapters.DEFAULT_RETRIES = 10 5 | SYNACK_API_URL = "https://platform.synack.com/api" 6 | REGISTERED_TARGETS = "/targets/registered_summary" 7 | ALL_TARGETS = "/targets/" 8 | HYDRA_TARGET = "/hydra_search/search" 9 | 10 | auth_header = raw_input("Please enter your Synack Auth Header (Command from web console: sessionStorage.getItem('shared-session-com.synack.accessToken')): ") 11 | target_codename = raw_input("Please enter your target codename: ") 12 | headers = {"Authorization": "Bearer "+auth_header} 13 | 14 | iterator = 1 15 | next_page = True 16 | results = [[],[]] 17 | results_final = [] 18 | 19 | while next_page: 20 | try: 21 | url = SYNACK_API_URL + HYDRA_TARGET + "?page="+str(iterator)+"&listing_uids="+target_codename+"&q=%2Bport_is_open%3Atrue" 22 | target_response = requests.get(url, headers=headers).json() 23 | for i in range (len(target_response)): 24 | ports = str(target_response[i]["ports"]).split("}}}}") 25 | for j in range (len(ports)-1): 26 | results[0].append((target_response[i]["ip"])) 27 | results[1].append(str(ports[j]).split("'")[1]) 28 | print("Page "+str(iterator)+" done.") 29 | if len(target_response) < 10: 30 | print("Done loading target.") 31 | next_page = False 32 | iterator += 1 33 | except Exception as e: 34 | print(e) 35 | next_page = False 36 | 37 | for i in range (len(results[0])): 38 | results_final.append (str(results[0][i])+":"+str(results[1][i])) 39 | results_final.sort() 40 | 41 | for i in range (len(results_final)): 42 | print results_final[i] 43 | -------------------------------------------------------------------------------- /hydra_export_py3.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | import time 3 | import getpass 4 | import json 5 | import requests 6 | import argparse 7 | from warnings import filterwarnings 8 | from colorama import Fore, Style 9 | 10 | filterwarnings('ignore') 11 | 12 | proxy = "http://127.0.0.1:8080" 13 | proxies = {'http':proxy, 'https':proxy} 14 | 15 | s = requests.Session() 16 | 17 | SYNACK_API_URL = "https://platform.synack.com/api" 18 | REGISTERED_TARGETS = "/targets/registered_summary" 19 | HYDRA_TARGET = "/hydra_search/search" 20 | 21 | def get_args(): 22 | p = argparse.ArgumentParser(description="Hydra API Script") 23 | p.add_argument('-t','--token',type=str,help="API Token", required=False) 24 | p.add_argument('-c','--codename',type=str,help="Codename Listing UID", required=False) 25 | 26 | args = p.parse_args() 27 | 28 | return args 29 | 30 | def get_uid(access_token, codename): 31 | headers = { 32 | 'Authorization':f'Bearer {access_token}' 33 | } 34 | url = f'{SYNACK_API_URL}{REGISTERED_TARGETS}' 35 | # data = s.get(url, headers=headers, verify=False, proxies=proxies).json() 36 | data = s.get(url, headers=headers, verify=False).json() 37 | 38 | for item in data: 39 | if item['codename'] == codename: 40 | return item['id'] 41 | else: 42 | continue 43 | 44 | def make_request(url, headers): 45 | status_code = "" 46 | try: 47 | # r = requests.get(url, headers=headers, verify=False, proxies=proxies) 48 | r = requests.get(url, headers=headers, verify=False) 49 | if r.status_code == 200: 50 | print (Fore.YELLOW+"[*] Status Code: " + Style.RESET_ALL + "%s" % r.status_code) 51 | return r.json() 52 | else: 53 | print (Fore.YELLOW+"[*] Status Code: " + Style.RESET_ALL + "%s" % r.status_code) 54 | return None 55 | except Exception as e: 56 | print (Fore.RED+"[!] Error Connecting: "+Style.RESET_ALL + "%s" % str(e)) 57 | return None 58 | 59 | def check_errors(data): 60 | try: 61 | if data['error']: 62 | print (Fore.RED+"[!] ElasticSearch Error"+ Style.RESET_ALL) 63 | return False 64 | except Exception as e: 65 | return True 66 | 67 | def query_api(access_token, target_codename): 68 | 69 | headers = {"Authorization": "Bearer " + access_token} 70 | 71 | iterator = 1 72 | next_page = True 73 | results = [] 74 | results_final = [] 75 | 76 | while next_page: 77 | print (Fore.MAGENTA+"[*] Page %s starting." % str(iterator) + Style.RESET_ALL) 78 | # try: 79 | url = f'{SYNACK_API_URL}{HYDRA_TARGET}?page={str(iterator)}&listing_uids={target_codename}&q=%2Bport_is_open%3Atrue' 80 | target_response = make_request(url, headers) 81 | if target_response is not None: 82 | if check_errors(target_response): 83 | for target in target_response: 84 | for port in target['ports']: 85 | results.append(f"{target['ip']}:{port}") 86 | print(Fore.CYAN+"Page "+str(iterator)+" done." + Style.RESET_ALL) 87 | if len(target_response) < 10: 88 | print(Fore.BLUE+Style.BRIGHT+"Done loading target."+Style.RESET_ALL) 89 | next_page = False 90 | iterator += 1 91 | else: 92 | print (Fore.YELLOW+"[!] Invalid Response Code. Saving current data and moving on."+Style.RESET_ALL) 93 | iterator += 1 94 | # except Exception as e: 95 | # print (e) 96 | # next_page = False 97 | 98 | 99 | for target in results: 100 | print (target) 101 | 102 | with open('open-ports.txt', 'w') as f: 103 | for target in results: 104 | f.write(target+"\n") 105 | 106 | print (Fore.GREEN+"[+] Open Ports stored in 'open-ports.txt'"+Style.RESET_ALL) 107 | 108 | def main(): 109 | args = get_args() 110 | 111 | Listing_UID = get_uid(args.token, args.codename.upper()) 112 | print (Fore.GREEN+"[+] Listing_UID for %s: " % args.codename + Style.RESET_ALL + "%s" % Listing_UID) 113 | query_api(args.token, Listing_UID) 114 | 115 | if __name__ == '__main__': 116 | main() 117 | -------------------------------------------------------------------------------- /register_all_targets.py: -------------------------------------------------------------------------------- 1 | import json 2 | import requests 3 | import warnings 4 | 5 | requests.adapters.DEFAULT_RETRIES = 10 6 | warnings.filterwarnings("ignore") 7 | auth_header = raw_input("Please enter your Synack Auth Header (Command from web console: sessionStorage.getItem('shared-session-com.synack.accessToken')): ") 8 | headers = {"Authorization": "Bearer "+auth_header} 9 | 10 | iter = 1 11 | next_page = True 12 | slugs = [] 13 | passed_assessments = ["Web Application", "Host", "Mobile", "Hardware", "Reverse Engineering", "Source Code"] 14 | 15 | print "Getting target slugs." 16 | while next_page: 17 | url = "https://platform.synack.com/api/targets?filter%5Bprimary%5D=unregistered&filter%5Bsecondary%5D=all&filter%5Bcategory%5D=all&sorting%5Bfield%5D=dateUpdated&sorting%5Bdirection%5D=desc&pagination%5Bpage%5D="+str(iter) 18 | target_response = requests.get(url, headers=headers, verify=False).json() 19 | if (len(target_response)!=0): 20 | for i in range (len(target_response)): 21 | if target_response[i]["category"]["name"] in passed_assessments: 22 | slugs.append(str(target_response[i]["slug"])) 23 | iter += 1 24 | print "Page "+str(iter)+" done." 25 | else: 26 | next_page = False 27 | print "All slugs for not-registered targets are successfully gathered!" 28 | print "Total count of not-registered targets are: "+str(len(slugs)) 29 | print "Starting process of registering all targets." 30 | for i in range (len(slugs)): 31 | url = "https://platform.synack.com/api/targets/"+slugs[i]+"/signup" 32 | target_response = requests.post(url, headers=headers, verify=False, json={"ResearcherListing":{"terms":1}}) 33 | if target_response.status_code == 200: 34 | print "Registered target with slug "+slugs[i]+" successfully!" 35 | else: 36 | print "Error while registering target with slug "+slugs[i] 37 | print "All processes are completed." 38 | -------------------------------------------------------------------------------- /scope_download.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import warnings 3 | import json 4 | import os 5 | 6 | warnings.filterwarnings("ignore") 7 | 8 | token = raw_input("Please enter your Synack Auth Header (Command from web console: sessionStorage.getItem('shared-session-com.synack.accessToken')): ") 9 | target_code = raw_input("Please enter your target codename: ") 10 | 11 | blocks = [] 12 | x = 1 13 | 14 | print ("Downloading scope for target.") 15 | response = requests.get('https://platform.synack.com/api/targets/'+target_code+'/cidrs',params={'page': x},headers={'Authorization': 'Bearer '+token},verify=False) 16 | temp = json.dumps(response.json()['cidrs']).replace("[","").replace("]","").replace("\"","").replace(", ","\n").split("\n") 17 | blocks.extend(temp) 18 | print("Page "+str(x)+" done.") 19 | while len(temp) > 1: 20 | x = x + 1 21 | response = requests.get('https://platform.synack.com/api/targets/'+target_code+'/cidrs',params={'page': x},headers={'Authorization': 'Bearer '+token},verify=False) 22 | if (response.json().get("cidrs")==None): 23 | break 24 | else: 25 | temp = json.dumps(response.json()['cidrs']).replace("[","").replace("]","").replace("\"","").replace(", ","\n").split("\n") 26 | blocks.extend(temp) 27 | print("Page "+str(x)+" done.") 28 | if os.path.isfile("blocks.txt"): 29 | os.remove("blocks.txt") 30 | f = open("blocks.txt","w+") 31 | for i in range (len(blocks)): 32 | if blocks[i] != "": f.write(blocks[i]+"\n") 33 | f.close() 34 | print ("All done! Blocks have been added to blocks.txt file.") 35 | --------------------------------------------------------------------------------