示例#1
0
def create():
    # ---------Level Initialization---------
    # Create randomized bucket name to avoid namespace conflict
    nonce = str(random.randint(100000000000, 999999999999))
    bucket_name = f'{RESOURCE_PREFIX}-bucket-{nonce}'
    # --------------------------------------

    # ---------Deployment Insertion---------
    # Insert deployment
    config_template_args = {'nonce': nonce}
    template_files = ['core/framework/templates/bucket_acl.jinja']
    deployments.insert(LEVEL_PATH,
                       template_files=template_files,
                       config_template_args=config_template_args)
    # --------------------------------------

    # --------------Level Setup-------------
    print("Level setup started for: " + LEVEL_PATH)
    # Insert secret into bucket
    storage_client = storage.Client()
    bucket = storage_client.get_bucket(bucket_name)
    secret_blob = storage.Blob('secret.txt', bucket)
    secret = levels.make_secret(LEVEL_PATH)
    secret_blob.upload_from_string(secret)

    # Print complete message and print/save start info
    print(
        f'Level creation complete for: {LEVEL_PATH}\n'
        f'Instruction for the level can be accessed at thunder-ctf.cloud/thunder/{LEVEL_PATH}.html'
    )
    start_message = f'The secret for this level can be found in the Google Cloud Storage (GCS) bucket {bucket_name}'
    levels.write_start_info(LEVEL_PATH, start_message)
示例#2
0
def create(second_deploy=True):
    # Create randomized bucket name to avoid namespace conflict
    nonce = str(random.randint(100000000000, 999999999999))
    bucket_name = f'{RESOURCE_PREFIX}-bucket-{nonce}'

    # Set role of default cloud function account
    credentials, project_id = google.auth.default()
    
    func_upload_url = cloudfunctions.upload_cloud_function(
        f'core/levels/{LEVEL_PATH}/function', FUNCTION_LOCATION)
    print("Level initialization finished for: " + LEVEL_PATH)
    # Insert deployment
    config_template_args = {'nonce': nonce,
                            'func_upload_url': func_upload_url}
    template_files = [
        'core/framework/templates/service_account.jinja',
        'core/framework/templates/cloud_function.jinja',
        'core/framework/templates/iam_policy.jinja',
        'core/framework/templates/bucket_acl.jinja']
   
    if second_deploy:
        deployments.insert(LEVEL_PATH, template_files=template_files, config_template_args=config_template_args, second_deploy=True)
    else:
        deployments.insert(LEVEL_PATH, template_files=template_files,
                       config_template_args=config_template_args)
    try:

        print("Level setup started for: " + LEVEL_PATH)
        # Allow player to use cloud function's service account
        iam_api = discovery.build('iam', 'v1', credentials=credentials)
        policy_body = {"policy": {
            "bindings": [{
                "members": [f"serviceAccount:a5-access@{project_id}.iam.gserviceaccount.com"],
                "role": "roles/iam.serviceAccountUser"}]}}
        iam_api.projects().serviceAccounts().setIamPolicy(
            resource=f'projects/{project_id}/serviceAccounts/a5-func-{nonce}-sa@{project_id}.iam.gserviceaccount.com', body=policy_body).execute()

        # Insert secret into bucket
        storage_client = storage.Client()
        bucket = storage_client.get_bucket(bucket_name)
        secret_blob = storage.Blob('secret.txt', bucket)
        secret = levels.make_secret(LEVEL_PATH)
        secret_blob.upload_from_string(secret)

        # Create service account key file
        sa_key = iam.generate_service_account_key(f'{RESOURCE_PREFIX}-access')
        print(f'Level creation complete for: {LEVEL_PATH}')
        start_message = (
            f'Use the compromised service account credentials stored in {RESOURCE_PREFIX}-access.json to find the secret, '
            'which is located in a file called secret.txt in a private bucket on the project.')
        levels.write_start_info(
            LEVEL_PATH, start_message, file_name=f'{RESOURCE_PREFIX}-access.json', file_content=sa_key)
        print(
            f'Instruction for the level can be accessed at thunder-ctf.cloud/thunder/{LEVEL_PATH}.html')
    except Exception as e: 
        exit()
