python如何提取瀏覽器中保存的網站登錄用戶名密碼

  python如何提取Chrome中的保存的網站登錄用戶名密碼?

  很多瀏覽器都貼心地提供了保存用戶密碼功能,用戶一旦開啓,就不需要每次都輸入用戶名、密碼,非常方便。作爲python腳本,能否拿到用戶提前保存在瀏覽器中的用戶名密碼,用以自動登錄呢?必須有,小爬已經提前踩過很多坑,找到了可行的方案。

  以Chrome瀏覽器爲例,瀏覽器中的用戶數據(包含加密後的密碼)都存在下圖所示的位置中:

 

    文件的路徑就像這樣 C: => Users => <Your_Name> => AppData =>Local => Google => Chrome => User Data =>Local State

由於每臺電腦的用戶名是不確定的,因此小爬這裏用python中的OS庫來動態得到:

local_computer_directory_path = os.path.join(os.environ["USERPROFILE"], "AppData", "Local", "Google", "Chrome","User Data", "Local State")

  知道了具體位置後,我們需要先拿到加密後的密文,顯然該密碼肯定不是以明文的形式保存在文件中,否則安全無法保證。獲取密文之前,還得先知道用於加密的密鑰,這需要先安裝pycryptodomex庫,直接用pip來安裝即可。一切就緒,現在編寫一個獲取密鑰的python函數:

 1 import os,json,base64,sqlite3,win32crypt,shutil
 2 from Cryptodome.Cipher import AES
 3 #需要安裝pip install pycryptodomex 庫
 4 from datetime import  datetime, timedelta
 5 def fetching_encryption_key():
 6     '''動態獲取保存用戶數據的文件的路徑,然後讀出加密後的密文'''
 7     local_computer_directory_path = os.path.join(os.environ["USERPROFILE"], "AppData", "Local", "Google", "Chrome","User Data", "Local State")
 8     with open(local_computer_directory_path, "r", encoding="utf-8") as f:
 9         local_state_data = f.read()
10         local_state_data = json.loads(local_state_data)
11 
12     # decoding the encryption key using base64
13     encryption_key = base64.b64decode(
14     local_state_data["os_crypt"]["encrypted_key"])
15     
16     # remove Windows Data Protection API (DPAPI) str
17     encryption_key = encryption_key[5:]
18     # return decrypted key
19     return win32crypt.CryptUnprotectData(encryption_key, None, None, None, 0)[1]

  有了這個密鑰,咱們還需要編寫一個解密的方法將密碼變成明文,考慮到Chrome瀏覽器的版本80之前和之後用了截然不同的加密手段,因此,對應的解密方法也不同,小爬將他們一併整合到解密的函數中:

def password_decryption(password, encryption_key):
    try:
        iv = password[3:15]
        password = password[15:]
        
        # generate cipher
        cipher = AES.new(encryption_key, AES.MODE_GCM, iv)
        
        # decrypt password
        return cipher.decrypt(password)[:-16].decode()
    except:
        
        try:
            return str(win32crypt.CryptUnprotectData(password, None, None, None, 0)[1])
        except:
            return "No Passwords"
  核心搞定之後,還涉及到一個知識點,用於某個網站登錄的用戶名 以及加密後的密文存儲在哪裏?別急,還是之前提到的Local State文件,其實它是一個本地sqlite3數據庫文件,我們可以藉助sqlite3庫以及sql語法輕鬆獲取。當然需要先知道目標網站的域名,比如小爬就想取本地chrome瀏覽器中我自己保存用於登錄博客園網站(base_url="cnblogs.com")的用戶名密碼。另外需要注意的是,同一個網站,瀏覽器是支持同時保存幾組用戶名密碼的。代碼示例如下:
 1 def get_url_credential(base_url):
 2     '''如果chrome瀏覽器本地存儲了OA密碼,則返回用戶和密碼列表,否則返回False'''
 3     key = fetching_encryption_key()
 4     db_path = os.path.join(os.environ["USERPROFILE"], "AppData", "Local",
 5                         "Google", "Chrome", "User Data", "default", "Login Data")
 6     filename = "ChromePasswords.db"
 7     shutil.copyfile(db_path, filename) # 爲了避免程序bug將原有的login Data 文件損壞,複製一份出來供程序用
 8     
 9     # connecting to the database
10     db = sqlite3.connect(filename)
11     cursor = db.cursor()
12     cursor.execute("select origin_url, action_url, username_value, password_value, date_created, date_last_used from logins order by date_last_used")
13     user_name,pass_word=None,None
14     userInfos=[] # 用於存放多組同一個網站的用戶名 密碼
15     for row in cursor.fetchall():
16         main_url = row[0]
17         if base_url in main_url:
18             user_name = row[2]
19             pass_word = password_decryption(row[3], key)
20             userInfos.append([user_name,pass_word])
21     cursor.close()
22     db.close()
23     try:
24         os.remove(filename)
25     except:
26         pass
27     return userInfos

  還在圍觀嗎?動手能力強的已經躍躍欲試,把它用到真正的辦公自動化場景中了。希望這些對現實業務的思考和代碼實現,能對您的工作有所啓發。不管咋說,活到老,學到老。拒絕躺平,一起捲起來!

快來關注本公衆號 獲取更多爬蟲、數據分析的知識!

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章