def start(self): try: if 'ALL' in self.modules: for filename in os.listdir(self.modules_dir): if filename.endswith('.yml') and filename != 'template.yml': msg, module = load_module(self.modules_dir + filename) print(process_icon, module['name'], 'Analyze started.') self.req_timout = int(module.get('delay', 2)) + 3 self.run(module) print(c('[*]', 'Green', attrs=['bold']), module['name'], 'Analyze done!') print(c('[*]', 'Green', attrs=['bold']), c(len(self.project['vulnerabilities'][module['severity']].get(module['name'], [])), 'Red', attrs=['bold']), module['name'], 'Found!') else: for filename in self.modules: msg, module = load_module(self.modules_dir + filename + '.yml') print(process_icon, module['name'], 'Analyze started.') self.req_timout = int(module.get('delay', 2)) + 3 self.run(module) print(c('[*]', 'Green', attrs=['bold']), module['name'], 'Analyze done! \t') print(process_icon, c(len(self.project['vulnerabilities'][module['severity']].get(module['name'], [])), 'Red', attrs=['bold']), module['name'], 'Found!') except KeyError as e: printc(f'[!] Invalid Module format, please check the template. {e}', 'Red', attrs=['bold']) logging.error(f'The module contain unsupported key {e}') except TypeError as e: printc(f'[!] Module not found please check the modules names.', 'Red', attrs=['bold']) logging.error(f'Module not found please check the modules names. {e}')
def load_file_as_strings_list(path): if os.path.isfile(path): with open(path, 'r') as f: strings_list = f.read().split("\n") return strings_list else: printc("[!] Your attack file contain incorrect path.", "Red") return []
def run(self, module): """ This function gets the module info as dict object and start the module by parse the inputs and send requests to the module vectors. No return, the results are stored in the project dict.""" if module['module_type'] == 'check': printc('Module type not supported yet.', 'Blue', attrs=['bold']) for element in module['check']['contain']: # TODO pass for element in module['check']['does_not_contain']: # TODO pass return if module['module_type'] == 'input_output': # Load the input to a dictionary inputs = {} outputs = None for num in range(module['input_number']): inputs[num] = list(itertools.chain.from_iterable( [load_file_as_strings_list(path) for path in module['input_' + str(num)]])) \ if module['input_type'][num] == 'files' else module['input_' + str(num)] if not inputs[num]: return if len(inputs[0]) > 10: printc( '[!] This process may take a long time you have {} input need to be checked with every possible ' 'entry point'.format( len(inputs[0]) * module['input_number']), 'LightSalmon3') if module.get('output', None) is not None: outputs = list(itertools.chain.from_iterable( [load_file_as_strings_list(path) for path in module['output']])) \ if module['output_type'] == 'files' else module['output'] if module['entry_points'] == 'ALL': self.queries_names_test(module, inputs, outputs) self.forms_inp_names_test(module, inputs, outputs) self.requests_headers_names_test(module, inputs, outputs) self.raw_requests_test(module, inputs, outputs) self.paths_test(module, inputs, outputs) else: if module['entry_points'].get('queries_names') is not None: self.queries_names_test(module, inputs, outputs) if module['entry_points'].get('forms_inputs_names') is not None: self.forms_inp_names_test(module, inputs, outputs) if module['entry_points'].get('requests_headers_names') is not None: self.requests_headers_names_test(module, inputs, outputs) if module['entry_points'].get('raw_requests') is not None: self.raw_requests_test(module, inputs, outputs) if module['entry_points'].get('paths') is not None: self.paths_test(module, inputs, outputs)
def analyze_the_output(self, module, resp, inp, mod_vector, outputs): """Gets the info about the module and the output as parameters and analyze the output to find if the module is success. Return Boolean value.""" vuln = False if module['output_path'] != 'SAME': resp = Get(url_check(module['output_path'], urlparse(self.project['base_url'])), headers=self.project['headers'], timeout=self.req_timout, cookies=self.project['cookies']) if module['output_type'] == 'DELAY': if module['delay'] + 3 >= resp.elapsed.total_seconds() >= module['delay']: vuln = True if module['output_type'] == 'REFLECT': outputs = inp if isinstance(inp, list) else [inp] if not outputs: printc('[!] This output type is not supported for the module entry points', 'Red', attrs=['bold']) return None if resp and 'response_contents' in module['output_points']: if any(output in str(resp.content) for output in outputs): vuln = True if resp and 'response_headers_names' in module['output_points']: if set(outputs) & set(resp.headers.keys()): vuln = True if resp and 'response_headers_values' in module['output_points']: if set(outputs) & set(resp.headers.values()): vuln = True if resp and 'status_codes' in module['output_points']: if resp.status_code in outputs: vuln = True if vuln: if mod_vector not in self.project['vulnerabilities'][module['severity']].get(module['name'], []): self.project['vulnerabilities'][module['severity']][module['name']] = self.project['vulnerabilities'][ module['severity']].get( module['name'], []) + [mod_vector] save_project(self.project) print(process_icon, c(len(self.project['vulnerabilities'][module['severity']].get(module['name'], [])), 'Red', attrs=['bold']), module['name'].replace('_', ' ') + '\'s', 'Detected.\r', end='') # print(c('\r[+]', 'Blue', attrs=['bold']), # 'Checking', # c(next(iter(mod_vector.values())) if isinstance(mod_vector, dict) else mod_vector, 'DarkOrange3'), # end='') return vuln
def start(): try: # Print the banner print(BANNERS[random.randint(0, len(BANNERS) - 1)]) # configure the logs logging.basicConfig(level=logging.INFO, format='%(message)s', filename=None) file_handler = logging.FileHandler('logs/log', 'w') formatter = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s') file_handler.setFormatter(formatter) log = logging.getLogger() for h in log.handlers: log.removeHandler(h) log.addHandler(file_handler) # Get the arguments from the console parser = argparse.ArgumentParser("YAWSS") parser.add_argument("-ui", "--user-interface", help="Set the preferred UI: cli, web", type=str, default='cli') parser.add_argument( "-s", "--scan", help= "The scan yaml config file path (required if you are using the cli)", type=str) parser.add_argument( "-m", "--modules", help="Set the modules by writing the names without extensions" " (Leave empty or set to ALL for using all the modules). EX: -m xss,sql", type=str) parser.add_argument("--host", help="Web UI host (can be used just with web UI)", type=str) parser.add_argument("--port", help="Web UI port (can be used just with web UI)", type=int) args = parser.parse_args() if args.user_interface == 'web': # disable the printing to console with open('logs/console', "w") as logger: host = args.host if args.host else '127.0.0.1' port = args.port if args.port else 5000 printc(f'YAWSS server started at {host}:{port}', "DarkSeaGreen") sys.stdout = logger start_the_web_ui(host=host, port=port) elif args.user_interface == 'cli': modules = args.modules.split(",") if args.modules else None if args.scan: yawss_cli(args.scan, modules) else: printc("Please enter the scan path!", "Red", attrs=["bold"]) else: printc( "Sorry! for now we just support two type of UI's: web and cli.", "Red", attrs=["bold"]) except KeyboardInterrupt as e: printc('[X] Ok ok, quitting.', 'Red', attrs=['bold']) except Exception as e: logging.error(e)
def yawss_cli(project_path, modules=None): # Start a new project msg, project = load_scan(project_path) if not project: printc('[!] Scan config not found.', 'DeepPink4', attrs=['bold']) return resp, err = Get(project['base_url'], headers=project['headers'], cookies=project['cookies']) if err: printc('[!] Host can not be reached', 'Red', attrs=['bold']) return project['queue'].add(project['base_url']) try: msg, project = load_project(project) printc('[~] ' + msg, 'SteelBlue', attrs=['blink']) if project['enable_crawler']: print(process_icon, 'Parsing robots.txt file.') Spider(project).crawl_robots_txt() print(process_icon, 'Start Crawling.') printc('[~] The spiders are Just Doing Their Best.', 'Grey69') Spider(project).run() # Delete the duplicated forms forms_hashes = set() new_forms = [] for form in project['forms']: form_hash = hashlib.sha1(str(form).encode()).hexdigest() if form_hash in forms_hashes: continue else: forms_hashes.add(form_hash) new_forms.append(form) project['forms'] = new_forms del forms_hashes print('\n' + process_icon, 'Crawling DONE!') if project['subdomains_research']: print(process_icon, 'Subdomain research started.') project['subdomains'] = get_subdomains(project['base_url']) print(process_icon, 'Subdomain research done!') nums_color = 'DarkSeaGreen' print( process_icon, c(f'{len(project["links"])}', nums_color, attrs=['bold']) + ' Links,', c(f'{len(project["forms"])}', nums_color, attrs=['bold']) + ' Forms,', c(f'{len(project["queries"])}', nums_color, attrs=['bold']) + ' Queries', c(f'{len(project["subdomains"])}', nums_color, attrs=['bold']) + ' Subdomains and', c(f'{len(project["files"])}', nums_color, attrs=['bold']) + ' Files Found.') save_project(project) print(process_icon + ' Analysis Engine started.') AnalysisEngine(project, modules).start() save_project(project) except KeyboardInterrupt as e: printc('[X] Ok ok, quitting.', 'Red', attrs=['bold']) save_project(project) except KeyError as e: logging.error( 'Invalid project please check the template and try again') print(c('[!]', 'Red'), e, 'value not found') printc('Invalid project please check the template and try again', 'Red', attrs=['bold']) except Exception as e: logging.error(e) save_project(project) printc(error_icon + '\n\tAn Unexpected Error Occurred! Please check the logs', 'Red', attrs=['bold'])