aboutsummaryrefslogtreecommitdiffstats
path: root/extract_token_from_browser.py
diff options
context:
space:
mode:
authorTrygve Aaberge <trygveaa@gmail.com>2023-06-29 02:14:16 +0200
committerTrygve Aaberge <trygveaa@gmail.com>2023-06-29 22:15:55 +0200
commit4b6042a33bc276446b8ce937ef137947e292a048 (patch)
tree69646d0749d814593a3bada3c5db232454cfdbbb /extract_token_from_browser.py
parent3fa2bbc8985f8250a4cea1cd4f6d9ae7cf80ea83 (diff)
downloadwee-slack-4b6042a33bc276446b8ce937ef137947e292a048.tar.gz
Clearly separate code for Firefox and Chrome
This makes the code much easier to read in my opinion. It also fixes some errors about potentially unbound variables.
Diffstat (limited to 'extract_token_from_browser.py')
-rwxr-xr-xextract_token_from_browser.py112
1 files changed, 61 insertions, 51 deletions
diff --git a/extract_token_from_browser.py b/extract_token_from_browser.py
index 375b290..3cc110a 100755
--- a/extract_token_from_browser.py
+++ b/extract_token_from_browser.py
@@ -3,27 +3,15 @@
from __future__ import annotations
import argparse
-from contextlib import contextmanager
import json
import os
-from typing import TYPE_CHECKING
-import secretstorage
import shutil
import sqlite3
import sys
-
+from contextlib import contextmanager
from pathlib import Path
-from secretstorage.exceptions import SecretStorageException
from sqlite3 import OperationalError
-
-try:
- import_err = None
- from Crypto.Cipher import AES
- from Crypto.Protocol.KDF import PBKDF2
- from plyvel import DB
- from plyvel._plyvel import IOError as pIOErr
-except ModuleNotFoundError as e:
- import_err = e
+from typing import TYPE_CHECKING, Literal, assert_never
if TYPE_CHECKING:
from _typeshed import StrPath
@@ -50,6 +38,20 @@ def sqlite3_connect(path: StrPath):
con.close()
+def get_cookies(cookies_path: StrPath, cookie_d_query: str, cookie_ds_query: str):
+ cookie_d_value = None
+ try:
+ with sqlite3_connect(cookies_path) as con:
+ cookie_d_value = con.execute(cookie_d_query).fetchone()[0]
+ cookie_ds_value = con.execute(cookie_ds_query).fetchone()[0]
+ return cookie_d_value, cookie_ds_value
+ except TypeError:
+ if not cookie_d_value:
+ print("Couldn't find the 'd' cookie value", file=sys.stderr)
+ sys.exit(1)
+ return cookie_d_value, None
+
+
parser = argparse.ArgumentParser(
description="Extract Slack tokens from the browser files"
)
@@ -61,15 +63,21 @@ parser.add_argument(
)
args = parser.parse_args()
+browser: Literal["firefox", "chrome"]
+
if sys.platform.startswith("linux"):
chrome_key_iterations = 1
if args.browser == "firefox-snap":
+ browser = "firefox"
browser_data = Path.home().joinpath("snap/firefox/common/.mozilla/firefox")
elif args.browser == "firefox":
+ browser = "firefox"
browser_data = Path.home().joinpath(".mozilla/firefox")
elif args.browser == "chromium":
+ browser = "chrome"
browser_data = Path.home().joinpath(".config/chromium")
elif args.browser in ["chrome", "chrome-beta"]:
+ browser = "chrome"
browser_data = Path.home().joinpath(".config/google-%s" % args.browser)
else:
print(
@@ -79,12 +87,15 @@ if sys.platform.startswith("linux"):
elif sys.platform.startswith("darwin"):
chrome_key_iterations = 1003
if args.browser in ["firefox", "firefox-snap"]:
+ browser = "firefox"
browser_data = Path.home().joinpath(
"Library/Application Support/Firefox/Profiles"
)
elif args.browser == "chromium":
+ browser = "chrome"
browser_data = Path.home().joinpath("Library/Application Support/Chromium")
elif args.browser in ["chrome", "chrome-beta"]:
+ browser = "chrome"
browser_data = Path.home().joinpath("Library/Application Support/Google/Chrome")
else:
print(
@@ -95,9 +106,9 @@ else:
print("Currently only Linux and macOS is supported by this script", file=sys.stderr)
sys.exit(1)
-leveldb_path = None
profile = args.profile
-if args.browser in ["firefox", "firefox-snap"]:
+
+if browser == "firefox":
cookie_d_query = (
"SELECT value FROM moz_cookies WHERE host = '.slack.com' " "AND name = 'd'"
)
@@ -114,10 +125,28 @@ if args.browser in ["firefox", "firefox-snap"]:
print("Couldn't find the default profile for Firefox", file=sys.stderr)
sys.exit(1)
cookies_path = default_profile_path.joinpath("cookies.sqlite")
-else:
- if import_err:
- print("Missing required modules for Chrome browser support", file=sys.stderr)
- raise import_err
+
+ cookie_d_value, cookie_ds_value = get_cookies(
+ cookies_path, cookie_d_query, cookie_ds_query
+ )
+
+ local_storage_path = default_profile_path.joinpath("webappsstore.sqlite")
+ local_storage_query = "SELECT value FROM webappsstore2 WHERE key = 'localConfig_v2'"
+ local_config = None
+ try:
+ with sqlite3_connect(local_storage_path) as con:
+ local_config_str = con.execute(local_storage_query).fetchone()[0]
+ local_config = json.loads(local_config_str)
+ except (OperationalError, TypeError):
+ pass
+
+elif browser == "chrome":
+ import secretstorage
+ from Crypto.Cipher import AES
+ from Crypto.Protocol.KDF import PBKDF2
+ from plyvel import DB
+ from plyvel._plyvel import IOError as pIOErr
+ from secretstorage.exceptions import SecretStorageException
cookie_d_query = (
"SELECT encrypted_value FROM cookies WHERE "
@@ -134,18 +163,10 @@ else:
cookies_path = default_profile_path.joinpath("Cookies")
leveldb_path = default_profile_path.joinpath("Local Storage/leveldb")
-cookie_d_value = None
-cookie_ds_value = None
-try:
- with sqlite3_connect(cookies_path) as con:
- cookie_d_value = con.execute(cookie_d_query).fetchone()[0]
- cookie_ds_value = con.execute(cookie_ds_query).fetchone()[0]
-except TypeError:
- if not cookie_d_value:
- print("Couldn't find the 'd' cookie value", file=sys.stderr)
- sys.exit(1)
+ cookie_d_value, cookie_ds_value = get_cookies(
+ cookies_path, cookie_d_query, cookie_ds_query
+ )
-if args.browser in ["chromium", "chrome", "chrome-beta"]:
bus = secretstorage.dbus_init()
try:
collection = secretstorage.get_default_collection(bus)
@@ -174,24 +195,6 @@ if args.browser in ["chromium", "chrome", "chrome-beta"]:
if cookie_ds_value:
cookie_ds_value = cipher.decrypt(cookie_ds_value[3:]).decode("utf8")
-if cookie_ds_value:
- cookie_value = f"d={cookie_d_value};d-s={cookie_ds_value}"
-else:
- cookie_value = cookie_d_value
-
-teams = []
-
-if args.browser in ["firefox", "firefox-snap"]:
- local_storage_path = default_profile_path.joinpath("webappsstore.sqlite")
- local_storage_query = "SELECT value FROM webappsstore2 WHERE key = 'localConfig_v2'"
- local_config = None
- try:
- with sqlite3_connect(local_storage_path) as con:
- local_config_str = con.execute(local_storage_query).fetchone()[0]
- local_config = json.loads(local_config_str)
- except (OperationalError, TypeError):
- pass
-else:
try:
db = DB(str(leveldb_path))
except pIOErr:
@@ -208,14 +211,21 @@ else:
local_storage_value = db.get(b"_https://app.slack.com\x00\x01localConfig_v2")
local_config = json.loads(local_storage_value[1:])
+else:
+ assert_never(browser)
+
+if cookie_ds_value:
+ cookie_value = f"d={cookie_d_value};d-s={cookie_ds_value}"
+else:
+ cookie_value = cookie_d_value
+
if local_config:
teams = [
team
for team in local_config["teams"].values()
if not team["id"].startswith("E")
]
-
-if not teams:
+else:
teams = [
{
"token": "<token>",