Sebastian's Blog

computer-science student. software developer. security enthusiast.

HACKVent 2019

HV19.17 Unicode Portal

Sebastian

After registering and logging in, I got a page showing different Unicode characters and their different representations.

The website also allows to view some part of the source code:

<?php
 
if (isset($_GET['show'])) highlight_file(__FILE__);
 
/**
 * Verifies user credentials.
 */
function verifyCreds($conn, $username, $password) {
  $usr = $conn->real_escape_string($username);
  $res = $conn->query("SELECT password FROM users WHERE username='".$usr."'");
  $row = $res->fetch_assoc();
  if ($row) {
    if (password_verify($password, $row['password'])) return true;
    else addFailedLoginAttempt($conn, $_SERVER['REMOTE_ADDR']);
  }
  return false;
}
 
/**
 * Determines if the given user is admin.
 */
function isAdmin($username) {
  return ($username === 'santa');
}
 
/**
 * Determines if the given username is already taken.
 */
function isUsernameAvailable($conn, $username) {
  $usr = $conn->real_escape_string($username);
  $res = $conn->query("SELECT COUNT(*) AS cnt FROM users WHERE LOWER(username) = BINARY LOWER('".$usr."')");
  $row = $res->fetch_assoc();
  return (int)$row['cnt'] === 0;
}
 
/**
 * Registers a new user.
 */
function registerUser($conn, $username, $password) {
  $usr = $conn->real_escape_string($username);
  $pwd = password_hash($password, PASSWORD_DEFAULT);
  $conn->query("INSERT INTO users (username, password) VALUES (UPPER('".$usr."'),'".$pwd."') ON DUPLICATE KEY UPDATE password='".$pwd."'");
}
 
/**
 * Adds a failed login attempt for the given ip address. An ip address gets blacklisted for 15 minutes if there are more than 3 failed login attempts.
 */
function addFailedLoginAttempt($conn, $ip) {
  $ip = $conn->real_escape_string($ip);
  $conn->query("INSERT INTO fails (ip) VALUES ('".$ip."')");
}
 
?>

The registerUser function actually updates a users password (INSERT INTO … ON DUPLICATE KEY UPDATE password=) if we register with an existing username. But we only get there, if isUsernameAvailable returns true.

Registering using śáńtá as username bypasses the isUsernameAvailable function, but resets the password for the user santa. So we can log in as user santa and retrieve the flag HV19{h4v1ng_fun_w1th_un1c0d3}.

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top