class SearchUserDetail(DetectBase): def __init__(self): super().__init__(code=ALERT_CODE, title=TITLE, desc=DESC_TEMPLATE) self.account_info = AccountInfo() self.account_history = AccountHistory() def run(self, log: Log): self.init(log=log) if log.object_info.type != "SAM_USER": return user_name = log.subject_info.user_name if user_name.endswith("$"): return target_sid = log.object_info.name if not target_sid.startswith("S-1-5-21-"): return # 查询自身也忽略 if log.subject_info.user_sid == target_sid: return # 判断域名是否存在于需要检查的域名中 domain_name = log.subject_info.domain_name if filter_domain(domain_name): return # 如果账号是管理员 直接忽略 if self.account_info.check_target_is_admin_by_sid( sid=log.subject_info.user_sid, domain=domain_name): return # 判断操作者是否为Users if not self.account_info.check_target_is_user_by_name( user_name, domain_name): return # 判断是否为敏感用户 if not self.account_info.user_is_sensitive_by_sid(sid=target_sid, domain=domain_name): return ldap = LDAPSearch(domain_name) target_user_name = str( ldap.search_by_sid(target_sid, attributes=["cn"])["cn"]) return self._generate_alert_doc(target_user_name=target_user_name) def _generate_alert_doc(self, **kwargs) -> dict: source_ip = self._get_source_ip_by_logon_id( self.log.subject_info.logon_id, self.log.subject_info.full_user_name) form_data = { "source_workstation": self._get_workstation_by_source_ip(source_ip), "source_ip": source_ip, "source_user_name": self.log.subject_info.user_name, "source_user_sid": self.log.subject_info.user_sid, "source_logon_id": self.log.subject_info.logon_id, "source_domain": self.log.subject_info.domain_name, **kwargs } doc = self._get_base_doc(level=self._get_level(), unique_id=self._get_unique_id( self.code, self.log.subject_info.user_name), form_data=form_data) return doc def _get_level(self) -> str: return LOW_LEVEL
class EnumerateGroup(DetectBase): def __init__(self): super().__init__(code=ALERT_CODE, title=TITLE, desc=DESC_TEMPLATE) self.account_info = AccountInfo() def run(self, log: Log): self.init(log=log) if log.object_info.server != "Security Account Manager": return if log.object_info.type != "SAM_GROUP": return sid = log.object_info.name if not sid.startswith("S-1-5-21-"): return user_name = log.subject_info.user_name if user_name.endswith("$"): return # 如果账号是管理员 直接忽略 if self.account_info.check_target_is_admin_by_sid( sid=sid, domain=log.subject_info.domain_name): return # 判断账号是否为 Users,如果不是,直接退出 if not self.account_info.check_target_is_user_by_name( user_name, log.subject_info.domain_name): return group_name = self._get_group_name(sid, log.subject_info.domain_name) if not group_name: return sensitive_groups = list( map(lambda x: x["name"], main_config.sensitive_groups)) if group_name in sensitive_groups: return self._generate_alert_doc(group_name=group_name) def _get_group_name(self, sid, domain): ldap = LDAPSearch(domain) entry = ldap.search_by_sid(sid, attributes=["cn"]) if entry: return str(entry["cn"]) def _generate_alert_doc(self, **kwargs) -> dict: source_ip = self._get_source_ip_by_logon_id( self.log.subject_info.logon_id, self.log.subject_info.full_user_name) form_data = { "source_workstation": self._get_workstation_by_source_ip(source_ip), "source_ip": source_ip, "source_user_name": self.log.subject_info.user_name, "source_user_sid": self.log.subject_info.user_sid, "source_logon_id": self.log.subject_info.logon_id, "source_domain": self.log.subject_info.domain_name, **kwargs } doc = self._get_base_doc(level=self._get_level(), unique_id=self._get_unique_id( self.code, self.log.subject_info.user_name), form_data=form_data) return doc def _get_level(self) -> str: return LOW_LEVEL