예제 #1
0
 def _deal_powershell_json_result(result):
     result_without_error = re.sub('ERROR:.+\s', '', result)
     result_without_empty = result_without_error.replace('\r', '').replace('\n', '').replace('\t', '')
     try:
         result_json = json.loads(result_without_empty)
         return result_json
     except Exception as E:
         logger.warning(E)
         logger.warning("解析powershell结果失败")
         return None
예제 #2
0
    def create_bot(ipportlist=None, custom_param=None, loadpath=None):
        module_config = Xcache.get_moduleconfig(loadpath)
        # 获取模块配置
        if module_config is None:
            context = dict_data_return(305, PostModuleActuator_MSG.get(305),
                                       {})
            return context

        # 处理模块参数
        try:
            custom_param = json.loads(custom_param)
        except Exception as E:
            logger.warning(E)
            custom_param = {}

        # 获取模块实例
        group_uuid = str(uuid.uuid1()).replace('-', "")
        class_intent = importlib.import_module(loadpath)
        for ipport in ipportlist:
            post_module_intent = class_intent.PostModule(
                ip=ipport.get("ip"),
                port=ipport.get("port"),
                protocol=ipport.get("protocol"),
                custom_param=custom_param)

            # 模块前序检查,调用check函数
            try:
                flag, msg = post_module_intent.check()
                if flag is not True:
                    # 如果检查未通过,返回未通过原因(msg)
                    Notices.send_warning(
                        f"模块:{post_module_intent.NAME} IP:{ipport.get('ip')} 检查未通过,原因:{msg}"
                    )
                    continue

            except Exception as E:
                logger.warning(E)
                Notices.send_warning(
                    f"模块:{post_module_intent.NAME} IP:{ipport.get('ip')} 检查函数执行异常"
                )
                continue

            tmp_self_uuid = str(uuid.uuid1())
            req = {
                'uuid': tmp_self_uuid,
                'group_uuid': group_uuid,
                'broker': post_module_intent.MODULE_BROKER,
                'module': post_module_intent,
                'time': int(time.time()),
            }
            Xcache.putin_bot_wait(req)

        context = dict_data_return(201, PostModuleActuator_MSG.get(201), {})
        return context
예제 #3
0
 def find_local_admin_access(self):
     module_type = 'post'
     mname = 'windows/manage/powershell/exec_powershell_function_mem'
     opts = {
         'SESSION': self._sessionid,
         'SCRIPT': 'PowerView_dev.ps1',
         'EXECUTE_STRING': 'Find-LocalAdminAccess -Delay 1',
         'CHECK_FUNCTION': False,
     }
     result = MsfModule.run_with_output(module_type, mname, opts)
     try:
         result_json = json.loads(result.replace('\r', '').replace('\n', '').replace('\t', ''))
         return result_json
     except Exception as E:
         logger.warning(E)
         return None
예제 #4
0
 def get_group_member(self, group):
     module_type = 'post'
     mname = 'windows/manage/powershell/exec_powershell_function_mem'
     opts = {
         'SESSION': self._sessionid,
         'SCRIPT': 'PowerView_dev.ps1',
         'EXECUTE_STRING': ' \'{}\' | Get-DomainGroupMember'.format(group),
         'CHECK_FUNCTION': False,
     }
     result = MsfModule.run_with_output(module_type, mname, opts)
     try:
         result_json = json.loads(result.replace('\r', '').replace('\n', '').replace('\t', ''))
         return result_json
     except Exception as E:
         logger.warning(E)
         return None
예제 #5
0
    def param(self, name):
        """获取输入参数的接口"""
        if name in [
                HANDLER_OPTION.get('name'),
                CREDENTIAL_OPTION.get('name'),
                FILE_OPTION.get('name')
        ]:
            if self._custom_param.get(name) is None:
                return None
            try:
                tmp_param = json.loads(self._custom_param.get(name))
                return tmp_param
            except Exception as E:
                logger.warning(E)
                return None

        else:
            return self._custom_param.get(name)
예제 #6
0
    def add_credential(username='',
                       password='',
                       password_type='',
                       tag=None,
                       source_module='',
                       host_ipaddress='',
                       desc=''):
        if tag is None:
            tag = {}
        if isinstance(tag, dict) is not True:
            logger.warning('数据类型检查错误,数据 {}'.format(tag))
            tag = {}
        if password is '' or password.find('n.a.(') > 0 or len(password) > 100:
            return False

        result = postCredential.add_or_update(username, password,
                                              password_type, tag,
                                              source_module, host_ipaddress,
                                              desc)
        return result
