Example #1
0
    def down_docker_compose(user_id, challenge_id):
        basedir = os.path.dirname(__file__)
        socket = DockerUtils.get_socket()
        challenge = DynamicCheckChallenge.query.filter_by(
            id=challenge_id).first_or_404()
        dirname = challenge.dirname.split("/")[1]
        name = "User{}_{}".format(user_id, dirname)
        dname = os.path.join(basedir, "source/run/" + name)
        command = "cd " + dname + " && docker-compose \
-H={} -f run.yml down".format(socket)
        print(command)

        try:
            os.system(command)
            os.system("rm -rf " + dname)
            msg = name + " down."
            log(
                "containers",
                "[{date}] {name} {msg}",
                msg=msg,
            )
            return True
        except Exception as e:
            msg = name + " up." + str(e)
            log(
                "containers",
                "[{date}] {name} {msg}",
                msg=msg,
            )
            return False
Example #2
0
    def token_login():
        secret = current_app.secret_key
        if not secret:
           abort(500)

        data = request.form or request.get_json()
        token = data.get('token', None)
        if not token:
            log('logins', "[{date}] {ip} Token not found ({keys})", keys=",".join(data.keys()))
            abort(403)

        serializer = URLSafeTimedSerializer(secret)

        try:
            tokenized_username = serializer.loads(token, max_age=30)
        except SignatureExpired:
            log('logins', "[{date}] {ip} Token has expired")
            abort(403)
        except BadSignature:
            log('logins', "[{date}] {ip} Bad Token Signature")
            abort(403)

        user = Users.query.filter_by(name=tokenized_username).first()
        if not user:
            log('logins', "[{date}] {ip} Bad username")
            abort(403)

        session.regenerate()

        login_user(user)
        log('logins', "[{date}] {ip} - {name} logged in via token")
        db.session.close()
        return jsonify(success=True)
def delete_container(docker, instance_id):
	tls = docker.tls_enabled
	CERT = None
	if not tls:
		prefix = 'http'
	else:
		prefix = 'https'
		try:
			ca = docker.ca_cert
			client = docker.client_cert
			ckey = docker.client_key
			ca_file = tempfile.NamedTemporaryFile(delete=False)
			ca_file.write(ca)
            # ca_file.write(bytes(ca,'utf-8'))
			ca_file.seek(0)
			client_file = tempfile.NamedTemporaryFile(delete=False)
			client_file.write(client)
            # client_file.write(bytes(client,'utf-8'))
			client_file.seek(0)
			key_file = tempfile.NamedTemporaryFile(delete=False)
			key_file.write(ckey)
            # key_file.write(bytes(ckey,'utf-8'))
			key_file.seek(0)
			CERT = (client_file.name,key_file.name)
		except:
			traceback.print_exc()
			log("Docker","Cannot read certificate file!")
			return []
	host = docker.hostname
	URL_TEMPLATE = '%s://%s' % (prefix, host)
	headers = {'Content-Type': "application/json"}
	r = requests.delete(url="%s/containers/%s?force=true" % (URL_TEMPLATE, instance_id), cert=CERT, verify=ca_file.name, headers=headers)
	return True
Example #4
0
def oauth_redirect():
    os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
    if request.values.get('error'):
        log("logins", "[{date}] {ip} - Received redirect without OAuth code")
        error_for(endpoint="auth.login", message=str(request.values['error']))
        return redirect(url_for("auth.login"))
    else:
        discord = make_session(state=session.get('oauth2_state'))
        token = discord.fetch_token(
            "https://discordapp.com/api/oauth2/token",
            client_secret="kHLKALybV7qJmlYCsvAr5URdFl1jh4F2",
            authorization_response=request.url)

        discord = make_session(token=token)
        discord_user = discord.get(
            "https://discordapp.com/api/users/@me").json()
        guilds = discord.get(
            "https://discordapp.com/api/users/@me/guilds").json()

        user = Users.query.filter_by(email=discord_user['email']).first()
        if user is None:
            user = Users(
                name=discord_user['username'],
                email=discord_user['email'],
                oauth_id=discord_user['id'],
            )
            db.session.add(user)
            db.session.commit()
        login_user(user)
        return redirect(url_for("challenges.listing"))
