Exemple #1
0
 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))
Exemple #2
0
    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="镜像正在使用,无法删除!"))
Exemple #3
0
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)
Exemple #4
0
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
Exemple #5
0
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
Exemple #6
0
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
Exemple #7
0
    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))
Exemple #8
0
    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)