예제 #7
0
    def add_vulnerability(hid_or_ipaddress=None,
                          source_module_loadpath='',
                          extra_data=None,
                          desc=''):
        if extra_data is None:
            extra_data = {}
        if isinstance(extra_data, dict) is not True:
            logger.warning('数据类型检查错误,数据 {}'.format(extra_data))
            extra_data = {}
        if isinstance(hid_or_ipaddress, int):
            result = postVulnerability.add_or_update(hid_or_ipaddress,
                                                     source_module_loadpath,
                                                     extra_data, desc)
            return result
        elif isinstance(hid_or_ipaddress, str):

            result = postVulnerability.add_or_update(
                Host.get_by_ipaddress(hid_or_ipaddress).get('id'),
                source_module_loadpath, extra_data, desc)
            return result
예제 #8
0
 def get_celery_result_scheduler(self):
     """循环调用函数,用于处理celery结果"""
     try:
         msg = self.redis_celery_result_sub.parse_response()
     except Exception as E:
         logger.warning("redis连接错误")
         return False
     try:
         result = json.loads(msg[2])
         task_id = result.get('task_id')
         status = result.get('status')
         retval = result.get('retval')
         einfo = result.get('einfo')
         logger.info("开始存储任务结果,task_id: {}".format(task_id))
         flag = Task.update_task(task_id=task_id,
                                 status=status,
                                 retval=retval,
                                 einfo=einfo)
         logger.info("存储任务完成,task_id: {}".format(task_id))
         return True
     except Exception as E:
         logger.warning("json解析task结果失败,详细信息: {} 异常:{}".format(msg, E))
예제 #9
0
    def __init__(self):
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.bind(("127.0.0.1", 47200))
        except socket.error:
            logger.warning("Monitor 已经启动")
            return
        # 初始化redis实例
        self.redisHelper = RedisHelper()
        self.redis_celery_result_sub = self.redisHelper.subscribe(
            REDIS_CELERY_RESULT_CHANNEL)

        log = logging.getLogger('apscheduler.scheduler')
        log.setLevel(logging.ERROR)  # 关闭apscheduler的警告
        self.Scheduler = BackgroundScheduler()

        self.Scheduler.add_job(func=self.get_celery_result_scheduler,
                               max_instances=1,
                               trigger='interval',
                               seconds=5,
                               id='get_celery_result_scheduler')
        self.Scheduler.start()
        logger.warning("Monitor 启动完成")
예제 #10
0
 def _webcheck_store(pid, retval):
     logger.info("wafw00f 存储结果: {} {}".format(pid, retval))
     for one in retval:
         website = one.get('website')
         wid = Website.get_wid_by_website(pid, website)
         if wid is None:
             logger.warning("数据库中无法找到网站:{}".format(website))
             continue
         else:
             # 更新网站存活信息
             Website.update_website_alive(wid, one.get('alive'))
             # 更新cdn信息
             WebsiteCDN.update_website_cdn(wid=wid, hascdn=one.get('hascdn'), ipaddress=one.get('ipaddress'),
                                           title=one.get('title'))
             # 更新techs信息
             techs = one.get('techs')
             for tech in techs:
                 WebsiteTech.update_website_tech(wid=wid, name=tech.get('name'), version=tech.get('version'),
                                                 icon=tech.get('icon'))
             # 更新waf信息
             waf = one.get('waf')
             WebsiteWaf.update_website_waf(wid=wid, hasWaf=waf.get('haswaf'), waf=waf.get('waf'),
                                           detect_tech=waf.get('detectTech'))
     return True
예제 #11
0
 def callback(self, status, message, data):
     """后台运行模块回调函数"""
     logger.warning(self.type)
     logger.warning(self.mname)
     logger.warning(self.opts)