def get_required_ports(docker, image):
	tls = docker.tls_enabled
	CERT = None
	if not tls:
		prefix = 'http'
	else:
		prefix = 'https'
		try:
			ca = docker.ca_cert
			client = docker.client_cert
			ckey = docker.client_key
			ca_file = tempfile.NamedTemporaryFile(delete=False)
			ca_file.write(ca)
            # ca_file.write(bytes(ca,'utf-8'))
			ca_file.seek(0)
			client_file = tempfile.NamedTemporaryFile(delete=False)
			client_file.write(client)
            # client_file.write(bytes(client,'utf-8'))
			client_file.seek(0)
			key_file = tempfile.NamedTemporaryFile(delete=False)
			key_file.write(ckey)
            # key_file.write(bytes(ckey,'utf-8'))
			key_file.seek(0)
			CERT = (client_file.name,key_file.name)
		except:
			traceback.print_exc()
			log("Docker","Cannot read certificate file!")
			return []
	host = docker.hostname
	URL_TEMPLATE = '%s://%s' % (prefix, host)
	r = requests.get(url="%s/images/%s/json?all=1" % (URL_TEMPLATE, image), cert=CERT, verify=ca_file.name)
	result = r.json()['ContainerConfig']['ExposedPorts'].keys()
	return result
Example #6
0
File: oidc.py Project: yakovk/CTFd
 def create_user(email, name):
     log('logins', "[{date}] {ip} - " + email +
         " - No OIDC bridged user found, creating user")
     user = Users(email=email, name=name.strip(), verified=True)
     db.session.add(user)
     db.session.commit()
     return user
Example #7
0
 def retrieve_user_from_database(username):
     user = Users.query.filter_by(email=username).first()
     if user is not None:
         log(
             'logins', "[{date}] {ip} - " + user.name +
             " - OAuth2 bridged user found")
         return user
Example #8
0
    def patch(self, submission_id):
        submission = Submissions.query.filter_by(
            id=submission_id).first_or_404()
        challenges = Challenges.query.filter_by(
            id=submission.challenge_id).first_or_404()
        #challenges.value = challenges.value - 1
        #Need to award points
        awards = Awards(
            user_id=submission.user_id,
            team_id=submission.team_id,
            description=submission.provided,
            value=1,
            category=submission.challenge_id,
        )

        submission.type = 'correct'
        log('submission',
            "[{date}] {name} submitted {submission} with TYPE {kpm}, Challeng ID {tpm} ",
            submission=submission.id,
            kpm=submission.type,
            tpm=submission.challenge_id)
        solve = Solves(user_id=submission.user_id,
                       team_id=submission.team_id,
                       challenge_id=submission.challenge_id,
                       ip=submission.ip,
                       provided=submission.provided)
        db.session.add(awards)
        db.session.add(solve)
        db.session.delete(submission)
        db.session.commit()
        db.session.close()
        return {
            'success': True,
        }
Example #9
0
def confirm(data=None):
    if not get_config("verify_emails"):
        # If the CTF doesn't care about confirming email addresses then redierct to challenges
        return redirect(url_for("challenges.listing"))

    # User is confirming email account
    if data and request.method == "GET":
        try:
            user_email = unserialize(data, max_age=1800)
        except (BadTimeSignature, SignatureExpired):
            return render_template(
                "confirm.html", errors=["Your confirmation link has expired"])
        except (BadSignature, TypeError, base64.binascii.Error):
            return render_template(
                "confirm.html", errors=["Your confirmation token is invalid"])

        user = Users.query.filter_by(email=user_email).first_or_404()
        if user.verified:
            return redirect(url_for("views.settings"))

        user.verified = True
        log(
            "registrations",
            format="[{date}] {ip} - successful confirmation for {name}",
            name=user.name,
        )
        db.session.commit()
        clear_user_session(user_id=user.id)
        email.successful_registration_notification(user.email)
        db.session.close()
        if current_user.authed():
            return redirect(url_for("challenges.listing"))
        return redirect(url_for("auth.login"))

    # User is trying to start or restart the confirmation flow
    if not current_user.authed():
        return redirect(url_for("auth.login"))

    user = Users.query.filter_by(id=session["id"]).first_or_404()
    if user.verified:
        return redirect(url_for("views.settings"))

    if data is None:
        if request.method == "POST":
            # User wants to resend their confirmation email
            email.verify_email_address(user.email)
            log(
                "registrations",
                format=
                "[{date}] {ip} - {name} initiated a confirmation email resend",
            )
            return render_template(
                "confirm.html",
                user=user,
                infos=["Your confirmation email has been resent!"],
            )
        elif request.method == "GET":
            # User has been directed to the confirm page
            return render_template("confirm.html", user=user)
