Beispiel #1
0
def admin_create_chal():
    files = request.files.getlist('files[]')

    ## TODO: Expand to support multiple flags
    flags = [{'flag':request.form['key'], 'type':int(request.form['key_type[0]'])}]

    # Create challenge
    chal = Challenges(request.form['name'], request.form['desc'], request.form['value'], request.form['category'], flags)
    if 'hidden' in request.form:
        chal.hidden = True
    else:
        chal.hidden = False
    db.session.add(chal)
    db.session.commit()

    for f in files:
        filename = secure_filename(f.filename)

        if len(filename) <= 0:
            continue

        md5hash = hashlib.md5(os.urandom(64)).hexdigest()

        if not os.path.exists(os.path.join(os.path.normpath(app.static_folder), 'uploads', md5hash)):
            os.makedirs(os.path.join(os.path.normpath(app.static_folder), 'uploads', md5hash))

        f.save(os.path.join(os.path.normpath(app.static_folder), 'uploads', md5hash, filename))
        db_f = Files(chal.id, os.path.join('static', 'uploads', md5hash, filename))
        db.session.add(db_f)

    db.session.commit()
    db.session.close()
    return redirect(url_for('admin.admin_chals'))
Beispiel #2
0
def admin_create_chal():
    if request.method == 'POST':
        files = request.files.getlist('files[]')

        # Create challenge
        chal = Challenges(request.form['name'], request.form['desc'],
                          request.form['value'], request.form['category'],
                          int(request.form['chaltype']))
        if 'hidden' in request.form:
            chal.hidden = True
        else:
            chal.hidden = False
        db.session.add(chal)
        db.session.flush()

        flag = Keys(chal.id, request.form['key'],
                    int(request.form['key_type[0]']))
        if request.form.get('keydata'):
            flag.data = request.form.get('keydata')
        db.session.add(flag)

        db.session.commit()

        for f in files:
            upload_file(file=f, chalid=chal.id)

        db.session.commit()
        db.session.close()
        return redirect(url_for('admin_challenges.admin_chals'))
    else:
        return render_template('admin/chals/create.html')
Beispiel #3
0
def admin_create_chal():
    files = request.files.getlist('files[]')

    ## TODO: Expand to support multiple flags
    flags = [{'flag':request.form['key'], 'type':int(request.form['key_type[0]'])}]

    # Create challenge
    chal = Challenges(request.form['name'], request.form['desc'], request.form['value'], request.form['category'], flags)
    if 'hidden' in request.form:
        chal.hidden = True
    else:
        chal.hidden = False
    db.session.add(chal)
    db.session.commit()

    for f in files:
        filename = secure_filename(f.filename)

        if len(filename) <= 0:
            continue

        md5hash = hashlib.md5(os.urandom(64)).hexdigest()

        if not os.path.exists(os.path.join(os.path.normpath(app.static_folder), 'uploads', md5hash)):
            os.makedirs(os.path.join(os.path.normpath(app.static_folder), 'uploads', md5hash))

        f.save(os.path.join(os.path.normpath(app.static_folder), 'uploads', md5hash, filename))
        db_f = Files(chal.id, os.path.join('static', 'uploads', md5hash, filename))
        db.session.add(db_f)

    db.session.commit()
    db.session.close()
    return redirect(url_for('admin.admin_chals'))
Beispiel #4
0
def admin_create_chal():
    files = request.files.getlist('files[]')

    # TODO: Expand to support multiple flags
    flags = [{
        'flag': request.form['key'],
        'type': int(request.form['key_type[0]'])
    }]

    # Create challenge
    chal = Challenges(request.form['name'], request.form['desc'],
                      request.form['value'], request.form['category'], flags)
    if 'hidden' in request.form:
        chal.hidden = True
    else:
        chal.hidden = False
    db.session.add(chal)
    db.session.commit()

    for f in files:
        upload_file(file=f, chalid=chal.id)

    db.session.commit()
    db.session.close()
    return redirect(url_for('admin.admin_chals'))
