dissect.target.plugins.os.windows.sam#

Module Contents#

Classes#

SamPlugin

SAM plugin.

Functions#

Attributes#

dissect.target.plugins.os.windows.sam.c_sam_def = Multiline-String#
Show Value
"""
struct user_F {
  char      unknown1[8];
  uint64    t_last_login;           /* Time of last login */
  char      unknown2[8];
  uint64    t_last_password_set;    /* Time of last password set */
  char      unknown3[8];
  uint64    t_last_incorrect_login; /* Time of last incorrect password */
  int32     rid;
  char      unknown4[4];
  uint16    ACB_bits;               /* Account type and status flags */
  char      unknown5[2];
  uint16    country_code;
  char      unknown6[2];
  uint16    failedcnt;        /* Count of failed logins, if > than policy it is locked. Resets after successful login */
  uint16    logins;           /* Total logins since creation (max. 0xFFFF = 65535) */
  char      unknown7[0xc];
};

#define ACB_DISABLED   0x0001
#define ACB_HOMDIRREQ  0x0002
#define ACB_PWNOTREQ   0x0004
#define ACB_TEMPDUP    0x0008
#define ACB_NORMAL     0x0010
#define ACB_MNS        0x0020
#define ACB_DOMTRUST   0x0040
#define ACB_WSTRUST    0x0080
#define ACB_SVRTRUST   0x0100
#define ACB_PWNOEXP    0x0200
#define ACB_AUTOLOCK   0x0400

// char *acb_fields[16] = {
//    "Disabled" ,
//    "Homedir req." ,
//    "Passwd not req." ,
//    "Temp. duplicate" ,
//    "Normal account" ,
//    "NMS account" ,
//    "Domain trust act." ,
//    "Wks trust act." ,
//    "Srv trust act" ,
//    "Pwd don't expire" ,
//    "Auto lockout" ,
//    "(unknown 0x08)" ,
//    "(unknown 0x10)" ,
//    "(unknown 0x20)" ,
//    "(unknown 0x40)" ,
//    "(unknown 0x80)" ,
// };


struct user_V {

  int unknown1_1;           /* 0x00 - always zero? */
  int unknown1_2;           /* 0x04 - points to username? */
  int unknown1_3;           /* 0x08 - always 0x02 0x00 0x01 0x00 ? */

  int username_ofs;         /* 0x0c */
  int username_len;         /* 0x10 */

  int unknown2_1;           /* 0x14 - always zero? */

  int fullname_ofs;         /* 0x18 */
  int fullname_len;         /* 0x1c */

  int unknown3_1;           /* 0x20 - always zero? */

  int admin_comment_ofs;    /* 0x24 */
  int admin_comment_len;    /* 0x28 */

  int unknown4_1;           /* 0x2c - alway zero? */

  int user_comment_ofs;     /* 0x30 */
  int user_comment_len;     /* 0x34 */

  int unknown5_1;           /* 0x38 - zero? */
  int unknown5_2;           /* 0x3c - to field 8 bytes before hashes */
  int unknown5_3;           /* 0x40 - zero? or size of above? */
  int unknown5_4;           /* 0x44 - zero? */

  int homedir_ofs;          /* 0x48 */
  int homedir_len;          /* 0x4c */

  int unknown6_1;           /* 0x50 - zero? */

  int drvletter_ofs;        /* 0x54 - drive letter for home dir */
  int drvletter_len;        /* 0x58 - len of above, usually 4   */

  int unknown7_1;           /* 0x5c - zero? */

  int logonscr_ofs;         /* 0x60 - users logon script path */
  int logonscr_len;         /* 0x64 - length of string */

  int unknown8_1;           /* 0x68 - zero? */

  int profilep_ofs;         /* 0x6c - profile path string */
  int profilep_len;         /* 0x70 - profile path stringlen */

  int unknown9_1;           /* 0x74 */

  int workstations_ofs;     /* 0x78 */
  int workstations_len;     /* 0x7c */

  int unknowna_1;          /* 0x80 */

  int allowed_hours_ofs;    /* 0x84 */
  int allowed_hours_len;    /* 0x88 */

  int unknownb_1;          /* 0x8c */
  int unknownb_2;          /* 0x90 - pointer to some place before hashes, after comments */
  int unknownb_3;          /* 0x94 - size of above? */
  int unknownb_4;          /* 0x98 - unknown? always 1? */

  int lmpw_ofs;             /* 0x9c */
  int lmpw_len;             /* 0xa0 */

  int unknownc_1;           /* 0xa4 - zero? */

  int ntpw_ofs;             /* 0xa8 */
  int ntpw_len;             /* 0xac */

  int unknownd_1;           /* 0xb0 */
  int unknownd_2;           /* 0xb4 - points to field after hashes */
  int unknownd_3;           /* 0xb8 - size of above field */
  int unknownd_4;           /* 0xbc - zero? */
  int unknownd_5;           /* 0xc0 - points to field after that */
  int unknownd_6;           /* 0xc4 - size of above */
  int unknownd_7;           /* 0xc8 - zero ? */

  char data[4];             /* Data starts here. All pointers above is relative to this,
                               that is V + 0xCC */
};

struct DOMAIN_ACCOUNT_F {
  uint16 revision;                          /* 0x00 */
  uint16 unknown1_1;                        /* 0x02 */
  uint32 unknown1_2;                        /* 0x04 */
  uint64 creation_time;                     /* 0x08 */
  uint64 domain_modified_count;             /* 0x10 */
  uint64 max_password_age;                  /* 0x18 */
  uint64 min_password_age;                  /* 0x20 */
  uint64 force_logoff;                      /* 0x28 */
  uint64 lock_duration;                     /* 0x30 */
  uint64 lock_observation_window;           /* 0x38 */
  uint64 modified_count_at_last_promotion;  /* 0x40 */
  uint32 next_rid;                          /* 0x48 */
  uint32 password_properties;               /* 0x4c */
  uint16 min_password_length;               /* 0x50 */
  uint16 password_history_length;           /* 0x52 */
  uint16 lockout_threshold;                 /* 0x54 */
  uint16 unknown1_1;                        /* 0x56 */
  uint32 server_state;                      /* 0x58 */
  uint16 server_role;                       /* 0x5c */
  uint16 uas_compability_required;          /* 0x5e */
  uint64 unknown2_1;                        /* 0x60 */
  /* char sam_key[];                           0x70, variable size */
};

struct SAM_KEY {      /* size: 64 */
  uint32 revision;    /* 0x00 */
  uint32 length;      /* 0x04 */
  char salt[16];      /* 0x08 */
  char key[16];       /* 0x18 */
  char checksum[16];  /* 0x28 */
  uint64 reserved;    /* 0x38 */
};

struct SAM_KEY_AES {  /* size: >= 32 */
  uint32 revision;     /* 0x00 */
  uint32 length;       /* 0x04 */
  uint32 checksum_len; /* 0x08 */
  uint32 data_len;     /* 0x0c */
  char salt[16];       /* 0x10 */
  /* char data[];         0x20, variable size */
};

struct SAM_HASH {      /* size: 20 */
  uint16 pek_id;       /* 0x00 */
  uint16 revision;     /* 0x02 */
  /* char hash[16];       0x04, variable size */
};

struct SAM_HASH_AES {  /* size: >=24 */
  uint16 pek_id;        /* 0x00 */
  uint16 revision;      /* 0x02 */
  uint32 data_offset;   /* 0x04 */
  char salt[16];        /* 0x08 */
  /* char data[];          0x18, variable size */
};
"""
dissect.target.plugins.os.windows.sam.c_sam#
dissect.target.plugins.os.windows.sam.SamRecord#
dissect.target.plugins.os.windows.sam.expand_des_key(key: bytes) bytes#
dissect.target.plugins.os.windows.sam.rid_to_key(rid: int) tuple[bytes, bytes]#
dissect.target.plugins.os.windows.sam.decrypt_single_hash(rid: int, samkey: bytes, enc_hash: bytes, apwd: bytes) bytes#
class dissect.target.plugins.os.windows.sam.SamPlugin(target: dissect.target.Target)#