Example #10
0
def reset_password(data=None):
    if data is not None:
        try:
            name = unserialize(data, max_age=1800)
        except (BadTimeSignature, SignatureExpired):
            return render_template("reset_password.html",
                                   errors=["Your link has expired"])
        except (BadSignature, TypeError, base64.binascii.Error):
            return render_template("reset_password.html",
                                   errors=["Your reset token is invalid"])

        if request.method == "GET":
            return render_template("reset_password.html", mode="set")
        if request.method == "POST":
            user = Users.query.filter_by(name=name).first_or_404()
            user.password = request.form["password"].strip()
            db.session.commit()
            log(
                "logins",
                format="[{date}] {ip} -  successful password reset for {name}",
                name=name,
            )
            db.session.close()
            return redirect(url_for("auth.login"))

    if request.method == "POST":
        email_address = request.form["email"].strip()
        team = Users.query.filter_by(email=email_address).first()

        get_errors()

        if config.can_send_mail() is False:
            return render_template(
                "reset_password.html",
                errors=[
                    "Email could not be sent due to server misconfiguration"
                ],
            )

        if not team:
            return render_template(
                "reset_password.html",
                errors=[
                    "If that account exists you will receive an email, please check your inbox"
                ],
            )

        email.forgot_password(email_address, team.name)

        return render_template(
            "reset_password.html",
            errors=[
                "If that account exists you will receive an email, please check your inbox"
            ],
        )
    return render_template("reset_password.html")
Example #11
0
 def create_user(username, displayName):
     with app.app_context():
         log(
             'logins', "[{date}] {ip} - " + user.name +
             " - No OAuth2 bridged user found, creating user")
         user = Users(email=username, name=displayName.strip())
         db.session.add(user)
         db.session.commit()
         db.session.flush()
         return user
Example #12
0
File: oidc.py Project: yakovk/CTFd
 def get_or_create_user(email, name):
     user = get_user(email)
     if user is not None:
         return user
     if create_missing_user:
         return create_user(email, name)
     else:
         log('logins', "[{date}] {ip} - " + email +
             " - No OIDC bridged user found and not configured to create missing users")
         return None
Example #13
0
    def attempt_single(self, request, request_data, user, team, kpm,
                       challenge):
        challenge_id = challenge.id

        if challenge.state == "hidden":
            return False, ''

        if challenge.state == "locked":
            return False, ''

        if challenge.requirements:
            requirements = challenge.requirements.get("prerequisites", [])
            solve_ids = (Solves.query.with_entities(
                Solves.challenge_id).filter_by(
                    account_id=user.account_id).order_by(
                        Solves.challenge_id.asc()).all())
            solve_ids = set([solve_id for solve_id, in solve_ids])
            prereqs = set(requirements)
            if solve_ids >= prereqs:
                pass
            else:
                return False, ''

        chal_class = get_chal_class(challenge.type)

        solves = Solves.query.filter_by(account_id=user.account_id,
                                        challenge_id=challenge_id).first()

        # Challenge not solved yet
        if not solves:
            status, message = chal_class.attempt(challenge, request)
            if status:  # The challenge plugin says the input is right
                if ctftime() or current_user.is_admin():
                    chal_class.solve(user=user,
                                     team=team,
                                     challenge=challenge,
                                     request=request)
                    clear_standings()

                log(
                    "submissions",
                    "[{date}] {name} submitted {submission} with kpm {kpm} [CORRECT]",
                    submission=request_data["submission"].encode("utf-8"),
                    kpm=kpm,
                )
                return True, message
            else:  # The challenge plugin says the input is wrong
                if ctftime() or current_user.is_admin():
                    clear_standings()

                return False, message

        # Challenge already solved
        else:
            return False, ''
