smbclientng.core.Credentials

  1#!/usr/bin/env python3
  2# -*- coding: utf-8 -*-
  3# File name          : Credentials.py
  4# Author             : Podalirius (@podalirius_)
  5# Date created       : 22 June 2024
  6
  7
  8from smbclientng.core.utils import parse_lm_nt_hashes
  9import re
 10import binascii
 11 
 12
 13class Credentials(object):
 14    """
 15    Documentation for class Credentials
 16    """
 17
 18    # Identity
 19    domain = None
 20    username = None
 21    password = None
 22    # Hashes
 23    nt_hex = ""
 24    nt_raw = ""
 25    lm_hex = ""
 26    lm_raw = ""
 27    # Kerberos
 28    use_kerberos = False
 29    aesKey = None
 30    kdcHost = None
 31
 32    def __init__(self, domain, username, password, hashes=None, use_kerberos=False, aesKey=None, kdcHost=None):
 33        super(Credentials, self).__init__()
 34        # Identity
 35        self.domain = domain
 36        self.username = username
 37        self.password = password
 38        # Hashes
 39        self.nt_hex = ""
 40        self.nt_raw = ""
 41        self.lm_hex = ""
 42        self.lm_raw = ""
 43        self.set_hashes(hashes=hashes)
 44        # Kerberos
 45        self.use_kerberos = use_kerberos
 46        self.kdcHost = kdcHost
 47        self.aesKey = aesKey
 48
 49    def set_hashes(self, hashes):
 50        """
 51        Sets the LM and NT hashes for the credentials.
 52
 53        This method parses the provided hash string and sets the LM and NT hash values accordingly.
 54        If the hash string is valid and contains both LM and NT hashes, they are set directly.
 55        If only one hash is provided, the other is set to its default value.
 56        If the hash string is None or invalid, both hashes are set to None.
 57
 58        Args:
 59            hashes (str): A string containing LM and NT hashes separated by a colon.
 60        """
 61
 62        self.nt_hex = ""
 63        self.nt_raw = ""
 64        self.lm_hex = ""
 65        self.lm_raw = ""
 66
 67        lmhash, nthash = None, None
 68        if hashes is not None:
 69            matched = re.search("([0-9a-f]{32})(:)?([0-9a-f]{32})?", hashes.lower(), re.IGNORECASE)
 70            if matched is not None:
 71                lmhash = matched.groups()[0]
 72                nthash = matched.groups()[2]
 73                if lmhash is None:
 74                    lmhash = "aad3b435b51404eeaad3b435b51404ee"
 75                if nthash is None:
 76                    nthash = "31d6cfe0d16ae931b73c59d7e0c089c0"
 77                self.lm_hex = lmhash
 78                self.lm_raw = binascii.unhexlify(lmhash)
 79                self.nt_hex = nthash
 80                self.nt_raw = binascii.unhexlify(nthash)
 81
 82    def canPassTheHash(self):
 83        """
 84        Determines if the current credentials can be used for a pass-the-hash attack.
 85
 86        This method checks if both LM and NT hashes are available and not None. If both hashes are set,
 87        it indicates that the credentials may be used for a pass-the-hash attack.
 88
 89        Returns:
 90            bool: True if both LM and NT hashes are available, False otherwise.
 91        """
 92
 93        return bool(
 94            (self.nt_hex is not None)
 95            and (self.nt_raw is not None)
 96            and (self.lm_hex is not None)
 97            and (self.lm_raw is not None)
 98        )
 99
100    def __dict__(self):
101        return {
102            "domain": self.domain,
103            "username": self.username,
104            "password": self.password,
105            "hashes": {
106                "lm_hash": self.lm_hex,
107                "nt_hash": self.nt_hex
108            },
109            "use_kerberos": self.use_kerberos,
110            "aesKey": self.aesKey,
111            "kdcHost": self.kdcHost
112        }
113    
114    def __repr__(self):
115        return f"<Credentials for '{self.domain}\\{self.username}'>"
class Credentials:
 14class Credentials(object):
 15    """
 16    Documentation for class Credentials
 17    """
 18
 19    # Identity
 20    domain = None
 21    username = None
 22    password = None
 23    # Hashes
 24    nt_hex = ""
 25    nt_raw = ""
 26    lm_hex = ""
 27    lm_raw = ""
 28    # Kerberos
 29    use_kerberos = False
 30    aesKey = None
 31    kdcHost = None
 32
 33    def __init__(self, domain, username, password, hashes=None, use_kerberos=False, aesKey=None, kdcHost=None):
 34        super(Credentials, self).__init__()
 35        # Identity
 36        self.domain = domain
 37        self.username = username
 38        self.password = password
 39        # Hashes
 40        self.nt_hex = ""
 41        self.nt_raw = ""
 42        self.lm_hex = ""
 43        self.lm_raw = ""
 44        self.set_hashes(hashes=hashes)
 45        # Kerberos
 46        self.use_kerberos = use_kerberos
 47        self.kdcHost = kdcHost
 48        self.aesKey = aesKey
 49
 50    def set_hashes(self, hashes):
 51        """
 52        Sets the LM and NT hashes for the credentials.
 53
 54        This method parses the provided hash string and sets the LM and NT hash values accordingly.
 55        If the hash string is valid and contains both LM and NT hashes, they are set directly.
 56        If only one hash is provided, the other is set to its default value.
 57        If the hash string is None or invalid, both hashes are set to None.
 58
 59        Args:
 60            hashes (str): A string containing LM and NT hashes separated by a colon.
 61        """
 62
 63        self.nt_hex = ""
 64        self.nt_raw = ""
 65        self.lm_hex = ""
 66        self.lm_raw = ""
 67
 68        lmhash, nthash = None, None
 69        if hashes is not None:
 70            matched = re.search("([0-9a-f]{32})(:)?([0-9a-f]{32})?", hashes.lower(), re.IGNORECASE)
 71            if matched is not None:
 72                lmhash = matched.groups()[0]
 73                nthash = matched.groups()[2]
 74                if lmhash is None:
 75                    lmhash = "aad3b435b51404eeaad3b435b51404ee"
 76                if nthash is None:
 77                    nthash = "31d6cfe0d16ae931b73c59d7e0c089c0"
 78                self.lm_hex = lmhash
 79                self.lm_raw = binascii.unhexlify(lmhash)
 80                self.nt_hex = nthash
 81                self.nt_raw = binascii.unhexlify(nthash)
 82
 83    def canPassTheHash(self):
 84        """
 85        Determines if the current credentials can be used for a pass-the-hash attack.
 86
 87        This method checks if both LM and NT hashes are available and not None. If both hashes are set,
 88        it indicates that the credentials may be used for a pass-the-hash attack.
 89
 90        Returns:
 91            bool: True if both LM and NT hashes are available, False otherwise.
 92        """
 93
 94        return bool(
 95            (self.nt_hex is not None)
 96            and (self.nt_raw is not None)
 97            and (self.lm_hex is not None)
 98            and (self.lm_raw is not None)
 99        )
