diff --git a/modules/post/windows/gather/ad_groupusers_to_sql.rb b/modules/post/windows/gather/ad_groupusers_to_sql.rb index 6b9f921c33..925e0f8963 100644 --- a/modules/post/windows/gather/ad_groupusers_to_sql.rb +++ b/modules/post/windows/gather/ad_groupusers_to_sql.rb @@ -226,7 +226,14 @@ class Metasploit3 < Msf::Post computers[:results].each do |comp| computer_sid, computer_rid = sid_hex_to_string(comp[1][:value]) + uac_int = comp_user[8][:value].to_i #Set this because it is used so frequently below + # Add the group to the database + # Also parse the ADF_ flags from userAccountControl: https://msdn.microsoft.com/en-us/library/windows/desktop/ms680832(v=vs.85).aspx + # Note that userAccountControl is basically the same for a computer as a user; this is because a computer account is derived from a user account + # (if you look at the objectClass for a computer account, it includes 'user') and, for efficiency, we should really store it all in one + # table. However, the reality is that it will get annoying for users to have to remember to use the userAccountControl flags to work out whether + # its a user or a computer and so, for convenience and ease of use, I have put them in completely separate tables. sql_param_computer = { rid: computer_rid.to_i, distinguishedName: comp[0][:value].to_s, cn: comp[2][:value].to_s, @@ -235,7 +242,7 @@ class Metasploit3 < Msf::Post sAMAccountName: comp[5][:value].to_s, displayName: comp[6][:value].to_s, logonCount: comp[7][:value].to_i, - userAccountControl: comp[8][:value].to_s, + userAccountControl: uac_int, whenChanged: comp[9][:value].to_s, whenCreated: comp[10][:value].to_s, primaryGroupID: comp[11][:value].to_i, @@ -243,6 +250,55 @@ class Metasploit3 < Msf::Post operatingSystem: comp[13][:value].to_s, operatingSystemServicePack: comp[14][:value].to_s, operatingSystemVersion: comp[15][:value].to_s, + #The login script is executed + ADS_UF_SCRIPT: (uac_int & 0x00000001).zero? ? 0 : 1, + #The user account is disabled. + ADS_UF_ACCOUNTDISABLE: (uac_int & 0x00000002).zero? ? 0 : 1, + #The home directory is required. + ADS_UF_HOMEDIR_REQUIRED: (uac_int & 0x00000008).zero? ? 0 : 1, + #The account is currently locked out. + ADS_UF_LOCKOUT: (uac_int & 0x00000010).zero? ? 0 : 1, + #No password is required. + ADS_UF_PASSWD_NOTREQD: (uac_int & 0x00000020).zero? ? 0 : 1, + #The user cannot change the password. + ADS_UF_PASSWD_CANT_CHANGE: (uac_int & 0x00000040).zero? ? 0 : 1, + #The user can send an encrypted password. + ADS_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED: (uac_int & 0x00000080).zero? ? 0 : 1, + #This is an account for users whose primary account is in another domain. This account + #provides user access to this domain, but not to any domain that trusts this domain. + #Also known as a local user account. + ADS_UF_TEMP_DUPLICATE_ACCOUNT: (uac_int & 0x00000100).zero? ? 0 : 1, + #This is a default account type that represents a typical user. + ADS_UF_NORMAL_ACCOUNT: (uac_int & 0x00000200).zero? ? 0 : 1, + #This is a permit to trust account for a system domain that trusts other domains. + ADS_UF_INTERDOMAIN_TRUST_ACCOUNT: (uac_int & 0x00000800).zero? ? 0 : 1, + #This is a computer account for a computer that is a member of this domain. + ADS_UF_WORKSTATION_TRUST_ACCOUNT: (uac_int & 0x00001000).zero? ? 0 : 1, + #This is a computer account for a system backup domain controller that is a member of this domain. + ADS_UF_SERVER_TRUST_ACCOUNT: (uac_int & 0x00002000).zero? ? 0 : 1, + #The password for this account will never expire. + ADS_UF_DONT_EXPIRE_PASSWD: (uac_int & 0x00010000).zero? ? 0 : 1, + #This is an MNS logon account. + ADS_UF_MNS_LOGON_ACCOUNT: (uac_int & 0x00020000).zero? ? 0 : 1, + #The user must log on using a smart card. + ADS_UF_SMARTCARD_REQUIRED: (uac_int & 0x00040000).zero? ? 0 : 1, + #The service account (user or computer account), under which a service runs, is trusted for Kerberos delegation. + #Any such service can impersonate a client requesting the service. + ADS_UF_TRUSTED_FOR_DELEGATION: (uac_int & 0x00080000).zero? ? 0 : 1, + #The security context of the user will not be delegated to a service even if the service + #account is set as trusted for Kerberos delegation. + ADS_UF_NOT_DELEGATED: (uac_int & 0x00100000).zero? ? 0 : 1, + #Restrict this principal to use only Data #Encryption Standard (DES) encryption types for keys. + ADS_UF_USE_DES_KEY_ONLY: (uac_int & 0x00200000).zero? ? 0 : 1, + #This account does not require Kerberos pre-authentication for logon. + ADS_UF_DONT_REQUIRE_PREAUTH: (uac_int & 0x00400000).zero? ? 0 : 1, + #The password has expired + ADS_UF_PASSWORD_EXPIRED: (uac_int & 0x00800000).zero? ? 0 : 1, + #The account is enabled for delegation. This is a security-sensitive setting; accounts with + #this option enabled should be strictly controlled. This setting enables a service running + #under the account to assume a client identity and authenticate as that user to other remote + #servers on the network. + ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION: (uac_int & 0x01000000).zero? ? 0 : 1 } run_sqlite_query(db, 'ad_computers', sql_param_computer) print_line "Computer [#{sql_param_computer[:cn]}][#{sql_param_computer[:dNSHostName]}][#{sql_param_computer[:rid]}]" if datastore['SHOW_USERGROUPS'] @@ -281,7 +337,7 @@ class Metasploit3 < Msf::Post 'distinguishedName TEXT UNIQUE NOT NULL,'\ 'cn TEXT,'\ 'sAMAccountType INTEGER,'\ - 'sAMAccountName TEXT UNIQUE,'\ + 'sAMAccountName TEXT UNIQUE NOT NULL,'\ 'dNSHostName TEXT,'\ 'displayName TEXT,'\ 'logonCount INTEGER,'\ @@ -292,7 +348,28 @@ class Metasploit3 < Msf::Post 'operatingSystemServicePack TEXT,'\ 'operatingSystemVersion TEXT,'\ 'whenChanged TEXT,'\ - 'whenCreated TEXT)' + 'whenChanged TEXT,'\ + 'ADS_UF_SCRIPT INTEGER,'\ + 'ADS_UF_ACCOUNTDISABLE INTEGER,'\ + 'ADS_UF_HOMEDIR_REQUIRED INTEGER,'\ + 'ADS_UF_LOCKOUT INTEGER,'\ + 'ADS_UF_PASSWD_NOTREQD INTEGER,'\ + 'ADS_UF_PASSWD_CANT_CHANGE INTEGER,'\ + 'ADS_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED INTEGER,'\ + 'ADS_UF_TEMP_DUPLICATE_ACCOUNT INTEGER,'\ + 'ADS_UF_NORMAL_ACCOUNT INTEGER,'\ + 'ADS_UF_INTERDOMAIN_TRUST_ACCOUNT INTEGER,'\ + 'ADS_UF_WORKSTATION_TRUST_ACCOUNT INTEGER,'\ + 'ADS_UF_SERVER_TRUST_ACCOUNT INTEGER,'\ + 'ADS_UF_DONT_EXPIRE_PASSWD INTEGER,'\ + 'ADS_UF_MNS_LOGON_ACCOUNT INTEGER,'\ + 'ADS_UF_SMARTCARD_REQUIRED INTEGER,'\ + 'ADS_UF_TRUSTED_FOR_DELEGATION INTEGER,'\ + 'ADS_UF_NOT_DELEGATED INTEGER,'\ + 'ADS_UF_USE_DES_KEY_ONLY INTEGER,'\ + 'ADS_UF_DONT_REQUIRE_PREAUTH INTEGER,'\ + 'ADS_UF_PASSWORD_EXPIRED INTEGER,'\ + 'ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION INTEGER)' db.execute(sql_table_computers) # Create the table for the AD Groups