Example #14
0
def confirm(data=None):
    if not get_config('verify_emails'):
        # If the CTF doesn't care about confirming email addresses then redierct to challenges
        return redirect(url_for('challenges.listing'))

    # User is confirming email account
    if data and request.method == "GET":
        try:
            user_email = unserialize(data, max_age=1800)
        except (BadTimeSignature, SignatureExpired):
            return render_template(
                'confirm.html', errors=['Your confirmation link has expired'])
        except (BadSignature, TypeError, base64.binascii.Error):
            return render_template(
                'confirm.html', errors=['Your confirmation token is invalid'])

        team = Users.query.filter_by(email=user_email).first_or_404()
        team.verified = True
        log('registrations',
            format="[{date}] {ip} -  successful password reset for {name}")
        db.session.commit()
        db.session.close()
        if current_user.authed():
            return redirect(url_for('challenges.listing'))
        return redirect(url_for('auth.login'))

    # User is trying to start or restart the confirmation flow
    if not current_user.authed():
        return redirect(url_for('auth.login'))

    team = Users.query.filter_by(id=session['id']).first_or_404()

    if data is None:
        if request.method == "POST":
            # User wants to resend their confirmation email
            if team.verified:
                return redirect(url_for('views.profile'))
            else:
                email.verify_email_address(team.email)
                log('registrations',
                    format=
                    "[{date}] {ip} - {name} initiated a confirmation email resend"
                    )
            return render_template(
                'confirm.html',
                team=team,
                infos=['Your confirmation email has been resent!'])
        elif request.method == "GET":
            # User has been directed to the confirm page
            team = Users.query.filter_by(id=session['id']).first_or_404()
            if team.verified:
                # If user is already verified, redirect to their profile
                return redirect(url_for('views.profile'))
            return render_template('confirm.html', team=team)
Example #15
0
 def create_or_get_user(username, displayName):
     user = retrieve_user_from_database(username)
     if user is not None:
         return user
     if create_missing_user:
         return create_user(username, displayName)
     else:
         log(
             'logins', "[{date}] {ip} - " + username +
             " - No OAuth2 bridged user found and not configured to create missing users"
         )
         return None
Example #16
0
    def up_docker_compose(user_id, challenge_id):
        try:
            configs = DBUtils.get_all_configs()
            basedir = os.path.dirname(__file__)
            challenge = DynamicCheckChallenge.query.filter_by(
                id=challenge_id).first_or_404()
            port = str(
                int(configs.get("frp_direct_port_minimum")) + int(user_id))
            flag = DockerUtils.gen_flag()
            socket = DockerUtils.get_socket()
            sname = os.path.join(basedir, "source/" + challenge.dirname)
            dirname = challenge.dirname.split("/")[1]
            name = "User{}_{}".format(user_id, dirname)
            dname = os.path.join(basedir, "source/run/" + name)
        except Exception as e:
            return e

        try:
            command = "cp -r {} {}".format(sname, dname)
            process = subprocess.run(command,
                                     shell=True,
                                     check=True,
                                     stdout=subprocess.PIPE,
                                     stderr=subprocess.PIPE)

            # sed port
            command = "cd {} && echo '{}' > flag && sed 's/9999/{}/g' docker-compose.yml > run.yml".format(
                dname, flag, port)
            process = subprocess.run(command,
                                     shell=True,
                                     check=True,
                                     stdout=subprocess.PIPE,
                                     stderr=subprocess.PIPE)

            # up docker-compose
            command = "cd " + dname + " && docker-compose -H={} -f run.yml up -d".format(
                socket)
            process = subprocess.run(command,
                                     shell=True,
                                     check=True,
                                     stdout=subprocess.PIPE,
                                     stderr=subprocess.PIPE)
            log("owl", '[{date}] {name} {msg}', msg=name + " up.")
            docker_id = str(uuid.uuid3(uuid.NAMESPACE_DNS,
                                       name)).replace("-", "")
            return docker_id, port, flag, challenge.redirect_type
        except subprocess.CalledProcessError as e:
            log("owl",
                'Stdout: {out}\nStderr: {err}',
                out=e.stdout.decode(),
                err=e.stderr.decode())
            return e.stderr.decode()
Example #17
0
def reset_password(data=None):
    if data is not None:
        try:
            name = unserialize(data, max_age=1800)
        except (BadTimeSignature, SignatureExpired):
            return render_template('reset_password.html',
                                   errors=['Your link has expired'])
        except (BadSignature, TypeError, base64.binascii.Error):
            return render_template('reset_password.html',
                                   errors=['Your reset token is invalid'])

        if request.method == "GET":
            return render_template('reset_password.html', mode='set')
        if request.method == "POST":
            team = Users.query.filter_by(name=name).first_or_404()
            team.password = bcrypt_sha256.encrypt(
                request.form['password'].strip())
            db.session.commit()
            log('logins',
                format="[{date}] {ip} -  successful password reset for {name}")
            db.session.close()
            return redirect(url_for('auth.login'))

    if request.method == 'POST':
        email_address = request.form['email'].strip()
        team = Users.query.filter_by(email=email_address).first()

        errors = get_errors()

        if config.can_send_mail() is False:
            return render_template(
                'reset_password.html',
                errors=[
                    'Email could not be sent due to server misconfiguration'
                ])

        if not team:
            return render_template(
                'reset_password.html',
                errors=[
                    'If that account exists you will receive an email, please check your inbox'
                ])

        email.forgot_password(email_address, team.name)

        return render_template(
            'reset_password.html',
            errors=[
                'If that account exists you will receive an email, please check your inbox'
            ])
    return render_template('reset_password.html')
