示例#1
0
    def add_or_update(username=None,
                      password=None,
                      password_type=None,
                      tag=None,
                      source_module=None,
                      host_ipaddress=None,
                      desc=None):
        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

        # 没有此主机数据时新建
        default_dict = {
            'username': username,
            'password': password,
            'password_type': password_type,
            'tag': tag,
            'source_module': source_module,
            'host_ipaddress': host_ipaddress,
            'desc': desc
        }
        CredentialModel.objects.update_or_create(username=username,
                                                 password=password,
                                                 password_type=password_type,
                                                 tag=tag,
                                                 defaults=default_dict)
        return True
示例#2
0
    def deal_path(path=None):
        """处理成linux路径"""
        tmppath = path.replace('\\\\', '/').replace('\\', '/')

        if re.match("^/[a-zA-Z]:/", tmppath) is not None:
            tmppath = tmppath[1:]

        # 只支持最后加/..和/../
        if tmppath.startswith('/'):  # linux路径
            if tmppath.endswith('/..') or tmppath.endswith('/../'):
                parts = PurePosixPath(tmppath).parent.parent.parts
                if len(parts) == 1:
                    tmppath = '/'
                elif len(parts) == 0:
                    tmppath = '/'
                else:
                    tmppath = "/".join(parts)

        else:
            if tmppath.endswith('/..') or tmppath.endswith('/../'):
                parts = PurePosixPath(tmppath).parent.parent.parts
                if len(parts) == 1:
                    tmppath = parts[0] + '/'
                elif len(parts) == 0:
                    tmppath = '/'
                else:
                    tmppath = "/".join(parts)

        tmppath = tmppath.replace('//', '/')
        if tmppath == '' or tmppath is None:
            logger.warning('输入错误字符')
            tmppath = '/'
        return tmppath
示例#3
0
 def send_text(token, chat_id, proxy, msg):
     if isinstance(chat_id, str):
         chat_id = [chat_id]
     elif isinstance(chat_id, list):
         pass
     else:
         return []
     send_result = []
     if proxy is None or proxy == "":
         try:
             bot = Bot(token=token)
         except Exception as E:
             logger.exception(E)
             return []
     else:
         proxy_url = proxy
         request = telegram.utils.request.Request(proxy_url=proxy_url)
         try:
             bot = Bot(token=token, request=request)
         except Exception as E:
             logger.exception(E)
             return []
     for one_chat_id in chat_id:
         try:
             bot.send_message(chat_id=one_chat_id, text=msg, timeout=1)
             send_result.append(one_chat_id)
         except Exception as E:
             logger.exception(E)
             logger.warning("无效的chat_id: {}".format(one_chat_id))
     return send_result
示例#4
0
    def delete_job_by_uuid(self, task_uuid=None):
        req = Xcache.get_module_task_by_uuid(task_uuid=task_uuid)
        Xcache.del_module_task_by_uuid(task_uuid=task_uuid)  # 清理缓存信息

        # 删除后台任务
        try:
            self.ModuleJobsScheduler.remove_job(task_uuid)
        except Exception as E:
            logger.error(E)

        try:
            module_common_instance = req.get("module")
        except Exception as E:
            logger.error(E)
            return False

        # 存储已经生成的结果
        try:
            module_common_instance.log_status("用户手动删除任务")
            module_common_instance._store_result_in_history()
        except Exception as E:
            logger.error("删除多模块实例异常:{} 异常信息: {}".format(module_common_instance.NAME, E))
            Notice.send_exception("模块: {} 执行异常,异常信息: {}".format(module_common_instance.NAME, E))
            logger.error(E)
            return False

        # 发送通知
        Notice.send_info(
            "模块: {} {} 手动删除".format(module_common_instance.NAME, module_common_instance.target_str))
        logger.warning("多模块实例手动删除:{}".format(module_common_instance.NAME))
        return True