示例#3
0
def create():
    print("Level initialization started for: " + LEVEL_PATH)
    # Create randomized nonce name to avoid namespace conflicts
    nonce = str(random.randint(100000000000, 999999999999))
    bucket_name = f'{RESOURCE_PREFIX}-bucket-{nonce}'
    print("Level initialization finished for: " + LEVEL_PATH)

    # Insert deployment
    config_template_args = {'nonce': nonce}
    template_files = [
        'core/framework/templates/bucket_acl.jinja',
        'core/framework/templates/service_account.jinja',
        'core/framework/templates/iam_policy.jinja',
        'core/framework/templates/container_vm.jinja'
    ]
    deployments.insert(LEVEL_PATH,
                       template_files=template_files,
                       config_template_args=config_template_args)

    print("Level setup started for: " + LEVEL_PATH)
    # Insert secret into bucket
    storage_client = storage.Client()
    bucket = storage_client.get_bucket(bucket_name)
    secret_blob = storage.Blob('secret.txt', bucket)
    secret = levels.make_secret(LEVEL_PATH)
    secret_blob.upload_from_string(secret)

    # Create service account key file
    sa_key = iam.generate_service_account_key(f'{RESOURCE_PREFIX}-access')
    print(f'Level creation complete for: {LEVEL_PATH}')
    start_message = (
        f'Use the compromised service account credentials stored in {RESOURCE_PREFIX}-access.json to find the secret, '
        'which is located in a file called secret.txt in a private bucket on the project.'
    )
    levels.write_start_info(LEVEL_PATH,
                            start_message,
                            file_name=f'{RESOURCE_PREFIX}-access.json',
                            file_content=sa_key)
    print(
        f'Instruction for the level can be accessed at thunder-ctf.cloud/thunder/{LEVEL_PATH}.html'
    )
示例#4
0
def create_logs():
    # Load list of framework names
    with open(f'core/levels/{LEVEL_PATH}/first-names.txt') as f:
        first_names = f.read().split('\n')
    with open(f'core/levels/{LEVEL_PATH}/last-names.txt') as f:
        last_names = f.read().split('\n')
    # Randomly determine a name associated with the secret
    secret_name = (first_names[random.randint(0, 199)] + '_' +
                   last_names[random.randint(0, 299)])
    # Randomly determine an index of logging of the secret transaction
    secret_position = random.randint(0, 99)

    logger = glogging.Client().logger(LOG_NAME)
    for i in range(0, 100):
        # On secret index, log the transaction with the secret as the credit card number of the struct
        if i == secret_position:
            logger.log_struct({
                'name':
                secret_name,
                'transaction-total':
                f'${random.randint(1,300)}.{random.randint(0,9)}{random.randint(0,9)}',
                'credit-card-number':
                levels.make_secret(LEVEL_PATH, 16)
            })
        else:
            # For the other entities, determine a random name
            name = (first_names[random.randint(0, 199)] + '_' +
                    last_names[random.randint(0, 299)])
            # If the name is not equal to the secret name, log the transaction with a random credit card number
            if not name == secret_name:
                logger.log_struct({
                    'name':
                    name,
                    'transaction-total':
                    f'${random.randint(1,150)}.{random.randint(1,99)}',
                    'credit-card-number':
                    str(random.randint(1000000000000000, 9999999999999999))
                })
    return secret_name.replace('_', ' ')