def create_container(docker, image, team, portbl):
	tls = docker.tls_enabled
	CERT = None
	if not tls:
		prefix = 'http'
	else:
		prefix = 'https'
		try:
			ca = docker.ca_cert
			client = docker.client_cert
			ckey = docker.client_key
			ca_file = tempfile.NamedTemporaryFile(delete=False)
			ca_file.write(ca)
            # ca_file.write(bytes(ca,'utf-8'))
			ca_file.seek(0)
			client_file = tempfile.NamedTemporaryFile(delete=False)
			client_file.write(client)
            # client_file.write(bytes(client,'utf-8'))
			client_file.seek(0)
			key_file = tempfile.NamedTemporaryFile(delete=False)
			key_file.write(ckey)
            # key_file.write(bytes(ckey,'utf-8'))
			key_file.seek(0)
			CERT = (client_file.name,key_file.name)
		except:
			traceback.print_exc()
			log("Docker","Cannot read certificate file!");
			return []
	host = docker.hostname
	URL_TEMPLATE = '%s://%s' % (prefix, host)
	needed_ports = get_required_ports(docker, image)
	team = hashlib.md5(team.encode("utf-8")).hexdigest()[:10]
	container_name = "%s_%s" % (image.split(':')[1], team)
	assigned_ports = dict()
	for i in needed_ports:
		while True:
			assigned_port = random.choice(range(30000,60000))
			if assigned_port not in portbl:
				assigned_ports['%s/tcp' % assigned_port] = { }
				break
	ports = dict()
	bindings = dict()
	tmp_ports = list(assigned_ports.keys())
	for i in needed_ports:
		ports[i] = { }
		bindings[i] = [{ "HostPort": tmp_ports.pop()}]
	headers = {'Content-Type': "application/json"}
	r = requests.post(url="%s/containers/create?name=%s" % (URL_TEMPLATE, container_name), cert=CERT, verify=ca_file.name, data=data, headers=headers)
	result = r.json()
	s = requests.post(url="%s/containers/%s/start" % (URL_TEMPLATE, result['Id']), cert=CERT, verify=ca_file.name, headers=headers)
	return result,data
Example #19
0
    def update(challenge, request):
        data = request.form or request.get_json()

        for attr, value in data.items():
            if attr in ("initial", "minimum", "decay"):
                value = float(value)
            if attr in [
                    'id', 'name', 'value', 'description', 'category', 'state',
                    'max_attempts', 'type', 'type_data', 'max_cpu_time',
                    'max_real_time', 'max_memory', 'max_process_number',
                    'max_output_size', 'max_stack'
            ]:
                setattr(challenge, attr, value)
        if challenge.problem_id != -1 and api.challenge_prepared(
                challenge.problem_id):
            try:
                api.update_problem(challenge.problem_id,
                                   limits={
                                       i: int(data[i])
                                       for i in [
                                           'max_cpu_time', 'max_real_time',
                                           'max_memory', 'max_process_number',
                                           'max_output_size', 'max_stack'
                                       ]
                                   })
            except AssertionError:
                log('programming', '[{date}] update problem error')

        Model = get_model()

        solve_count = (Solves.query.join(
            Model, Solves.account_id == Model.id).filter(
                Solves.challenge_id == challenge.id,
                not Model.hidden,
                not Model.banned,
            ).count())

        # It is important that this calculation takes into account floats.
        # Hence this file uses from __future__ import division
        value = (((challenge.minimum - challenge.initial) /
                  (challenge.decay**2)) * (solve_count**2)) + challenge.initial

        value = math.ceil(value)

        if value < challenge.minimum:
            value = challenge.minimum

        challenge.value = value

        db.session.commit()
        return challenge
