-
Notifications
You must be signed in to change notification settings - Fork 36
Expand file tree
/
Copy pathcredential.py
More file actions
102 lines (78 loc) · 2.83 KB
/
credential.py
File metadata and controls
102 lines (78 loc) · 2.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
"""Data model to define user credentials found in leaks."""
import re
from dataclasses import dataclass
from urllib.parse import ParseResult, ParseResultBytes, urlparse
from .types import StealerNameType
@dataclass
class Credential:
"""Class defining a credential.
Attributes
----------
software : str, optional
Used software like web browser or email client.
host : str, optional
Hostname or URL visited by user.
username : str, optional
Username or email address used to login.
password : str, optional
Password.
domain : str, optional
Domain name extracted from host/URL.
local_part : str, optional
The part before the @ in an email address.
email_domain : str, optional
Domain name extracted from email address.
filepath : str, optional
The credential file path.
stealer_name : stealer_parser.models.types.StealerType, optional
If applicable, the stealer that harvested the data.
"""
software: str | None = None
host: str | None = None
username: str | None = None
password: str | None = None
domain: str | None = None
local_part: str | None = None
email_domain: str | None = None
filepath: str | None = None
stealer_name: StealerNameType | None = None
NORM_TEXT_PATTERN: re.Pattern[str] = re.compile(r"[\[\]\"']")
EMAIL_PATTERN: re.Pattern[str] = re.compile(r"\b(\S+)@(\S+\.\S+)\b")
def normalize_credential_text(credential: Credential) -> None:
"""Clean credential's text attributes.
Parameters
----------
credential : stealer_parser.models.credential.Credential
The credential object to update.
"""
if credential.software:
software: str = NORM_TEXT_PATTERN.sub("", credential.software.lower())
credential.software = software.replace("_", " ")
def split_credential_email(credential: Credential) -> None:
"""Extract email domain from credential's email address.
Parameters
----------
credential : stealer_parser.models.credential.Credential
The credential object to update.
"""
if not credential.username:
return
email_address: re.Match[str] | None = EMAIL_PATTERN.match(
credential.username
)
if email_address:
credential.local_part = email_address.group(1)
credential.email_domain = email_address.group(2)
def extract_credential_domain_name(credential: Credential) -> None:
"""Extract domain name from credential's URL.
Parameters
----------
credential : stealer_parser.models.credential.Credential
The credential object to update.
"""
if not credential.host:
return
url: ParseResult | ParseResultBytes = urlparse(credential.host)
if isinstance(url, ParseResult):
if url.hostname:
credential.domain = url.hostname