mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-31 00:17:41 +03:00
Initial commit - 611 cybersecurity skills across all subdomains
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
---
|
||||
name: performing-hash-cracking-with-hashcat
|
||||
description: Hash cracking is an essential skill for penetration testers and security auditors to evaluate password strength. Hashcat is the world's fastest password recovery tool, supporting over 300 hash types w
|
||||
domain: cybersecurity
|
||||
subdomain: cryptography
|
||||
tags: [cryptography, hash-cracking, password-security, hashcat, penetration-testing]
|
||||
version: "1.0"
|
||||
author: mahipal
|
||||
license: MIT
|
||||
---
|
||||
# Performing Hash Cracking with Hashcat
|
||||
|
||||
## Overview
|
||||
|
||||
Hash cracking is an essential skill for penetration testers and security auditors to evaluate password strength. Hashcat is the world's fastest password recovery tool, supporting over 300 hash types with GPU acceleration. This skill covers using hashcat for authorized password auditing, understanding attack modes, creating effective rule sets, and generating hash analysis reports. This is strictly for authorized penetration testing and password policy assessment.
|
||||
|
||||
## Objectives
|
||||
|
||||
- Identify hash types from captured hashes
|
||||
- Execute dictionary, brute-force, and rule-based attacks
|
||||
- Create custom hashcat rules for targeted cracking
|
||||
- Analyze password strength from cracking results
|
||||
- Generate compliance reports on password policy effectiveness
|
||||
- Benchmark GPU performance for hash cracking
|
||||
|
||||
## Key Concepts
|
||||
|
||||
### Hashcat Attack Modes
|
||||
|
||||
| Mode | Flag | Description | Use Case |
|
||||
|------|------|-------------|----------|
|
||||
| Dictionary | -a 0 | Wordlist attack | Known password patterns |
|
||||
| Combination | -a 1 | Combine two wordlists | Compound passwords |
|
||||
| Brute-force | -a 3 | Mask-based enumeration | Short passwords |
|
||||
| Rule-based | -a 0 -r | Dictionary + transformation rules | Complex variations |
|
||||
| Hybrid | -a 6/7 | Wordlist + mask | Passwords with appended numbers |
|
||||
|
||||
### Common Hash Types
|
||||
|
||||
| Hash Mode | Type | Example Use |
|
||||
|-----------|------|-------------|
|
||||
| 0 | MD5 | Legacy web apps |
|
||||
| 100 | SHA-1 | Legacy systems |
|
||||
| 1000 | NTLM | Windows credentials |
|
||||
| 1800 | sha512crypt | Linux /etc/shadow |
|
||||
| 3200 | bcrypt | Modern web apps |
|
||||
| 13100 | Kerberos TGS-REP | Active Directory |
|
||||
|
||||
## Security Considerations
|
||||
|
||||
- Only perform hash cracking with explicit written authorization
|
||||
- Secure all captured hash data in transit and at rest
|
||||
- Report all cracked passwords immediately to asset owners
|
||||
- Use results to improve password policies, not exploit users
|
||||
- Destroy cracked password data after engagement concludes
|
||||
- Follow rules of engagement for penetration test scope
|
||||
|
||||
## Validation Criteria
|
||||
|
||||
- [ ] Hash type identification is correct
|
||||
- [ ] Dictionary attack cracks weak passwords
|
||||
- [ ] Rule-based attack cracks policy-compliant passwords
|
||||
- [ ] Mask attack cracks short passwords
|
||||
- [ ] Results report shows password strength distribution
|
||||
- [ ] All operations performed within authorized scope
|
||||
@@ -0,0 +1,49 @@
|
||||
# Hash Cracking Assessment Template
|
||||
|
||||
## Authorization Verification
|
||||
|
||||
- [ ] Written authorization obtained from asset owner
|
||||
- [ ] Scope of engagement defines which hashes may be cracked
|
||||
- [ ] Data handling requirements documented
|
||||
- [ ] Results reporting chain defined
|
||||
- [ ] Data destruction timeline agreed
|
||||
|
||||
## Hashcat Quick Reference
|
||||
|
||||
```bash
|
||||
# Identify hash type
|
||||
hashcat --identify hash.txt
|
||||
|
||||
# MD5 dictionary
|
||||
hashcat -m 0 -a 0 hashes.txt wordlist.txt
|
||||
|
||||
# NTLM with rules
|
||||
hashcat -m 1000 -a 0 hashes.txt wordlist.txt -r rules/best64.rule
|
||||
|
||||
# bcrypt dictionary (slow)
|
||||
hashcat -m 3200 -a 0 hashes.txt wordlist.txt
|
||||
|
||||
# Benchmark
|
||||
hashcat -b
|
||||
```
|
||||
|
||||
## Mask Charsets
|
||||
|
||||
| Charset | Characters | Symbol |
|
||||
|---------|-----------|--------|
|
||||
| ?l | a-z | lowercase |
|
||||
| ?u | A-Z | uppercase |
|
||||
| ?d | 0-9 | digits |
|
||||
| ?s | special chars | symbols |
|
||||
| ?a | ?l?u?d?s | all printable |
|
||||
|
||||
## Reporting Template
|
||||
|
||||
| Metric | Value |
|
||||
|--------|-------|
|
||||
| Total hashes | [count] |
|
||||
| Cracked | [count] ([%]) |
|
||||
| < 1 minute | [count] (CRITICAL) |
|
||||
| < 1 hour | [count] (HIGH) |
|
||||
| < 1 day | [count] (MEDIUM) |
|
||||
| Not cracked | [count] (OK) |
|
||||
@@ -0,0 +1,30 @@
|
||||
# Standards and References - Hash Cracking with Hashcat
|
||||
|
||||
## Tools
|
||||
|
||||
### Hashcat
|
||||
- **URL**: https://hashcat.net/hashcat/
|
||||
- **GitHub**: https://github.com/hashcat/hashcat
|
||||
- **Wiki**: https://hashcat.net/wiki/
|
||||
- **Hash modes**: https://hashcat.net/wiki/doku.php?id=hashcat
|
||||
|
||||
### Wordlists
|
||||
- **SecLists**: https://github.com/danielmiessler/SecLists
|
||||
- **RockYou**: Classic breach wordlist (14 million passwords)
|
||||
- **CrackStation**: https://crackstation.net/crackstation-wordlist-password-cracking-dictionary.htm
|
||||
|
||||
## Standards
|
||||
|
||||
### NIST SP 800-63B - Digital Identity Guidelines (Authentication)
|
||||
- **URL**: https://pages.nist.gov/800-63-3/sp800-63b.html
|
||||
- **Description**: Password requirements and memorized secret guidelines
|
||||
|
||||
### OWASP Password Storage Cheat Sheet
|
||||
- **URL**: https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html
|
||||
|
||||
## Legal Framework
|
||||
|
||||
- Computer Fraud and Abuse Act (CFAA) - US
|
||||
- Computer Misuse Act 1990 - UK
|
||||
- Always obtain written authorization before testing
|
||||
- Follow penetration testing rules of engagement
|
||||
@@ -0,0 +1,62 @@
|
||||
# Workflows - Hash Cracking with Hashcat
|
||||
|
||||
## Workflow 1: Hash Identification and Cracking
|
||||
|
||||
```
|
||||
[Captured Hashes]
|
||||
|
|
||||
[Identify Hash Type]
|
||||
(hashcat --identify, hashid, haiti)
|
||||
|
|
||||
[Select Attack Strategy]:
|
||||
1. Dictionary attack (rockyou.txt)
|
||||
2. Dictionary + rules (best64.rule)
|
||||
3. Mask attack (brute-force)
|
||||
4. Hybrid (wordlist + mask)
|
||||
|
|
||||
[Execute Hashcat]
|
||||
|
|
||||
[Analyze Results]
|
||||
(cracked count, time, patterns)
|
||||
|
|
||||
[Generate Password Strength Report]
|
||||
```
|
||||
|
||||
## Workflow 2: Hashcat Command Examples
|
||||
|
||||
```bash
|
||||
# Dictionary attack
|
||||
hashcat -m 0 -a 0 hashes.txt rockyou.txt
|
||||
|
||||
# Dictionary + rules
|
||||
hashcat -m 0 -a 0 hashes.txt rockyou.txt -r best64.rule
|
||||
|
||||
# Mask (brute-force 8-char lowercase)
|
||||
hashcat -m 0 -a 3 hashes.txt ?l?l?l?l?l?l?l?l
|
||||
|
||||
# Hybrid (wordlist + 4 digits)
|
||||
hashcat -m 0 -a 6 hashes.txt rockyou.txt ?d?d?d?d
|
||||
|
||||
# Show cracked passwords
|
||||
hashcat -m 0 hashes.txt --show
|
||||
```
|
||||
|
||||
## Workflow 3: Password Audit Report
|
||||
|
||||
```
|
||||
[Cracking Results]
|
||||
|
|
||||
[Categorize]:
|
||||
- Cracked in < 1 min: CRITICAL
|
||||
- Cracked in < 1 hour: HIGH
|
||||
- Cracked in < 1 day: MEDIUM
|
||||
- Not cracked: Acceptable
|
||||
|
|
||||
[Pattern Analysis]:
|
||||
- Common base words
|
||||
- Character set distribution
|
||||
- Length distribution
|
||||
- Policy compliance
|
||||
|
|
||||
[Generate Report with Recommendations]
|
||||
```
|
||||
@@ -0,0 +1,265 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Hash Cracking Analysis and Hashcat Automation Tool
|
||||
|
||||
Provides hash identification, hashcat command generation, result analysis,
|
||||
and password strength reporting for authorized security assessments.
|
||||
|
||||
Requirements:
|
||||
pip install passlib argon2-cffi
|
||||
|
||||
Usage:
|
||||
python process.py identify --hash "5f4dcc3b5aa765d61d8327deb882cf99"
|
||||
python process.py generate-cmd --hash-file hashes.txt --mode 0 --attack dictionary
|
||||
python process.py analyze-results --potfile hashcat.potfile --hash-file hashes.txt
|
||||
python process.py create-test-hashes --output test_hashes.txt
|
||||
"""
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import json
|
||||
import hashlib
|
||||
import argparse
|
||||
import logging
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Optional, Tuple
|
||||
from collections import Counter
|
||||
|
||||
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
HASH_PATTERNS = {
|
||||
r"^[a-f0-9]{32}$": [("MD5", 0), ("NTLM", 1000)],
|
||||
r"^[a-f0-9]{40}$": [("SHA-1", 100)],
|
||||
r"^[a-f0-9]{64}$": [("SHA-256", 1400)],
|
||||
r"^[a-f0-9]{128}$": [("SHA-512", 1700)],
|
||||
r"^\$2[aby]\$\d{2}\$.{53}$": [("bcrypt", 3200)],
|
||||
r"^\$6\$": [("sha512crypt", 1800)],
|
||||
r"^\$5\$": [("sha256crypt", 7400)],
|
||||
r"^\$argon2(i|d|id)\$": [("Argon2", 32600)],
|
||||
r"^\$1\$": [("md5crypt", 500)],
|
||||
r"^\$apr1\$": [("Apache APR1", 1600)],
|
||||
r"^[a-f0-9]{32}:[a-f0-9]+$": [("MD5 salted", 10)],
|
||||
r"^\$krb5tgs\$": [("Kerberos TGS-REP", 13100)],
|
||||
r"^[a-f0-9]{32}:[a-f0-9]{32}$": [("NetNTLMv1", 5500)],
|
||||
}
|
||||
|
||||
|
||||
def identify_hash(hash_value: str) -> List[Dict]:
|
||||
"""Identify the type of a hash value."""
|
||||
hash_value = hash_value.strip()
|
||||
matches = []
|
||||
|
||||
for pattern, hash_types in HASH_PATTERNS.items():
|
||||
if re.match(pattern, hash_value, re.IGNORECASE):
|
||||
for name, mode in hash_types:
|
||||
matches.append({
|
||||
"hash_type": name,
|
||||
"hashcat_mode": mode,
|
||||
"confidence": "high" if len(hash_types) == 1 else "medium",
|
||||
})
|
||||
|
||||
if not matches:
|
||||
matches.append({
|
||||
"hash_type": "Unknown",
|
||||
"hashcat_mode": None,
|
||||
"confidence": "none",
|
||||
})
|
||||
|
||||
return matches
|
||||
|
||||
|
||||
def generate_hashcat_command(
|
||||
hash_file: str,
|
||||
mode: int,
|
||||
attack: str = "dictionary",
|
||||
wordlist: str = "rockyou.txt",
|
||||
rules: Optional[str] = None,
|
||||
mask: Optional[str] = None,
|
||||
output_file: Optional[str] = None,
|
||||
) -> str:
|
||||
"""Generate a hashcat command string."""
|
||||
cmd_parts = ["hashcat"]
|
||||
cmd_parts.extend(["-m", str(mode)])
|
||||
|
||||
if attack == "dictionary":
|
||||
cmd_parts.extend(["-a", "0"])
|
||||
cmd_parts.append(hash_file)
|
||||
cmd_parts.append(wordlist)
|
||||
if rules:
|
||||
cmd_parts.extend(["-r", rules])
|
||||
elif attack == "bruteforce":
|
||||
cmd_parts.extend(["-a", "3"])
|
||||
cmd_parts.append(hash_file)
|
||||
cmd_parts.append(mask or "?a?a?a?a?a?a?a?a")
|
||||
elif attack == "hybrid_wm":
|
||||
cmd_parts.extend(["-a", "6"])
|
||||
cmd_parts.append(hash_file)
|
||||
cmd_parts.append(wordlist)
|
||||
cmd_parts.append(mask or "?d?d?d?d")
|
||||
elif attack == "hybrid_mw":
|
||||
cmd_parts.extend(["-a", "7"])
|
||||
cmd_parts.append(hash_file)
|
||||
cmd_parts.append(mask or "?d?d?d?d")
|
||||
cmd_parts.append(wordlist)
|
||||
|
||||
if output_file:
|
||||
cmd_parts.extend(["-o", output_file])
|
||||
|
||||
cmd_parts.extend(["--force", "--status", "--status-timer=10"])
|
||||
return " ".join(cmd_parts)
|
||||
|
||||
|
||||
def create_test_hashes(output_path: str) -> Dict:
|
||||
"""Create a set of test password hashes for practice."""
|
||||
test_passwords = [
|
||||
"password", "123456", "admin", "letmein", "welcome",
|
||||
"monkey", "dragon", "master", "qwerty", "login",
|
||||
"P@ssw0rd", "Summer2024!", "company123", "test1234",
|
||||
"hunter2", "trustno1", "batman", "shadow", "sunshine",
|
||||
"iloveyou",
|
||||
]
|
||||
|
||||
hashes = {"md5": [], "sha1": [], "sha256": []}
|
||||
for pwd in test_passwords:
|
||||
pwd_bytes = pwd.encode("utf-8")
|
||||
hashes["md5"].append(hashlib.md5(pwd_bytes).hexdigest())
|
||||
hashes["sha1"].append(hashlib.sha1(pwd_bytes).hexdigest())
|
||||
hashes["sha256"].append(hashlib.sha256(pwd_bytes).hexdigest())
|
||||
|
||||
output = Path(output_path)
|
||||
for hash_type, hash_list in hashes.items():
|
||||
path = output.parent / f"{output.stem}_{hash_type}{output.suffix}"
|
||||
path.write_text("\n".join(hash_list) + "\n")
|
||||
logger.info(f"Created {path} with {len(hash_list)} hashes")
|
||||
|
||||
return {
|
||||
"test_passwords_count": len(test_passwords),
|
||||
"hash_types": list(hashes.keys()),
|
||||
"output_directory": str(output.parent),
|
||||
"note": "These are intentionally weak passwords for authorized testing only",
|
||||
}
|
||||
|
||||
|
||||
def analyze_cracked_results(potfile_path: str, hash_file_path: str) -> Dict:
|
||||
"""Analyze hashcat results from potfile."""
|
||||
potfile = Path(potfile_path)
|
||||
hash_file = Path(hash_file_path)
|
||||
|
||||
if not potfile.exists():
|
||||
return {"error": f"Potfile not found: {potfile_path}"}
|
||||
|
||||
total_hashes = 0
|
||||
if hash_file.exists():
|
||||
total_hashes = sum(1 for line in hash_file.read_text().strip().split("\n") if line.strip())
|
||||
|
||||
cracked_passwords = []
|
||||
for line in potfile.read_text().strip().split("\n"):
|
||||
if ":" in line:
|
||||
parts = line.rsplit(":", 1)
|
||||
if len(parts) == 2:
|
||||
cracked_passwords.append(parts[1])
|
||||
|
||||
cracked_count = len(cracked_passwords)
|
||||
crack_rate = (cracked_count / total_hashes * 100) if total_hashes > 0 else 0
|
||||
|
||||
# Password analysis
|
||||
lengths = [len(p) for p in cracked_passwords]
|
||||
charset_analysis = {"lowercase_only": 0, "with_uppercase": 0, "with_digits": 0, "with_special": 0}
|
||||
|
||||
for pwd in cracked_passwords:
|
||||
has_upper = any(c.isupper() for c in pwd)
|
||||
has_digit = any(c.isdigit() for c in pwd)
|
||||
has_special = any(not c.isalnum() for c in pwd)
|
||||
if has_special:
|
||||
charset_analysis["with_special"] += 1
|
||||
elif has_digit and has_upper:
|
||||
charset_analysis["with_digits"] += 1
|
||||
elif has_upper:
|
||||
charset_analysis["with_uppercase"] += 1
|
||||
else:
|
||||
charset_analysis["lowercase_only"] += 1
|
||||
|
||||
# Strength categories
|
||||
strength = {"critical": 0, "weak": 0, "moderate": 0}
|
||||
for pwd in cracked_passwords:
|
||||
if len(pwd) < 8:
|
||||
strength["critical"] += 1
|
||||
elif len(pwd) < 12 or not any(not c.isalnum() for c in pwd):
|
||||
strength["weak"] += 1
|
||||
else:
|
||||
strength["moderate"] += 1
|
||||
|
||||
common_words = Counter()
|
||||
for pwd in cracked_passwords:
|
||||
base = re.sub(r"[^a-zA-Z]", "", pwd).lower()
|
||||
if len(base) >= 3:
|
||||
common_words[base] += 1
|
||||
|
||||
return {
|
||||
"total_hashes": total_hashes,
|
||||
"cracked_count": cracked_count,
|
||||
"crack_rate_percent": round(crack_rate, 1),
|
||||
"uncracked_count": total_hashes - cracked_count,
|
||||
"password_length": {
|
||||
"min": min(lengths) if lengths else 0,
|
||||
"max": max(lengths) if lengths else 0,
|
||||
"avg": round(sum(lengths) / len(lengths), 1) if lengths else 0,
|
||||
},
|
||||
"charset_distribution": charset_analysis,
|
||||
"strength_distribution": strength,
|
||||
"top_base_words": dict(common_words.most_common(10)),
|
||||
"recommendations": [
|
||||
"Enforce minimum 12-character passwords",
|
||||
"Require mixed character sets (upper, lower, digit, special)",
|
||||
"Block common dictionary words and patterns",
|
||||
"Implement password breach checking (Have I Been Pwned API)",
|
||||
"Use Argon2id or bcrypt for password hashing (not MD5/SHA)",
|
||||
"Consider passphrase-based policies over complexity rules",
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Hash Cracking Analysis Tool")
|
||||
subparsers = parser.add_subparsers(dest="command")
|
||||
|
||||
ident = subparsers.add_parser("identify", help="Identify hash type")
|
||||
ident.add_argument("--hash", required=True, help="Hash value to identify")
|
||||
|
||||
gen = subparsers.add_parser("generate-cmd", help="Generate hashcat command")
|
||||
gen.add_argument("--hash-file", required=True, help="Hash file path")
|
||||
gen.add_argument("--mode", type=int, required=True, help="Hashcat hash mode")
|
||||
gen.add_argument("--attack", choices=["dictionary", "bruteforce", "hybrid_wm", "hybrid_mw"], default="dictionary")
|
||||
gen.add_argument("--wordlist", default="rockyou.txt")
|
||||
gen.add_argument("--rules", help="Rules file")
|
||||
gen.add_argument("--mask", help="Mask pattern")
|
||||
|
||||
create = subparsers.add_parser("create-test-hashes", help="Create test hashes")
|
||||
create.add_argument("--output", "-o", default="test_hashes.txt")
|
||||
|
||||
analyze = subparsers.add_parser("analyze-results", help="Analyze cracking results")
|
||||
analyze.add_argument("--potfile", required=True, help="Hashcat potfile")
|
||||
analyze.add_argument("--hash-file", required=True, help="Original hash file")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.command == "identify":
|
||||
result = identify_hash(args.hash)
|
||||
print(json.dumps(result, indent=2))
|
||||
elif args.command == "generate-cmd":
|
||||
cmd = generate_hashcat_command(args.hash_file, args.mode, args.attack, args.wordlist, args.rules, args.mask)
|
||||
print(cmd)
|
||||
elif args.command == "create-test-hashes":
|
||||
result = create_test_hashes(args.output)
|
||||
print(json.dumps(result, indent=2))
|
||||
elif args.command == "analyze-results":
|
||||
result = analyze_cracked_results(args.potfile, args.hash_file)
|
||||
print(json.dumps(result, indent=2))
|
||||
else:
|
||||
parser.print_help()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user