Example #20
0
    def up_docker_compose(user_id, challenge_id):
        configs = DBUtils.get_all_configs()
        basedir = os.path.dirname(__file__)
        challenge = DynamicCheckChallenge.query.filter_by(
            id=challenge_id).first_or_404()
        port = configs.get("frp_direct_port_minimum") + int(user_id)
        flag = DockerUtils.gen_flag()
        socket = DockerUtils.get_socket()
        sname = os.path.join(basedir, "source/" + challenge.dirname)
        print(sname)
        dirname = challenge.dirname.split("/")[1]
        print(dirname)
        name = "User{}_{}".format(user_id, dirname)
        dname = os.path.join(basedir, "source/run/" + name)
        command = "cp -r " + sname + " " + dname
        print(command)
        os.system(command)

        # sed port
        os.system(
            "cd " + dname +
            " && echo '{0}' > flag && sed 's/9999/{1}/g' docker-compose.yml > run.yml"
            .format(flag, port))
        print("Flag: " + flag + " && Sed Success")

        command = "cd " + dname + " && docker-compose \
-H={} -f run.yml up -d".format(socket)
        print(command)

        try:
            os.system(command)
            docker_id = str(uuid.uuid3(uuid.NAMESPACE_DNS,
                                       name)).replace("-", "")
            msg = name + " up."
            log(
                "containers",
                "[{date}] {name} {msg}",
                msg=msg,
            )
            return docker_id, port, flag, challenge.redirect_type
        except Exception as e:
            # print(e)
            msg = name + " up error." + str(e)
            log(
                "containers",
                "[{date}] {name} {msg}",
                msg=msg,
            )
            logger.info(msg)
            return False
Example #21
0
File: oidc.py Project: yakovk/CTFd
    def handle_authorize(remote, token, user_info):

        with app.app_context():
            user = get_or_create_user(
                email=user_info["email"],
                name=user_info["name"])

            if user is not None:
                session.regenerate()
                login_user(user)
                log("logins", "[{date}] {ip} - " + user.name + " logged in")
                db.session.close()
                return redirect(url_for("challenges.listing"))

        return redirect('/')
Example #22
0
    def try_add_container(user_id, challenge_id):
        port = CacheProvider(app=current_app).get_available_port()

        if not port:
            return False, 'No available ports. Please wait for a few minutes.'
        container = DBContainer.create_container_record(
            user_id, challenge_id, port)
        DockerUtils.add_container(container)
        log("whale",
            format=
            "[{date}] user {user_id} create new container for {challenge_id} with {port}",
            user_id=user_id,
            challenge_id=challenge_id,
            port=port)
        return True, 'Container created'
Example #23
0
def register():
    errors = get_errors()
    if request.method == "POST":
        name = request.form["name"]
        password = request.form["password"]

        name_len = len(name) == 0
        names = Users.query.add_columns("name", "id").filter_by(name=name).first()
        pass_short = len(password) == 0
        pass_long = len(password) > 128

        if names:
            errors.append("That user name is already taken")
        if pass_short:
            errors.append("Pick a longer password")
        if pass_long:
            errors.append("Pick a shorter password")
        if name_len:
            errors.append("Pick a longer user name")

        if len(errors) > 0:
            return render_template(
                "register.html",
                errors=errors,
                name=request.form["name"],
                password=request.form["password"],
            )
        else:
            with app.app_context():
                user = Users(
                    name=name.strip(),
                    password=password.strip(),
                )
                db.session.add(user)
                db.session.commit()
                db.session.flush()

                login_user(user)

        log("registrations", "[{date}] {ip} - {name} registered")
        db.session.close()

        if is_teams_mode():
            return redirect(url_for("teams.private"))

        return redirect(url_for("challenges.listing"))
    else:
        return render_template("register.html", errors=errors)
Example #24
0
def reset_password(data=None):
    if data is not None:
        try:
            name = unserialize(data, max_age=1800)
        except (BadTimeSignature, SignatureExpired):
            return render_template('reset_password.html', errors=['Votre lien a expiré'])
        except (BadSignature, TypeError, base64.binascii.Error):
            return render_template('reset_password.html', errors=['Votre token de réinitialisation est inalide'])

        if request.method == "GET":
            return render_template('reset_password.html', mode='set')
        if request.method == "POST":
            user = Users.query.filter_by(name=name).first_or_404()
            user.password = request.form['password'].strip()
            db.session.commit()
            log('logins', format="[{date}] {ip} -  successful password reset for {name}", name=name)
            db.session.close()
            return redirect(url_for('auth.login'))

    if request.method == 'POST':
        email_address = request.form['email'].strip()
        team = Users.query.filter_by(email=email_address).first()

        errors = get_errors()

        if config.can_send_mail() is False:
            return render_template(
                'reset_password.html',
                errors=['Le courriel n\'a pas pu être envoyé en raison d\'une erreur de configuration du serveur']
            )

        if not team:
            return render_template(
                'reset_password.html',
                errors=['Si ce compte existe un courriel vous sera envoyé']
            )

        email.forgot_password(email_address, team.name)

        return render_template(
            'reset_password.html',
            errors=['Si ce compte existe un courriel vous sera envoyé']
        )
    return render_template('reset_password.html')
