mirror of https://github.com/JohnHammond/CTFd.git
Admins can bypass ctftime (#374)
* Admins can see/solve challenges regardless of ctftime * Adding tests for ctftime based functionalityselenium-screenshot-testing
parent
bcaff30a7d
commit
6f60ddd2f5
|
@ -3,7 +3,7 @@ import logging
|
|||
import re
|
||||
import time
|
||||
|
||||
from flask import render_template, request, redirect, jsonify, url_for, session, Blueprint
|
||||
from flask import render_template, request, redirect, jsonify, url_for, session, Blueprint, abort
|
||||
from sqlalchemy.sql import or_
|
||||
|
||||
from CTFd.models import db, Challenges, Files, Solves, WrongKeys, Keys, Tags, Teams, Awards, Hints, Unlocks
|
||||
|
@ -104,7 +104,7 @@ def chals():
|
|||
if utils.view_after_ctf():
|
||||
pass
|
||||
else:
|
||||
return redirect(url_for('views.static_html'))
|
||||
abort(403)
|
||||
if utils.user_can_view_challenges() and (utils.ctf_started() or utils.is_admin()):
|
||||
chals = Challenges.query.filter(or_(Challenges.hidden != True, Challenges.hidden == None)).order_by(Challenges.value).all()
|
||||
json = {'game': []}
|
||||
|
@ -136,7 +136,7 @@ def chals():
|
|||
return jsonify(json)
|
||||
else:
|
||||
db.session.close()
|
||||
return redirect(url_for('auth.login', next='chals'))
|
||||
abort(403)
|
||||
|
||||
|
||||
@challenges.route('/chals/solves')
|
||||
|
@ -250,10 +250,10 @@ def who_solved(chalid):
|
|||
@challenges.route('/chal/<int:chalid>', methods=['POST'])
|
||||
def chal(chalid):
|
||||
if utils.ctf_ended() and not utils.view_after_ctf():
|
||||
return redirect(url_for('challenges.challenges_view'))
|
||||
abort(403)
|
||||
if not utils.user_can_view_challenges():
|
||||
return redirect(url_for('auth.login', next=request.path))
|
||||
if utils.authed() and utils.is_verified() and (utils.ctf_started() or utils.view_after_ctf()):
|
||||
if (utils.authed() and utils.is_verified() and (utils.ctf_started() or utils.view_after_ctf())) or utils.is_admin():
|
||||
fails = WrongKeys.query.filter_by(teamid=session['id'], chalid=chalid).count()
|
||||
logger = logging.getLogger('keys')
|
||||
data = (time.strftime("%m/%d/%Y %X"), session['username'].encode('utf-8'), request.form['key'].encode('utf-8'), utils.get_kpm(session['id']))
|
||||
|
@ -289,7 +289,7 @@ def chal(chalid):
|
|||
chal_class = get_chal_class(chal.type)
|
||||
status, message = chal_class.solve(chal, provided_key)
|
||||
if status: # The challenge plugin says the input is right
|
||||
if utils.ctftime():
|
||||
if utils.ctftime() or utils.is_admin():
|
||||
solve = Solves(teamid=session['id'], chalid=chalid, ip=utils.get_ip(), flag=provided_key)
|
||||
db.session.add(solve)
|
||||
db.session.commit()
|
||||
|
@ -297,7 +297,7 @@ def chal(chalid):
|
|||
logger.info("[{0}] {1} submitted {2} with kpm {3} [CORRECT]".format(*data))
|
||||
return jsonify({'status': 1, 'message': message})
|
||||
else: # The challenge plugin says the input is wrong
|
||||
if utils.ctftime():
|
||||
if utils.ctftime() or utils.is_admin():
|
||||
wrong = WrongKeys(teamid=session['id'], chalid=chalid, ip=utils.get_ip(), flag=provided_key)
|
||||
db.session.add(wrong)
|
||||
db.session.commit()
|
||||
|
@ -324,4 +324,4 @@ def chal(chalid):
|
|||
return jsonify({
|
||||
'status': -1,
|
||||
'message': "You must be logged in to solve a challenge"
|
||||
})
|
||||
}), 403
|
||||
|
|
|
@ -70,21 +70,21 @@
|
|||
|
||||
{% block content %}
|
||||
|
||||
{% if errors %}
|
||||
<div class="container main-container">
|
||||
<div id='errors' class="row">
|
||||
{% for error in errors %}
|
||||
<h1>{{ error }}</h1>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
|
||||
<div class="jumbotron home">
|
||||
<div class="container">
|
||||
<h1>Challenges</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if errors %}
|
||||
<div id='errors' class="row">
|
||||
{% for error in errors %}
|
||||
<h1>{{ error }}</h1>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if admin or not errors %}
|
||||
<div class="container main-container">
|
||||
<div id='challenges-board' class="row">
|
||||
</div>
|
||||
|
@ -113,6 +113,8 @@
|
|||
{% block scripts %}
|
||||
<script src="{{ request.script_root }}/themes/{{ ctf_theme() }}/static/js/utils.js"></script>
|
||||
<script src="{{ request.script_root }}/themes/{{ ctf_theme() }}/static/js/multi-modal.js"></script>
|
||||
{% if not errors %}<script src="{{ request.script_root }}/themes/{{ ctf_theme() }}/static/js/chalboard.js"></script>{% endif %}
|
||||
{% if admin or not errors %}
|
||||
<script src="{{ request.script_root }}/themes/{{ ctf_theme() }}/static/js/chalboard.js"></script>
|
||||
{% endif %}
|
||||
<script src="{{ request.script_root }}/themes/{{ ctf_theme() }}/static/js/style.js"></script>
|
||||
{% endblock %}
|
||||
|
|
|
@ -2,13 +2,14 @@
|
|||
|
||||
{% block content %}
|
||||
|
||||
<div class="row">
|
||||
<h1 class="text-center">403</h1>
|
||||
<h2 class="text-center">An authorization error has occured</h2>
|
||||
<h2 class="text-center">Please try again</h2>
|
||||
<div class="container main-container">
|
||||
<div class="row">
|
||||
<h1 class="text-center">403</h1>
|
||||
<h2 class="text-center">An authorization error has occured</h2>
|
||||
<h2 class="text-center">Please try again</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
|
|
|
@ -2,10 +2,12 @@
|
|||
|
||||
{% block content %}
|
||||
|
||||
<div class="row">
|
||||
<h1 class="text-center">404</h1>
|
||||
<h2 class="text-center">Whoops, looks like we can't find that.</h2>
|
||||
<h2 class="text-center">Sorry about that</h2>
|
||||
<div class="container main-container">
|
||||
<div class="row">
|
||||
<h1 class="text-center">404</h1>
|
||||
<h2 class="text-center">Whoops, looks like we can't find that.</h2>
|
||||
<h2 class="text-center">Sorry about that</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
|
|
@ -2,9 +2,11 @@
|
|||
|
||||
{% block content %}
|
||||
|
||||
<div class="row">
|
||||
<h1 class="text-center">500</h1>
|
||||
<h2 class="text-center">An Internal Server Error has occured</h2>
|
||||
<div class="container main-container">
|
||||
<div class="row">
|
||||
<h1 class="text-center">500</h1>
|
||||
<h2 class="text-center">An Internal Server Error has occured</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
|
|
@ -2,9 +2,11 @@
|
|||
|
||||
{% block content %}
|
||||
|
||||
<div class="row">
|
||||
<h1 class="text-center">502</h1>
|
||||
<h2 class="text-center">That action isn't allowed</h2>
|
||||
<div class="container main-container">
|
||||
<div class="row">
|
||||
<h1 class="text-center">502</h1>
|
||||
<h2 class="text-center">That action isn't allowed</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
from tests.helpers import *
|
||||
from CTFd.models import Teams
|
||||
from CTFd.utils import get_config, set_config, override_template, sendmail, verify_email, ctf_started, ctf_ended
|
||||
from freezegun import freeze_time
|
||||
from mock import patch
|
||||
|
||||
|
||||
def test_admin_panel():
|
||||
|
@ -72,3 +75,31 @@ def test_admin_config():
|
|||
r = client.get('/admin/config')
|
||||
assert r.status_code == 200
|
||||
destroy_ctfd(app)
|
||||
|
||||
|
||||
def test_admins_can_access_challenges_before_ctftime():
|
||||
'''Admins can see and solve challenges despite it being before ctftime'''
|
||||
app = create_ctfd()
|
||||
with app.app_context():
|
||||
set_config('start', '1507089600') # Wednesday, October 4, 2017 12:00:00 AM GMT-04:00 DST
|
||||
set_config('end', '1507262400') # Friday, October 6, 2017 12:00:00 AM GMT-04:00 DST
|
||||
register_user(app)
|
||||
chal = gen_challenge(app.db)
|
||||
chal_id = chal.id
|
||||
flag = gen_flag(app.db, chal=chal.id, flag=u'flag')
|
||||
|
||||
with freeze_time("2017-10-2"):
|
||||
client = login_as_user(app, name='admin', password='password')
|
||||
r = client.get('/chals')
|
||||
assert r.status_code == 200
|
||||
|
||||
with client.session_transaction() as sess:
|
||||
data = {
|
||||
"key": 'flag',
|
||||
"nonce": sess.get('nonce')
|
||||
}
|
||||
r = client.post('/chal/{}'.format(chal_id), data=data)
|
||||
assert r.status_code == 200
|
||||
solve_count = app.db.session.query(app.db.func.count(Solves.id)).first()[0]
|
||||
assert solve_count == 1
|
||||
destroy_ctfd(app)
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
from tests.helpers import *
|
||||
from CTFd.models import ip2long, long2ip
|
||||
from CTFd.utils import get_config, set_config, override_template, sendmail, verify_email
|
||||
from CTFd.utils import get_config, set_config, override_template, sendmail, verify_email, ctf_started, ctf_ended
|
||||
from CTFd.utils import base64encode, base64decode
|
||||
from freezegun import freeze_time
|
||||
from mock import patch
|
||||
|
@ -169,3 +169,127 @@ def test_verify_email(mock_smtp):
|
|||
# For now just assert that sendmail was called.
|
||||
mock_smtp.return_value.sendmail.assert_called_with(from_addr, [to_addr], email_msg.as_string())
|
||||
destroy_ctfd(app)
|
||||
|
||||
|
||||
def test_ctftime_prevents_accessing_challenges_before_ctf():
|
||||
"""Test that the ctftime function prevents users from accessing challenges after the ctf"""
|
||||
app = create_ctfd()
|
||||
with app.app_context():
|
||||
set_config('start', '1507089600') # Wednesday, October 4, 2017 12:00:00 AM GMT-04:00 DST
|
||||
set_config('end', '1507262400') # Friday, October 6, 2017 12:00:00 AM GMT-04:00 DST
|
||||
register_user(app)
|
||||
chal = gen_challenge(app.db)
|
||||
chal_id = chal.id
|
||||
flag = gen_flag(app.db, chal=chal.id, flag=u'flag')
|
||||
|
||||
with freeze_time("2017-10-3"):
|
||||
client = login_as_user(app)
|
||||
r = client.get('/chals')
|
||||
assert r.status_code == 403
|
||||
|
||||
with client.session_transaction() as sess:
|
||||
data = {
|
||||
"key": 'flag',
|
||||
"nonce": sess.get('nonce')
|
||||
}
|
||||
r = client.post('/chal/{}'.format(chal_id), data=data)
|
||||
assert r.status_code == 403
|
||||
solve_count = app.db.session.query(app.db.func.count(Solves.id)).first()[0]
|
||||
assert solve_count == 0
|
||||
destroy_ctfd(app)
|
||||
|
||||
|
||||
def test_ctftime_allows_accessing_challenges_during_ctf():
|
||||
"""Test that the ctftime function allows accessing challenges during the ctf"""
|
||||
app = create_ctfd()
|
||||
with app.app_context():
|
||||
set_config('start', '1507089600') # Wednesday, October 4, 2017 12:00:00 AM GMT-04:00 DST
|
||||
set_config('end', '1507262400') # Friday, October 6, 2017 12:00:00 AM GMT-04:00 DST
|
||||
register_user(app)
|
||||
chal = gen_challenge(app.db)
|
||||
chal_id = chal.id
|
||||
flag = gen_flag(app.db, chal=chal.id, flag=u'flag')
|
||||
|
||||
with freeze_time("2017-10-5"):
|
||||
client = login_as_user(app)
|
||||
r = client.get('/chals')
|
||||
assert r.status_code == 200
|
||||
|
||||
with client.session_transaction() as sess:
|
||||
data = {
|
||||
"key": 'flag',
|
||||
"nonce": sess.get('nonce')
|
||||
}
|
||||
r = client.post('/chal/{}'.format(chal_id), data=data)
|
||||
assert r.status_code == 200
|
||||
solve_count = app.db.session.query(app.db.func.count(Solves.id)).first()[0]
|
||||
assert solve_count == 1
|
||||
destroy_ctfd(app)
|
||||
|
||||
|
||||
def test_ctftime_prevents_accessing_challenges_after_ctf():
|
||||
"""Test that the ctftime function prevents accessing challenges after the ctf"""
|
||||
app = create_ctfd()
|
||||
with app.app_context():
|
||||
set_config('start', '1507089600') # Wednesday, October 4, 2017 12:00:00 AM GMT-04:00 DST
|
||||
set_config('end', '1507262400') # Friday, October 6, 2017 12:00:00 AM GMT-04:00 DST
|
||||
register_user(app)
|
||||
chal = gen_challenge(app.db)
|
||||
chal_id = chal.id
|
||||
flag = gen_flag(app.db, chal=chal.id, flag=u'flag')
|
||||
|
||||
with freeze_time("2017-10-7"):
|
||||
client = login_as_user(app)
|
||||
r = client.get('/chals')
|
||||
assert r.status_code == 403
|
||||
|
||||
with client.session_transaction() as sess:
|
||||
data = {
|
||||
"key": 'flag',
|
||||
"nonce": sess.get('nonce')
|
||||
}
|
||||
r = client.post('/chal/{}'.format(chal_id), data=data)
|
||||
assert r.status_code == 403
|
||||
solve_count = app.db.session.query(app.db.func.count(Solves.id)).first()[0]
|
||||
assert solve_count == 0
|
||||
destroy_ctfd(app)
|
||||
|
||||
|
||||
def test_ctf_started():
|
||||
'''Tests that the ctf_started function returns the correct value'''
|
||||
app = create_ctfd()
|
||||
with app.app_context():
|
||||
assert ctf_started() == True
|
||||
|
||||
set_config('start', '1507089600') # Wednesday, October 4, 2017 12:00:00 AM GMT-04:00 DST
|
||||
set_config('end', '1507262400') # Friday, October 6, 2017 12:00:00 AM GMT-04:00 DST
|
||||
|
||||
with freeze_time("2017-10-3"):
|
||||
assert ctf_started() == False
|
||||
|
||||
with freeze_time("2017-10-5"):
|
||||
assert ctf_started() == True
|
||||
|
||||
with freeze_time("2017-10-7"):
|
||||
assert ctf_started() == True
|
||||
destroy_ctfd(app)
|
||||
|
||||
|
||||
def test_ctf_ended():
|
||||
'''Tests that the ctf_ended function returns the correct value'''
|
||||
app = create_ctfd()
|
||||
with app.app_context():
|
||||
assert ctf_ended() == False
|
||||
|
||||
set_config('start', '1507089600') # Wednesday, October 4, 2017 12:00:00 AM GMT-04:00 DST
|
||||
set_config('end', '1507262400') # Friday, October 6, 2017 12:00:00 AM GMT-04:00 DST
|
||||
|
||||
with freeze_time("2017-10-3"):
|
||||
assert ctf_ended() == False
|
||||
|
||||
with freeze_time("2017-10-5"):
|
||||
assert ctf_ended() == False
|
||||
|
||||
with freeze_time("2017-10-7"):
|
||||
assert ctf_ended() == True
|
||||
destroy_ctfd(app)
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from CTFd.models import Teams, Solves, WrongKeys
|
||||
from CTFd.utils import get_config, set_config
|
||||
from CTFd import utils
|
||||
from tests.helpers import *
|
||||
from freezegun import freeze_time
|
||||
from mock import patch
|
||||
import json
|
||||
|
||||
|
||||
def test_user_get_challenges():
|
||||
"""Can a registered user load /challenges"""
|
||||
app = create_ctfd()
|
||||
with app.app_context():
|
||||
register_user(app)
|
||||
client = login_as_user(app)
|
||||
r = client.get('/challenges')
|
||||
assert r.status_code == 200
|
||||
destroy_ctfd(app)
|
||||
|
||||
|
||||
def test_user_get_chals():
|
||||
"""Can a registered user load /chals"""
|
||||
app = create_ctfd()
|
||||
with app.app_context():
|
||||
register_user(app)
|
||||
client = login_as_user(app)
|
||||
r = client.get('/chals')
|
||||
assert r.status_code == 200
|
||||
destroy_ctfd(app)
|
||||
|
||||
|
||||
def test_viewing_challenges():
|
||||
"""Test that users can see added challenges"""
|
||||
app = create_ctfd()
|
||||
with app.app_context():
|
||||
register_user(app)
|
||||
client = login_as_user(app)
|
||||
gen_challenge(app.db)
|
||||
r = client.get('/chals')
|
||||
chals = json.loads(r.get_data(as_text=True))
|
||||
assert len(chals['game']) == 1
|
||||
destroy_ctfd(app)
|
||||
|
||||
|
||||
def test_submitting_correct_flag():
|
||||
"""Test that correct flags are correct"""
|
||||
app = create_ctfd()
|
||||
with app.app_context():
|
||||
register_user(app)
|
||||
client = login_as_user(app)
|
||||
chal = gen_challenge(app.db)
|
||||
flag = gen_flag(app.db, chal=chal.id, flag='flag')
|
||||
with client.session_transaction() as sess:
|
||||
data = {
|
||||
"key": 'flag',
|
||||
"nonce": sess.get('nonce')
|
||||
}
|
||||
r = client.post('/chal/{}'.format(chal.id), data=data)
|
||||
assert r.status_code == 200
|
||||
resp = json.loads(r.data.decode('utf8'))
|
||||
assert resp.get('status') == 1 and resp.get('message') == "Correct"
|
||||
destroy_ctfd(app)
|
||||
|
||||
|
||||
def test_submitting_incorrect_flag():
|
||||
"""Test that incorrect flags are incorrect"""
|
||||
app = create_ctfd()
|
||||
with app.app_context():
|
||||
register_user(app)
|
||||
client = login_as_user(app)
|
||||
chal = gen_challenge(app.db)
|
||||
flag = gen_flag(app.db, chal=chal.id, flag='flag')
|
||||
with client.session_transaction() as sess:
|
||||
data = {
|
||||
"key": 'notflag',
|
||||
"nonce": sess.get('nonce')
|
||||
}
|
||||
r = client.post('/chal/{}'.format(chal.id), data=data)
|
||||
assert r.status_code == 200
|
||||
resp = json.loads(r.data.decode('utf8'))
|
||||
assert resp.get('status') == 0 and resp.get('message') == "Incorrect"
|
||||
destroy_ctfd(app)
|
||||
|
||||
|
||||
def test_submitting_unicode_flag():
|
||||
"""Test that users can submit a unicode flag"""
|
||||
app = create_ctfd()
|
||||
with app.app_context():
|
||||
register_user(app)
|
||||
client = login_as_user(app)
|
||||
chal = gen_challenge(app.db)
|
||||
flag = gen_flag(app.db, chal=chal.id, flag=u'你好')
|
||||
with client.session_transaction() as sess:
|
||||
data = {
|
||||
"key": '你好',
|
||||
"nonce": sess.get('nonce')
|
||||
}
|
||||
r = client.post('/chal/{}'.format(chal.id), data=data)
|
||||
assert r.status_code == 200
|
||||
resp = json.loads(r.data.decode('utf8'))
|
||||
assert resp.get('status') == 1 and resp.get('message') == "Correct"
|
||||
destroy_ctfd(app)
|
||||
|
||||
|
||||
def test_submitting_flags_with_large_ips():
|
||||
'''Test that users with high octect IP addresses can submit flags'''
|
||||
app = create_ctfd()
|
||||
with app.app_context():
|
||||
register_user(app)
|
||||
client = login_as_user(app)
|
||||
|
||||
# SQLite doesn't support BigInteger well so we can't test it properly
|
||||
ip_addresses = ['172.18.0.1', '255.255.255.255', '2001:0db8:85a3:0000:0000:8a2e:0370:7334']
|
||||
for ip_address in ip_addresses:
|
||||
# Monkeypatch get_ip
|
||||
utils.get_ip = lambda: ip_address
|
||||
|
||||
# Generate challenge and flag
|
||||
chal = gen_challenge(app.db)
|
||||
chal_id = chal.id
|
||||
flag = gen_flag(app.db, chal=chal.id, flag=u'correct_key')
|
||||
|
||||
# Submit wrong_key
|
||||
with client.session_transaction() as sess:
|
||||
data = {
|
||||
"key": 'wrong_key',
|
||||
"nonce": sess.get('nonce')
|
||||
}
|
||||
r = client.post('/chal/{}'.format(chal_id), data=data)
|
||||
assert r.status_code == 200
|
||||
resp = json.loads(r.data.decode('utf8'))
|
||||
assert resp.get('status') == 0 and resp.get('message') == "Incorrect"
|
||||
assert WrongKeys.query.filter_by(ip=ip_address).first()
|
||||
|
||||
# Submit correct key
|
||||
with client.session_transaction() as sess:
|
||||
data = {
|
||||
"key": 'correct_key',
|
||||
"nonce": sess.get('nonce')
|
||||
}
|
||||
r = client.post('/chal/{}'.format(chal_id), data=data)
|
||||
assert r.status_code == 200
|
||||
resp = json.loads(r.data.decode('utf8'))
|
||||
assert resp.get('status') == 1 and resp.get('message') == "Correct"
|
||||
assert Solves.query.filter_by(ip=ip_address).first()
|
||||
destroy_ctfd(app)
|
|
@ -141,28 +141,6 @@ def test_user_get_topteams():
|
|||
destroy_ctfd(app)
|
||||
|
||||
|
||||
def test_user_get_challenges():
|
||||
"""Can a registered user load /challenges"""
|
||||
app = create_ctfd()
|
||||
with app.app_context():
|
||||
register_user(app)
|
||||
client = login_as_user(app)
|
||||
r = client.get('/challenges')
|
||||
assert r.status_code == 200
|
||||
destroy_ctfd(app)
|
||||
|
||||
|
||||
def test_user_get_chals():
|
||||
"""Can a registered user load /chals"""
|
||||
app = create_ctfd()
|
||||
with app.app_context():
|
||||
register_user(app)
|
||||
client = login_as_user(app)
|
||||
r = client.get('/chals')
|
||||
assert r.status_code == 200
|
||||
destroy_ctfd(app)
|
||||
|
||||
|
||||
def test_user_get_solves_per_chal():
|
||||
"""Can a registered user load /chals/solves"""
|
||||
app = create_ctfd()
|
||||
|
@ -231,123 +209,6 @@ def test_user_get_reset_password():
|
|||
destroy_ctfd(app)
|
||||
|
||||
|
||||
def test_viewing_challenges():
|
||||
"""Test that users can see added challenges"""
|
||||
app = create_ctfd()
|
||||
with app.app_context():
|
||||
register_user(app)
|
||||
client = login_as_user(app)
|
||||
gen_challenge(app.db)
|
||||
r = client.get('/chals')
|
||||
chals = json.loads(r.get_data(as_text=True))
|
||||
assert len(chals['game']) == 1
|
||||
destroy_ctfd(app)
|
||||
|
||||
|
||||
def test_submitting_correct_flag():
|
||||
"""Test that correct flags are correct"""
|
||||
app = create_ctfd()
|
||||
with app.app_context():
|
||||
register_user(app)
|
||||
client = login_as_user(app)
|
||||
chal = gen_challenge(app.db)
|
||||
flag = gen_flag(app.db, chal=chal.id, flag='flag')
|
||||
with client.session_transaction() as sess:
|
||||
data = {
|
||||
"key": 'flag',
|
||||
"nonce": sess.get('nonce')
|
||||
}
|
||||
r = client.post('/chal/{}'.format(chal.id), data=data)
|
||||
assert r.status_code == 200
|
||||
resp = json.loads(r.data.decode('utf8'))
|
||||
assert resp.get('status') == 1 and resp.get('message') == "Correct"
|
||||
destroy_ctfd(app)
|
||||
|
||||
|
||||
def test_submitting_incorrect_flag():
|
||||
"""Test that incorrect flags are incorrect"""
|
||||
app = create_ctfd()
|
||||
with app.app_context():
|
||||
register_user(app)
|
||||
client = login_as_user(app)
|
||||
chal = gen_challenge(app.db)
|
||||
flag = gen_flag(app.db, chal=chal.id, flag='flag')
|
||||
with client.session_transaction() as sess:
|
||||
data = {
|
||||
"key": 'notflag',
|
||||
"nonce": sess.get('nonce')
|
||||
}
|
||||
r = client.post('/chal/{}'.format(chal.id), data=data)
|
||||
assert r.status_code == 200
|
||||
resp = json.loads(r.data.decode('utf8'))
|
||||
assert resp.get('status') == 0 and resp.get('message') == "Incorrect"
|
||||
destroy_ctfd(app)
|
||||
|
||||
|
||||
def test_submitting_unicode_flag():
|
||||
"""Test that users can submit a unicode flag"""
|
||||
app = create_ctfd()
|
||||
with app.app_context():
|
||||
register_user(app)
|
||||
client = login_as_user(app)
|
||||
chal = gen_challenge(app.db)
|
||||
flag = gen_flag(app.db, chal=chal.id, flag=u'你好')
|
||||
with client.session_transaction() as sess:
|
||||
data = {
|
||||
"key": '你好',
|
||||
"nonce": sess.get('nonce')
|
||||
}
|
||||
r = client.post('/chal/{}'.format(chal.id), data=data)
|
||||
assert r.status_code == 200
|
||||
resp = json.loads(r.data.decode('utf8'))
|
||||
assert resp.get('status') == 1 and resp.get('message') == "Correct"
|
||||
destroy_ctfd(app)
|
||||
|
||||
|
||||
def test_submitting_flags_with_large_ips():
|
||||
'''Test that users with high octect IP addresses can submit flags'''
|
||||
app = create_ctfd()
|
||||
with app.app_context():
|
||||
register_user(app)
|
||||
client = login_as_user(app)
|
||||
|
||||
# SQLite doesn't support BigInteger well so we can't test it properly
|
||||
ip_addresses = ['172.18.0.1', '255.255.255.255', '2001:0db8:85a3:0000:0000:8a2e:0370:7334']
|
||||
for ip_address in ip_addresses:
|
||||
# Monkeypatch get_ip
|
||||
utils.get_ip = lambda: ip_address
|
||||
|
||||
# Generate challenge and flag
|
||||
chal = gen_challenge(app.db)
|
||||
chal_id = chal.id
|
||||
flag = gen_flag(app.db, chal=chal.id, flag=u'correct_key')
|
||||
|
||||
# Submit wrong_key
|
||||
with client.session_transaction() as sess:
|
||||
data = {
|
||||
"key": 'wrong_key',
|
||||
"nonce": sess.get('nonce')
|
||||
}
|
||||
r = client.post('/chal/{}'.format(chal_id), data=data)
|
||||
assert r.status_code == 200
|
||||
resp = json.loads(r.data.decode('utf8'))
|
||||
assert resp.get('status') == 0 and resp.get('message') == "Incorrect"
|
||||
assert WrongKeys.query.filter_by(ip=ip_address).first()
|
||||
|
||||
# Submit correct key
|
||||
with client.session_transaction() as sess:
|
||||
data = {
|
||||
"key": 'correct_key',
|
||||
"nonce": sess.get('nonce')
|
||||
}
|
||||
r = client.post('/chal/{}'.format(chal_id), data=data)
|
||||
assert r.status_code == 200
|
||||
resp = json.loads(r.data.decode('utf8'))
|
||||
assert resp.get('status') == 1 and resp.get('message') == "Correct"
|
||||
assert Solves.query.filter_by(ip=ip_address).first()
|
||||
destroy_ctfd(app)
|
||||
|
||||
|
||||
def test_scoring_logic():
|
||||
"""Test that scoring logic is correct"""
|
||||
app = create_ctfd()
|
Loading…
Reference in New Issue