Ejemplo n.º 1
0
def convert_one_operator(scene_name, **kwargs):
    start_time = time.time()

    opt = OPERATORS.get(kwargs.get("operator")) or \
          OPERATORS.get("default_operator")
    env_json = {
        "scene": {
            "name": scene_name,
            "vulns": [],
            "tools": [],
            "tag": [],
            "desc": ""
        },
        "networks": [{
            "name": "Internet",
            "id": "internet-1",
            "range": "",
            "dns": [],
            "dhcp": True,
            "gateway": ""
        }],
        "servers": [{
            "id": "server-1",
            "name": kwargs.get("operator"),
            "image": kwargs.get("operator"),
            "deployScript": "",
            "pushFlagScript": "",
            "wan_number": 0,
            "attackScript": "",
            "systemType": opt.get("systemType", "linux"),
            "lan_number": 0,
            "installScript": "",
            "attacker": "",
            "checker": "",
            "role": "operator",
            "external": True,
            "initScript": "",
            "cleanScript": "",
            "accessMode": opt.get("accessMode"),
            "flavor": opt.get("flavor", "m2.1c-1g-10g"),
            "checkScript": "",
            "net": ["internet-1"],
            "imageType": "vm"
        }]
    }

    sc = SceneCreater()
    scene = sc.create_scene(**{
        "type": "1",
        "json_config": json.dumps(env_json),
        "name": scene_name
    })
    if not scene:
        print "Unable to create scene {}".format(scene_name)
        sys.exit(-1)

    print "- Created {}, time cost {} s".format(scene_name,
                                                time.time() - start_time)
    return scene
Ejemplo n.º 2
0
def convert_one_vm(base_dir, scene_name, **kwargs):
    start_time = time.time()
    env = kwargs.get("env")
    env_fld = os.path.join(base_dir, env)
    conf_json = os.path.join(env_fld, CONFIG_JSON)

    with open(conf_json, 'r') as f:
        env_json = f.read().decode("utf-8")
        if "systemType" not in env_json:
            env_json = convert_config_json(env_json, scene_name)
        else:
            env_json = convert_config_json(env_json, scene_name, True)
    with open(conf_json, 'w') as f:
        f.write(env_json)

    zip_cmd = "zip -r {}.zip * -x *.zip".format(
        os.path.join(env_fld, scene_name))
    zip_proc = subprocess.Popen(zip_cmd, shell=True, cwd=env_fld)
    out, err = zip_proc.communicate()
    print out
    if zip_proc.returncode != 0:
        print "Non zero exit code: ({}) while executing ({}) " \
              ": {}".format(zip_proc.returncode, zip_cmd, err)
        sys.exit(-1)
    sc = SceneCreater()
    scene = sc.create_scene(
        **{
            "type": "1",
            "json_config": env_json,
            "name": scene_name,
            "files": {
                'env_file':
                open(os.path.join(env_fld, "{}.zip".format(scene_name)), 'rb')
            }
        })
    if not scene:
        print "Unable to create scene {}".format(scene_name)
        sys.exit(-1)

    print "- Created {}, time cost {} s".format(scene_name,
                                                time.time() - start_time)
    return scene
Ejemplo n.º 3
0
 def __init__(self):
     self.sc = SceneCreater()
