120 lines
4.0 KiB
Python
120 lines
4.0 KiB
Python
import re
|
|
import time
|
|
from datetime import datetime
|
|
|
|
from flask import jsonify, render_template, request, redirect
|
|
|
|
from __init__ import app
|
|
import auth
|
|
import database
|
|
import reloader
|
|
from models import FlagStatus
|
|
|
|
|
|
@app.template_filter('timestamp_to_datetime')
|
|
def timestamp_to_datetime(s):
|
|
return datetime.fromtimestamp(s)
|
|
|
|
@app.route('/', methods=['GET', 'POST'])
|
|
def index_redirect():
|
|
if request.method == 'POST':
|
|
response = redirect('/')
|
|
response.set_cookie('password', request.form['password'])
|
|
return response
|
|
config = reloader.get_config()
|
|
if request.cookies.get('password') == config['SERVER_PASSWORD']:
|
|
return redirect('/farm')
|
|
return render_template('hello.html')
|
|
|
|
@app.route('/farm')
|
|
@auth.auth_required
|
|
def index():
|
|
distinct_values = {}
|
|
for column in ['sploit', 'status', 'team']:
|
|
rows = database.query('SELECT DISTINCT {} FROM flags ORDER BY {}'.format(column, column))
|
|
distinct_values[column] = [item[column] for item in rows] # Access by key, not index
|
|
|
|
config = reloader.get_config()
|
|
|
|
server_tz_name = time.strftime('%Z')
|
|
if server_tz_name.startswith('+'):
|
|
server_tz_name = 'UTC' + server_tz_name
|
|
|
|
return render_template('index.html',
|
|
flag_format=config['FLAG_FORMAT'],
|
|
distinct_values=distinct_values,
|
|
server_tz_name=server_tz_name)
|
|
|
|
|
|
FORM_DATETIME_FORMAT = '%Y-%m-%d %H:%M'
|
|
FLAGS_PER_PAGE = 30
|
|
|
|
@app.route('/ui/show_flags', methods=['POST'])
|
|
@auth.auth_required
|
|
def show_flags():
|
|
conditions = []
|
|
for column in ['sploit', 'status', 'team']:
|
|
value = request.form[column]
|
|
if value:
|
|
conditions.append(('{} = %s'.format(column), value))
|
|
for column in ['flag', 'checksystem_response']:
|
|
value = request.form[column]
|
|
if value:
|
|
conditions.append(('LOWER({}) LIKE %s'.format(column), '%' + value.lower() + '%')) # Changed INSTR to LIKE
|
|
for param in ['time-since', 'time-until']:
|
|
value = request.form[param].strip()
|
|
if value:
|
|
timestamp = round(datetime.strptime(value, FORM_DATETIME_FORMAT).timestamp())
|
|
sign = '>=' if param == 'time-since' else '<='
|
|
conditions.append(('time {} %s'.format(sign), timestamp))
|
|
page_number = int(request.form['page-number'])
|
|
if page_number < 1:
|
|
raise ValueError('Invalid page-number')
|
|
|
|
if conditions:
|
|
chunks, values = list(zip(*conditions))
|
|
conditions_sql = 'WHERE ' + ' AND '.join(chunks)
|
|
conditions_args = list(values)
|
|
else:
|
|
conditions_sql = ''
|
|
conditions_args = []
|
|
|
|
sql = 'SELECT * FROM flags ' + conditions_sql + ' ORDER BY time DESC LIMIT %s OFFSET %s'
|
|
args = conditions_args + [FLAGS_PER_PAGE, FLAGS_PER_PAGE * (page_number - 1)]
|
|
flags = database.query(sql, args)
|
|
|
|
sql = 'SELECT COUNT(*) as count FROM flags ' + conditions_sql # Added alias
|
|
args = conditions_args
|
|
total_count_result = database.query(sql, args)
|
|
total_count = total_count_result[0]['count'] if total_count_result else 0 # Access by key
|
|
|
|
return jsonify({
|
|
'rows': [dict(item) for item in flags],
|
|
'rows_per_page': FLAGS_PER_PAGE,
|
|
'total_count': total_count,
|
|
})
|
|
|
|
|
|
@app.route('/ui/post_flags_manual', methods=['POST'])
|
|
@auth.auth_required
|
|
def post_flags_manual():
|
|
config = reloader.get_config()
|
|
flags = re.findall(config['FLAG_FORMAT'], request.form['text'])
|
|
|
|
cur_time = round(time.time())
|
|
rows = [(item, 'Manual', '*', cur_time, FlagStatus.QUEUED.name)
|
|
for item in flags]
|
|
app.logger.info('Inserting flags: %s', rows)
|
|
|
|
# Use the execute function instead of direct db access
|
|
for row in rows:
|
|
database.execute(
|
|
"INSERT INTO flags (flag, sploit, team, time, status) VALUES (%s, %s, %s, %s, %s) ON CONFLICT (flag) DO NOTHING",
|
|
row
|
|
)
|
|
return ''
|
|
|
|
@app.route('/robots.txt', methods=['GET'])
|
|
def robots_txt():
|
|
return 'User-agent: *\nDisallow: /'
|