Bases: dissect.target.plugin.Plugin

SAM plugin.

References

SAM_KEY = 'HKEY_LOCAL_MACHINE\\SAM\\SAM\\Domains\\Account'#
check_compatible() None#

Perform a compatibility check with the target.

This function should return None if the plugin is compatible with the current target (self.target). For example, check if a certain file exists. Otherwise it should raise an UnsupportedPluginError.

Raises:

UnsupportedPluginError – If the plugin could not be loaded.

calculate_samkey(syskey: bytes) bytes#
sam() Iterator[SamRecord]#

Dump SAM entries

The Security Account Manager (SAM) registry hive contains registry keys that store usernames, full names and passwords in a hashed format, either an LM or NT hash.

References

Yields SamRecords with fields:

rid (uint32): The RID. fullname (string): Parsed fullname. username (string): Parsed username. admincomment (string): Parsed admin comment. usercomment (string): Parsed user comment. lastlogin (datetime): Parsed last login date. lastpasswordset (datetime): Parsed last password set date. lastincorrectlogin (datetime): Parsed last incorrect login date. flags (uint32): Parsed flags. countrycode (uint16): Parsed country code (international country calling code). failedlogins (uint32): Parsed failed logins, reset after sucessful login. logins (uint32): Parsed logins (max 0xFFFF = 65535). lm (string): Parsed LM-hash. nt (string): Parsed NT-hash.