Ejemplo n.º 4
0
class SceneCreaterTest(object):
    def __init__(self):
        self.sc = SceneCreater()

    def test_create_target(self):
        return self.sc.create_target(
            **{
                "name": "223344",
                "role": "3",
                "logo": "server.png",
                "role_type": "0",
                "source_image_name": "centos7-64",
                "disk_format": "docker",
                "image_type": "docker",
                "system_type": "linux",
                "access_mode": "ssh",
                "access_port": "22",
                "access_user": "******",
                "access_password": "******",
                "flavor": "m1.1c-0.5g-8g"
            })

    def test_create_scene(self):
        config_json = {
            "scene": {
                "name": "123123",
                "vulns": [],
                "tools": [],
                "tag": [],
                "desc": ""
            },
            "routers": [{
                "net": ["network-1", "internet-1"],
                "staticRouting": [],
                "name": "Default Router",
                "id": "router-1"
            }],
            "networks": [{
                "dhcp": True,
                "range": "",
                "id": "network-1",
                "name": "network"
            }, {
                "dhcp": True,
                "range": "",
                "id": "internet-1",
                "name": "Internet"
            }],
            "servers": [{
                "id":
                "scene-target",
                "name":
                "docker-ubuntu-attacker",
                "image":
                "docker-ubuntu-attacker",
                "imageType":
                "docker",
                "role":
                "target",
                "flavor":
                "m2.1c-1g-10g",
                "systemType":
                "linux",
                "initScript":
                "./start.sh",
                "accessMode": [{
                    "username": "******",
                    "password": "******",
                    "protocol": "ssh",
                    "port": 22
                }],
                "external":
                True,
                "net": ["network-1"],
            }]
        }
        config_json["servers"].append({
            "id":
            "scene-operator",
            "name":
            "ubuntu14-64",
            "image":
            "ubuntu14-64",
            "imageType":
            "vm",
            "role":
            "operator",
            "flavor":
            "m2.1c-1g-10g",
            "systemType":
            "linux",
            "accessMode": [{
                "username": "",
                "password": "",
                "protocol": "console",
                "port": ""
            }],
            "external":
            True,
            "net": ["network-1"],
        })
        return self.sc.create_scene(**{
            "type": "1",
            "json_config": json.dumps(config_json),
            "name": "123123"
        })