示例#5
0
def create(second_deploy=True):

    # Create randomized bucket name to avoid namespace conflict
    nonce = str(random.randint(100000000000, 999999999999))
    nonce_file = f'core/levels/{LEVEL_PATH}/nonce.txt'
    #write key file in function directory
    with open(nonce_file, 'w') as f:
        f.write(nonce)
    os.chmod(nonce_file, 0o700)
    print(f'Nonce {nonce} has been written to {nonce_file}')

    # Set role of default cloud function account
    credentials, project_id = google.auth.default()

    print("Level initialization finished for: " + LEVEL_PATH)
    # Insert deployment
    config_template_args = {'nonce': nonce}

    template_files = [
        'core/framework/templates/service_account.jinja',
        'core/framework/templates/iam_policy.jinja',
        'core/framework/templates/bucket_acl.jinja',
        'core/framework/templates/ubuntu_vm.jinja',
        'core/framework/templates/cloud_function.jinja'
    ]

    print("Level setup started for: " + LEVEL_PATH)

    start_message = ' Use function entrypoints below to access levels \n\n'

    for RESOURCE_PREFIX in LEVEL_NAMES:

        LEVEL_NAME = LEVEL_NAMES[RESOURCE_PREFIX]
        fvar = FARS[RESOURCE_PREFIX]

        func_patha = f'core/levels/{LEVEL_PATH}/{RESOURCE_PREFIX}/functionaccess'
        func_pathc = f'core/levels/{LEVEL_PATH}/{RESOURCE_PREFIX}/functioncheck'

        #Generate function urls
        func_template_argc = {'fvar': fvar}
        func_upload_urla = cloudfunctions.upload_cloud_function(
            func_patha, FUNCTION_LOCATION)
        func_upload_urlc = cloudfunctions.upload_cloud_function(
            func_pathc, FUNCTION_LOCATION, template_args=func_template_argc)

        #Update deployment with functions
        config_template_args_patch = {
            f'funca_upload_url_{RESOURCE_PREFIX}': func_upload_urla,
            f'funcc_upload_url_{RESOURCE_PREFIX}': func_upload_urlc,
            f'level_name_{RESOURCE_PREFIX}': LEVEL_NAME,
            f'resource_prefix_{RESOURCE_PREFIX}': RESOURCE_PREFIX
        }
        config_template_args.update(config_template_args_patch)

        msg = f'https://{FUNCTION_LOCATION}-{project_id}.cloudfunctions.net/{RESOURCE_PREFIX}-f-access-{nonce}    {LEVEL_NAMES[RESOURCE_PREFIX]}'
        start_message += msg + '\n'

    # scores funciton
    func_pathsc = f'core/levels/{LEVEL_PATH}/scores'

    #Generate scores function urls
    func_template_arg = {'anws': FARS, 'level_names': LEVEL_NAMES}
    func_upload_urlsc = cloudfunctions.upload_cloud_function(
        func_pathsc, FUNCTION_LOCATION, template_args=func_template_arg)

    login_user = os.environ.get('USER', 'USER is not set.')
    #Update deployment with functions
    config_template_args_patch = {
        'funcc_upload_url_scores': func_upload_urlsc,
        'login_user': login_user
    }
    config_template_args.update(config_template_args_patch)

    msg = f'https://{FUNCTION_LOCATION}-{project_id}.cloudfunctions.net/scores-f-{nonce}'
    start_message += '\n Or access levels through Score Board: \n' + msg + '\n'

    if second_deploy:
        deployments.insert(LEVEL_PATH,
                           template_files=template_files,
                           config_template_args=config_template_args,
                           second_deploy=True)
    else:
        deployments.insert(LEVEL_PATH,
                           template_files=template_files,
                           config_template_args=config_template_args)

    try:
        # Insert secret into bucket
        storage_client = storage.Client()
        for b in BUCKETS:
            bucket_name = f'{b}-bucket-{nonce}'
            secret = levels.make_secret(LEVEL_PATH)
            bucket = storage_client.get_bucket(bucket_name)
            secret_blob = storage.Blob(f'secret_{b}.txt', bucket)
            secret_blob.upload_from_string(secret)

        # Create and insert data in datastore
        for k in KINDS:
            entities = [{
                'name': f'admin-{k}',
                'password': '******',
                'active': True
            }, {
                'name': f'editor-{k}',
                'password': '******',
                'active': True
            }]
            kind = f'{k}-{nonce}-{project_id}'
            client = datastore.Client(project_id)
            for entity in entities:
                entity_key = client.key(kind)
                task = datastore.Entity(key=entity_key)
                task.update(entity)
                client.put(task)
            #print(f'Datastore {kind}  created')

        levels.write_start_info(LEVEL_PATH, start_message)

    except Exception as e:
        exit()
