Example #1
0
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
Example #2
0
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