reverse-skills-max: initial public release (restored, redacted, hardened)
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
Apache License 2.0 — see the repository root LICENSE file for the full text.
|
||||
|
||||
Copyright the AnalystAIPack contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
@@ -0,0 +1,88 @@
|
||||
---
|
||||
name: analyzing-infostealer-credential-theft
|
||||
description: 'Analyzes infostealer samples by mapping the browser, credential store, wallet, and
|
||||
application paths they target, and the exfiltration channel used, from static strings and
|
||||
behavior. Activates for requests to analyze an infostealer, identify targeted credential stores,
|
||||
or map stealer collection and exfiltration behavior.'
|
||||
domain: cybersecurity
|
||||
subdomain: malware-analysis
|
||||
tags:
|
||||
- malware-analysis
|
||||
- infostealer
|
||||
- credential-theft
|
||||
- exfiltration
|
||||
- triage
|
||||
version: 1.0.0
|
||||
author: analyst-ai-pack
|
||||
license: Apache-2.0
|
||||
mitre_attack:
|
||||
- T1555.003
|
||||
- T1539
|
||||
- T1005
|
||||
d3fend:
|
||||
- D3-FAPA
|
||||
- D3-DA
|
||||
references:
|
||||
- 'MITRE ATT&CK T1555.003 Credentials from Web Browsers — https://attack.mitre.org/techniques/T1555/003/'
|
||||
- 'MITRE ATT&CK T1539 Steal Web Session Cookie — https://attack.mitre.org/techniques/T1539/'
|
||||
---
|
||||
|
||||
# Analyzing Infostealer Credential Theft
|
||||
|
||||
## When to Use
|
||||
|
||||
- You have an infostealer sample and need to enumerate what it targets: browser credential/cookie
|
||||
stores, crypto wallets, FTP/VPN/messaging app configs, and the exfil channel.
|
||||
- You are building detections from the file paths and endpoints a stealer references.
|
||||
|
||||
**Do not use** this to recover credentials yourself — it characterizes what the malware targets
|
||||
from inert static analysis.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- The sample (read inertly), optionally with extracted strings.
|
||||
|
||||
## Safety & Handling
|
||||
|
||||
- Read bytes statically; defang exfil endpoints; never run the stealer.
|
||||
|
||||
## Workflow
|
||||
|
||||
### Step 1: Map targeted artifacts
|
||||
|
||||
```bash
|
||||
python scripts/analyst.py profile sample.bin
|
||||
```
|
||||
|
||||
Matches references to known browser paths (`Login Data`, `Cookies`, `Web Data`), wallet
|
||||
directories, app config paths, and credential APIs, grouped by category.
|
||||
|
||||
### Step 2: Identify exfiltration channel
|
||||
|
||||
Detects HTTP(S) POST endpoints, Telegram bot tokens, Discord webhooks, and FTP/SMTP usage in
|
||||
strings.
|
||||
|
||||
### Step 3: Build the target/exfil profile
|
||||
|
||||
Summarize targeted stores and the exfil channel, mapping to ATT&CK.
|
||||
|
||||
### Step 4: Defang and report
|
||||
|
||||
Defang endpoints and produce IOCs for detection.
|
||||
|
||||
## Validation
|
||||
|
||||
- Targeted artifacts are grouped (browsers, wallets, apps, system credential stores).
|
||||
- The exfil channel is identified with a defanged endpoint where present.
|
||||
- Findings map to ATT&CK credential-access/collection/exfiltration techniques.
|
||||
|
||||
## Pitfalls
|
||||
|
||||
- Generic browser paths can appear in benign tools — corroborate with theft behavior.
|
||||
- Missing wallet/app targets that use obfuscated path strings.
|
||||
- Reporting live exfil endpoints (webhooks, bot tokens) without defanging.
|
||||
|
||||
## References
|
||||
|
||||
- See [`references/api-reference.md`](references/api-reference.md) for the profiler.
|
||||
- ATT&CK T1555.003 and T1539 (linked in frontmatter).
|
||||
@@ -0,0 +1,39 @@
|
||||
# API Reference: Analyzing Infostealer Credential Theft
|
||||
|
||||
## Overview
|
||||
|
||||
`scripts/analyst.py` extracts strings from a sample and maps them to targeted artifacts (browser
|
||||
credential stores, crypto wallets, application configs, credential APIs) and exfiltration channels
|
||||
(Telegram, Discord webhooks, HTTP POST, FTP, SMTP). It reads bytes statically, defangs endpoints,
|
||||
and executes nothing.
|
||||
|
||||
## Dependencies
|
||||
|
||||
| Package | Version | Purpose |
|
||||
|---------|---------|---------|
|
||||
| (stdlib) | — | regex, JSON, file IO |
|
||||
|
||||
## Core functions
|
||||
|
||||
### `profile(path)`
|
||||
Returns targeted artifacts (grouped), exfiltration channels (defanged), and an infostealer
|
||||
likelihood flag (≥2 target categories).
|
||||
|
||||
## Target categories
|
||||
|
||||
- **browser_credentials**: Chromium `Login Data`/`Cookies`/`Local State`, Firefox `key4.db`/`logins.json`.
|
||||
- **crypto_wallets**: `wallet.dat`, Electrum/Exodus/MetaMask/Monero/Ledger.
|
||||
- **applications**: FileZilla, OpenVPN, Telegram `tdata`, Discord, WinSCP, AnyDesk.
|
||||
- **credential_api**: `CryptUnprotectData`, `CredEnumerate`, vault/LSA APIs.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
python scripts/analyst.py profile sample.bin
|
||||
```
|
||||
|
||||
## Sources
|
||||
|
||||
- MITRE ATT&CK T1555.003 Credentials from Web Browsers — https://attack.mitre.org/techniques/T1555/003/
|
||||
- MITRE ATT&CK T1539 Steal Web Session Cookie — https://attack.mitre.org/techniques/T1539/
|
||||
- Browser/wallet artifact paths from public stealer family analyses
|
||||
@@ -0,0 +1,82 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Profile an infostealer's targeted artifacts and exfiltration channel from static strings.
|
||||
|
||||
Extracts ASCII/UTF-16LE strings and matches them against curated lists of browser credential
|
||||
stores, crypto wallets, application configs, and credential APIs, plus exfil-channel indicators
|
||||
(HTTP POST, Telegram, Discord webhooks, FTP/SMTP). Reads bytes statically; executes nothing.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ASCII_RE = re.compile(rb"[\x20-\x7e]{4,}")
|
||||
UTF16_RE = re.compile(rb"(?:[\x20-\x7e]\x00){4,}")
|
||||
|
||||
TARGETS = {
|
||||
"browser_credentials": ["login data", "web data", "cookies", "logins.json", "key4.db",
|
||||
"signons.sqlite", "\\user data\\", "local state"],
|
||||
"crypto_wallets": ["wallet.dat", "\\electrum\\", "\\exodus\\", "\\ethereum\\keystore",
|
||||
"metamask", "\\monero\\", "ledger live"],
|
||||
"applications": ["filezilla\\recentservers.xml", "\\openvpn\\", "\\telegram desktop\\tdata",
|
||||
"\\discord\\local storage", "winscp.ini", "\\pidgin\\", "anydesk"],
|
||||
"credential_api": ["cryptunprotectdata", "vaultcli", "credenumerate", "lsadump"],
|
||||
}
|
||||
|
||||
EXFIL = {
|
||||
"telegram": [r"api\.telegram\.org", r"bot\d{6,}:[a-z0-9_-]{30,}"],
|
||||
"discord_webhook": [r"discord(?:app)?\.com/api/webhooks/"],
|
||||
"http_post": [r"https?://[^\s\"']+"],
|
||||
"ftp": [r"ftp://[^\s\"']+"],
|
||||
"smtp": [r"smtp\.[a-z0-9.-]+"],
|
||||
}
|
||||
|
||||
|
||||
def _strings(data: bytes) -> str:
|
||||
parts = [m.decode("ascii", "ignore") for m in ASCII_RE.findall(data)]
|
||||
parts += [m.decode("utf-16-le", "ignore") for m in UTF16_RE.findall(data)]
|
||||
return "\n".join(parts)
|
||||
|
||||
|
||||
def _defang(s: str) -> str:
|
||||
return s.replace("http", "hxxp").replace(".", "[.]")
|
||||
|
||||
|
||||
def profile(path: str) -> dict:
|
||||
blob = _strings(Path(path).read_bytes())
|
||||
low = blob.lower()
|
||||
targets = {}
|
||||
for cat, needles in TARGETS.items():
|
||||
hits = sorted({n for n in needles if n in low})
|
||||
if hits:
|
||||
targets[cat] = hits
|
||||
exfil = {}
|
||||
for chan, patterns in EXFIL.items():
|
||||
found = set()
|
||||
for pat in patterns:
|
||||
for m in re.findall(pat, blob, re.I):
|
||||
found.add(_defang(m))
|
||||
if found:
|
||||
exfil[chan] = sorted(found)[:10]
|
||||
return {
|
||||
"targeted_artifacts": targets,
|
||||
"exfiltration_channels": exfil,
|
||||
"is_likely_infostealer": len(targets) >= 2,
|
||||
}
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None) -> int:
|
||||
parser = argparse.ArgumentParser(description="Profile infostealer targets/exfil")
|
||||
sub = parser.add_subparsers(dest="cmd", required=True)
|
||||
p = sub.add_parser("profile")
|
||||
p.add_argument("file")
|
||||
args = parser.parse_args(argv)
|
||||
print(json.dumps(profile(args.file), indent=2))
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user