예제 #12
0
    def load_all_modules_config():
        def _sort_by_moduletype(module_config=None):
            return TAG2CH.get_moduletype_order(module_config.get('MODULETYPE'))

        all_modules_config = []
        # viper 内置模块
        viper_module_count = 0
        modulenames = os.listdir(os.path.join(settings.BASE_DIR, 'MODULES'))
        for modulename in modulenames:
            modulename = modulename.split(".")[0]
            if modulename == "__init__" or modulename == "__pycache__":  # __init__.py的特殊处理
                continue

            class_intent = importlib.import_module(
                'MODULES.{}'.format(modulename))

            try:
                if isinstance(class_intent.PostModule.ATTCK, str):
                    attck = [class_intent.PostModule.ATTCK]
                elif isinstance(class_intent.PostModule.ATTCK, list):
                    attck = [class_intent.PostModule.ATTCK]
                else:
                    attck = []

                one_module_config = {
                    "BROKER": class_intent.PostModule.MODULE_BROKER,  # 处理器
                    "NAME": class_intent.PostModule.NAME,
                    "DESC": class_intent.PostModule.DESC,
                    "WARN": class_intent.PostModule.WARN,
                    "AUTHOR": class_intent.PostModule.AUTHOR,
                    "REFERENCES": class_intent.PostModule.REFERENCES,
                    "MODULETYPE": class_intent.PostModule.MODULETYPE,
                    "OPTIONS": class_intent.PostModule.OPTIONS,
                    "loadpath": 'MODULES.{}'.format(modulename),

                    # post类配置
                    "REQUIRE_SESSION": class_intent.PostModule.REQUIRE_SESSION,
                    "PLATFORM": class_intent.PostModule.PLATFORM,
                    "PERMISSIONS": class_intent.PostModule.PERMISSIONS,
                    "ATTCK": attck,

                    # bot类配置
                    "SEARCH": class_intent.PostModule.SEARCH,
                }
                all_modules_config.append(one_module_config)
                viper_module_count += 1
            except Exception as E:
                logger.error(E)
                continue
        logger.warning("内置模块加载完成,加载{}个模块".format(viper_module_count))
        Notices.send_success(f"内置模块加载完成,加载{viper_module_count}个模块")
        # 自定义模块
        diy_module_count = 0
        modulenames = os.listdir(
            os.path.join(settings.BASE_DIR, 'Docker', "module"))
        for modulename in modulenames:
            modulename = modulename.split(".")[0]
            if modulename == "__init__" or modulename == "__pycache__":  # __init__.py的特殊处理
                continue

            class_intent = importlib.import_module(
                'Docker.module.{}'.format(modulename))
            importlib.reload(class_intent)
            try:
                if isinstance(class_intent.PostModule.ATTCK, str):
                    attck = [class_intent.PostModule.ATTCK]
                elif isinstance(class_intent.PostModule.ATTCK, list):
                    attck = [class_intent.PostModule.ATTCK]
                else:
                    attck = []

                one_module_config = {
                    "BROKER": class_intent.PostModule.MODULE_BROKER,  # 处理器
                    "NAME": class_intent.PostModule.NAME,
                    "DESC": class_intent.PostModule.DESC,
                    "WARN": class_intent.PostModule.WARN,
                    "AUTHOR": class_intent.PostModule.AUTHOR,
                    "REFERENCES": class_intent.PostModule.REFERENCES,
                    "MODULETYPE": class_intent.PostModule.MODULETYPE,
                    "OPTIONS": class_intent.PostModule.OPTIONS,
                    "loadpath": 'Docker.module.{}'.format(modulename),

                    # post类配置
                    "REQUIRE_SESSION": class_intent.PostModule.REQUIRE_SESSION,
                    "PLATFORM": class_intent.PostModule.PLATFORM,
                    "PERMISSIONS": class_intent.PostModule.PERMISSIONS,
                    "ATTCK": attck,

                    # bot类配置
                    "SEARCH": class_intent.PostModule.SEARCH,
                }
                all_modules_config.append(one_module_config)
                diy_module_count += 1
            except Exception as E:
                logger.error(E)
                continue
        logger.warning("自定义模块加载完成,加载{}个模块".format(diy_module_count))
        Notices.send_success(f"自定义模块加载完成,加载{diy_module_count}个模块")
        all_modules_config.sort(key=_sort_by_moduletype)
        if Xcache.update_moduleconfigs(all_modules_config):
            return len(all_modules_config)
        else:
            return 0
예제 #13
0
    def create_post(loadpath=None,
                    sessionid=None,
                    hid=None,
                    custom_param=None):
        module_config = Xcache.get_moduleconfig(loadpath)
        # 获取模块配置
        if module_config is None:
            context = dict_data_return(305, PostModuleActuator_MSG.get(305),
                                       {})
            return context

        # 处理模块参数
        try:
            custom_param = json.loads(custom_param)
        except Exception as E:
            logger.warning(E)
            custom_param = {}
        # 获取模块实例
        class_intent = importlib.import_module(loadpath)
        post_module_intent = class_intent.PostModule(sessionid, hid,
                                                     custom_param)

        # 模块前序检查,调用check函数
        try:
            flag, msg = post_module_intent.check()
            if flag is not True:
                # 如果检查未通过,返回未通过原因(msg)
                context = dict_data_return(405, msg, {})
                return context
        except Exception as E:
            logger.warning(E)
            context = dict_data_return(301, PostModuleActuator_MSG.get(301),
                                       {})
            return context

        try:
            broker = post_module_intent.MODULE_BROKER
        except Exception as E:
            logger.warning(E)
            context = dict_data_return(305, PostModuleActuator_MSG.get(305),
                                       {})
            return context

        if broker == BROKER.post_python_job:
            # 放入多模块队列
            if aps_module.putin_post_python_module_queue(post_module_intent):
                context = dict_data_return(201,
                                           PostModuleActuator_MSG.get(201), {})
                return context
            else:
                context = dict_data_return(306,
                                           PostModuleActuator_MSG.get(306), {})
                return context
        elif broker == BROKER.post_msf_job:
            # 放入后台运行队列
            if MSFModule.putin_post_msf_module_queue(post_module_intent):
                context = dict_data_return(201,
                                           PostModuleActuator_MSG.get(201), {})
                return context
            else:
                context = dict_data_return(306,
                                           PostModuleActuator_MSG.get(306), {})
                return context
        else:
            logger.warning("错误的broker")
