Extract Chrome Passwords in Python

hello i m trying to use python script to retrieve my save password in chrome database
the first they i created the script i had no errors and the result was printed on the screen , the problem i m facing it all about the next day i came in to test run the same script it execute well with no errors but the result didn’t print to the screen

1 Like

I have been able to get this code to work but only with Python 2.7.x
I have a project I been working on and getting things to work in 3.10.4 has been an issue.
I get this error in version 3.10.4

pwd = win32crypt.CryptUnprotectData(pwd, None, None, None, 0) #This returns a tuple description and the password
pywintypes.error: (87, 'CryptUnprotectData', 'The parameter is incorrect.')
import os
import sqlite3
import win32crypt

#path to user's login data
data_path = os.path.expanduser('~')+"\\AppData\\Local\\Google\\Chrome\\User Data\\Default"

login_db = os.path.join(data_path, 'Login Data')

#db connect and query
c = sqlite3.connect(login_db)
cursor = c.cursor()
select_statement = "SELECT origin_url, username_value, password_value FROM logins"
cursor.execute(select_statement)

login_data = cursor.fetchall()

#URL: credentials dictionary
credential = {}

#decrytping the password
for url, user_name, pwd, in login_data:
    pwd = win32crypt.CryptUnprotectData(pwd, None, None, None, 0) #This returns a tuple description and the password
    credential[url] = (user_name, pwd[1])

#writing to a text file (CAUTION: Don't leave this text file around!)
prompt = raw_input("[.] Are you sure you want to write all this sensitive data to a text file? \n[.]  or \n[>] ")
if prompt == 'y':
    with open('pwd.txt', 'w') as f:
        for url, credentials in credential.iteritems():
            if credentials[1]:
                f.write("\n"+url+"\n"+credentials[0].encode('utf-8')+ " | "+credentials[1]+"\n")
            else:
                f.write("\n"+url+"\n"+"USERNAME NOT FOUND | PASSWORD NOT FOUND \n")
    print ("[.] Successfully written to pwd.txt!")
else:
    quit()

Here is one I found in my files but it gives me same error in 3.10.4

# Make sure Google Chrome and other browser are closed before running.
# If not, then the program will hang and not complete.
os.chdir(myDir)
username1 = "Username: "
siteId = "Site ID: "
password_field = "Password: "
f = open("passwordsusers.txt", "w")
conn = sqlite3.connect(getenv("APPDATA") + "\\..\\Local\\Google\\Chrome\\User Data\\Default\\Login Data")
conn3 = sqlite3.connect(getenv("APPDATA") + "\\..\\Local\\Google\\Chrome\\User Data\\Default\\History")
conn1 = sqlite3.connect(getenv("APPDATA") + "\\..\\Local\\Google\\Chrome\\User Data\\Default\\Web Data")
conn4 = sqlite3.connect(getenv("APPDATA") + "\\..\\Local\\Google\\Chrome\\User Data\\Default\\Web Data")
cursor3 = conn3.cursor()
cursor1 = conn1.cursor()
cursor4 = conn4.cursor()
cursor = conn.cursor()
cursor.execute('SELECT action_url, username_value, password_value FROM logins')
for result in cursor.fetchall():
  password = win32crypt.CryptUnprotectData(result[2], None, None, None, 0)[1]
  if password:
    f.writelines(siteId + result[0] + '\n' + username1 + result[1] + '\n' + password_field + password + '\n' + '--------------------------------' + '\n')

f1 = open('keywordsearches.txt','w')   
cursor3.execute("SELECT * FROM keyword_search_terms") 
result3 = cursor3.fetchall() 
for r3 in result3:
        f1.writelines(str(r3[2] + '\n'))
        
        
f2 = open('history.txt', 'w')
cursor3.execute("SELECT * FROM urls") 
result4 = cursor3.fetchall() 
for r4 in result4:
        f2.writelines(str('\n' + r4[1] + '\n'))

f6 = open('autofill.txt','w')
cursor4.execute("SELECT * FROM autofill")
result1 = cursor4.fetchall() 
for r6 in result1:
  f6.writelines(str('\n' + r6[0] + ":       "+ r6[2]))