Beispiel #5
0
def admin_create_chal():
    if request.method == 'POST':
        files = request.files.getlist('files[]')

        # Create challenge
        chal = Challenges(request.form['name'], request.form['desc'], request.form['value'], request.form['category'], int(request.form['chaltype']))
        if 'hidden' in request.form:
            chal.hidden = True
        else:
            chal.hidden = False

        max_attempts = request.form.get('max_attempts')
        if max_attempts and max_attempts.isdigit():
            chal.max_attempts = int(max_attempts)

        db.session.add(chal)
        db.session.flush()

        flag = Keys(chal.id, request.form['key'], int(request.form['key_type[0]']))
        if request.form.get('keydata'):
            flag.data = request.form.get('keydata')
        db.session.add(flag)

        db.session.commit()

        for f in files:
            utils.upload_file(file=f, chalid=chal.id)

        db.session.commit()
        db.session.close()
        return redirect(url_for('admin_challenges.admin_chals'))
    else:
        return render_template('admin/chals/create.html')
Beispiel #6
0
    def create(request):
        """
        This method is used to process the challenge creation request.

        :param request:
        :return:
        """
        files = request.files.getlist('files[]')

        # Create challenge
        chal = Challenges(name=request.form['name'],
                          description=request.form['desc'],
                          value=request.form['value'],
                          category='Bonus Flags',
                          type=request.form['chaltype'])

        chal.hidden = True

        db.session.add(chal)
        db.session.commit()

        flag = Keys(chal.id, request.form['key'], request.form['key_type[0]'])
        if request.form.get('keydata'):
            flag.data = request.form.get('keydata')
        db.session.add(flag)

        db.session.commit()

        for f in files:
            utils.upload_file(file=f, chalid=chal.id)

        db.session.commit()
Beispiel #7
0
    def create(request):
        """
        This method is used to process the challenge creation request.

        :param request:
        :return:
        """
        # Create challenge
        chal = Challenges(
            name=request.form['name'],
            description=request.form['description'],
            value=request.form['value'],
            category=request.form['category'],
            type=request.form['chaltype'],
            penalty = request.form['penalty']
        )

        if 'hidden' in request.form:
            chal.hidden = True
        else:
            chal.hidden = False

        max_attempts = request.form.get('max_attempts')
        if max_attempts and max_attempts.isdigit():
            chal.max_attempts = int(max_attempts)

        db.session.add(chal)
        db.session.commit()

        flag = Keys(chal.id, request.form['key'], request.form['key_type[0]'])
        if request.form.get('keydata'):
            flag.data = request.form.get('keydata')
        db.session.add(flag)

        db.session.commit()

        files = request.files.getlist('files[]')
        for f in files:
            utils.upload_file(file=f, chalid=chal.id)
   
        file_generators = request.files.getlist('file_generators[]')
        for g in file_generators:
            utils.upload_file(file=g, chalid=chal.id, isgenerator=True)

        db.session.commit()