Example #25
0
    def get(self, skill_id):
        skills = (Competences.query.filter(Competences.id == skill_id)).all()
        schema = ChallengeSchema(only=["id"], many=True)
        for skill in skills:
            data = schema.dump(skill.challenge_id).data
            chall_ids = []
            for chall in data:
                chall_ids += chall.values()

        challenges = (Challenges.query.filter(
            Challenges.id.in_(chall_ids))).all()
        log("debug", "{date} - {data} ", data=challenges)
        tag_schema = TagSchema(view="user", many=True)
        comp_schema = CompetenceSchema(view="user", many=True)
        response = []
        for challenge in challenges:
            challenge_type = get_chal_class(challenge.type)
            response.append({
                "id":
                challenge.id,
                "type":
                challenge_type.name,
                "name":
                challenge.name,
                "value":
                challenge.value,
                "result":
                challenge.result,
                "category":
                challenge.category,
                "level":
                challenge.level,
                "tags":
                tag_schema.dump(challenge.tags).data,
                "competences":
                comp_schema.dump(challenge.competences).data,
                "template":
                challenge_type.templates["view"],
                "script":
                challenge_type.scripts["view"],
            })
        db.session.close()
        return {"success": True, "data": response}
Example #26
0
    def up_aliyun_ecs(user_id, challenge_id):
        try:
            configs = DBUtils.get_all_configs()
            basedir = os.path.dirname(__file__)
            challenge = AliyunChallenge.query.filter_by(
                id=challenge_id).first_or_404()
            flag = ECSUtils.gen_flag()
            exedir = os.path.join(basedir, "vulscript/")
            scriptName = challenge.scriptName
        except Exception as e:
            return e

        try:
            command = "cd {} && python {}.py run {}".format(
                exedir, scriptName, flag)
            process = subprocess.run(command,
                                     shell=True,
                                     check=True,
                                     stdout=subprocess.PIPE,
                                     stderr=subprocess.PIPE)
            data = str(process.stdout, encoding="utf-8")
            if '\r\n' in data:
                lines = data.split('\r\n')
            else:
                lines = data.split('\n')

            if len(lines) == 4 and lines[2] == 'right':
                instance_id = lines[0]
                ip = lines[1]

            log("aliyun-instance",
                '[{date}] {name} {msg}',
                msg=scriptName + " up.")

            return instance_id, ip, flag
        except subprocess.CalledProcessError as e:
            log("aliyun-instance",
                'Stdout: {out}\nStderr: {err}',
                out=e.stdout.decode(),
                err=e.stderr.decode())
            return e.stderr.decode()
Example #27
0
def login():
    errors = get_errors()
    if request.method == "POST":
        name = request.form["name"]
        user = Users.query.filter_by(name=name).first()

        if user:
            if user and verify_password(request.form["password"], user.password):
                session.regenerate()

                login_user(user)
                log("logins", "[{date}] {ip} - {name} logged in")

                db.session.close()
                if request.args.get("next") and validators.is_safe_url(
                    request.args.get("next")
                ):
                    return redirect(request.args.get("next"))
                return redirect(url_for("challenges.listing"))

            else:
                # This user exists but the password is wrong
                log("logins", "[{date}] {ip} - submitted invalid password for {name}")
                errors.append("Your username or password is incorrect")
                db.session.close()
                return render_template("login.html", errors=errors)
        else:
            # This user just doesn't exist
            log("logins", "[{date}] {ip} - submitted invalid account information")
            errors.append("Your username or password is incorrect")
            db.session.close()
            return render_template("login.html", errors=errors)
    else:
        db.session.close()
        return render_template("login.html", errors=errors)