示例#5
0
 def _set_advanced_info(self, result_dict=None):
     try:
         if result_dict.get('status'):
             self.is_in_admin_group = result_dict.get('data').get(
                 'IS_IN_ADMIN_GROUP')
             # self.is_admin = result_dict.get('data').get('IS_ADMIN')
             self.tmpdir = result_dict.get('data').get('TEMP')
             self.is_uac_enable = result_dict.get('data').get(
                 'IS_UAC_ENABLE')
             self.uac_level = result_dict.get('data').get('UAC_LEVEL')
             if self.uac_level is None:
                 self.uac_level = -1
             self.integrity = self.SID_TO_INTEGERITY_LEVEL.get(
                 result_dict.get('data').get('INTEGRITY'))
             self.pid = result_dict.get('data').get('PID')
             self.pname = result_dict.get('data').get('PNAME')
             self.ppath = result_dict.get('data').get('PPATH')
             self.puser = result_dict.get('data').get('PUSER')
             self.parch = result_dict.get('data').get('PARCH')
             self.processes = result_dict.get('data').get('PROCESSES')
             self.update_time = result_dict.get('update_time')
         else:
             logger.warning("模块执行错误")
     except Exception as E:
         logger.warning(E)
示例#6
0
    def create(sessionid=None, filename=None, dirpath=None, operation=None):
        if operation == 'create_dir' and sessionid is not None and dirpath is not None:  # 新建文件夹
            formatdir = FileSession.deal_path(dirpath)
            opts = {'OPERATION': 'create_dir', 'SESSION': sessionid, 'SESSION_DIR': formatdir}
            result = MSFModule.run('post', 'multi/manage/file_system_operation_api', opts, runasjob=False, timeout=12)
            if result is None:
                context = data_return(301, FileSession_MSG.get(301), [])
                return context
            try:
                result = json.loads(result)
            except Exception as E:
                logger.warning(E)
                context = data_return(302, FileSession_MSG.get(302), {})
                return context

            if result.get('status') is not True:
                context = data_return(303, FileSession_MSG.get(303), [])
                return context
            else:
                context = data_return(201, FileSession_MSG.get(201), result.get('data'))
                return context
        # 上传文件
        elif operation == 'upload_file' and sessionid is not None and filename is not None and dirpath is not None:
            formatdir = FileSession.deal_path(dirpath)
            opts = {'OPERATION': 'upload', 'SESSION': sessionid, 'SESSION_DIR': formatdir, 'MSF_FILE': filename}
            result = MSFModule.run('post', 'multi/manage/file_system_operation_api', opts, runasjob=True, timeout=12)
            if result is None:
                context = data_return(301, FileSession_MSG.get(301), {})
                return context
            else:
                context = data_return(201, FileSession_MSG.get(201), result)
                return context
        else:
            context = data_return(306, FileSession_MSG.get(306), [])
            return context
示例#7
0
    def putin_post_python_module_queue(self, post_module_intent=None):
        try:
            # 存储uuid
            tmp_self_uuid = str(uuid.uuid1())

            # 清空历史记录
            post_module_intent.clean_log()

            logger.warning("模块放入列表:{} job_id: {} uuid: {}".format(post_module_intent.NAME, None, tmp_self_uuid))
            post_module_intent.module_self_uuid = tmp_self_uuid
            self.ModuleJobsScheduler.add_job(func=post_module_intent._thread_run, max_instances=1, id=tmp_self_uuid)

            # 放入缓存队列,用于后续删除任务,存储结果等
            req = {
                'broker': post_module_intent.MODULE_BROKER,
                'uuid': tmp_self_uuid,
                'module': post_module_intent,
                'time': int(time.time()),
                'job_id': None,
            }
            Xcache.create_module_task(req)
            Notice.send_info(
                "模块: {} {} 开始执行".format(post_module_intent.NAME, post_module_intent.target_str))
            return True
        except Exception as E:
            logger.error(E)
            return False
