From 945e1adf58daa93211a1ea95c65e4f4d9354e24c Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Wed, 9 Jun 2021 09:47:23 -0400 Subject: [PATCH] island: Split has_expected_permissions() into os-specific functions --- .../cc/server_utils/file_utils.py | 81 ++++++++++--------- 1 file changed, 44 insertions(+), 37 deletions(-) diff --git a/monkey/monkey_island/cc/server_utils/file_utils.py b/monkey/monkey_island/cc/server_utils/file_utils.py index 82184e168..cf8d344e0 100644 --- a/monkey/monkey_island/cc/server_utils/file_utils.py +++ b/monkey/monkey_island/cc/server_utils/file_utils.py @@ -9,45 +9,52 @@ def expand_path(path: str) -> str: def has_expected_permissions(path: str, expected_permissions: int) -> bool: if is_windows_os(): - # checks that admin has any permissions, user has `expected_permissions`, - # and everyone else has no permissions + return _has_expected_windows_permissions(path, expected_permissions) - import win32api # noqa: E402 - import win32security # noqa: E402 + return _has_expected_linux_permissions(path, expected_permissions) - FULL_CONTROL = 2032127 - ACE_TYPE_ALLOW = 0 - ACE_TYPE_DENY = 1 - admins_sid, _, _ = win32security.LookupAccountName("", "Administrators") - user_sid, _, _ = win32security.LookupAccountName("", win32api.GetUserName()) - - security_descriptor = win32security.GetNamedSecurityInfo( - path, win32security.SE_FILE_OBJECT, win32security.DACL_SECURITY_INFORMATION - ) - - acl = security_descriptor.GetSecurityDescriptorDacl() - - for i in range(acl.GetAceCount()): - ace = acl.GetAce(i) - ace_type, _ = ace[0] # 0 for allow, 1 for deny - permissions = ace[1] - sid = ace[-1] - - if sid == user_sid: - if not (permissions == expected_permissions and ace_type == ACE_TYPE_ALLOW): - return False - elif sid == admins_sid: - continue - # TODO: consider removing; so many system accounts/groups exist, it's likely to fail - else: - if not (permissions == FULL_CONTROL and ace_type == ACE_TYPE_DENY): - return False - - return True - - else: - file_mode = os.stat(path).st_mode - file_permissions = file_mode & 0o777 +def _has_expected_linux_permissions(path: str, expected_permissions: int) -> bool: + file_mode = os.stat(path).st_mode + file_permissions = file_mode & 0o777 return file_permissions == expected_permissions + + +def _has_expected_windows_permissions(path: str, expected_permissions: int) -> bool: + # checks that admin has any permissions, user has `expected_permissions`, + # and everyone else has no permissions + + import win32api # noqa: E402 + import win32security # noqa: E402 + + FULL_CONTROL = 2032127 + ACE_TYPE_ALLOW = 0 + ACE_TYPE_DENY = 1 + + admins_sid, _, _ = win32security.LookupAccountName("", "Administrators") + user_sid, _, _ = win32security.LookupAccountName("", win32api.GetUserName()) + + security_descriptor = win32security.GetNamedSecurityInfo( + path, win32security.SE_FILE_OBJECT, win32security.DACL_SECURITY_INFORMATION + ) + + acl = security_descriptor.GetSecurityDescriptorDacl() + + for i in range(acl.GetAceCount()): + ace = acl.GetAce(i) + ace_type, _ = ace[0] # 0 for allow, 1 for deny + permissions = ace[1] + sid = ace[-1] + + if sid == user_sid: + if not (permissions == expected_permissions and ace_type == ACE_TYPE_ALLOW): + return False + elif sid == admins_sid: + continue + # TODO: consider removing; so many system accounts/groups exist, it's likely to fail + else: + if not (permissions == FULL_CONTROL and ace_type == ACE_TYPE_DENY): + return False + + return True