f.close()
f1.close()
f2.close()
f6.close()

If you wish, this is what I have working in 2.7.x

# Shout-out to CoreyMSchafer for all his great tutorial videos on Python.
# Corey does a great job in his start to finnish tutorials on Python.
# Check Corey out on YouTube and if you can, help support his great work.
# Corey's YouTube channel is below
# https://www.youtube.com/playlist?list=PL-osiE80TeTt2d9bfVyTiXJA-UTHn6WwU

from __future__ import print_function
import os
from os import getenv, listdir, getcwd
from os.path import isfile, join, normpath, basename
import hashlib
import sqlite3
import win32crypt
import sys
import wmi
import datetime
import sys
import platform
import getpass
import socket
import ifaddr
import shutil
import winreg
import win32com
from psutil import virtual_memory
import win32com.client as wincl
import builtins
from collections import OrderedDict
import operator
import win32api
import win32file
from importlib import reload

# Set variables for platform and OS information
ps = platform.system()
pr = platform.release()
build = platform.version()
mem = virtual_memory()
username = getpass.getuser()
hostname = socket.gethostname()
adapters = ifaddr.get_adapters()
mType = platform.machine()
pType = platform.processor()
currentDT = datetime.datetime.now()
speak = wincl.Dispatch("SAPI.SpVoice")
data_path = os.path.expanduser('~')+ r"\\AppData\\Local\\Google\\Chrome\\User Data\\Default"
files = os.listdir(data_path)
history_db = os.path.join(data_path, 'history')
c = sqlite3.connect(history_db)
cursor = c.cursor()
select_statement = "SELECT urls.url, urls.visit_count FROM urls, visits WHERE urls.id = visits.url;"
cursor.execute(select_statement)
results = cursor.fetchall()
myDir = "Chrome Dump"


def createFolder(directory):
  try:
    if not os.path.exists(hostname):
      os.makedirs(hostname)
  except OSError:
    return ('Error: Creating directory. ' + hostname)

createFolder(hostname)

def printCurrentUserIETypedURLs():
    print("Typed IE URL\'s:", '\n') 
    # Open the key and return the handle object.
    hKey = winreg.OpenKey(winreg.HKEY_CURRENT_USER,
                          r'Software\\Microsoft\\Internet Explorer\\TypedURLs')
    # Get the information about the key.
    subkeyCnt, valuesCnt, modtime = winreg.QueryInfoKey(hKey)
    print(subkeyCnt, valuesCnt)
    # Retrieve the value tuples (name, value, type).
    for n in range(valuesCnt):
        print(winreg.EnumValue(hKey, n))
    # Close the handle object.
    winreg.CloseKey(hKey)

def usersSubkeys():
    print("User ID:", '\n') 
    hKey2 = winreg.OpenKey(winreg.HKEY_USERS, '')
    subkeyCnt, valuesCnt, modtime = winreg.QueryInfoKey(hKey2)
    # Retrieve the subkeys.
    for n in range(subkeyCnt):
        print (winreg.EnumKey(hKey2, n))  

    winreg.CloseKey(hKey2)

# We created the directory to dump our files in, now we change to that location and set
# that as the current working directory
os.chdir(hostname)
cdir = os.getcwd()

def createFolder(directory):
  try:
    if not os.path.exists(myDir):
      os.makedirs(myDir)
  except OSError:
    return ('Error: Creating directory. ' + myDir)

createFolder(myDir)

# Lets print the data we collect below, to a file.
sys.stdout = open("%s %s" % (hostname, (currentDT.strftime("%m%d%Y %H%M%S"))) + ".txt", "w+")

# Get the Physical Drives numbers and or serial numbers
# Strip out unwanted items
HDs = wmi.WMI()
for hdSerialnum in HDs.Win32_PhysicalMedia():
  print(hdSerialnum.Tag.strip("\\.\\PHYSICAL"), hdSerialnum.SerialNumber)
