function dynamic_menu_content() { $cache_name = user_is_logged_in() ? 'logged_in_' . $_SESSION['class'] : 'guest'; if (cache_start($cache_name, CONFIG_CACHE_TIME_DYNAMIC, CONST_CACHE_DYNAMIC_MENU_GROUP)) { $entries = db_query_fetch_all('SELECT title, internal_page, permalink, url, visibility FROM dynamic_menu WHERE ' . (user_is_logged_in() ? 'min_user_class <= ' . $_SESSION['class'] . ' AND (visibility = "private" OR visibility = "both")' : 'visibility = "public" OR visibility = "both"') . ' ORDER BY priority DESC'); foreach ($entries as $entry) { echo ' <li> <a href="', $entry['internal_page'] ? CONFIG_SITE_URL . 'content?show=' . $entry['permalink'] : htmlspecialchars($entry['url']), '">', htmlspecialchars($entry['title']), '</a> </li> '; } cache_end($cache_name, CONST_CACHE_DYNAMIC_MENU_GROUP); } }
function json_scoreboard() { // generate a json scoreboard // this function is so hacky.. // could probably do with a rewrite $user_types = db_select_all('user_types', array('id', 'title AS category')); if (empty($user_types)) { $user_types = array(array('id' => 0, 'category' => 'all')); } for ($i = 0; $i < count($user_types); $i++) { $scores = db_query_fetch_all(' SELECT u.id AS user_id, u.team_name, u.competing, co.country_code, SUM(c.points) AS score, MAX(s.added) AS tiebreaker FROM users AS u LEFT JOIN countries AS co ON co.id = u.country_id LEFT JOIN submissions AS s ON u.id = s.user_id AND s.correct = 1 LEFT JOIN challenges AS c ON c.id = s.challenge WHERE u.competing = 1 AND u.user_type = :user_type GROUP BY u.id ORDER BY score DESC, tiebreaker ASC', array('user_type' => $user_types[$i]['id'])); unset($user_types[$i]['id']); for ($j = 0; $j < count($scores); $j++) { $user_types[$i]['teams'][htmlspecialchars($scores[$j]['team_name'])] = array('position' => $j + 1, 'score' => isset($scores[$j]['score']) ? $scores[$j]['score'] : 0, 'country' => $scores[$j]['country_code']); } } echo json_encode($user_types); }
function json_scoreboard($user_type = null) { $values = array(); if (is_valid_id($user_type)) { $values['user_type'] = $user_type; } $scores = db_query_fetch_all(' SELECT u.id AS user_id, u.team_name, co.country_code, SUM(c.points) AS score, MAX(s.added) AS tiebreaker FROM users AS u LEFT JOIN countries AS co ON co.id = u.country_id LEFT JOIN submissions AS s ON u.id = s.user_id AND s.correct = 1 LEFT JOIN challenges AS c ON c.id = s.challenge WHERE u.competing = 1 ' . (is_valid_id($user_type) ? 'AND u.user_type = :user_type' : '') . ' GROUP BY u.id ORDER BY score DESC, tiebreaker ASC', $values); $scoreboard = array(); for ($i = 0; $i < count($scores); $i++) { $scoreboard['standings'][$i] = array('pos' => $i + 1, 'team' => $scores[$i]['team_name'], 'score' => array_get($scores[$i], 'score', 0), 'country' => $scores[$i]['country_code']); } echo json_encode($scoreboard); }
<tbody> '; $query = 'SELECT INET_NTOA(ipl.ip) AS ip, ipl.added, ipl.last_used, ipl.times_used, u.team_name, u.id AS user_id FROM ip_log AS ipl LEFT JOIN users AS u ON ipl.user_id = u.id '; if (!empty($where)) { $query .= 'WHERE ' . implode('=? AND ', array_keys($where)) . '=? '; } $entries = db_query_fetch_all($query, array_values($where)); foreach ($entries as $entry) { echo ' <tr> <td> <a href="', CONFIG_SITE_ADMIN_URL, 'list_ip_log?user_id=', htmlspecialchars($entry['user_id']), '"> ', htmlspecialchars($entry['team_name']), ' </a> </td> <td><a href="', CONFIG_SITE_ADMIN_URL, 'list_ip_log?ip=', htmlspecialchars($entry['ip']), '">', htmlspecialchars(CONFIG_GET_IP_HOST_BY_ADDRESS ? gethostbyaddr($entry['ip']) : '<i>Lookup disabled in config</i>'), '</a></td> <td>', date_time($entry['added']), '</td> <td>', date_time($entry['last_used']), '</td> <td>', number_format($entry['times_used']), '</td> </tr> '; }
<th>Team name</th> <th>Added</th> <th>Flag</th> <th>Correct</th> <th>Manage</th> </tr> </thead> <tbody> '; $submissions = db_query_fetch_all(' SELECT s.id, u.id AS user_id, u.team_name, s.added, s.correct, s.flag, c.id AS challenge_id, c.title AS challenge_title ' . $query . ' ORDER BY s.added DESC LIMIT ' . $from . ', ' . $results_per_page, array_values($where)); foreach ($submissions as $submission) { echo ' <tr> <td><a href="', CONFIG_SITE_URL, 'challenge.php?id=', htmlspecialchars($submission['challenge_id']), '">', htmlspecialchars($submission['challenge_title']), '</a></td> <td><a href="', CONFIG_SITE_ADMIN_URL, 'user.php?id=', htmlspecialchars($submission['user_id']), '">', htmlspecialchars($submission['team_name']), '</a></td> <td>', time_elapsed($submission['added']), ' ago</td> <td>', htmlspecialchars($submission['flag']), '</td> <td> ', $submission['correct'] ? '<img src="' . CONFIG_SITE_URL_STATIC_RESOURCES . 'img/accept.png" alt="Correct!" title="Correct!" />' : '<img src="' . CONFIG_SITE_URL_STATIC_RESOURCES . 'img/stop.png" alt="Wrong!" title="Wrong!" />', '
GROUP BY u.id ORDER BY score DESC, tiebreaker ASC', array('user_type' => $user_type['id'])); scoreboard($scores); } } echo ' </div> <!-- / span6 --> <div class="col-lg-6"> '; section_head(lang_get('challenges')); $categories = db_query_fetch_all(' SELECT id, title, available_from, available_until FROM categories WHERE available_from < ' . $now . ' AND exposed = 1 ORDER BY title'); challenges($categories); echo ' </div> <!-- / span6 --> </div> <!-- / row --> '; cache_end(CONST_CACHE_NAME_SCORES); } foot();
<?php require '../../include/mellivora.inc.php'; enforce_authentication(CONST_USER_CLASS_MODERATOR); head('Site management'); menu_management(); check_server_configuration(); $categories = db_query_fetch_all('SELECT * FROM categories ORDER BY title'); if (empty($categories)) { message_generic('Welcome', 'Your CTF is looking a bit empty! Start by adding a category using the menu above.'); } section_subhead('CTF Overview', '<a href="' . CONFIG_SITE_ADMIN_URL . 'visualise">Visualise challenge availability</a>', false); foreach ($categories as $category) { echo ' <h4> ', htmlspecialchars($category['title']), ' <a href="edit_category.php?id=', htmlspecialchars($category['id']), '" class="btn btn-xs btn-primary">Edit category</a> <a href="new_challenge.php?category=', htmlspecialchars($category['id']), '" class="btn btn-xs btn-primary">Add challenge</a> </h4> '; $challenges = db_select_all('challenges', array('id', 'title', 'description', 'exposed', 'available_from', 'available_until', 'points'), array('category' => $category['id']), 'points ASC'); if (empty($challenges)) { message_inline_blue('This category is empty! Use the link above to add a challenge.'); } else { echo ' <table class="table table-striped table-hover"> <thead> <tr> <th>Title</th> <th>Description</th> <th class="center">Points</th>
if ($search_for) { $values['search_for_team_name'] = '%' . $search_for . '%'; $values['search_for_email'] = '%' . $search_for . '%'; } $from = get_pager_from($_GET); $num_users = db_count_num('users'); $results_per_page = 100; $users = db_query_fetch_all(' SELECT u.id, u.email, u.team_name, u.added, u.class, u.enabled, co.country_name, co.country_code, COUNT(ipl.id) AS num_ips FROM users AS u LEFT JOIN ip_log AS ipl ON ipl.user_id = u.id LEFT JOIN countries AS co ON co.id = u.country_id ' . ($search_for ? 'WHERE u.team_name LIKE :search_for_team_name OR u.email LIKE :search_for_email' : '') . (verifySA() ? '' : 'WHERE u.instanceID =' . $_SESSION["IID"]) . ' GROUP BY u.id ORDER BY u.team_name ASC LIMIT ' . $from . ', ' . $results_per_page, $values); pager(CONFIG_SITE_ADMIN_URL . 'list_users/', count($users), $results_per_page, $from); foreach ($users as $user) { echo ' <tr> <td> <a href="', CONFIG_SITE_URL, 'user?id=', htmlspecialchars($user['id']), '">', htmlspecialchars($user['team_name']), '</a> </td>
if (strlen(array_get($_GET, 'code')) != 2) { message_error(lang_get('please_supply_country_code')); } $country = db_select_one('countries', array('id', 'country_name', 'country_code'), array('country_code' => $_GET['code'])); if (!$country) { message_error(lang_get('please_supply_country_code')); } head($country['country_name']); if (cache_start(CONST_CACHE_NAME_COUNTRY . $_GET['code'], CONFIG_CACHE_TIME_COUNTRIES)) { section_head(htmlspecialchars($country['country_name']) . country_flag_link($country['country_name'], $country['country_code'], true), '', false); $scores = db_query_fetch_all(' SELECT u.id AS user_id, u.team_name, u.competing, co.id AS country_id, co.country_name, co.country_code, SUM(c.points) AS score, MAX(s.added) AS tiebreaker FROM users AS u LEFT JOIN countries AS co ON co.id = u.country_id LEFT JOIN submissions AS s ON u.id = s.user_id AND s.correct = 1 LEFT JOIN challenges AS c ON c.id = s.challenge WHERE u.competing = 1 AND co.id = :country_id GROUP BY u.id ORDER BY score DESC, tiebreaker ASC', array('country_id' => $country['id'])); scoreboard($scores); cache_end(CONST_CACHE_NAME_COUNTRY . $_GET['code']); } foot();
</thead> <tbody> '; $from = get_pager_from($_GET); $num_users = db_count_num('users'); $results_per_page = 100; pager(CONFIG_SITE_ADMIN_URL . 'list_users/', $num_users, $results_per_page, $from); $users = db_query_fetch_all(' SELECT u.id, u.email, u.team_name, u.added, u.class, u.enabled, co.country_name, co.country_code, COUNT(ipl.id) AS num_ips FROM users AS u LEFT JOIN ip_log AS ipl ON ipl.user_id = u.id LEFT JOIN countries AS co ON co.id = u.country_id GROUP BY u.id ORDER BY u.team_name ASC LIMIT ' . $from . ', ' . $results_per_page); foreach ($users as $user) { echo ' <tr> <td> ', country_flag_link($user['country_name'], $user['country_code']), ' <a href="', CONFIG_SITE_URL, 'user?id=', htmlspecialchars($user['id']), '">', htmlspecialchars($user['team_name']), '</a> </td>
function challenges($categories) { $now = time(); $num_participating_users = get_num_participating_users(); foreach ($categories as $category) { echo ' <table class="team-table table table-striped table-hover"> <thead> <tr> <th>', htmlspecialchars($category['title']), '</th> <th class="center">', lang_get('points'), '</th> <th class="center"><span class="has-tooltip" data-toggle="tooltip" data-placement="top" title="% of actively participating users">', lang_get('percentage_solvers'), '</span></th> <th>', lang_get('first_solvers'), '</th> </tr> </thead> <tbody> '; $challenges = db_query_fetch_all(' SELECT id, title, points, available_from FROM challenges WHERE available_from < ' . $now . ' AND category = :category AND exposed = 1 ORDER BY points ASC', array('category' => $category['id'])); foreach ($challenges as $challenge) { $num_solvers = db_count_num('submissions', array('correct' => 1, 'challenge' => $challenge['id'])); echo ' <tr> <td> <a href="challenge?id=', htmlspecialchars($challenge['id']), '">', htmlspecialchars($challenge['title']), '</a> </td> <td class="center"> ', number_format($challenge['points']), ' </td> <td class="center"> ', number_format($num_solvers / $num_participating_users * 100), '% </td> <td class="team-name">'; $users = db_query_fetch_all(' SELECT u.id, u.team_name FROM users AS u JOIN submissions AS s ON s.user_id = u.id WHERE u.competing = 1 AND s.correct = 1 AND s.challenge = :challenge ORDER BY s.added ASC LIMIT 3', array('challenge' => $challenge['id'])); if (count($users)) { $pos = 1; foreach ($users as $user) { echo get_position_medal($pos++), '<a href="user?id=', htmlspecialchars($user['id']), '">', htmlspecialchars($user['team_name']), '</a><br />'; } } else { echo '<i>', lang_get('unsolved'), '</i>'; } echo ' </td> </tr>'; } echo ' </tbody> </table>'; } }
e.id, e.message, e.added, e.added_by, e.trace, INET_NTOA(e.user_ip) AS user_ip, u.team_name FROM exceptions AS e LEFT JOIN users AS u ON u.id = e.added_by '; if (!empty($where)) { $query .= 'WHERE ' . implode('=? AND ', array_keys($where)) . '=? '; } $query .= 'ORDER BY e.id DESC LIMIT ' . $from . ', ' . CONST_NUM_EXCEPTIONS_PER_PAGE; $exceptions = db_query_fetch_all($query, array_values($where)); foreach ($exceptions as $exception) { echo ' <tr> <td>', htmlspecialchars($exception['message']), '</td> <td>', date_time($exception['added']), '</td> <td>', $exception['added_by'] ? '<a href="' . CONFIG_SITE_ADMIN_URL . 'user.php?id=' . htmlspecialchars($exception['added_by']) . '">' . htmlspecialchars($exception['team_name']) . '</a>' : '<i>N/A</i>', ' </td> <td><a href="', CONFIG_SITE_ADMIN_URL, 'list_ip_log.php?ip=', htmlspecialchars($exception['user_ip']), '">', htmlspecialchars($exception['user_ip']), '</a></td> </tr> <tr> <td colspan="4"> <pre>', nl2br(htmlspecialchars($exception['trace'])), ' </pre> </td> </tr> ';
<th>Added by</th> <th>Type</th> <th>Priority</th> <th>Enabled</th> <th>Manage</th> </tr> </thead> <tbody> '; $rules = db_query_fetch_all(' SELECT re.id, re.added, re.added_by, re.rule, re.enabled, re.white, re.priority, u.team_name FROM restrict_email AS re LEFT JOIN users AS u ON re.added_by = u.id ORDER BY re.priority ASC'); foreach ($rules as $rule) { echo ' <tr> <td>', htmlspecialchars($rule['rule']), '</td> <td>', date_time($rule['added']), '</td> <td>', htmlspecialchars($rule['team_name']), '</td> <td> ', $rule['white'] ? '<img src="' . CONFIG_SITE_URL_STATIC_RESOURCES . 'img/accept.png" alt="Whitelisted" title="Whitelisted" />' : '<img src="' . CONFIG_SITE_URL_STATIC_RESOURCES . 'img/stop.png" alt="Blacklisted" title="Blacklisted" />', ' </td>
<tr> <td> <a href="challenge?id=', htmlspecialchars($challenge['id']), '">', htmlspecialchars($challenge['title']), '</a> </td> <td> ', number_format($challenge['points']), ' </td> <td>'; $users = db_query_fetch_all(' SELECT u.id, u.team_name FROM users AS u JOIN submissions AS s ON s.user_id = u.id WHERE u.competing = 1 AND s.correct = 1 AND s.challenge=:challenge ORDER BY s.added ASC LIMIT 3', array('challenge' => $challenge['id'])); if (count($users)) { $pos = 1; foreach ($users as $user) { echo get_position_medal($pos++), '<a href="user?id=', htmlspecialchars($user['id']), '">', htmlspecialchars($user['team_name']), '</a><br />'; } } else { echo '<i>Unsolved</i>'; } echo ' </td>
function print_user_ip_log($user_id, $limit = 0) { validate_id($user_id); section_subhead('IP address usage', ($limit ? 'Limited to ' . $limit . ' results ' : '') . button_link('Show all for user', 'list_ip_log?user_id=' . htmlspecialchars($user_id)), false); echo ' <table id="files" class="table table-striped table-hover"> <thead> <tr> <th>IP</th> <th>Hostname</th> <th>First used</th> <th>Last used</th> <th>Times used</th> </tr> </thead> <tbody> '; $entries = db_query_fetch_all(' SELECT INET_NTOA(ip) AS ip, added, last_used, times_used FROM ip_log WHERE user_id = :user_id ORDER BY last_used DESC ' . ($limit ? 'LIMIT ' . $limit : ''), array('user_id' => $user_id)); foreach ($entries as $entry) { echo ' <tr> <td><a href="', CONFIG_SITE_ADMIN_URL, 'list_ip_log.php?ip=', htmlspecialchars($entry['ip']), '">', htmlspecialchars($entry['ip']), '</a></td> <td>', CONFIG_GET_IP_HOST_BY_ADDRESS ? gethostbyaddr($entry['ip']) : '<i>Lookup disabled in config</i>', '</td> <td>', date_time($entry['added']), '</td> <td>', date_time($entry['last_used']), '</td> <td>', number_format($entry['times_used']), '</td> </tr> '; } echo ' </tbody> </table> '; }
<?php require '../include/mellivora.inc.php'; enforce_authentication(); head(lang_get('hints')); if (cache_start(CONST_CACHE_NAME_HINTS, CONFIG_CACHE_TIME_HINTS)) { $hints = db_query_fetch_all(' SELECT h.id, h.added, h.body, c.title, ca.title AS category_title FROM hints AS h LEFT JOIN challenges AS c ON c.id = h.challenge LEFT JOIN categories AS ca ON ca.id = c.category WHERE c.available_from < UNIX_TIMESTAMP() AND c.available_until > UNIX_TIMESTAMP() AND h.visible = 1 AND c.exposed = 1 AND ca.exposed = 1 ORDER BY h.id DESC '); if (!count($hints)) { message_generic(lang_get('hints'), lang_get('no_hints_available'), false); } section_head('Hints'); echo ' <table id="files" class="table table-striped table-hover"> <thead>
function user_exception_log($user_id, $limit = null) { validate_id($user_id); echo ' <table id="hints" class="table table-striped table-hover"> <thead> <tr> <th>Message</th> <th>Added</th> <th>IP</th> <th>Trace</th> </tr> </thead> <tbody> '; $exceptions = db_query_fetch_all(' SELECT e.id, e.message, e.added, e.added_by, e.trace, INET_NTOA(e.user_ip) AS user_ip, u.team_name FROM exceptions AS e LEFT JOIN users AS u ON u.id = e.added_by WHERE e.added_by = :user_id ORDER BY e.id DESC ' . ($limit ? 'LIMIT ' . $limit : ''), array('user_id' => $user_id)); foreach ($exceptions as $exception) { echo ' <tr> <td>', htmlspecialchars($exception['message']), '</td> <td>', date_time($exception['added']), '</td> <td><a href="', CONFIG_SITE_ADMIN_URL, 'list_ip_log.php?ip=', htmlspecialchars($exception['user_ip']), '">', htmlspecialchars($exception['user_ip']), '</a></td> <td>', htmlspecialchars($exception['trace']), '</td> </tr> '; } echo ' </tbody> </table> '; }
<?php require '../../include/ctf.inc.php'; enforce_authentication(CONST_USER_CLASS_MODERATOR); validate_id($_GET['id']); $user = db_select_one('users', array('team_name', 'email', 'enabled', 'competing', 'country_id'), array('id' => $_GET['id'])); head('Site management'); menu_management(); section_subhead('Edit user: '******'team_name']); form_start(CONFIG_SITE_ADMIN_RELPATH . 'actions/edit_user'); form_input_text('Email', $user['email']); form_input_text('Team name', $user['team_name']); $opts = db_query_fetch_all('SELECT * FROM countries ORDER BY country_name ASC'); form_select($opts, 'Country', 'id', $user['country_id'], 'country_name'); form_input_checkbox('Enabled', $user['enabled']); form_input_checkbox('Competing', $user['competing']); form_hidden('action', 'edit'); form_hidden('id', $_GET['id']); form_button_submit('Save changes'); form_end(); section_subhead('Reset password'); form_start(CONFIG_SITE_ADMIN_RELPATH . 'actions/edit_user'); form_input_checkbox('Reset confirmation'); form_hidden('action', 'reset_password'); form_hidden('id', $_GET['id']); form_button_submit('Reset password', 'warning'); form_end(); section_subhead('Delete user'); form_start(CONFIG_SITE_ADMIN_RELPATH . 'actions/edit_user'); form_input_checkbox('Delete confirmation'); form_hidden('action', 'delete');
foreach ($challenges as $challenge) { echo '<strong>', htmlspecialchars($challenge['title']), '</strong>, ', number_format($challenge['points']), ' / ', number_format($challenge['category_total']), ' (', round($challenge['points'] / max(1, $challenge['category_total']) * 100), '%)'; progress_bar($challenge['points'] / max(1, $challenge['category_total']) * 100); $user_total += $challenge['points']; $ctf_total += $challenge['category_total']; } echo 'Total: ', number_format($user_total), ' / ', number_format($ctf_total), ' (', round($user_total / $ctf_total * 100, 1), '%)'; section_head('Solved challenges'); $submissions = db_query_fetch_all(' SELECT s.added, ((SELECT COUNT(*) FROM submissions AS ss WHERE ss.correct = 1 AND ss.added < s.added AND ss.challenge=s.challenge)+1) AS pos, ch.id AS challenge_id, ch.available_from, ch.title, ch.points, ca.title AS category_title FROM submissions AS s LEFT JOIN challenges AS ch ON ch.id = s.challenge LEFT JOIN categories AS ca ON ca.id = ch.category WHERE s.correct = 1 AND s.user_id = :user_id ORDER BY s.added DESC', array('user_id' => $_GET['id'])); if (count($submissions)) { echo ' <table class="table table-striped table-hover"> <thead> <tr> <th>Challenge</th> <th>Solved</th> <th>Points</th>
<?php require '../../include/mellivora.inc.php'; enforce_authentication(CONFIG_UC_MODERATOR); require CONFIG_PATH_THIRDPARTY . 'nbbc/nbbc.php'; $bbc = new BBCode(); $bbc->SetEnableSmileys(false); head('Site management'); menu_management(); section_head('List news'); $news = db_query_fetch_all('SELECT * FROM news WHERE instanceID=\'' . $_SESSION["IID"] . '\' ORDER BY added DESC'); foreach ($news as $item) { echo ' <div class="news-container">'; section_head($item['title'] . ' <a href="edit_news.php?id=' . htmlspecialchars($item['id']) . '" class="btn btn-xs btn-primary">Edit</a>', '', false); echo ' <div class="news-body"> ', $item['body'], ' </div> </div> '; } foot();
<tr> <th>Team name</th> <th>Hostname</th> <th>First used</th> <th>Last used</th> <th>Times used</th> </tr> </thead> <tbody> '; $entries = db_query_fetch_all(' SELECT INET_NTOA(ipl.ip) AS ip, ipl.added, ipl.last_used, ipl.times_used, u.team_name, u.id AS user_id FROM ip_log AS ipl LEFT JOIN users AS u ON ipl.user_id = u.id WHERE ipl.ip=INET_ATON(:ip)', array('ip' => $_GET['ip'])); $host = CONFIG_GET_IP_HOST_BY_ADDRESS ? gethostbyaddr($_GET['ip']) : '<i>Lookup disabled in config</i>'; foreach ($entries as $entry) { echo ' <tr> <td> <a href="list_ip_log.php?id=', htmlspecialchars($entry['user_id']), '"> ', htmlspecialchars($entry['team_name']), ' </a> </td> <td>', $host, '</td>
<?php require '../include/mellivora.inc.php'; login_session_refresh(); head('Home'); if (cache_start('home', CONFIG_CACHE_TIME_HOME)) { require CONFIG_PATH_THIRDPARTY . 'nbbc/nbbc.php'; $bbc = new BBCode(); $bbc->SetEnableSmileys(false); $news = db_query_fetch_all('SELECT * FROM news ORDER BY added DESC'); foreach ($news as $item) { echo ' <div class="news-container">'; section_head($item['title']); echo ' <div class="news-body"> ', $bbc->parse($item['body']), ' </div> </div> '; } cache_end('home'); } foot();
echo ' <table id="hints" class="table table-striped table-hover"> <thead> <tr> <th>Challenge</th> <th>Added</th> <th>Hint</th> <th>Manage</th> </tr> </thead> <tbody> '; $hints = db_query_fetch_all(' SELECT h.id, h.added, h.body, c.title FROM hints AS h LEFT JOIN challenges AS c ON c.id = h.challenge'); foreach ($hints as $hint) { echo ' <tr> <td>', htmlspecialchars($hint['title']), '</td> <td>', date_time($hint['added']), '</td> <td>', htmlspecialchars($hint['body']), '</td> <td><a href="edit_hint.php?id=', $hint['id'], '" class="btn btn-xs btn-primary">Edit</a></td> </tr> '; } echo ' </tbody>
<?php require '../../include/mellivora.inc.php'; enforce_authentication(CONST_USER_CLASS_MODERATOR); head('Dynamic menu items'); menu_management(); section_head('Dynamic menu items', button_link('New menu item', 'new_dynamic_menu_item'), false); $menu_items = db_query_fetch_all('SELECT dm.id, dm.title, dm.permalink, dm.visibility, dm.min_user_class, dm.url, dc.title AS link_title FROM dynamic_menu AS dm LEFT JOIN dynamic_pages AS dc ON dc.id = dm.internal_page ORDER BY dm.title ASC'); echo ' <table id="dynamic_menus" class="table table-striped table-hover"> <thead> <tr> <th>Title</th> <th>Links to</th> <th>visibility</th> <th>Min user class</th> <th>Manage</th> </tr> </thead>
// write out the category description, if one exists if ($current_category['description']) { echo '<div id="category-description">', $bbc->parse($current_category['description']), '</div>'; } // get all the challenges for the selected category $challenges = db_query_fetch_all(' SELECT c.id, c.title, c.description, c.available_from, c.available_until, c.points, c.num_attempts_allowed, c.min_seconds_between_submissions, c.automark, c.relies_on, IF(c.automark = 1, 0, (SELECT ss.id FROM submissions AS ss WHERE ss.challenge = c.id AND ss.user_id = :user_id_1 AND ss.marked = 0)) AS unmarked, -- a submission is waiting to be marked (SELECT ss.added FROM submissions AS ss WHERE ss.challenge = c.id AND ss.user_id = :user_id_2 AND ss.correct = 1) AS correct_submission_added, -- a correct submission has been made (SELECT COUNT(*) FROM submissions AS ss WHERE ss.challenge = c.id AND ss.user_id = :user_id_3) AS num_submissions, -- number of submissions made (SELECT max(ss.added) FROM submissions AS ss WHERE ss.challenge = c.id AND ss.user_id = :user_id_4) AS latest_submission_added FROM challenges AS c WHERE c.category = :category AND c.exposed = 1 ORDER BY c.points ASC, c.id ASC', array('user_id_1' => $_SESSION['id'], 'user_id_2' => $_SESSION['id'], 'user_id_3' => $_SESSION['id'], 'user_id_4' => $_SESSION['id'], 'category' => $current_category['id'])); echo '<div id="challenges-container" class="panel-group">'; foreach ($challenges as $challenge) { // if the challenge isn't available yet, display a message and continue to next challenge if ($time < $challenge['available_from']) { echo '
<th>Added</th> <th>Flag</th> <th>Correct</th> <th>Manage</th> </tr> </thead> <tbody> '; $submissions = db_query_fetch_all(' SELECT s.id, u.id AS user_id, u.team_name, s.added, s.correct, s.flag, c.id AS challenge_id, c.title AS challenge_title FROM submissions AS s LEFT JOIN users AS u on s.user_id = u.id LEFT JOIN challenges AS c ON c.id = s.challenge ' . ($_GET['all'] ? '' : 'WHERE c.automark = 0 AND s.marked = 0') . ' ORDER BY s.added DESC LIMIT ' . $from . ', ' . $results_per_page); foreach ($submissions as $submission) { echo ' <tr> <td><a href="../challenge.php?id=', htmlspecialchars($submission['challenge_id']), '">', htmlspecialchars($submission['challenge_title']), '</a></td> <td><a href="/user.php?id=', htmlspecialchars($submission['user_id']), '">', htmlspecialchars($submission['team_name']), '</a></td> <td>', time_elapsed($submission['added']), ' ago</td> <td>', htmlspecialchars($submission['flag']), '</td> <td>
<th>User agent</th> </tr> </thead> <tbody> '; $from = get_pager_from($_GET); $num_exceptions = db_count_num('exceptions'); $results_per_page = 30; pager(CONFIG_SITE_ADMIN_URL . 'list_exceptions/', $num_exceptions, $results_per_page, $from); $exceptions = db_query_fetch_all(' SELECT e.id, e.message, e.added, e.added_by, e.trace, INET_NTOA(e.user_ip) AS user_ip, e.user_agent, u.team_name FROM exceptions AS e LEFT JOIN users AS u ON u.id = e.added_by ORDER BY e.id DESC LIMIT ' . $from . ', ' . $results_per_page); foreach ($exceptions as $exception) { echo ' <tr> <td>', htmlspecialchars($exception['message']), '</td> <td>', date_time($exception['added']), '</td> <td>', $exception['added_by'] ? '<a href="edit_user.php?id=' . htmlspecialchars($exception['added_by']) . '">' . htmlspecialchars($exception['team_name']) . '</a>' : '<i>Not logged in</i>', ' </td> <td><a href="list_ip_log.php?ip=', htmlspecialchars($exception['user_ip']), '">', htmlspecialchars($exception['user_ip']), '</a></td> <td>', htmlspecialchars($exception['trace']), '</td>
require '../../include/mellivora.inc.php'; enforce_authentication(CONFIG_UC_MODERATOR); head('User types'); menu_management(); section_head('Users types'); echo ' <table id="files" class="table table-striped table-hover"> <thead> <tr> <th>Title</th> <th>Description</th> <th></th> </tr> </thead> <tbody> '; $types = db_query_fetch_all('SELECT * FROM user_types ORDER BY title ASC'); foreach ($types as $type) { echo ' <tr> <td>', htmlspecialchars($type['title']), '</td> <td>', short_description($type['description'], 50), '</td> <td><a href="edit_user_type.php?id=', htmlspecialchars($type['id']), '" class="btn btn-xs btn-primary">Edit</a></td> </tr> '; } echo ' </tbody> </table> '; foot();
<?php require '../../include/ctf.inc.php'; enforce_authentication(CONST_USER_CLASS_MODERATOR); head('Site management'); menu_management(); section_subhead('New hint'); form_start(CONFIG_SITE_ADMIN_RELPATH . 'actions/new_hint'); form_textarea('Body'); $opts = db_query_fetch_all(' SELECT ch.id, ch.title, ca.title AS category FROM challenges AS ch LEFT JOIN categories AS ca ON ca.id = ch.category ORDER BY ca.title, ch.title'); form_select($opts, 'Challenge', 'id', array_get($_GET, 'id', 0), 'title', 'category'); form_input_checkbox('Visible'); form_hidden('action', 'new'); form_button_submit('Create hint'); form_end(); foot();
LEFT JOIN categories AS ca ON ca.id = ch.category WHERE ch.id = :id', array('id' => $_GET['id'])); if (empty($challenge)) { message_generic('Sorry', 'No challenge found with this ID', false); } $now = time(); if ($challenge['challenge_available_from'] > $now || $challenge['category_available_from'] > $now) { message_generic('Sorry', 'This challenge is not yet available', false); } $submissions = db_query_fetch_all('SELECT u.id AS user_id, u.team_name, s.added, c.available_from FROM users AS u LEFT JOIN submissions AS s ON s.user_id = u.id LEFT JOIN challenges AS c ON c.id = s.challenge WHERE u.competing = 1 AND s.challenge = :id AND s.correct = 1 ORDER BY s.added ASC', array('id' => $_GET['id'])); section_head($challenge['title']); $num_correct_solves = count($submissions); if (!$num_correct_solves) { echo 'This challenge has not yet been solved by any teams.'; } else { $user_count = db_query_fetch_one('SELECT COUNT(*) AS num FROM users WHERE competing = 1'); echo 'This challenge has been solved by ', number_format($num_correct_solves / $user_count['num'] * 100, 1), '% of users.'; echo ' <table class="challenge-table table table-striped table-hover">