diff --git a/ad_miner/sources/modules/main_page.py b/ad_miner/sources/modules/main_page.py
index 2286a7a..a6fb0ae 100644
--- a/ad_miner/sources/modules/main_page.py
+++ b/ad_miner/sources/modules/main_page.py
@@ -243,7 +243,8 @@ def create_dico_data(
"unpriviledged_users_with_admincount": len(users.unpriviledged_users_with_admincount),
"priviledge_users_without_admincount": len([dic for dic in users.users_nb_domain_admins if not dic["admincount"]]),
"privileged_accounts_outside_Protected_Users": len([dic for dic in users.users_nb_domain_admins if "Protected Users" not in dic["admin type"]]),
- "sid_singularities": users.sid_singularities
+ "sid_singularities": users.sid_singularities,
+ "pre_windows_2000_compatible_access_group": len(users.pre_windows_2000_compatible_access_group)
}
dico_data["color_category"] = dico_rating_color
@@ -338,7 +339,8 @@ def render(
"guest_accounts": f"{dico_data['value']['guest_accounts']} guests accounts are enabled",
"up_to_date_admincount": f"{dico_data['value']['priviledge_users_without_admincount']} priviledged accounts don't have admincount and {dico_data['value']['unpriviledged_users_with_admincount']} unpriviledged accounts have admincount",
"privileged_accounts_outside_Protected_Users": f"{dico_data['value']['privileged_accounts_outside_Protected_Users']} priviledged accounts are not part of the Protected Users group",
- "primaryGroupID_lower_than_1000": f"{dico_data['value']['sid_singularities']} accounts have unknown SIDs or unexpected names"
+ "primaryGroupID_lower_than_1000": f"{dico_data['value']['sid_singularities']} accounts have unknown SIDs or unexpected names",
+ "pre_Win_2000_accounts": f"{len(users.pre_windows_2000_compatible_access_group)} unauthenticated users in Pre-Win 2000 Compatible Access group"
}
descriptions = DESCRIPTION_MAP
diff --git a/ad_miner/sources/modules/rating.py b/ad_miner/sources/modules/rating.py
index 870a53e..45c33f8 100644
--- a/ad_miner/sources/modules/rating.py
+++ b/ad_miner/sources/modules/rating.py
@@ -170,7 +170,7 @@ def rating(users, domains, computers, objects, arguments):
d[rate_admincount(users.unpriviledged_users_with_admincount, users.users_nb_domain_admins)].append("up_to_date_admincount"),
d[1 if len([dic for dic in users.users_nb_domain_admins if "Protected Users" not in dic["admin type"]]) > 0 else 5].append("privileged_accounts_outside_Protected_Users"),
d[1 if users.sid_singularities > 0 else 5].append("primaryGroupID_lower_than_1000")
-
+ d[1 if "1-5-7" in [dni[2] for dni in users.pre_windows_2000_compatible_access_group] else 2 if len(users.pre_windows_2000_compatible_access_group) > 0 else 5].append("pre_windows_2000_compatible_access_group")
return d
diff --git a/ad_miner/sources/modules/requests.json b/ad_miner/sources/modules/requests.json
index 40237f5..4b92424 100644
--- a/ad_miner/sources/modules/requests.json
+++ b/ad_miner/sources/modules/requests.json
@@ -677,7 +677,7 @@
},
"pre_windows_2000_compatible_access_group": {
"name": "Pre-Windows 2000 Compatible Access contains unauthenticated users",
- "request": "MATCH (n:Group) WHERE n.name STARTS WITH \"PRE-WINDOWS 2000 COMPATIBLE ACCESS@\" MATCH (m)-[r:MemberOf]->(n) WHERE NOT m.objectid ENDS WITH \"-S-1-5-11\" return m.name,m.objectid",
+ "request": "MATCH (n:Group) WHERE n.name STARTS WITH \"PRE-WINDOWS 2000 COMPATIBLE ACCESS@\" MATCH (m)-[r:MemberOf]->(n) WHERE NOT m.objectid ENDS WITH \"-S-1-5-11\" return m,domain, m.name, m.objectid",
"output_type": "list"
},
"guest_accounts": {
diff --git a/ad_miner/sources/modules/smolcard_class.py b/ad_miner/sources/modules/smolcard_class.py
index 33f6c28..f78519a 100644
--- a/ad_miner/sources/modules/smolcard_class.py
+++ b/ad_miner/sources/modules/smolcard_class.py
@@ -51,6 +51,7 @@
"up_to_date_admincount",
"privileged_accounts_outside_Protected_Users",
"primaryGroupID_lower_than_1000"
+ "pre_windows_2000_compatible_access_group"
],
"misc": [
"computers_os_obsolete",
diff --git a/ad_miner/sources/modules/users.py b/ad_miner/sources/modules/users.py
index d55bc33..5d59b0a 100644
--- a/ad_miner/sources/modules/users.py
+++ b/ad_miner/sources/modules/users.py
@@ -216,6 +216,8 @@ def __init__(self, arguments, neo4j, domain):
self.primaryGroupID_lower_than_1000 = neo4j.all_requests["primaryGroupID_lower_than_1000"]["result"]
+ self.pre_windows_2000_compatible_access_group = neo4j.all_requests["pre_windows_2000_compatible_access_group"]["result"]
+
# Generate all the users-related pages
self.genComputersWithMostAdminsPage()
self.genServersCompromisablePage()
@@ -248,7 +250,7 @@ def __init__(self, arguments, neo4j, domain):
self.genUpToDateAdmincount()
self.genProtectedUsers()
self.genSID_lower_than_1000()
-
+ self.preWin2000()
logger.print_warning(timer_format(time.time() - self.start))
# List of Servers with the most user compromise paths (and if to handle empty cases)
@@ -1729,3 +1731,28 @@ def genSID_lower_than_1000(self):
grid.setData(sorted_data)
page.addComponent(grid)
page.render()
+
+ def genPreWin2000(self):
+ page = Page(
+ self.arguments.cache_prefix,
+ "pre_windows_2000_compatible_access_group",
+ "Pre-Windows 2000 Compatible Access accounts",
+ "pre_windows_2000_compatible_access_group",
+ )
+ grid = Grid("Pre-Windows 2000 Compatible Access")
+ grid.setheaders(["Domain", "Name", "User type"])
+
+ # Sort accounts with anonymous accounts first
+ sorted_list = [dni for dni in self.pre_windows_2000_compatible_access_group if "1-5-7" in dni[2]]
+ sorted_list += [dni for dni in self.pre_windows_2000_compatible_access_group if "1-5-7" not in dni[2]]
+
+ data = []
+ for domain, account_name, objectid in sorted_list:
+ tmp_data = {"Domain": ' ' + domain}
+ tmp_data["Name"] = ' ' + account_name
+ tmp_data["User type"] = "Unauthenticated" if objectid != "1-5-7" else "Anonymous"
+ data.append(tmp_data)
+
+ grid.setData(data)
+ page.addComponent(grid)
+ page.render()
\ No newline at end of file