示例#8
0
    def to_dict(self):
        """将参数对象转化为json格式数据"""
        _dict = {
            'name': self._name,
            'name_tag': self._name_tag,
            'type': self._type,
            'required': self._required,
            'desc': self._desc,
            'default': self._default,
            'extra_data': self._extra_data,
        }

        # 处理option_length参数的兼容性
        if self._option_length is None:
            _dict['option_length'] = option_type_default_length.get(self._type)
        else:
            _dict['option_length'] = self._option_length

        # 处理enum_list参数的兼容性,请注意,此处无法处理handler和凭证等动态参数
        tmp_enmu_list = []
        for one_enmu in self._enum_list:
            if isinstance(one_enmu, str) or isinstance(one_enmu, bytes):
                tmp_enmu_list.append({'name': one_enmu, 'value': one_enmu})
            else:
                if one_enmu.get('name') is not None and one_enmu.get(
                        'value') is not None:
                    tmp_enmu_list.append(one_enmu)
                else:
                    logger.warning("参数错误, name: {} name_tag:{}".format(
                        self._name, self._name_tag))
        _dict['enum_list'] = tmp_enmu_list
        return _dict
示例#9
0
    def create(portfwdtype=None, lhost=None, lport=None, rhost=None, rport=None, sessionid=None):
        # 获取不同转发的默认参数
        flag, context = PortFwd._check_host_port(portfwdtype, lhost, lport, rhost, rport)
        if flag is not True:
            return context

        # flag, lportsstr = is_empty_ports(lportint)
        # if flag is not True:
        #       # 端口已占用
        #     context = dict_data_return(CODE, CODE_MSG.get(CODE), {})
        #     return context

        opts = {'TYPE': portfwdtype,
                'LHOST': lhost, 'LPORT': lport, 'RHOST': rhost, 'RPORT': rport,
                'SESSION': sessionid, 'CMD': 'add'}

        result = MSFModule.run(module_type="post", mname="multi/manage/portfwd_api", opts=opts)
        if result is None:
            context = data_return(308, PORTFWD_MSG.get(308), {})
            return context
        try:
            result_dict = json.loads(result)
        except Exception as E:
            logger.warning(E)
            context = data_return(301, PORTFWD_MSG.get(301), [])
            return context
        if result_dict.get('status') is True:
            Notice.send_success(f"新增端口转发 SID:{sessionid} {portfwdtype} {lhost}/{lport} {rhost}/{rport}")
            context = data_return(201, PORTFWD_MSG.get(201), result_dict.get('data'))
            return context
        else:
            context = data_return(301, PORTFWD_MSG.get(301), [])
            return context
示例#10
0
    def destory(subnet=None, netmask=None, sessionid=None):
        opts = {
            'CMD': 'delete',
            'SUBNET': subnet,
            'NETMASK': netmask,
            'SESSION': sessionid
        }
        result = MSFModule.run(module_type="post",
                               mname="multi/manage/routeapi",
                               opts=opts)
        if result is None:
            context = data_return(505, CODE_MSG.get(505), [])
            return context
        try:
            result_dict = json.loads(result)
        except Exception as E:
            logger.warning(E)
            context = data_return(306, Route_MSG.get(306), {})
            return context

        if result_dict.get('status') is True:
            Notice.send_info(f"删除路由,SID:{sessionid} {subnet}/{netmask}")
            context = data_return(204, Route_MSG.get(204), {})
            return context
        else:
            context = data_return(304, Route_MSG.get(304), {})
            return context
示例#11
0
 def get_result_connection():
     """用于订阅类操作,无需使用连接池"""
     try:
         rcon = redis.Redis.from_url(url=f"{REDIS_URL}5")
         return rcon
     except Exception as E:
         logger.warning(E)
         return None
示例#12
0
文件: host.py 项目: j5s/viperpython
 def get_by_hid(hid=None):
     try:
         model = HostModel.objects.get(id=hid)
         result = HostSerializer(model).data
         return result
     except Exception as E:
         logger.warning(E)
         return None