def import_challenges(in_file, dst_attachments, exit_on_error=True, move=False):
    from CTFd.models import db, Challenges, Keys, Tags, Files
    chals = []
    with open(in_file, 'r') as in_stream:
        chals = yaml.safe_load_all(in_stream)

        for chal in chals:
            skip = False
            for req_field in REQ_FIELDS:
                if req_field not in chal:
                    if exit_on_error:
                        raise MissingFieldError(req_field)
                    else:
                        print "Skipping challenge: Missing field '{}'".format(req_field)
                        skip = True
                        break
            if skip:
                continue

            for flag in chal['flags']:
                if 'flag' not in flag:
                    if exit_on_error:
                        raise MissingFieldError('flag')
                    else:
                        print "Skipping flag: Missing field 'flag'"
                        continue
                flag['flag'] = flag['flag'].strip()
                if 'type' not in flag:
                    flag['type'] = "static"

            # We ignore traling and leading whitespace when importing challenges
            chal_dbobj = Challenges(
                chal['name'].strip(),
                chal['description'].strip(),
                chal['value'],
                chal['category'].strip()
            )

            if 'hidden' in chal and chal['hidden']:
                chal_dbobj.hidden = True

            matching_chals = Challenges.query.filter_by(
                name=chal_dbobj.name,
                description=chal_dbobj.description,
                value=chal_dbobj.value,
                category=chal_dbobj.category,
                hidden=chal_dbobj.hidden
            ).all()

            for match in matching_chals:
                if 'tags' in chal:
                    tags_db = [tag.tag for tag in Tags.query.add_columns('tag').filter_by(chal=match.id).all()]
                    if all([tag not in tags_db for tag in chal['tags']]):
                        continue
                if 'files' in chal:
                    files_db = [f.location for f in Files.query.add_columns('location').filter_by(chal=match.id).all()]
                    if len(files_db) != len(chal['files']):
                        continue

                    hashes = []
                    for file_db in files_db:
                        with open(os.path.join(dst_attachments, file_db), 'r') as f:
                            hash = hashlib.md5(f.read()).digest()
                            hashes.append(hash)

                    mismatch = False
                    for file in chal['files']:
                        filepath = os.path.join(os.path.dirname(in_file), file)
                        with open(filepath, 'r') as f:
                            hash = hashlib.md5(f.read()).digest()
                            if hash in hashes:
                                hashes.remove(hash)
                            else:
                                mismatch = True
                                break
                    if mismatch:
                        continue

                flags_db = Keys.query.filter_by(chal=match.id).all()
                for flag in chal['flags']:
                    for flag_db in flags_db:
                        if flag['flag'] != flag_db.flag:
                            continue
                        if flag['type'] != flag_db.key_type:
                            continue

                skip = True
                break
            if skip:
                print "Skipping {}: Duplicate challenge found in DB".format(chal['name'].encode('utf8'))
                continue

            print "Adding {}".format(chal['name'].encode('utf8'))
            db.session.add(chal_dbobj)
            db.session.commit()

            if 'tags' in chal:
                for tag in chal['tags']:
                    tag_dbobj = Tags(chal_dbobj.id, tag)
                    db.session.add(tag_dbobj)

            for flag in chal['flags']:
                flag_db = Keys(chal_dbobj.id, flag['flag'], flag['type'])
                db.session.add(flag_db)


            if 'files' in chal:
                for file in chal['files']:
                    filename = os.path.basename(file)
                    dst_filename = secure_filename(filename)

                    dst_dir = None
                    while not dst_dir or os.path.exists(dst_dir):
                        md5hash = hashlib.md5(os.urandom(64)).hexdigest()
                        dst_dir = os.path.join(dst_attachments, md5hash)

                    os.makedirs(dst_dir)
                    dstpath = os.path.join(dst_dir, dst_filename)
                    srcpath = os.path.join(os.path.dirname(in_file), file)

                    if move:
                        shutil.move(srcpath, dstpath)
                    else:
                        shutil.copy(srcpath, dstpath)
                    file_dbobj = Files(chal_dbobj.id, os.path.relpath(dstpath, start=dst_attachments))

                    db.session.add(file_dbobj)

    db.session.commit()
    db.session.close()
