def delete_image(self, request, pk=None): """ 删除镜像 :param request: :param pk: :return: """ user = request.user if not user.is_superuser: return JsonResponse(R.build(msg="权限不足")) img_info = ImageInfo.objects.filter(image_id=pk).first() if not img_info: return JsonResponse(R.ok()) operation_args = ImageInfoSerializer(img_info).data request_ip = get_request_ip(request) sys_log = SysLog(user_id=user.id, operation_type="镜像", operation_name="删除", operation_value=operation_args["image_vul_name"], operation_args=json.dumps(operation_args), ip=request_ip) sys_log.save() image_id = img_info.image_id container_vul = ContainerVul.objects.filter(image_id=image_id) data_json = ContainerVulSerializer(container_vul, many=True) if container_vul.count() == 0: img_info.delete() return JsonResponse(R.ok()) else: return JsonResponse( R.build(msg="镜像正在使用,无法删除!", data=data_json.data))
def destroy(self, request, *args, **kwargs): """ 删除镜像 :param request: :param args: :param kwargs: :return: """ user = request.user if not user.is_superuser: return JsonResponse(R.build(msg="权限不足")) img = self.get_object() operation_args = ImageInfoSerializer(img).data request_ip = get_request_ip(request) sys_log = SysLog(user_id=user.id, operation_type="镜像", operation_name="删除", operation_value=operation_args["image_vul_name"], operation_args=operation_args, ip=request_ip) sys_log.save() image_id = img.image_id container_vul = ContainerVul.objects.filter(image_id=image_id) if container_vul.count() == 0: img.delete() return JsonResponse(R.ok()) else: return JsonResponse(R.build(msg="镜像正在使用,无法删除!"))
def get_img_info(req): if req.method == "GET": imgs = ImageInfo.objects.all() imglist = list() for i in imgs: img = ImageInfoSerializer(i).data imglist.append(img) return JsonResponse(imglist, safe=False)
def share_image_task(image_info, user_info, request_ip): """ 共享镜像 :param image_info: 镜像信息 :param user_info: 用户信息 :param request_ip: 请求 IP :return: """ task_id = create_share_image_task(image_info=image_info, user_info=user_info) operation_args = ImageInfoSerializer(image_info).data sys_log = SysLog(user_id=user_info.id, operation_type="镜像", operation_name="分享", ip=request_ip, operation_value=operation_args["image_vul_name"], operation_args=json.dumps(operation_args)) sys_log.save() share_image.delay(task_id) return task_id
def create_container_task(container_vul, user_info, request_ip): """ 创建漏洞容器 :param container_vul: container vul :param user_info: user info :param request_ip: request ip :return: """ image_info = container_vul.image_id user_id = user_info.id task_id = create_run_container_task(container_vul, user_info) if user_info.is_superuser or user_id == container_vul.user_id: operation_args = ImageInfoSerializer(image_info).data sys_log = SysLog(user_id=user_id, operation_type="容器", operation_name="启动", ip=request_ip, operation_value=operation_args["image_vul_name"], operation_args=json.dumps(operation_args)) sys_log.save() setting_config = get_setting_config() try: countdown = int(setting_config["time"]) except: countdown = int(DEFAULT_CONFIG["time"]) if countdown == 0: run_container.delay(container_vul.container_id, user_id, task_id, countdown) elif countdown != 0 and countdown > 60: # run_container(container_vul.container_id, user_id, task_id, countdown) setting_config = get_setting_config() if 'del_container' in setting_config: del_container = setting_config['del_container'] if not del_container or del_container == 0 or del_container == '0': add_chain_sig = chain(run_container.s(container_vul.container_id, user_id, task_id, countdown) | stop_container.s().set(countdown=countdown)) else: add_chain_sig = chain(run_container.s(container_vul.container_id, user_id, task_id, countdown) | delete_container.s().set(countdown=countdown)) add_chain_sig.apply_async() else: task_info = TaskInfo.objects.filter(task_id=task_id).first() task_info.task_msg = json.dumps(R.build(msg="停止时间最小为 1 分钟")) task_info.task_status = 4 task_info.update_date = timezone.now() task_info.save() else: task_info = TaskInfo.objects.filter(task_id=task_id).first() task_info.task_msg = json.dumps(R.build(msg="权限不足")) task_info.task_status = 3 task_info.update_date = timezone.now() task_info.save() return task_id
def create_image_task(image_info, user_info, request_ip, image_file=None): """ 创建镜像任务 """ user_id = user_info.id task_id = create_create_image_task(image_info=image_info, user_info=user_info) if user_info.is_superuser: image_name = image_info.image_name image_desc = image_info.image_desc image_vul_name = image_info.image_vul_name image_rank = image_info.rank task_info = TaskInfo.objects.filter(task_id=task_id).first() if image_file: task_msg = {} try: file_info = image_file.read() images = client.images.load(file_info) image = images[0] repo_tags = image.attrs["RepoTags"] if len(repo_tags) == 0: # 移除本地镜像 try: client.images.remove(image.id) except Exception as e: pass task_msg = R.build(msg="文件镜像 Tag 不能为空") else: config = image.attrs["ContainerConfig"] port_list = [] if "ExposedPorts" in config: port_list = config["ExposedPorts"] ports = [] for port in port_list: port = port.replace("/", "").replace("tcp", "").replace("udp", "") ports.append(port) image_name = repo_tags[0] image_port = ",".join(ports) image_info = ImageInfo.objects.filter(image_name=image_name).first() if not image_info: image_info = ImageInfo() image_info.image_name = image_name image_info.image_port = image_port # image_vul_name image_info.image_vul_name = image_name.replace("vulfocus/","") if not image_vul_name else image_vul_name # image_desc image_info.image_desc = image_name.replace("vulfocus/","") if not image_desc else image_desc # rank image_info.rank = 2.5 if image_rank > 5 or image_rank < 0.5 else image_rank image_info.is_ok = True image_info.save() task_info.task_name = "拉取镜像:"+image_name task_info.task_status = 3 task_msg = R.ok(data="%s 添加成功" % (image_name, )) except Exception as e: traceback.print_exc() task_msg = R.err() try: image_info.delete() except: pass task_info.task_status = 4 finally: task_info.task_msg = json.dumps(task_msg) task_info.update_date = timezone.now() task_info.save() elif image_name: # 创建任务 # create_image(task_id=task_id) create_image.delay(task_id) else: R.build(msg="镜像文件或镜像名称不能为空") operation_args = ImageInfoSerializer(image_info).data sys_log = SysLog(user_id=user_id, operation_type="镜像", operation_name="创建", ip=request_ip, operation_value=operation_args["image_vul_name"], operation_args=json.dumps(operation_args)) sys_log.save() else: task_info = TaskInfo.objects.filter(task_id=task_id).first() task_info.task_msg = json.dumps(R.build(msg="权限不足")) task_info.task_status = 3 task_info.update_date = timezone.now() task_info.save() return task_id
def create(self, request, *args, **kwargs): """ 创建镜像 :param request: :param args: :param kwargs: :return: """ user = request.user if not user.is_superuser: return JsonResponse(R.build(msg="权限不足!")) file = request.FILES.get("file") rank = request.POST.get("rank", default=2.5) image_name = request.POST.get("name") try: rank = float(rank) except Exception as e: return JsonResponse(R.build(msg="Rank 格式错误")) image_vul_name = request.POST.get("vul_name", default="") if not image_vul_name: return JsonResponse(R.build(msg="漏洞名称不能为空")) image_desc = request.POST.get("desc", default="") if not file and not image_name: return JsonResponse(R.build(msg="镜像文件或名称不能为空")) if file and image_name: return JsonResponse(R.build(msg="镜像文件或名称不能同时填写")) image_port = "" if not image_name and file: try: file_info = file.read() images = client.images.load(file_info) image = images[0] repo_tags = image.attrs["RepoTags"] if len(repo_tags) == 0: # 移除本地镜像 try: client.images.remove(image.id) except Exception as e: pass return JsonResponse(msg="镜像名称不能为空") config = image.attrs["ContainerConfig"] port_list = [] if "ExposedPorts" in config: port_list = config["ExposedPorts"] ports = [] for port in port_list: port = port.replace("/", "").replace("tcp", "").replace("udp", "") ports.append(port) image_name = repo_tags[0] image_port = ",".join(ports) except Exception as e: return JsonResponse(R.err()) """ 查重 """ count = ImageInfo.objects.filter(image_name=image_name).count() if count > 0: return JsonResponse(R.build(msg="漏洞镜像已存在!")) if not file and image_name: try: image = client.images.get(image_name) except Exception as e: images = client.images.pull(image_name) if Image == type(images): image = images else: if len(images) > 0: image = images[0] else: return JsonResponse(R.build("镜像不存在!")) config = image.attrs["ContainerConfig"] port_list = [] if "ExposedPorts" in config: port_list = config["ExposedPorts"] ports = [] for port in port_list: port = port.replace("/", "").replace("tcp", "").replace("udp", "") ports.append(port) image_port = ",".join(ports) image_info = ImageInfo(image_name=image_name, image_vul_name=image_vul_name, image_port=image_port, rank=rank, image_desc=image_desc) image_info.save() rs_data = ImageInfoSerializer(image_info).data request_ip = get_request_ip(request) sys_log = SysLog(user_id=user.id, operation_type="镜像", operation_name="创建", operation_value=rs_data["image_vul_name"], operation_args=rs_data, ip=request_ip) sys_log.save() return JsonResponse(R.ok(data=rs_data))
def start_container(self, request, pk=None): """ 启动靶场 :param request: :param pk: :return: """ Img = self.get_object() # 当前用户登录ID user_id = request.user.id image_id = Img.image_id time_model_id = '' try: container_vul = ContainerVul.objects.filter(user_id=user_id, image_id=image_id, time_model_id=time_model_id).first() # 连接Docker容器 docker_container = client.containers.get(container_id=container_vul.docker_container_id) # 当前状态 if 'exited' == container_vul.container_status or 'exited' == docker_container.status: # 启动 docker_container.start() time_sleep_count = 10 container_status = str(docker_container.status) for i in range(time_sleep_count): docker_container.reload() container_status = str(docker_container.status) if 'running' == container_status: break elif 'exited' == container_status: pass time.sleep(1) if 'running' != container_status: return JsonResponse({"info": "", "msg": "漏洞容器启动失败"}, status=202) container_vul.container_status = container_status container_vul.save() operation_args = ImageInfoSerializer(Img).data request_ip = get_request_ip(request) sys_log = SysLog(user_id=user_id, operation_type="镜像", operation_name="启动", operation_value=operation_args["image_vul_name"], operation_args=operation_args, ip=request_ip) sys_log.save() return JsonResponse({"info": container_vul.vul_host, "container_id": container_vul.container_id, "msg": "容器已启动"},status=201) except AttributeError as attribute_error: pass except NotFound as docker_not_found: # 容器不存在,直接删除数据库记录 container_vul.delete() except Exception as e: return JsonResponse({"info": "", "msg": "服务器内部错误,请联系管理员"}, status=500) vul_flag = "flag-{bmh%s}" % (uuid.uuid4(),) vul_ip = get_local_ip() if not vul_ip: return JsonResponse({"info": "", "msg": "服务器内部错误,请联系管理员"}, status=500) command = 'touch /tmp/%s' % (vul_flag, ) image_port = Img.image_port image_port_list = image_port.split(',') port_dict = {} for tmp_port in image_port_list: tmp_random_port = '' for i in range(20): try: # 端口 tmp_random_port = random.randint(8000, 65536) ContainerVul.objects.get(container_port=tmp_random_port) print('端口重复 --> %s' % (tmp_random_port,)) except Exception as e: break if not tmp_random_port: return JsonResponse({"info": "", "msg": "端口无效"}, status=202) port_dict['%s/tcp' % (tmp_port, )] = tmp_random_port try: container = client.containers.run(image=Img.image_name, ports=port_dict, detach=True) time_sleep_count = 10 container_status = str(container.status) for i in range(time_sleep_count): container.reload() container_status = str(container.status) if 'running' == container_status: print(container.exec_run(command)) break elif 'exited' == container_status: break time.sleep(1) # docker 容器 id docker_container_id = container.id port_list = port_dict.values() tmp_port_list = [] for tmp_port in port_list: tmp_port_list.append(str(tmp_port)) port_str = ",".join(tmp_port_list) vul_host = vul_ip + ':' + port_str container_vul = ContainerVul(image_id=Img, user_id=request.user.id, vul_host=vul_host, container_status=container_status, docker_container_id=docker_container_id, container_port=port_str, time_model_id=time_model_id, create_date=django.utils.timezone.now(), container_flag=vul_flag) container_vul.save() operation_args = ImageInfoSerializer(Img).data request_ip = get_request_ip(request) sys_log = SysLog(user_id=user_id, operation_type="镜像", operation_name="启动", operation_value=operation_args["image_vul_name"], operation_args=operation_args, ip=request_ip) sys_log.save() return JsonResponse({"info": vul_host, "container_id": container_vul.container_id}, status=201) except ImageNotFound as image_not_found: return JsonResponse({"info": "", "msg": "镜像不存在"}) except Exception as e: traceback.print_exc() return JsonResponse({"info": "", "msg": "服务器内部错误,请联系管理员"}, status=500)