示例#13
0
    def store_result_from_sub(message=None):
        # 回调报文数据格式
        # {
        # 'job_id': None,
        # 'uuid': '1b1a1ac0-95db-0137-5103-000c2966078a',
        # 'status': True,
        # 'message': None,
        # 'data': {'WHOAMI': 'nt authority\\system', 'IS_SYSTEM': True, }
        # }
        body = message.get('data')
        # 解析报文
        try:
            msf_module_return_dict = json.loads(body)
        except Exception as E:
            logger.error(E)
            return False

        # 获取对应模块实例
        try:
            req = Xcache.get_module_task_by_uuid(task_uuid=msf_module_return_dict.get("uuid"))
        except Exception as E:
            logger.error(E)
            return False

        if req is None:
            logger.error("未找到请求模块实例")
            logger.error(msf_module_return_dict)
            return False

        module_intent = req.get('module')
        if module_intent is None:
            logger.error("获取模块失败,body: {}".format(msf_module_return_dict))
            return False

        # 调用回调函数
        try:
            logger.warning(f"模块回调:{module_intent.NAME} "
                           f"job_id: {msf_module_return_dict.get('job_id')} "
                           f"uuid: {msf_module_return_dict.get('uuid')}")
            module_intent._clean_log()  # 清理历史结果
        except Exception as E:
            logger.error(E)
            return False

        try:
            module_intent.callback(status=msf_module_return_dict.get("status"),
                                   message=msf_module_return_dict.get("message"),
                                   data=msf_module_return_dict.get("data"))
        except Exception as E:
            Notice.send_error("模块 {} 的回调函数callhack运行异常".format(module_intent.NAME))
            logger.error(E)
        try:
            module_intent._store_result_in_history()  # 存储到历史记录
        except Exception as E:
            logger.error(E)

        Xcache.del_module_task_by_uuid(task_uuid=msf_module_return_dict.get("uuid"))  # 清理缓存信息
        Notice.send_success("模块: {} {} 执行完成".format(module_intent.NAME, module_intent._target_str))
示例#14
0
文件: api.py 项目: j5s/viperpython
def is_empty_ports(useport=None):
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.bind(("0.0.0.0", useport))
        sock.close()
        return True, ""
    except socket.error:
        logger.warning(f"端口: {useport},已占用")
        return False, ""
示例#15
0
 def sub_msf_module_log_thread():
     """这个函数必须以线程的方式运行,监控msf发送的redis消息,获取job类任务推送的消息"""
     rcon = RedisClient.get_result_connection()
     if rcon is None:
         return
     ps = rcon.pubsub(ignore_subscribe_messages=True)
     ps.subscribe(**{MSF_RPC_LOG_CHANNEL: MSFModule.store_log_from_sub})
     for message in ps.listen():
         if message:
             logger.warning("不应获取非空message {}".format(message))
示例#16
0
    def sub_send_sms_thread():
        """这个函数必须以线程的方式运行,监控msf发送的redis消息,获取job类任务推送的数据"""

        rcon = RedisClient.get_result_connection()
        if rcon is None:
            return
        ps = rcon.pubsub(ignore_subscribe_messages=True)
        ps.subscribe(**{VIPER_SEND_SMS_CHANNEL: Settings._send_bot_msg})
        for message in ps.listen():
            if message:
                logger.warning("不应获取非空message {}".format(message))
示例#17
0
 def upload_file_to_msf(file=None):
     try:
         filename = file.name
         filepath = os.path.join(MSFLOOT, filename)
         with open(filepath, "wb+") as f:
             for chunk in file.chunks():
                 f.write(chunk)
         return True
     except Exception as E:
         logger.warning(E)
         return False
示例#18
0
    def add_vulnerability(self, ipaddress=None, 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 = {}

        result = Vulnerability.add_or_update(ipaddress, self.loadpath,
                                             extra_data, desc)
        return result
示例#19
0
 def tabs(line=None):
     cid = Xcache.get_console_id()
     if cid is None:
         return False, {}
     params = [cid, line]
     result = RpcClient.call(Method.ConsoleTabs, params)
     if result is None or result.get("result") == "failure":
         logger.warning("Cid: {}错误".format(cid))
         return False, {}
     else:
         return True, result
示例#20
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
示例#21
0
    def create_bot(ipportlist=None, custom_param=None, loadpath=None):
        module_config = Xcache.get_moduleconfig(loadpath)
        # 获取模块配置
        if module_config is None:
            context = 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)
                    Notice.send_warning(
                        f"模块:{post_module_intent.NAME} IP:{ipport.get('ip')} 检查未通过,原因:{msg}"
                    )
                    continue

            except Exception as E:
                logger.warning(E)
                Notice.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 = data_return(201, PostModuleActuator_MSG.get(201), {})
        return context
