def analyse_shadow_file(self, shadow, hashes): """Analyses a Linux shadow file. Args: shadow (list): shadow file content (list of str). hashes (dict): dict of hashes to usernames Returns: Tuple( report_text(str): The report data report_priority(int): The priority of the report (0 - 100) summary(str): A summary of the report (used for task status) ) """ report = [] summary = 'No weak passwords found' priority = Priority.LOW weak_passwords = bruteforce_password_hashes(shadow) if weak_passwords: priority = Priority.CRITICAL summary = 'Shadow file analysis found {0:n} weak password(s)'.format( len(weak_passwords)) report.insert(0, fmt.heading4(fmt.bold(summary))) line = '{0:n} weak password(s) found:'.format(len(weak_passwords)) report.append(fmt.bullet(fmt.bold(line))) for password_hash, plaintext in weak_passwords: line = """User '{0:s}' with password '{1:s}'""".format( hashes[password_hash], plaintext) report.append(fmt.bullet(line, level=2)) report = '\n'.join(report) return (report, priority, summary)
def analyze_jenkins(version, credentials): """Analyses a Jenkins configuration. Args: version (str): Version of Jenkins. credentials (list): of tuples with username and password hash. Returns: str: of description of security of Jenkins configuration file. """ findings = [] credentials_registry = { hash: username for username, hash in credentials } # TODO: Add timeout parameter when dynamic configuration is ready. # Ref: https://github.com/google/turbinia/issues/244 weak_passwords = bruteforce_password_hashes( credentials_registry.keys()) if not version: version = 'Unknown' findings.append('Jenkins version: {0:s}'.format(version)) if weak_passwords: findings.insert(0, 'Jenkins analysis found potential issues.\n') findings.append('{0:n} weak password(s) found:'.format( len(weak_passwords))) for password_hash, plaintext in weak_passwords: findings.append(' - User "{0:s}" with password "{1:s}"'.format( credentials_registry.get(password_hash), plaintext)) return '\n'.join(findings)
def analyze_jenkins(version, credentials, timeout=300): """Analyses a Jenkins configuration. Args: version (str): Version of Jenkins. credentials (list): of tuples with username and password hash. timeout (int): Time in seconds to run password bruteforcing. Returns: Tuple( report_text(str): The report data report_priority(int): The priority of the report (0 - 100) summary(str): A summary of the report (used for task status) ) """ report = [] summary = '' priority = Priority.LOW credentials_registry = { hash: username for username, hash in credentials } # '3200' is "bcrypt $2*$, Blowfish (Unix)" weak_passwords = bruteforce_password_hashes( credentials_registry.keys(), tmp_dir=None, timeout=timeout, extra_args='-m 3200') if not version: version = 'Unknown' report.append(fmt.bullet('Jenkins version: {0:s}'.format(version))) if weak_passwords: priority = Priority.CRITICAL summary = 'Jenkins analysis found potential issues' report.insert(0, fmt.heading4(fmt.bold(summary))) line = '{0:n} weak password(s) found:'.format(len(weak_passwords)) report.append(fmt.bullet(fmt.bold(line))) for password_hash, plaintext in weak_passwords: line = 'User "{0:s}" with password "{1:s}"'.format( credentials_registry.get(password_hash), plaintext) report.append(fmt.bullet(line, level=2)) elif credentials_registry or version != 'Unknown': summary = ( 'Jenkins version {0:s} found with {1:d} credentials, but no issues ' 'detected'.format(version, len(credentials_registry))) report.insert(0, fmt.heading4(summary)) priority = Priority.MEDIUM else: summary = 'No Jenkins instance found' report.insert(0, fmt.heading4(summary)) report = '\n'.join(report) return (report, priority, summary)
def analyze_jenkins(version, credentials): """Analyses a Jenkins configuration. Args: version (str): Version of Jenkins. credentials (list): of tuples with username and password hash. Returns: Tuple( report_text(str): The report data report_priority(int): The priority of the report (0 - 100) summary(str): A summary of the report (used for task status) ) """ report = [] summary = '' priority = Priority.LOW credentials_registry = { hash: username for username, hash in credentials } # TODO: Add timeout parameter when dynamic configuration is ready. # Ref: https://github.com/google/turbinia/issues/244 weak_passwords = bruteforce_password_hashes( credentials_registry.keys()) if not version: version = 'Unknown' report.append(fmt.bullet('Jenkins version: {0:s}'.format(version))) if weak_passwords: priority = Priority.CRITICAL summary = 'Jenkins analysis found potential issues' report.insert(0, fmt.heading4(fmt.bold(summary))) line = '{0:n} weak password(s) found:'.format(len(weak_passwords)) report.append(fmt.bullet(fmt.bold(line))) for password_hash, plaintext in weak_passwords: line = 'User "{0:s}" with password "{1:s}"'.format( credentials_registry.get(password_hash), plaintext) report.append(fmt.bullet(line, level=2)) elif credentials_registry or version != 'Unknown': summary = ( 'Jenkins version {0:s} found with {1:d} credentials, but no issues ' 'detected'.format(version, len(credentials_registry))) report.insert(0, fmt.heading4(summary)) priority = Priority.MEDIUM else: summary = 'No Jenkins instance found' report.insert(0, fmt.heading4(summary)) report = '\n'.join(report) return (report, priority, summary)
def _analyse_wordpress_creds(self, creds, hashnames, timeout=300): """Attempt to brute force extracted Wordpress credentials. Args: creds (list): List of strings containing raw extracted credentials hashnames (dict): Dict mapping hash back to username for convenience. timeout (int): How long to spend cracking. Returns: Tuple( report_text(str): The report data report_priority(int): The priority of the report (0 - 100) summary(str): A summary of the report (used for task status) ) """ report = [] summary = 'No weak passwords found' priority = Priority.LOW # 1000 is "phpass" weak_passwords = bruteforce_password_hashes( creds, tmp_dir=self.tmp_dir, timeout=timeout, extra_args='--username -m 400') if weak_passwords: priority = Priority.CRITICAL summary = 'Wordpress analysis found {0:d} weak password(s)'.format( len(weak_passwords)) report.insert(0, fmt.heading4(fmt.bold(summary))) line = '{0:n} weak password(s) found:'.format(len(weak_passwords)) report.append(fmt.bullet(fmt.bold(line))) for password_hash, plaintext in weak_passwords: if password_hash in hashnames: line = """User '{0:s}' with password '{1:s}'""".format( hashnames[password_hash], plaintext) report.append(fmt.bullet(line, level=2)) report = '\n'.join(report) return (report, priority, summary)
def analyse_shadow_file(self, shadow, hashes, timeout=300): """Analyses a Linux shadow file. Args: shadow (list): shadow file content (list of str). hashes (dict): dict of hashes to usernames timeout (int): Time in seconds to run password bruteforcing. Returns: Tuple( report_text(str): The report data report_priority(int): The priority of the report (0 - 100) summary(str): A summary of the report (used for task status) ) """ report = [] summary = 'No weak passwords found' priority = Priority.LOW # 1800 is "sha512crypt $6$, SHA512 (Unix)" weak_passwords = bruteforce_password_hashes(shadow, tmp_dir=self.tmp_dir, timeout=timeout, extra_args='-m 1800') if weak_passwords: priority = Priority.CRITICAL summary = 'Shadow file analysis found {0:n} weak password(s)'.format( len(weak_passwords)) report.insert(0, fmt.heading4(fmt.bold(summary))) line = '{0:n} weak password(s) found:'.format(len(weak_passwords)) report.append(fmt.bullet(fmt.bold(line))) for password_hash, plaintext in weak_passwords: line = """User '{0:s}' with password '{1:s}'""".format( hashes[password_hash], plaintext) report.append(fmt.bullet(line, level=2)) report = '\n'.join(report) return (report, priority, summary)