print("")
w = wmi.WMI()
for drive in w.Win32_LogicalDisk():
    print ("Drive Letter: " + drive.Caption, "HD Size: " + str(drive.Size), "Free: " + str(drive.FreeSpace))
    isNetworkDrive = win32file.GetDriveType(drive.Caption) == win32file.DRIVE_REMOTE
    print("Network Drive: " + str(isNetworkDrive), "\n")
    

# Print OS and machine information below
# There is most likely a neater way to do this but this is how we got it to work
print("Installed OS: " + ps + '\n' + "OS Version: " + pr + '\n' + "OS Build: " + build + '\n' +
      "Current Dir: " + cdir + '\n' + "Machine Type: " + mType + '\n' + "Processor: " +
      pType + '\n' + "RAM Total: " + str(mem.total) + '\n' + "Current User Name: "
      + username + '\n' + "Computer Name: " + hostname + '\n')

# speak.Speak("Operating System Information collected")
# Get the network devices and IP's of said devices
for adapter in adapters:
  print(adapter.nice_name)
  for ip in adapter.ips:
    print("   %s/%s" % (ip.ip, ip.network_prefix))

# Want a space between
print('')

print("Root Dir List: " + "\n" + str(os.listdir('C:\\')) + "\n")

print("User Dir List: " + "\n" + str(os.listdir(r'C:\Users')) + "\n")

print("Current User Dir List: " + "\n" + str(os.listdir(r'C:\Users\\' + username)) + "\n")

print(printCurrentUserIETypedURLs())

print('')

print(usersSubkeys())

# Lets close our file we just wrote to.
sys.stdout.close()

reload(sys)
sys.getdefaultencoding()

#execfile('D:\\Python Triage\\hashdeep.py')

# Make sure Google Chrome and other browser are closed before running.
# If not, then the program will hang and not complete.
os.chdir(myDir)
username1 = "Username: "
siteId = "Site ID: "
password_field = "Password: "
f = open("passwordsusers.txt", "w")
conn = sqlite3.connect(getenv("APPDATA") + "\\..\\Local\\Google\\Chrome\\User Data\\Default\\Login Data")
conn3 = sqlite3.connect(getenv("APPDATA") + "\\..\\Local\\Google\\Chrome\\User Data\\Default\\History")
conn1 = sqlite3.connect(getenv("APPDATA") + "\\..\\Local\\Google\\Chrome\\User Data\\Default\\Web Data")
conn4 = sqlite3.connect(getenv("APPDATA") + "\\..\\Local\\Google\\Chrome\\User Data\\Default\\Web Data")
cursor3 = conn3.cursor()
cursor1 = conn1.cursor()
cursor4 = conn4.cursor()
cursor = conn.cursor()
cursor.execute('SELECT action_url, username_value, password_value FROM logins')
for result in cursor.fetchall():
  password = win32crypt.CryptUnprotectData(result[2], None, None, None, 0)[1]
  if password:
    f.writelines(siteId + result[0] + '\n' + username1 + result[1] + '\n' + password_field + password + '\n' + '--------------------------------' + '\n')

f1 = open('keywordsearches.txt','w')   
cursor3.execute("SELECT * FROM keyword_search_terms") 
result3 = cursor3.fetchall() 
for r3 in result3:
        f1.writelines(str(r3[2] + '\n'))
        
        
f2 = open('history.txt', 'w')
cursor3.execute("SELECT * FROM urls") 
result4 = cursor3.fetchall() 
for r4 in result4:
        f2.writelines(str('\n' + r4[1] + '\n'))

f6 = open('autofill.txt','w')
cursor4.execute("SELECT * FROM autofill")
result1 = cursor4.fetchall() 
for r6 in result1:
  f6.writelines(str('\n' + r6[0] + ":       "+ r6[2]))

f.close()
f1.close()
f2.close()
f6.close()

os.chdir('.')

#execfile('D:\\Python Triage\\hashdeep.py')

speak.Speak("Completed running your code")

I have a python EXE created with pysimplegui, if you wish to see the above code in action.

It is something I have been working on for learning and work. It has been on back burner as issues popped up in life to cause it to be down on totem pole.

Extract zip to it’s own dir and run as admin. Make sure no browser is open and give a few seconds at end as I have it scanning drive(s) for jpeg files.