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
def update(sessionid=None, action=None, sleep=0): if sessionid is None or sessionid <= 0: context = data_return(306, TRANSPORT_MSG.get(306), {}) return context if action == "next": result_flag = RpcClient.call( Method.SessionMeterpreterTransportNext, [sessionid]) elif action == "prev": result_flag = RpcClient.call( Method.SessionMeterpreterTransportPrev, [sessionid]) elif action == "sleep": result_flag = RpcClient.call( Method.SessionMeterpreterTransportSleep, [sessionid, sleep]) if result_flag: reconnect_time = time.time() + sleep Notice.send_warn( f'切换Session到休眠 SID:{sessionid} 重连时间: {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(reconnect_time))}' ) context = data_return(203, TRANSPORT_MSG.get(203), {}) return context else: context = data_return(305, TRANSPORT_MSG.get(305), []) return context else: result_flag = False if result_flag: Notice.send_info(f"切换传输完成 SID:{sessionid}") context = data_return(202, TRANSPORT_MSG.get(202), {}) return context else: context = data_return(302, TRANSPORT_MSG.get(302), []) return context
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
def destory(query_params): opts = { "uuid": None, "transport": None, "lhost": None, "lport": None, "ua": None, "proxy_host": None, "proxy_port": None, "proxy_type": None, "proxy_user": None, "proxy_pass": None, "comm_timeout": None, "session_exp": None, "retry_total": None, "retry_wait": None, "cert": None, "luri": None, } sessionid = query_params.get("sessionid") opts["url"] = query_params.get("url") result_flag = RpcClient.call(Method.SessionMeterpreterTransportRemove, [sessionid, opts]) if result_flag: Notice.send_info(f"删除传输 SID:{sessionid}") context = data_return(204, TRANSPORT_MSG.get(204), {}) return context else: context = data_return(304, TRANSPORT_MSG.get(304), []) return context
def list(self, request, **kwargs): """查询数据库中的信息""" try: enfilename = request.query_params.get('en', None) filename = FileMsf.decrypt_file_name(enfilename) if filename is None: context = data_return(500, CODE_MSG.get(500), {}) return Response(context) binary_data = FileMsf.read_msf_file(filename) if binary_data is None: context = data_return(304, HostFile_MSG.get(304), {}) return context response = HttpResponse(binary_data) response['Content-Type'] = 'application/octet-stream' response['Content-Disposition'] = f'attachment;filename="{filename}"' response['Code'] = 200 response['Message'] = quote(FileMsf_MSG.get(203)) remote_client = request.META.get("HTTP_X_REAL_IP") Notice.send_info(f"IP: {remote_client} 下载文件 : {filename}") return response except Exception as E: logger.error(E) context = data_return(500, CODE_MSG.get(500), {}) return Response(context)
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
def destroy_adv_job(task_uuid=None, job_id=None, broker=None): try: if broker == BROKER.post_python_job: flag = aps_module.delete_job_by_uuid(task_uuid) if flag is not True: context = data_return(304, Job_MSG.get(304), {}) return context else: context = data_return(204, Job_MSG.get(204), { "uuid": task_uuid, "job_id": job_id }) return context elif broker == BROKER.post_msf_job: req = Xcache.get_module_task_by_uuid(task_uuid=task_uuid) common_module_instance = req.get("module") Xcache.del_module_task_by_uuid(task_uuid) params = [job_id] result = RpcClient.call(Method.JobStop, params) if result is None: context = data_return(305, Job_MSG.get(305), {}) return context if result.get('result') == 'success': # 发送通知 Notice.send_info("模块: {} {} 手动删除完成".format( common_module_instance.NAME, common_module_instance.target_str)) context = data_return(204, Job_MSG.get(204), { "uuid": task_uuid, "job_id": job_id }) return context else: context = data_return(304, Job_MSG.get(304), {}) return context elif broker == BROKER.bot_msf_job: flag = Xcache.del_bot_wait_by_group_uuid(task_uuid) if flag is not True: context = data_return(304, Job_MSG.get(304), {}) return context else: context = data_return(204, Job_MSG.get(204), {"uuid": task_uuid}) return context else: context = data_return(304, Job_MSG.get(304), {}) return context except Exception as E: logger.error(E) context = data_return(500, CODE_MSG.get(500), {}) return context
def create(self, request, pk=None, **kwargs): null_response = { "status": "error", "type": "account", "currentAuthority": "guest", "token": "forguest" } # 检查是否为diypassword password = request.data.get('password', None) if password == "diypassword": context = data_return(302, BASEAUTH_MSG.get(302), null_response) return Response(context) try: serializer = AuthTokenSerializer(data=request.data) if serializer.is_valid(): token, created = Token.objects.get_or_create( user=serializer.validated_data['user']) time_now = datetime.datetime.now() if created or token.created < time_now - datetime.timedelta( minutes=EXPIRE_MINUTES): # 更新创建时间,保持token有效 token.delete() token = Token.objects.create( user=serializer.validated_data['user']) token.created = time_now token.save() null_response['status'] = 'ok' null_response[ 'currentAuthority'] = 'admin' # 当前为单用户模式,默认为admin null_response['token'] = token.key # 成功登录通知 Notice.send_info(f"{serializer.validated_data['user']} 成功登录") context = data_return(201, BASEAUTH_MSG.get(201), null_response) return Response(context) else: if Xcache.login_fail_count(): Notice.send_alert("Viper遭到暴力破解,服务器地址可能已经暴露") context = data_return(301, BASEAUTH_MSG.get(301), null_response) return Response(context) except Exception as E: logger.error(E) context = data_return(301, BASEAUTH_MSG.get(301), null_response) return Response(context)
def recovery_cache_last_handler(cache_handlers): for one_handler in cache_handlers: opts = one_handler connext = Handler.create(opts) code = connext.get("code") payload = opts.get('PAYLOAD') port = opts.get('LPORT') if code == 201: Notice.send_info(f"历史监听 Payload:{payload} Port:{port} 加载成功") elif code in [301]: Notice.send_warning(f"历史监听 Payload:{payload} Port:{port} 加载失败") else: Notice.send_warning(f"历史监听 Payload:{payload} Port:{port} 加载失败,未知的返回值:f{code}") Notice.send_info("所有历史监听加载完成")
def putin_post_msf_module_queue(msf_module=None): """调用msgrpc生成job,放入列表""" params = [ msf_module.type, msf_module.mname, msf_module.opts, True, # 强制设置后台运行 0 # 超时时间 ] result = RpcClient.call(Method.ModuleExecute, params) if result is None: Notice.send_warning(f"渗透服务连接失败,无法执行模块 :{msf_module.NAME}") return False elif result == "license expire": Notice.send_warning(f"License 过期,无法执行模块 :{msf_module.NAME}") return False # result 数据格式 # {'job_id': 3, 'uuid': 'dbcb2530-95b1-0137-5100-000c2966078a', 'module': b'\x80\ub.'} if result.get("job_id") is None: logger.warning("模块实例:{} uuid: {} 创建后台任务失败".format( msf_module.NAME, result.get("uuid"))) Notice.send_warning("模块: {} {} 创建后台任务失败,请检查输入参数".format( msf_module.NAME, msf_module.target_str)) return False else: logger.warning("模块实例放入列表:{} job_id: {} uuid: {}".format( msf_module.NAME, result.get("job_id"), result.get("uuid"))) # 放入请求队列 req = { 'broker': msf_module.MODULE_BROKER, 'uuid': result.get("uuid"), 'module': msf_module, 'time': int(time.time()), 'job_id': result.get("job_id"), } Xcache.create_module_task(req) Notice.send_info("模块: {} {} 开始执行".format(msf_module.NAME, msf_module.target_str)) return True
def store_monitor_from_sub(message=None): body = message.get('data') try: msf_module_return_dict = json.loads(body) 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 try: module_intent = req.get('module') if module_intent is None: logger.error("获取模块失败,body: {}".format(msf_module_return_dict)) return False logger.warning("模块回调:{} job_id: {} uuid: {}".format( module_intent.NAME, msf_module_return_dict.get("job_id"), 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) Notice.send_info("模块: {} 回调执行完成".format(module_intent.NAME)) module_intent._store_result_in_history() # 存储到历史记录
def destory(portfwdtype=None, lhost=None, lport=None, rhost=None, rport=None, sessionid=None): if sessionid is not None or sessionid == -1: opts = {'TYPE': portfwdtype, 'LHOST': lhost, 'LPORT': lport, 'RHOST': rhost, 'RPORT': rport, 'SESSION': sessionid, 'CMD': 'delete'} 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(302, PORTFWD_MSG.get(302), []) return context if result_dict.get('status') is True: Notice.send_info(f"删除端口转发 SID:{sessionid} {portfwdtype} {lhost}/{lport} {rhost}/{rport}") context = data_return(204, PORTFWD_MSG.get(204), result_dict.get('data')) return context else: context = data_return(305, PORTFWD_MSG.get(305), []) return context else: context = data_return(306, PORTFWD_MSG.get(306), []) return context
def list_sessions(): uuid_msfjobid = {} msfjobs = Job.list_msfrpc_jobs() if msfjobs is not None: for jobid in msfjobs: datastore = msfjobs[jobid].get("datastore") if datastore is not None: uuid_msfjobid[msfjobs[jobid]["uuid"]] = {"job_id": int(jobid), "PAYLOAD": datastore.get("PAYLOAD"), "LPORT": datastore.get("LPORT"), "LHOST": datastore.get("LHOST"), "RHOST": datastore.get("RHOST")} sessions_available_count = 0 sessions = [] infos = RpcClient.call(Method.SessionList, timeout=3) if infos is None: return sessions if infos.get('error'): logger.warning(infos.get('error_string')) return sessions sessionhosts = [] for key in infos.keys(): info = infos.get(key) if info is not None: one_session = {} try: one_session['id'] = int(key) except Exception as E: logger.warning(E) continue # 处理linux的no-user问题 if str(info.get('info')).split(' @ ')[0] == "no-user": info['info'] = info.get('info')[10:] one_session['type'] = info.get('type') one_session['session_host'] = info.get('session_host') one_session['tunnel_local'] = info.get('tunnel_local') one_session['tunnel_peer'] = info.get('tunnel_peer') one_session['tunnel_peer_ip'] = info.get('tunnel_peer').split(":")[0] one_session['tunnel_peer_locate'] = Geoip.get_city(info.get('tunnel_peer').split(":")[0]) one_session['via_exploit'] = info.get('via_exploit') one_session['exploit_uuid'] = info.get('exploit_uuid') if uuid_msfjobid.get(info.get('exploit_uuid')) is None: one_session['job_info'] = {"job_id": -1, "PAYLOAD": None, "LPORT": None, "LHOST": None, "RHOST": None} else: one_session['job_info'] = uuid_msfjobid.get(info.get('exploit_uuid')) one_session['via_payload'] = info.get('via_payload') one_session['tunnel_peer_ip'] = info.get('tunnel_peer').split(":")[0] one_session['tunnel_peer_locate'] = Geoip.get_city(info.get('tunnel_peer').split(":")[0]) one_session['uuid'] = info.get('uuid') one_session['platform'] = info.get('platform') one_session['last_checkin'] = info.get('last_checkin') // 5 * 5 one_session['fromnow'] = (int(time.time()) - info.get('last_checkin')) // 5 * 5 one_session['info'] = info.get('info') one_session['arch'] = info.get('arch') try: one_session['user'] = str(info.get('info')).split(' @ ')[0] one_session['computer'] = str(info.get('info')).split(' @ ')[1] except Exception as _: one_session['user'] = "******" one_session['computer'] = "Initializing" one_session['advanced_info'] = {"sysinfo": {}, "username": "******"} one_session['os'] = None one_session['load_powershell'] = False one_session['load_python'] = False one_session['routes'] = [] one_session['isadmin'] = False one_session['available'] = False # 是否初始化完成 sessions.append(one_session) continue one_session['load_powershell'] = info.get('load_powershell') one_session['load_python'] = info.get('load_python') one_session['advanced_info'] = info.get('advanced_info') try: one_session['os'] = info.get('advanced_info').get("sysinfo").get("OS") one_session['os_short'] = info.get('advanced_info').get("sysinfo").get("OS").split("(")[0] except Exception as _: one_session['os'] = None one_session['os_short'] = None try: one_session['isadmin'] = info.get('advanced_info').get("sysinfo").get("IsAdmin") if info.get('platform').lower().startswith('linux'): if "uid=0" in one_session['info'].lower(): one_session['isadmin'] = True except Exception as _: one_session['isadmin'] = None routestrlist = info.get('routes') one_session['routes'] = [] try: if isinstance(routestrlist, list): for routestr in routestrlist: routestr.split('/') tmpdict = {"subnet": routestr.split('/')[0], 'netmask': routestr.split('/')[1]} one_session['routes'].append(tmpdict) except Exception as E: logger.error(E) one_session['available'] = True sessions.append(one_session) # session监控统计信息 sessionhosts.append(info.get('session_host')) sessions_available_count += 1 def split_ip(ip): try: result = tuple(int(part) for part in ip.split('.')) except Exception as E: logger.exception(E) return 0, 0, 0 return result def session_host_key(item): return split_ip(item.get("session_host")) sessions = sorted(sessions, key=session_host_key) # session监控功能 if Xcache.get_sessionmonitor_conf().get("flag"): if Xcache.get_session_count() < sessions_available_count: Notice.send_sms(f"当前Session数量: {sessions_available_count} IP列表: {','.join(sessionhosts)}") Notice.send_info(f"当前Session数量: {sessions_available_count}") if Xcache.get_session_count() != sessions_available_count: Xcache.set_session_count(sessions_available_count) return sessions
def create(kind=None, tag=None, setting=None): """创建系统配置""" if isinstance(setting, str): setting = json.loads(setting) if kind == "telegram": token = setting.get("token") chat_id = setting.get("chat_id") proxy = setting.get("proxy") if tag == "check": # 获取chat_id user_chat_id_list = Telegram.get_alive_chat_id(token, proxy) context = data_return(201, Setting_MSG.get(201), user_chat_id_list) return context else: if Settings._check_telegram_aliveable(token, chat_id, proxy) is not True: data = { "token": token, "chat_id": chat_id, "proxy": proxy, "alive": False } Xcache.set_telegram_conf(data) context = data_return(303, Setting_MSG.get(303), data) return context else: Notice.send_success("设置Telegram通知成功") data = { "token": token, "chat_id": chat_id, "proxy": proxy, "alive": True } Xcache.set_telegram_conf(data) context = data_return(202, Setting_MSG.get(202), data) return context elif kind == "dingding": access_token = setting.get("access_token") keyword = setting.get("keyword") if Settings._check_dingding_aliveable(access_token, keyword) is not True: data = { "access_token": access_token, "keyword": keyword, "alive": False } Xcache.set_dingding_conf(data) context = data_return(304, Setting_MSG.get(304), data) return context else: Notice.send_success("设置DingDing通知成功") data = { "access_token": access_token, "keyword": keyword, "alive": True } Xcache.set_dingding_conf(data) context = data_return(203, Setting_MSG.get(203), data) return context elif kind == "serverchan": sendkey = setting.get("sendkey") if Settings._check_serverchan_aliveable(sendkey) is not True: data = {"sendkey": sendkey, "alive": False} Xcache.set_serverchan_conf(data) context = data_return(305, Setting_MSG.get(305), data) return context else: Notice.send_success("设置Server酱通知成功") data = {"sendkey": sendkey, "alive": True} Xcache.set_serverchan_conf(data) context = data_return(207, Setting_MSG.get(207), data) return context elif kind == "FOFA": email = setting.get("email") key = setting.get("key") client = FOFAClient() client.set_email_and_key(email, key) if client.is_alive() is not True: data = {"email": email, "key": key, "alive": False} Xcache.set_fofa_conf(data) context = data_return(306, Setting_MSG.get(306), data) return context else: Notice.send_success("设置FOFA API 成功") data = {"email": email, "key": key, "alive": True} Xcache.set_fofa_conf(data) context = data_return(206, Setting_MSG.get(206), data) return context elif kind == "sessionmonitor": flag = setting.get("flag") Xcache.set_sessionmonitor_conf({"flag": flag}) if flag: msg = "Session监控功能已打开" Notice.send_success(msg) Notice.send_sms(msg) else: msg = "Session监控功能已关闭" Notice.send_info(msg) Notice.send_sms(msg) context = data_return(204, Setting_MSG.get(204), {"flag": flag}) return context elif kind == "lhost": Xcache.set_lhost_config(setting) Notice.send_success(f"设置回连地址成功,当前回连地址: {setting.get('lhost')}") context = data_return(205, Setting_MSG.get(205), setting) return context else: context = data_return(301, Setting_MSG.get(301), {}) return context