def import_challenges(in_file, dst_attachments, exit_on_error=True, move=False):
    from CTFd.models import db, Challenges, Keys, Tags, Files, Hints, Unlocks
    with open(in_file, 'r') as in_stream:
        chals = yaml.safe_load_all(in_stream)

        for chal in chals:
            # ensure all required fields are present before adding or updating a challenge
            try:
                validate_yaml(chal)
            except MissingFieldError as err:
                if exit_on_error:
                    raise
                else:
                    print "Skipping challenge: " + str(err)
                    continue

            # if the challenge already exists, update it
            chal_db = Challenges.query.filter_by(name=chal['name']).first()
            if chal_db is not None:
                print "Updating {}".format(chal['name'].encode('utf8'))
                chal_db.description = chal['description']
                chal_db.value = chal['value']
                chal_db.category = chal['category']
            else:
                print "Adding {}".format(chal['name'].encode('utf8'))
                chal_db = Challenges(
                    chal['name'],
                    chal['description'],
                    chal['value'],
                    chal['category'])
            chal_db.type = chal['type']
            chal_db.hidden = chal['hidden']

            db.session.add(chal_db)
            db.session.commit()

            # delete all tags and re-add them
            Tags.query.filter_by(chal=chal_db.id).delete()
            for tag in chal['tags']:
                tag_dbobj = Tags(chal_db.id, tag)
                db.session.add(tag_dbobj)

            # delete all flags and re-add them
            Keys.query.filter_by(chal=chal_db.id).delete()
            for flag in chal['flags']:
                flag_db = Keys(chal_db.id, flag['flag'], flag['type'])
                db.session.add(flag_db)

            # delete or update existing hints
            hints = {h['id']: h for h in chal['hints']}
            hints_db = Hints.query.filter_by(chal=chal_db.id).all()
            for hint_db in hints_db:
                if hint_db.type in hints:
                    # the hint is being updated
                    hint_db.hint = hints[hint_db.type]['hint']
                    hint_db.cost = hints[hint_db.type]['cost']
                    del hints[hint_db.type]
                else:
                    # the hint is being deleted - delete the hint and any related unlocks
                    print "  Removing hint {:d}".format(hint_db.type)
                    Unlocks.query.filter_by(model='hints', itemid=hint_db.id).delete()
                    Hints.query.filter_by(id=hint_db.id).delete()

            # add new hints
            for hint in hints.values():
                print "  Adding hint {:d}".format(hint['id'])
                hint_db = Hints(chal_db.id, hint['hint'], cost=hint['cost'], type=hint['id'])
                db.session.add(hint_db)

            # hash and compare existing files with the new uploaded files
            hashes_db = {}
            files_db = Files.query.filter_by(chal=chal_db.id).all()
            for file_db in files_db:
                with open(os.path.join(dst_attachments, file_db.location), 'rb') as f:
                    h = hashlib.md5(f.read()).digest()
                    hashes_db[h] = file_db

            to_upload = []
            for file in chal['files']:
                path = os.path.join(os.path.dirname(in_file), file)
                with open(path, "rb") as f:
                    h = hashlib.md5(f.read()).digest()
                if h in hashes_db and os.path.basename(file) == os.path.basename(hashes_db[h].location):
                    # the file is up to date
                    del hashes_db[h]
                else:
                    # the file has changed name or content
                    to_upload.append(path)

            # remove out of date files and add new uploads
            for file_db in hashes_db.values():
                print "  Removing file {}".format(file_db.location)
                utils.delete_file(file_db.id)
            for path in to_upload:
                basename = os.path.basename(path)
                print "  Adding file {}".format(basename)
                with open(path, "rb") as f:
                    f = FileStorage(stream=f, filename=basename)
                    utils.upload_file(file=f, chalid=chal_db.id)
                if move:
                    os.unlink(path)

            db.session.commit()

    db.session.commit()
    db.session.close()
Beispiel #10
0
    def admin_create_chal():
        if request.method == 'POST':
            print("[DEBUG] Post request sent to my modified admin_create_chal")
            files = request.files.getlist('files[]')

            # Create challenge
            chal = Challenges(
                name=request.form['name'],
                description=request.form['desc'],
                value=request.form['value'],
                category=request.form['category'],
                type=request.form['chaltype'],
            )

            if 'hidden' in request.form:
                chal.hidden = True
            else:
                chal.hidden = False

            max_attempts = request.form.get('max_attempts')
            if max_attempts and max_attempts.isdigit():
                chal.max_attempts = int(max_attempts)

            db.session.add(chal)
            db.session.flush()

            # This if added by me
            print("[DEBUG] chal.id: " + str(chal.id))
            if chal.type == 'ethereum':
                solidity = request.form['solidity']
                test_func = request.form['test_func']
                args = request.form['args']
                starting_ether = request.form['starting-ether']
                flag = request.form['key']
                print("[DEBUG] Type is ethereum!")
                if ethereumctf.compile_contract(str(chal.id), solidity,
                                                test_func,
                                                ast.literal_eval(args),
                                                starting_ether, flag):
                    print("[DEBUG] successful compile!")
                else:
                    db.session.rollback()
                    print("[DEBUG] failed compile")
                    return redirect(
                        url_for('admin_challenges.admin_create_chal')
                    )  # TODO: Fail better

            db.session.commit()

            flag = Keys(chal.id, request.form['key'],
                        int(request.form['key_type[0]']))
            if request.form.get('keydata'):
                flag.data = request.form.get('keydata')
            db.session.add(flag)

            db.session.commit()

            for f in files:
                utils.upload_file(file=f, chalid=chal.id)

            db.session.commit()
            db.session.close()
            return redirect(url_for('admin_challenges.admin_chals'))
        else:
            return render_template('admin/chals/create.html')