예제 #14
0
    def _deal_dynamic_option(one_module_config=None):
        """处理handler及凭证等动态变化参数,返回处理后参数列表"""
        options = one_module_config.get('OPTIONS')
        for option in options:
            # handler处理
            if option.get('name') == HANDLER_OPTION.get("name"):
                handlers = Handler.list_handler()
                tmp_enum_list = []
                for handler in handlers:
                    import json
                    lhost_str = ""
                    rhost_srt = ""

                    if handler.get('LHOST') is None:
                        try:
                            handler.pop('LHOST')
                        except Exception as _:
                            pass

                    else:
                        lhost_str = "LHOST:{} | ".format(handler.get('LHOST'))

                    if handler.get('RHOST') is None:
                        try:
                            handler.pop('RHOST')
                        except Exception as _:
                            pass
                    else:
                        rhost_srt = "RHOST:{} | ".format(handler.get('RHOST'))

                    # 虚拟监听与真实监听标签
                    if handler.get("ID") < 0:
                        handlertag = "虚拟 | "
                    else:
                        handlertag = ""

                    if handler.get("HandlerName") is None:
                        name = f"{handlertag}{handler.get('PAYLOAD')} | {lhost_str}{rhost_srt} LPORT:{handler.get('LPORT')}"
                    else:
                        name = f"{handlertag}{handler.get('HandlerName')} | {handler.get('PAYLOAD')} | {lhost_str}{rhost_srt} LPORT:{handler.get('LPORT')}"

                    value = json.dumps(handler)
                    tmp_enum_list.append({'name': name, 'value': value})

                option['enum_list'] = tmp_enum_list

                if len(tmp_enum_list) == 1:  # 只有一个监听
                    option['default'] = tmp_enum_list[0].get("value")

            # 凭证处理
            elif option.get('name') == CREDENTIAL_OPTION.get("name"):
                credentials = Credential.list_credential()
                tmp_enum_list = []
                try:
                    if option.get('extra_data') is None or option.get(
                            'extra_data').get('password_type') is None:
                        pass
                    else:
                        type_list = option.get('extra_data').get(
                            'password_type')
                        for credential in credentials:
                            if credential.get('password_type') in type_list:
                                name = "用户名:{} | 密码:{} | 标签:{} | 主机:{}".format(
                                    credential.get('username'),
                                    credential.get('password'),
                                    credential.get('tag'),
                                    credential.get('host_ipaddress'))
                                import json
                                value = json.dumps(credential)
                                tmp_enum_list.append({
                                    'name': name,
                                    'value': value
                                })
                    option['enum_list'] = tmp_enum_list
                except Exception as E:
                    logger.warning(E)
            # 文件处理
            elif option.get('name') == FILE_OPTION.get("name"):
                if option.get('extra_data') is None or option.get(
                        'extra_data').get('file_extension') is None:
                    file_extension_list = None
                else:
                    file_extension_list = option.get('extra_data').get(
                        'file_extension')

                files = FileMsf.list_msf_files()
                tmp_enum_list = []
                for file in files:
                    import json
                    # {
                    #     "filename": "test",
                    #     "filesize": 0,
                    #     "mtime": 1552273961
                    # },
                    name = file.get("name")
                    size = FileSession.get_size_in_nice_string(
                        file.get('size'))
                    mtime = file.get("mtime")
                    style_time = time.strftime("%Y-%m-%d %H:%M:%S",
                                               time.localtime(mtime))
                    show = False  # 是否满足文件后缀要求
                    if isinstance(file_extension_list, list):
                        for ext in file_extension_list:
                            if name.lower().endswith(ext.lower()):
                                show = True
                    else:
                        show = True
                    if show:
                        name = "文件: {}   大小: {}   修改时间: {}".format(
                            name, size, style_time)
                        value = json.dumps(file)
                        tmp_enum_list.append({'name': name, 'value': value})
                option['enum_list'] = tmp_enum_list
        return one_module_config