Ejemplo n.º 5
0
def convert_one_v2(base_dir, scene_name, **kwargs):
    start_time = time.time()
    env = kwargs.get("env")
    docker_fld = os.path.join(base_dir, env)
    conf_json = os.path.join(docker_fld, CONFIG_JSON)
    if os.path.exists(conf_json):
        return convert_one_vm(base_dir, scene_name, **kwargs)

    if os.path.isdir(docker_fld):
        compose_file = os.path.join(docker_fld, DOCKER_COMPOSE_NAME)
    else:
        compose_file = docker_fld

    scene_server_list = []

    tag = kwargs.get("tag")
    if not tag:
        tag = []
    elif isinstance(tag, list):
        if len(tag) == 1 and not tag[0] or tag[0].lower() == "none":
            tag = []
    elif isinstance(tag, basestring):
        if tag.lower() in ["none", "null"]:
            tag = []

    scene_params = {"type": "1", "name": scene_name}
    sc = SceneCreater()
    cy = ComposeYamlV2(compose_file)
    services = cy.services
    if len(services) > 1:
        raise MultiServiceException()
    for srv_name, service in services.items():
        update_glance = False
        image = service.get("image")
        image_name = image
        if "/" in image_name:
            image_name = image_name.split("/")[-1]
        if ":" in image_name:
            image_name = image_name.replace(':', "_")

        # pull docker image
        if kwargs.get("build"):
            cwd = docker_fld
            pull_proc_cmd = "docker build -t {}".format(image_name)
        else:
            cwd = None
            pull_proc_cmd = "docker pull {}".format(image)
        pull_proc = subprocess.Popen(pull_proc_cmd,
                                     shell=True,
                                     cwd=cwd,
                                     stdout=subprocess.PIPE,
                                     stderr=subprocess.PIPE)
        out, err = pull_proc.communicate()
        print out
        if pull_proc.returncode != 0:
            print "Non zero exit code: ({}) while executing ({}) " \
                  ": {}".format(pull_proc.returncode, pull_proc_cmd, err)
            raise Exception()
        if out and "Downloaded newer image" in out:
            update_glance = True

        # rename docker image, replace : to _
        # rename_img_cmd = "docker tag {} {} && docker rmi {}".format(image, image_name, image)
        rename_img_cmd = "docker tag {} {} ".format(image, image_name)
        rename_proc = subprocess.Popen(rename_img_cmd,
                                       shell=True,
                                       stdout=subprocess.PIPE,
                                       stderr=subprocess.PIPE)
        out, err = rename_proc.communicate()
        print out
        if rename_proc.returncode != 0:
            print "Non zero exit code: ({}) while executing ({}) " \
                  ": {}".format(rename_proc.returncode, rename_img_cmd, err)
            sys.exit(-1)

        # check image exists in openstack, if not ,upload to openstack
        check_proc_cmd = "{} openstack image list --name {}".format(
            OS_AUTH_STR, image_name)
        check_proc = subprocess.Popen(check_proc_cmd,
                                      shell=True,
                                      stdout=subprocess.PIPE,
                                      stderr=subprocess.PIPE)
        out, err = check_proc.communicate()
        print out
        # 如果docker镜像没有更新并且openstack上镜像已存在,则不用再次上传到openstack
        if update_glance:
            if image_name in out:
                print "Image {} found, delete from glance before update.".format(
                    image_name)
                delete_img_cmd = "{} openstack image delete {}".format(
                    OS_AUTH_STR, image_name)
                delete_img_proc = subprocess.Popen(delete_img_cmd,
                                                   shell=True,
                                                   stdout=subprocess.PIPE,
                                                   stderr=subprocess.PIPE)
                out, err = delete_img_proc.communicate()
                print out
                print "Upload new image {} to glance.".format(image_name)
            else:
                print "Image {} not found, upload to glance.".format(
                    image_name)

            create_proc_cmd = '{os_auth} docker save {img_name} | ' \
                              'glance image-create --visibility public ' \
                              '--container-format docker --disk-format raw ' \
                              '--name {img_name}'.format(os_auth=OS_AUTH_STR,
                                                         img_name=image_name)
            create_proc = subprocess.Popen(create_proc_cmd,
                                           shell=True,
                                           stdout=subprocess.PIPE,
                                           stderr=subprocess.PIPE)
            out, err = create_proc.communicate()
            print out
            if create_proc.returncode != 0:
                print "Non zero exit code: ({}) while executing ({}) " \
                      ": {}".format(create_proc.returncode, create_proc_cmd, err)
                sys.exit(-1)

        # create target and scene
        target = sc.create_target(
            **{
                "name": image_name,
                "role": "3",
                "logo": "server.png",
                "role_type": "0",
                "source_image_name": "ubuntu-16",
                "image_status": 2,
                "disk_format": "docker",
                "image_type": "docker",
                "system_type": "linux",
                # "access_mode": "ssh",
                # "access_port": 22,
                # "access_user": "******",
                # "access_password": "******",
                "init_support": True,
                "flavor": "m2.1c-1g-10g"
            })
        if not target:
            print "Unable to create target {}".format(image_name)
            sys.exit(-1)

        # 分析docker-compose文件
        initsh = service.get("command") or ""
        if initsh:
            startsh_file = os.path.join(docker_fld, START_SCRIPT)
            if os.path.exists(startsh_file):
                flag = kwargs.get("flag")
                if isinstance(flag, list):
                    if len(flag) == 1 and flag[0].lower() == "random":
                        initsh = "%s %s" % (initsh, FLAG_STR)
                elif isinstance(flag, basestring):
                    if flag.lower() == "random":
                        initsh = "%s %s" % (initsh, FLAG_STR)

        accessMode = []
        ports = service.get("ports") or []
        modes = service.get("labels")
        if isinstance(ports, basestring):
            ports = [ports]
        for port in ports:
            if isinstance(port, int):
                port = str(port)
            if ":" in port:
                acc_port = int(port.split(":")[-1])
            else:
                acc_port = int(port)
            acc_desc = ""
            acc_mode = ""
            acc_username = ""
            acc_password = ""
            if modes:
                acc_mode_str = modes.get(acc_port) or modes.get(str(acc_port))
                if acc_mode_str:
                    if acc_mode_str.startswith("http"):
                        p = urlparse.urlparse(acc_mode_str)
                        acc_mode = p.scheme
                        url_path = p.path
                        if url_path:
                            acc_desc = url_path[1:]
                    else:
                        acc_mode = acc_mode_str.split()[0]
                        if acc_mode and acc_mode.lower() == "ssh":
                            if "|" in acc_mode_str:
                                acc_user_info = acc_mode_str.split("|")[-1]
                                if "/" in acc_user_info:
                                    acc_username, acc_password = acc_user_info.split(
                                        "/")
                            else:
                                acc_username = "******"
                                acc_password = "******"
            if not acc_mode:
                acc_mode = get_acc_mode_by_port(scene_name, acc_port)
            accessMode.append({
                "username": acc_username.strip(),
                "password": acc_password.strip(),
                "protocol": acc_mode,
                "port": acc_port,
                "desc": acc_desc
            })
        scene_server_list.append({
            "id": "scene-target-{}".format(srv_name),
            "name": image_name,
            "image": image_name,
            "deployScript": "",
            "pushFlagScript": "",
            "wan_number": 0,
            "attackScript": "",
            "systemType": "linux",
            "lan_number": 0,
            "installScript": "",
            "attacker": "",
            "checker": "",
            "role": "target",
            "external": True,
            "initScript": initsh,
            "cleanScript": "",
            "accessMode": accessMode,
            "flavor": "m2.1c-1g-10g",
            "checkScript": "",
            "net": ["internet-1"],
            "imageType": "docker"
        })

    config_json = {
        "scene": {
            "name": scene_name,
            "vulns": kwargs.get("vulns") or [],
            "tools": kwargs.get("tools") or [],
            "tag": tag,
            "desc": kwargs.get("desc") or ""
        },
        "networks": [{
            "name": "Internet",
            "id": "internet-1",
            "range": "",
            "dns": [],
            "dhcp": True,
            "gateway": ""
        }],
        "servers":
        scene_server_list
    }

    operator = kwargs.get("operator")
    if operator and operator.lower() != "none":
        config_json.update({
            "routers": [{
                "canUserConfigure": False,
                "net": ["network-1", "internet-1"],
                "staticRouting": [],
                "name": "router",
                "id": "router-1"
            }]
        })
        config_json.get("networks").append({
            "name": "network",
            "id": "network-1",
            "range": "",
            "dns": [],
            "dhcp": True,
            "gateway": ""
        })
        config_json["servers"][0].update({"net": ["network-1"]})
        opt = OPERATORS.get(operator) or \
              OPERATORS.get("default_operator")
        config_json["servers"].append({
            "id": "scene-operator",
            "name": operator,
            "image": operator,
            "deployScript": "",
            "pushFlagScript": "",
            "wan_number": 0,
            "attackScript": "",
            "systemType": opt.get("systemType"),
            "lan_number": 0,
            "installScript": "",
            "attacker": "",
            "checker": "",
            "role": "operator",
            "external": True,
            "initScript": "",
            "cleanScript": "",
            "accessMode": opt.get("accessMode"),
            "flavor": opt.get("flavor"),
            "checkScript": "",
            "net": ["network-1"],
            "imageType": "vm"
        })

    zip_file_name = u"attachment.zip"
    temp_path = tempfile.mkdtemp(prefix="scene-")
    scene_zip_file_path = os.path.join(temp_path, zip_file_name)
    scene_zip_file = zipfile.ZipFile(scene_zip_file_path, 'w')

    # update docker compuse file
    tmp_compose_file = dump_yaml(convert_yaml(compose_file),
                                 os.path.join(temp_path, "docker-compose.yml"))
    scene_zip_file.write(tmp_compose_file, "docker-compose.yml")

    push_flag = kwargs.get("pushflag")
    if push_flag and "pushflag.sh" in push_flag:
        print "has pushflag.sh, compress"
        with open(os.path.join(base_dir, push_flag)) as f:
            cont = f.read().strip()
            if not cont:
                print "PUSHFLAGHASNOCONTENT-{}".format(scene_name)
        try:
            config_json["servers"][0].update(
                {"pushFlagScript": "pushflag.sh {}".format(FLAG_STR)})
        except:
            pass
        scene_zip_file.write(os.path.join(base_dir, push_flag), "pushflag.sh")
    scene_zip_file.writestr("config.json",
                            json.dumps(config_json, indent=4),
                            compress_type=zipfile.ZIP_DEFLATED)

    scene_zip_file.close()
    scene_params.update({
        "files": {
            'env_file': (zip_file_name, open(scene_zip_file_path,
                                             'rb'), "application/zip", {
                                                 'Expires': '0'
                                             })
        }
    })
    if config_json:
        scene_params.update({"json_config": json.dumps(config_json, indent=4)})

    print config_json
    scene = sc.create_scene(**scene_params)
    if not scene:
        print "Unable to create scene {}".format(scene_name)
        sys.exit(-1)

    print "+++ Created scene {}, time cost {} s".format(
        scene_name,
        time.time() - start_time)
    print "*" * 80
    return scene