100
101    def __dict__(self):
102        return {
103            "domain": self.domain,
104            "username": self.username,
105            "password": self.password,
106            "hashes": {
107                "lm_hash": self.lm_hex,
108                "nt_hash": self.nt_hex
109            },
110            "use_kerberos": self.use_kerberos,
111            "aesKey": self.aesKey,
112            "kdcHost": self.kdcHost
113        }
114    
115    def __repr__(self):
116        return f"<Credentials for '{self.domain}\\{self.username}'>"

Documentation for class Credentials

Credentials( domain, username, password, hashes=None, use_kerberos=False, aesKey=None, kdcHost=None)
33    def __init__(self, domain, username, password, hashes=None, use_kerberos=False, aesKey=None, kdcHost=None):
34        super(Credentials, self).__init__()
35        # Identity
36        self.domain = domain
37        self.username = username
38        self.password = password
39        # Hashes
40        self.nt_hex = ""
41        self.nt_raw = ""
42        self.lm_hex = ""
43        self.lm_raw = ""
44        self.set_hashes(hashes=hashes)
45        # Kerberos
46        self.use_kerberos = use_kerberos
47        self.kdcHost = kdcHost
48        self.aesKey = aesKey
domain = None
username = None
password = None
nt_hex = ''
nt_raw = ''
lm_hex = ''
lm_raw = ''
use_kerberos = False
aesKey = None
kdcHost = None
def set_hashes(self, hashes):
50    def set_hashes(self, hashes):
51        """
52        Sets the LM and NT hashes for the credentials.
53
54        This method parses the provided hash string and sets the LM and NT hash values accordingly.
55        If the hash string is valid and contains both LM and NT hashes, they are set directly.
56        If only one hash is provided, the other is set to its default value.
57        If the hash string is None or invalid, both hashes are set to None.
58
59        Args:
60            hashes (str): A string containing LM and NT hashes separated by a colon.
61        """
62
63        self.nt_hex = ""
64        self.nt_raw = ""
65        self.lm_hex = ""
66        self.lm_raw = ""
67
68        lmhash, nthash = None, None
69        if hashes is not None:
70            matched = re.search("([0-9a-f]{32})(:)?([0-9a-f]{32})?", hashes.lower(), re.IGNORECASE)
71            if matched is not None:
72                lmhash = matched.groups()[0]
73                nthash = matched.groups()[2]
74                if lmhash is None:
75                    lmhash = "aad3b435b51404eeaad3b435b51404ee"
76                if nthash is None:
77                    nthash = "31d6cfe0d16ae931b73c59d7e0c089c0"
78                self.lm_hex = lmhash
79                self.lm_raw = binascii.unhexlify(lmhash)
80                self.nt_hex = nthash
81                self.nt_raw = binascii.unhexlify(nthash)

Sets the LM and NT hashes for the credentials.

This method parses the provided hash string and sets the LM and NT hash values accordingly. If the hash string is valid and contains both LM and NT hashes, they are set directly. If only one hash is provided, the other is set to its default value. If the hash string is None or invalid, both hashes are set to None.

Args: hashes (str): A string containing LM and NT hashes separated by a colon.

def canPassTheHash(self):
83    def canPassTheHash(self):
84        """
85        Determines if the current credentials can be used for a pass-the-hash attack.
86
87        This method checks if both LM and NT hashes are available and not None. If both hashes are set,
88        it indicates that the credentials may be used for a pass-the-hash attack.
89
90        Returns:
91            bool: True if both LM and NT hashes are available, False otherwise.
92        """
93
94        return bool(
95            (self.nt_hex is not None)
96            and (self.nt_raw is not None)
97            and (self.lm_hex is not None)
98            and (self.lm_raw is not None)
99        )

Determines if the current credentials can be used for a pass-the-hash attack.

This method checks if both LM and NT hashes are available and not None. If both hashes are set, it indicates that the credentials may be used for a pass-the-hash attack.

Returns: bool: True if both LM and NT hashes are available, False otherwise.