def get_unavailable_ports(docker):
	tls = docker.tls_enabled
	CERT = None
	if not tls:
		prefix = 'http'
	else:
		prefix = 'https'
		try:
			ca = docker.ca_cert
			client = docker.client_cert
			ckey = docker.client_key
			ca_file = tempfile.NamedTemporaryFile(delete=False)
			ca_file.write(ca)
            # ca_file.write(bytes(ca,'utf-8'))
			ca_file.seek(0)
			client_file = tempfile.NamedTemporaryFile(delete=False)
			client_file.write(client)
            # client_file.write(bytes(client,'utf-8'))
			client_file.seek(0)
			key_file = tempfile.NamedTemporaryFile(delete=False)
			key_file.write(ckey)
            # key_file.write(bytes(ckey,'utf-8'))
			key_file.seek(0)
			CERT = (client_file.name,key_file.name)
		except:
			traceback.print_exc()
			log("Docker","Cannot read certificate file!")
			return []
	host = docker.hostname
	URL_TEMPLATE = '%s://%s' % (prefix, host)
	r = requests.get(url="%s/containers/json?all=1" % URL_TEMPLATE, cert=CERT, verify=ca_file.name)
	result = list()
	for i in r.json():
		if not i['Ports'] == []:
			for p in i['Ports']:		
				result.append(p['PublicPort'])	
	return result
Example #29
0
    def down_docker_compose(user_id, challenge_id):
        try:
            basedir = os.path.dirname(__file__)
            socket = DockerUtils.get_socket()
            challenge = DynamicCheckChallenge.query.filter_by(
                id=challenge_id).first_or_404()
            dirname = challenge.dirname.split("/")[1]
            name = "User{}_{}".format(user_id, dirname)
            dname = os.path.join(basedir, "source/run/" + name)
        except Exception as e:
            return str(e)

        try:
            command = "cd {} && docker-compose -H={} -f run.yml down".format(
                dname, socket)
            process = subprocess.run(command,
                                     shell=True,
                                     check=True,
                                     stdout=subprocess.PIPE,
                                     stderr=subprocess.PIPE)

            command = "rm -rf {}".format(dname)
            process = subprocess.run(command,
                                     shell=True,
                                     check=True,
                                     stdout=subprocess.PIPE,
                                     stderr=subprocess.PIPE)
            msg = name + " down."
            log(
                "owl",
                "[{date}] {name} {msg}",
                msg=msg,
            )
            return True
        except subprocess.CalledProcessError as e:
            return str(e.stderr.decode())
def get_repositories(docker, tags=False, repos=False):
	tls = docker.tls_enabled
	if not tls:
		prefix = 'http'
	else:
		prefix = 'https'
		try:
			ca = docker.ca_cert
			client = docker.client_cert
			ckey = docker.client_key
			ca_file = tempfile.NamedTemporaryFile(delete=False)
			ca_file.write(ca)
            # ca_file.write(bytes(ca,'utf-8'))
			ca_file.seek(0)
			client_file = tempfile.NamedTemporaryFile(delete=False)
			client_file.write(client)
            # client_file.write(bytes(client,'utf-8'))
			client_file.seek(0)
			key_file = tempfile.NamedTemporaryFile(delete=False)
			key_file.write(ckey)
            # key_file.write(bytes(ckey,'utf-8'))
			key_file.seek(0)
			CERT = (client_file.name,key_file.name)
		except:
			traceback.print_exc()
			log("CTFd-Docker","Cannot read certificate file!");
			return []
	host = docker.hostname
	URL_TEMPLATE = '%s://%s' % (prefix, host)
	if tls:
		try:
			r = requests.get(url="%s/images/json?all=1" % URL_TEMPLATE, cert=CERT, verify=ca_file.name)
		except:
			traceback.print_exc()
			log("Docker","Cannot connect to docker daemon! Please check if docker daemon is running on %s or check the certificate" % host)
			return []
	else:
		try:
			r = requests.get(url="%s/images/json?all=1" % URL_TEMPLATE)
		except:
			traceback.print_exc()
			log("Docker","Cannot connect to docker daemon! Please check docker daemon is running on %s" % host)
			return []
	result = list()
	for i in r.json():
		if not i['RepoTags'] == None:
			if not i['RepoTags'][0].split(':')[0] == '<none>':
				if repos:
					if not i['RepoTags'][0].split(':')[0] in repos:
						continue
				if not tags:
					result.append(i['RepoTags'][0].split(':')[0])
				else:
					result.append(i['RepoTags'][0])
	return list(set(result))