浏览器存储密码离线解密
一、任务目标
从Windows取证镜像中提取浏览器保存的网站 www.xxxxxxxx.top 账号 lulan 的密码。
二、最终结果
**答案:账号 lulan 的密码为 a8sa9syai**(保存在Edge浏览器中)
三、加密原理
Chrome/Edge(v80+)均基于Chromium,密码加密采用两层结构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| Windows用户密码 │ ▼ ┌─────────────────────┐ │ DPAPI Master Key │ ← 存储在 Protect\{SID}\{GUID} │ (用户密码派生解密) │ └─────────┬───────────┘ │ ▼ ┌─────────────────────┐ │ 浏览器 AES-256 Key │ ← 存储在 Local State(DPAPI加密) └─────────┬───────────┘ │ ▼ ┌─────────────────────┐ │ AES-256-GCM 解密 │ ← 密码密文存储在 Login Data └─────────┬───────────┘ │ ▼ 密码明文
|
密码密文格式(Login Data中的password_value字段):
1 2
| [v10] [nonce: 12字节] [ciphertext] [tag: 16字节] 3字节 AES-GCM随机数 密文 认证标签
|
四、所需取证文件
从镜像中导出以下文件(用户名 chenchen):
Chrome
| 文件 |
镜像路径 |
| Login Data |
C:\Users\chenchen\AppData\Local\Google\Chrome\User Data\Default\Login Data |
| Local State |
C:\Users\chenchen\AppData\Local\Google\Chrome\User Data\Local State |
Edge
| 文件 |
镜像路径 |
| Login Data |
C:\Users\chenchen\AppData\Local\Microsoft\Edge\User Data\Default\Login Data |
| Local State |
C:\Users\chenchen\AppData\Local\Microsoft\Edge\User Data\Local State |
DPAPI(Chrome和Edge共用)
| 文件 |
镜像路径 |
| Master Key |
C:\Users\chenchen\AppData\Roaming\Microsoft\Protect\S-1-5-21-17485621-1970499508-3307361946-1001\ad9b27cd-405e-44c5-9eb5-67e1f7c89def |
Master Key的GUID可从Local State中的DPAPI Blob解析得到。
五、解密步骤详解
步骤1:读取Login Data查看加密记录
Login Data是SQLite数据库,查询logins表:
1 2 3 4 5 6 7
| import sqlite3
conn = sqlite3.connect('Login Data') cursor = conn.cursor() cursor.execute('SELECT origin_url, username_value, password_value FROM logins') for url, username, pwd in cursor.fetchall(): print(f'{url} | {username} | {pwd.hex()}')
|
输出(以Edge为例):
1
| https://www.xxxxxxxx.top/ | lulan | 763130...(加密数据)
|
密码字段以 763130(ASCII “v10”)开头,确认为Chrome v80+加密格式。
步骤2:从Local State提取DPAPI加密的浏览器密钥
1 2 3 4 5 6 7
| import json, base64
with open('Local State', 'r', encoding='utf-8') as f: local_state = json.load(f)
encrypted_key = base64.b64decode(local_state['os_crypt']['encrypted_key']) dpapi_blob = encrypted_key[5:]
|
解析DPAPI Blob可得到所需Master Key的GUID:AD9B27CD-405E-44C5-9EB5-67E1F7C89DEF
步骤3:使用Windows密码解密DPAPI Master Key
DPAPI密钥派生过程:
1 2 3 4 5 6 7 8 9 10 11
| from hashlib import sha1 from Cryptodome.Hash import HMAC, SHA1
password = 'qwer123' user_sid = 'S-1-5-21-17485621-1970499508-3307361946-1001'
sha1_hash = sha1(password.encode('utf-16le')).digest()
prekey = HMAC.new(sha1_hash, (user_sid + '\0').encode('utf-16le'), SHA1).digest()
|
用预密钥解密Master Key文件:
1 2 3 4 5 6 7 8 9 10 11
| from impacket.dpapi import MasterKeyFile, MasterKey
with open('ad9b27cd-405e-44c5-9eb5-67e1f7c89def', 'rb') as f: mk_data = f.read()
mk_file = MasterKeyFile(mk_data) mk = MasterKey(mk_data[len(mk_file.getData()):])
master_key = mk.decrypt(prekey)
|
解密得到64字节的Master Key:
1 2 3
| 9555714bc67d3988852b2bb41dfec14d3d8cc9a2c7f0c577 0814c315ff391fc82405b46a190ce423e1b631e2848f30bf bc15b3133550629c11f54ca6aa86dfe4
|
步骤4:解密浏览器AES Key
1 2 3 4
| from impacket.dpapi import DPAPI_BLOB
blob = DPAPI_BLOB(dpapi_blob) browser_key = blob.decrypt(master_key)
|
| 浏览器 |
AES-256 Key |
| Chrome |
18b27bd82bfa6b739bb6f2149135dac512585599be00028f496ba91b81c407c2 |
| Edge |
717a8873ffa72c532e7378c3932ffa5ac0ee1b367e1a42a972b7647101ca44a9 |
步骤5:AES-256-GCM解密密码
1 2 3 4 5 6 7 8 9 10
| from Cryptodome.Cipher import AES
encrypted_pwd = ...
nonce = encrypted_pwd[3:15] ciphertext = encrypted_pwd[15:-16] tag = encrypted_pwd[-16:]
cipher = AES.new(browser_key, AES.MODE_GCM, nonce=nonce) password = cipher.decrypt_and_verify(ciphertext, tag).decode('utf-8')
|
六、完整解密脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| """浏览器密码离线解密工具(Chrome/Edge)"""
import json, base64, sqlite3 from hashlib import sha1 from Cryptodome.Hash import HMAC, SHA1 from Cryptodome.Cipher import AES from impacket.dpapi import MasterKeyFile, MasterKey, DPAPI_BLOB
def decrypt_browser_passwords(login_data_path, local_state_path, masterkey_path, user_sid, win_password): sha1_hash = sha1(win_password.encode('utf-16le')).digest() prekey = HMAC.new(sha1_hash, (user_sid + '\0').encode('utf-16le'), SHA1).digest()
with open(masterkey_path, 'rb') as f: mk_data = f.read() mk_file = MasterKeyFile(mk_data) mk = MasterKey(mk_data[len(mk_file.getData()):]) master_key = mk.decrypt(prekey) if not master_key: raise Exception("Master Key解密失败,Windows密码可能错误")
with open(local_state_path, 'r', encoding='utf-8') as f: local_state = json.load(f) encrypted_key = base64.b64decode(local_state['os_crypt']['encrypted_key']) blob = DPAPI_BLOB(encrypted_key[5:]) browser_key = blob.decrypt(master_key)
conn = sqlite3.connect(login_data_path) cursor = conn.cursor() cursor.execute('SELECT origin_url, username_value, password_value FROM logins')
results = [] for url, username, enc_pwd in cursor.fetchall(): if enc_pwd and len(enc_pwd) > 3 and enc_pwd[:3] == b'v10': nonce = enc_pwd[3:15] ct_tag = enc_pwd[15:] cipher = AES.new(browser_key, AES.MODE_GCM, nonce=nonce) pwd = cipher.decrypt_and_verify(ct_tag[:-16], ct_tag[-16:]).decode('utf-8') results.append((url, username, pwd)) conn.close() return results
if __name__ == '__main__': SID = 'S-1-5-21-17485621-1970499508-3307361946-1001' WIN_PWD = 'qwer123' MK_PATH = 'ad9b27cd-405e-44c5-9eb5-67e1f7c89def'
print("=== Chrome ===") for url, user, pwd in decrypt_browser_passwords( 'Chrome_Login Data', 'Chrome_Local State', MK_PATH, SID, WIN_PWD): print(f'{url} | {user} | {pwd}')
print("\n=== Edge ===") for url, user, pwd in decrypt_browser_passwords( 'Edge_Login Data', 'Edge_Local State', MK_PATH, SID, WIN_PWD): print(f'{url} | {user} | {pwd}')
|
七、总结
- Chrome/Edge共用DPAPI体系:同一用户下Chrome和Edge使用相同的DPAPI Master Key,但各自有独立的AES Key
- Master Key GUID定位:DPAPI Blob内嵌了所需Master Key的GUID,对应
Protect\{SID}\ 下的文件名
- 密钥派生链:
Windows密码 → SHA1 → HMAC-SHA1(+SID) → PBKDF2-SHA512(+salt, 8000轮) → 解密Master Key
- 离线解密必要条件:Windows用户密码 + Master Key文件 + 用户SID + Login Data + Local State
- 依赖库:
impacket(DPAPI解析)、pycryptodome(AES-GCM解密)