示例#6
0
def create(second_deploy=True):
    print("Level initialization started for: " + LEVEL_PATH)
    # Create randomized nonce name to avoid namespace conflicts
    nonce = str(random.randint(100000000000, 999999999999))
    bucket_name = f'{RESOURCE_PREFIX}-bucket-{nonce}'
    # Create random function password
    func_xor_password = str(random.randint(100000000000, 999999999999))
    xor_factor = str(random.randint(100000000000, 999999999999))
    func_template_args = {'bucket_name': bucket_name, 'xor_factor': xor_factor}
    # Upload function and get upload url
    func_upload_url = cloudfunctions.upload_cloud_function(
        f'core/levels/{LEVEL_PATH}/function',
        FUNCTION_LOCATION,
        template_args=func_template_args)
    print("Level initialization finished for: " + LEVEL_PATH)

    # Insert deployment
    config_template_args = {
        'nonce': nonce,
        'func_xor_password': func_xor_password,
        'func_upload_url': func_upload_url
    }
    template_files = [
        'core/framework/templates/bucket_acl.jinja',
        'core/framework/templates/cloud_function.jinja',
        'core/framework/templates/service_account.jinja',
        'core/framework/templates/iam_policy.jinja'
    ]

    if second_deploy:
        deployments.insert(LEVEL_PATH,
                           template_files=template_files,
                           config_template_args=config_template_args,
                           second_deploy=True)
    else:
        deployments.insert(LEVEL_PATH,
                           template_files=template_files,
                           config_template_args=config_template_args)
    try:
        print("Level setup started for: " + LEVEL_PATH)
        # Insert secret into bucket

        storage_client = storage.Client()
        bucket = storage_client.get_bucket(bucket_name)
        secret_blob = storage.Blob('secret.txt', bucket)
        secret = levels.make_secret(LEVEL_PATH)
        secret_blob.upload_from_string(secret)

        # Create service account key file
        sa_key = iam.generate_service_account_key(f'{RESOURCE_PREFIX}-access')
        print(f'Level creation complete for: {LEVEL_PATH}')
        start_message = (
            f'Use the given compromised credentials to find the secret hidden in the level.'
        )
        levels.write_start_info(LEVEL_PATH,
                                start_message,
                                file_name=f'{RESOURCE_PREFIX}-access.json',
                                file_content=sa_key)
        print(
            f'Instruction for the level can be accessed at thunder-ctf.cloud/thunder/{LEVEL_PATH}.html'
        )
    except Exception as e:
        exit()
示例#7
0
def create(second_deploy=True):
    print("Level initialization started for: " + LEVEL_PATH)
    # Create randomized nonce name to avoid namespace conflicts
    nonce = str(random.randint(100000000000, 999999999999))
    bucket_name = f'{RESOURCE_PREFIX}-bucket-{nonce}'

    func_template_args = {'bucket_name': bucket_name}
    # Upload function and get upload url
    func_upload_url = cloudfunctions.upload_cloud_function(
        f'core/levels/{LEVEL_PATH}/function',
        FUNCTION_LOCATION,
        template_args=func_template_args)
    print("Level initialization finished for: " + LEVEL_PATH)

    secret = levels.make_secret(LEVEL_PATH)
    # Insert deployment
    config_template_args = {
        'nonce': nonce,
        'secret': secret,
        'func_upload_url': func_upload_url
    }
    template_files = [
        'core/framework/templates/bucket_acl.jinja',
        'core/framework/templates/cloud_function.jinja',
        'core/framework/templates/service_account.jinja',
        'core/framework/templates/iam_policy.jinja',
        'core/framework/templates/ubuntu_vm.jinja'
    ]

    if second_deploy:
        deployments.insert(LEVEL_PATH,
                           template_files=template_files,
                           config_template_args=config_template_args,
                           second_deploy=True)
    else:
        deployments.insert(LEVEL_PATH,
                           template_files=template_files,
                           config_template_args=config_template_args)
    try:

        print("Level setup started for: " + LEVEL_PATH)
        # Insert dummy files into bucket
        gcstorage.upload_directory_recursive(
            f'core/levels/{LEVEL_PATH}/bucket', bucket_name)

        # Delete startup script that contains secret from instance metadata
        credentials, project_id = google.auth.default()
        compute_api = discovery.build('compute', 'v1', credentials=credentials)
        instance_info = compute_api.instances().get(
            project=project_id,
            zone=INSTANCE_ZONE,
            instance=f'{RESOURCE_PREFIX}-instance').execute()
        metadata_fingerprint = instance_info['metadata']['fingerprint']
        set_metadata_body = {'fingerprint': metadata_fingerprint, 'items': []}
        compute_api.instances().setMetadata(
            project=project_id,
            zone=INSTANCE_ZONE,
            instance=f'{RESOURCE_PREFIX}-instance',
            body=set_metadata_body).execute()

        # Create service account key file
        sa_key = iam.generate_service_account_key(f'{RESOURCE_PREFIX}-access')
        print(f'Level creation complete for: {LEVEL_PATH}')
        start_message = (
            f'In this level, look for a file named "secret.txt," which is owned by "secretuser." '
            'Use the given compromised credentials to find it.')
        levels.write_start_info(LEVEL_PATH,
                                start_message,
                                file_name=f'{RESOURCE_PREFIX}-access.json',
                                file_content=sa_key)
        print(
            f'Instruction for the level can be accessed at thunder-ctf.cloud/thunder/{LEVEL_PATH}.html'
        )
    except Exception as e:
        exit()