示例#22
0
 def session_kill():
     cid = Xcache.get_console_id()
     if cid is None:
         return False, {}
     params = [cid]
     result = RpcClient.call(Method.ConsoleSessionKill, params)
     if result is None:
         return False, {}
     elif result.get("result") == "failure":
         logger.warning("Cid: {}错误".format(cid))
         return False, {}
     else:
         return True, result
示例#23
0
    def add_portservice(self, ipaddress, port, banner=None, service=""):
        """增加一个端口/服务信息"""
        if banner is None:
            banner = {}

        if isinstance(banner, dict) is not True:
            logger.warning('数据类型检查错误,数据 {}'.format(banner))
            banner = {}
        result = PortService.add_or_update(ipaddress=ipaddress,
                                           port=port,
                                           banner=banner,
                                           service=service)
        return result
示例#24
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 = 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 = data_return(405, msg, {})
                return context
        except Exception as E:
            logger.warning(E)
            context = data_return(301, PostModuleActuator_MSG.get(301), {})
            return context

        try:
            broker = post_module_intent.MODULE_BROKER
        except Exception as E:
            logger.warning(E)
            context = 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 = data_return(201, PostModuleActuator_MSG.get(201), {})
                return context
            else:
                context = 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 = data_return(201, PostModuleActuator_MSG.get(201), {})
                return context
            else:
                context = data_return(306, PostModuleActuator_MSG.get(306), {})
                return context
        else:
            logger.warning("错误的broker")
示例#25
0
 def compile_c(self, src, arch="x64"):
     bindata = None
     exe_file = os.path.join(TMP_DIR, f"{self.file_name}.exe")
     cmd = self.build_cmd(src, arch)
     ret = subprocess.run(cmd, capture_output=True, text=True)
     if ret.returncode != 0:
         logger.warning(ret.stdout)
         logger.warning(ret.stderr)
     else:
         try:
             with open(exe_file, 'rb') as f:
                 bindata = f.read()
         except Exception as E:
             logger.exception(E)
     self.cleanup_files()
     return bindata
示例#26
0
文件: domain.py 项目: j5s/viperpython
 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
示例#27
0
文件: domain.py 项目: j5s/viperpython
 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
示例#28
0
 def send_serverchan_message(msg=None, conf=None):
     if conf is None:
         conf = Xcache.get_serverchan_conf()
     if conf is None:
         return False
     if conf.get("alive"):
         pass
     else:
         return False
     sendkey = conf.get("sendkey")
     serverchan = ServerChan(sendkey=sendkey)
     try:
         result = serverchan.send_text(msg)
         return result
     except Exception as E:
         logger.warning(E)
         return False
示例#29
0
    def list(sessionid=None):
        result_list = PortFwd.list_portfwd()
        if sessionid is None or sessionid == -1:

            context = data_return(200, CODE_MSG.get(200), result_list)
            return context
        else:
            tmplist = []
            try:
                for one in result_list:
                    if one.get('sessionid') == sessionid:
                        tmplist.append(one)
            except Exception as E:
                logger.warning(E)

            context = data_return(200, CODE_MSG.get(200), tmplist)
            return context
示例#30
0
 def is_in_domain(self):
     if self.platform == "windows":
         if self.user is not None:
             try:
                 session_domain = self.user.split('\\')[0]
                 if session_domain.lower() == self.domain.lower():
                     return True
                 if session_domain.lower() == self.computer.lower():
                     return False
                 if session_domain.lower(
                 ) == "nt authority":  # system权限默认在域中
                     return True
                 return False
             except Exception as E:
                 logger.warning(E)
                 return False
     else:
         return False