def start(): parser = argparse.ArgumentParser( description= 'Scan a SeCloud web application for security vulnerabilities.') parser.add_argument( '--delay', metavar='Delay', type=int, nargs='?', help='The delay in seconds when sending web requests.') parser.add_argument('path', metavar='Path', type=str, nargs='?', help='Path to the SeCloud project') try: PoliciesTester(parser.parse_args()).scan() except KeyboardInterrupt: pass except EOFError: pass except Exception, exception: Message.debug('Application error: %s' % exception.message) traceback.print_exc()
def execute_request(method, url): Message.debug('[HTTP %s] Testing endpoint [%s] for Security Policies' % (method, url)) try: return requests.request(method, url) except ConnectionError: Message.debug('The endpoint [%s] to [%s] is not reachable' % (method, url)) return None
def directory_exists(directory): Message.debug('Checking if %s is a valid directory' % directory) if os.path.isdir(directory): Message.debug('%s is a valid directory' % directory) return directory else: raise Exception('%s is not a valid directory' % directory)
def from_paths(self, paths, delay=None): count = 0 for path, methods in paths.iteritems(): for method in methods: count += self.from_path(method, path) if delay is not None: Message.debug('Waiting for a delay of %s second' % delay) time.sleep(delay) return count
def from_path(self, method, path): url = self.format_url(path) Message.debug('Found a new endpoint: [%s] to [%s]' % (method, url)) if Vulnerabilities.is_valid_method(method): response = Vulnerabilities.execute_request(method, url) if response is not None: return self.identify_vulnerabilities(response.request, response) Message.debug('Unable to test the Security Policies against endpoint [%s] to [%s]' % (method, url)) return 0
def identify_vulnerabilities(self, request, response): count = 0 variables = { 'count': count, 'request': request, 'response': response, 'Message': Message } for security_policy in self.security_policies: Message.debug('Security policy: %s' % security_policy) try: execfile(security_policy, dict(), variables) count += (variables['count'] - count) except Exception, exception: Message.debug(exception.message)
def from_directory(self, directory): for file in os.listdir(directory): if file.endswith('.yml'): config = os.path.join(directory, file) answer = Message.input( 'Is %s the open api config file? [Y/n] ' % config) if answer is 'Y': Message.debug( 'The %s file was selected as open api config file' % config) return self.from_file(config) else: Message.debug('Looking for other *.yml files') continue raise Exception('Unable not find *.yml OpenAPI config file in %s' % directory)
def from_file(self, file): Message.debug('Reading %s' % file) with open(file, 'r') as file_object: Message.debug('Loading %s' % file) self.data = yaml.load(file_object.read()) Message.debug('OpenAPI config file content: %s' % self.data) return self.data
def get_attribute(self, attribute): Message.debug('Looking for attribute %s in OpenAPI config' % attribute) element = self.data[attribute] if element: Message.debug('Successfully found attribute %s in OpenAPI config' % attribute) return element else: error = 'Unable to find attribute %s in OpenAPI config' % attribute Message.debug(error) raise Exception(error)