mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-20 14:30:59 +03:00
- Add mitre_f3 frontmatter block to 94 fraud-relevant skills (phishing, account takeover, banking malware, BEC, identity/KYC, payment/card fraud, money-mule/cash-out, ransomware extortion, DFIR, threat intel) - Map each skill to F3 v1.1 tactics + precise technique IDs, including the two F3-specific tactics ATT&CK lacks: Positioning (FA0001) and Monetization (FA0002) - All 123 F3 v1.1 technique IDs validated against the upstream STIX bundle (github.com/center-for-threat-informed-defense/fight-fraud-framework): 0 invalid IDs, 0 invalid tactics, 0 name mismatches, no placeholder IDs - mitre_f3 kept as a separate block from mitre_attack (F3 redefines several ATT&CK tactics for the fraud context) - Add docs/mitre-f3-mapping.md schema reference - Update README: F3 as the 6th framework, dedicated F3 section + badge
106 lines
2.9 KiB
Markdown
106 lines
2.9 KiB
Markdown
---
|
|
name: hunting-credential-stuffing-attacks
|
|
description: 'Detects credential stuffing attacks by analyzing authentication logs
|
|
for login velocity anomalies, ASN diversity, password spray patterns, and geographic
|
|
distribution of failed logins. Uses statistical analysis on Splunk or raw log data.
|
|
Use when investigating account takeover campaigns or building detection rules for
|
|
auth abuse.
|
|
|
|
'
|
|
domain: cybersecurity
|
|
subdomain: security-operations
|
|
tags:
|
|
- credential-stuffing
|
|
- authentication-logs
|
|
- login-anomaly
|
|
- asn-analysis
|
|
- threat-hunting
|
|
- account-takeover
|
|
version: '1.0'
|
|
author: mahipal
|
|
license: Apache-2.0
|
|
nist_csf:
|
|
- DE.CM-01
|
|
- RS.MA-01
|
|
- GV.OV-01
|
|
- DE.AE-02
|
|
mitre_attack:
|
|
- T1078
|
|
- T1190
|
|
- T1059
|
|
- T1003
|
|
- T1110
|
|
mitre_f3:
|
|
version: '1.1'
|
|
tactics:
|
|
- initial-access
|
|
- positioning
|
|
techniques:
|
|
- id: T1110.004
|
|
name: 'Brute Force: Credential Stuffing'
|
|
tactic: initial-access
|
|
source: attack
|
|
- id: T1110.003
|
|
name: 'Brute Force: Password Spraying'
|
|
tactic: initial-access
|
|
source: attack
|
|
- id: F1006.002
|
|
name: 'Account Takeover: Exposed Login Credential'
|
|
tactic: initial-access
|
|
source: f3
|
|
- id: F1006
|
|
name: Account Takeover
|
|
tactic: initial-access
|
|
source: f3
|
|
---
|
|
|
|
# Hunting Credential Stuffing Attacks
|
|
|
|
|
|
## When to Use
|
|
|
|
- When investigating security incidents that require hunting credential stuffing attacks
|
|
- When building detection rules or threat hunting queries for this domain
|
|
- When SOC analysts need structured procedures for this analysis type
|
|
- When validating security monitoring coverage for related attack techniques
|
|
|
|
## Prerequisites
|
|
|
|
- Familiarity with security operations concepts and tools
|
|
- Access to a test or lab environment for safe execution
|
|
- Python 3.8+ with required dependencies installed
|
|
- Appropriate authorization for any testing activities
|
|
|
|
## Instructions
|
|
|
|
Analyze authentication logs to detect credential stuffing by identifying patterns
|
|
of distributed login failures, high IP diversity, and suspicious ASN distribution.
|
|
|
|
```python
|
|
import pandas as pd
|
|
from collections import Counter
|
|
|
|
# Load auth logs
|
|
df = pd.read_csv("auth_logs.csv", parse_dates=["timestamp"])
|
|
|
|
# Credential stuffing indicator: many IPs trying few accounts
|
|
ip_per_account = df[df["status"] == "failed"].groupby("username")["source_ip"].nunique()
|
|
accounts_under_attack = ip_per_account[ip_per_account > 50]
|
|
```
|
|
|
|
Key detection indicators:
|
|
1. High unique source IPs per failed username
|
|
2. Low success rate across many accounts (< 1%)
|
|
3. ASN concentration from cloud/proxy providers
|
|
4. Geographic impossibility (same account, distant locations)
|
|
5. User-agent uniformity across distributed IPs
|
|
|
|
## Examples
|
|
|
|
```python
|
|
# Password spray: one password tried across many accounts
|
|
spray = df[df["status"] == "failed"].groupby(["source_ip", "password_hash"]).agg(
|
|
accounts=("username", "nunique")).reset_index()
|
|
sprays = spray[spray["accounts"] > 10]
|
|
```
|