Skip to content

Add support for email address identity type #3270

@mssalvatore

Description

@mssalvatore

Description

Some credentials collectors may be able to steal email addresses (e.g. from a browser), and some exploiters may use email addresses as identities. Add a new Identity type for email addresses

Tasks

  • Add a new EmailAddress identity type (see patch/prototype below) (0.25d)
  • Modify the configuration Credentials UI to allow the user to specify email addresses (0.25d)

Prototype

diff --git a/monkey/common/credentials/__init__.py b/monkey/common/credentials/__init__.py
index 1e4eeae0d..3fb27fdcb 100644
--- a/monkey/common/credentials/__init__.py
+++ b/monkey/common/credentials/__init__.py
@@ -1,8 +1,10 @@
+from .email_address import EmailAddress
+from .username import Username
+
 from .lm_hash import LMHash
 from .nt_hash import NTHash
 from .password import Password
 from .ssh_keypair import SSHKeypair
-from .username import Username
-from .encoding import get_plaintext, SecretEncodingConfig
 
+from .encoding import get_plaintext, SecretEncodingConfig
 from .credentials import Credentials, Identity, Secret
diff --git a/monkey/common/credentials/credentials.py b/monkey/common/credentials/credentials.py
index aff697eed..b3887d30b 100644
--- a/monkey/common/credentials/credentials.py
+++ b/monkey/common/credentials/credentials.py
@@ -3,11 +3,11 @@ from __future__ import annotations
 from typing import Optional, Unin
 
 from ..base_models import InfectionMonkeyBaseModel, InfectionMonkeyModelConfig
-from . import LMHash, NTHash, Password, SSHKeypair, Username
+from . import EmailAddress, LMHash, NTHash, Password, SSHKeypair, Username
 from .encoding import SecretEncodingConfig
 
 Secret = Union[Password, LMHash, NTHash, SSHKeypair]
-Identity = Username
+Identity = Union[Username, EmailAddress]
 
 
 class Credentials(InfectionMonkeyBaseModel):
diff --git a/monkey/common/credentials/email_address.py b/monkey/common/credentials/email_address.py
new file mode 100644
index 000000000..edd6f6607
--- /dev/null
+++ b/monkey/common/credentials/email_address.py
@@ -0,0 +1,8 @@
+from ..base_models import InfectionMonkeyBaseModel
+
+
+class EmailAddress(InfectionMonkeyBaseModel):
+    email_address: str
+
+    def __hash__(self) -> int:
+        return hash(self.email_address)
diff --git a/monkey/tests/data_for_tests/propagation_credentials.py b/monkey/tests/data_for_tests/propagation_credentials.py
index 35521e7b6..36450d19f 100644
--- a/monkey/tests/data_for_tests/propagation_credentials.py
+++ b/monkey/tests/data_for_tests/propagation_credentials.py
@@ -2,10 +2,19 @@ from itertools import product
monkey/tests/unit_tests/infection_monkey/exploit/tools/test_brute_force_credentials_generator.py 
index bde8766f0..b5fdd055a 100644
@@ -3,8 +3,21 @@ from typing import Callable, Iterable, List, Set
 import pytest
 from tests.data_for_tests.propagation_credentials import IDENTITIES, SECRETS
 
-from common.credentials import Credentials, Identity, LMHash, NTHash, Password, Secret
-from infection_monkey.exploit.tools import generate_brute_force_credentials, secret_type_filter
+from common.credentials import (
+    Credentials,
+    EmailAddress,
+    Identity,
+    LMHash,
+    NTHash,
+    Password,
+    Secret,
+    Username,
+)
+from infection_monkey.exploit.tools import (
+    generate_brute_force_credentials,
+    identity_type_filter,
+    secret_type_filter,
+)
 
 
 def generate_and_compare_credentials(
@@ -248,3 +261,29 @@ def test_secret_type_filter(
     filtered_secrets: Iterable[Secret] = filter(secret_type_filter, SECRETS)
 
     assert list(filtered_secrets) == expected_secrets
+
+
+@pytest.mark.parametrize(
+    "identity_type_filter,expected_identities",
+    [
+        (
+            identity_type_filter([Username]),
+            [IDENTITIES[0], IDENTITIES[2]],
+        ),
+        (
+            identity_type_filter([EmailAddress]),
+            [IDENTITIES[3]],
+        ),
+        (
+            identity_type_filter([Username, EmailAddress]),
+            [IDENTITIES[0], IDENTITIES[2], IDENTITIES[3]],
+        ),
+    ],
+)
+def test_identity_type_filter(
+    identity_type_filter: identity_type_filter,
+    expected_identities: List[Identity],
+):
+    filtered_secrets: Iterable[Identity] = filter(identity_type_filter, IDENTITIES)
+
+    assert list(filtered_secrets) == expected_identities

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions