Есть ли способ использовать этот код и войти под конкретным именем пользователя (например, Сэм)? Функция mysqli_real_escape_string () экранирует все символы NUL (ASCII 0), \ n, \ r, \, ', "и Control-Z.
Я пробовал с username = "Sam" и domain = "' union (SELECT 1, 123456) # a", но это не работает ..
$user = $_POST['user'];
$domain = $_POST['domain'];
$pwd = $_POST['pwd'];
function login($username, $domain, $password) {
global $vuln_db;
$starttime = microtime(true);
$username = mysqli_real_escape_string($vuln_db, trim($username));
$domain = mysqli_real_escape_string($vuln_db, trim($domain));
$password = trim($password);
if (empty($password) || empty($username) || empty($domain)) {
return FALSE;
}
// We store the password in plaintext to keep the homework's code short.
// For anything even remotely real, use a proper password storage scheme.
$query = "SELECT user_id, password FROM users WHERE username = '$username' AND domain LIKE '$domain'";
$result = mysqli_query($vuln_db, $query) or die(mysqli_error($vuln_db));
if ($result) {
$row = mysqli_fetch_row($result);
if ($row) {
$the_password = trim($row[1]);
for($i = 0; $i < strlen($the_password); $i++) {
/* Bruteforce is not the way! */
usleep(100000);
if ($password[$i] != $the_password[$i]) {
$endtime = microtime(true);
return FALSE;
}
}
return TRUE;
} else {
return FALSE;
}
}
}
Могу ли я получить истину из этой функции с помощью SQL-инъекции или других методов?
Лучше всего использовать подготовленное заявление вместо экранирования каждого параметра, чтобы упростить защиту ваших запросов. Но вы используете кавычки вокруг ваших строк, чтобы ваши переменные были в безопасности после экранирования.
Это упражнение по внедрению sql для университета, но я не могу найти способ войти в систему. Можно ли каким-то образом использовать глобальную переменную $ vuln_db?
@NigelRen Я прочитал эту тему перед тем, как открыть новую, но мой случай сильно отличается от этого. У меня одинарные кавычки между переменной, и она обрезана






Конкретный случай, который вы показываете, защищен mysqli_real_escape_string(). Если только ваш набор символов не ГБК или sjis, чего я не могу сказать, потому что я не знаю, как вы подключились к базе данных.
У экранирования есть ряд крайних случаев, когда он не работает, как описано в ответах на SQL-инъекция, обходящая mysql_real_escape_string (). Требуется тщательное обдумывание и тестирование, чтобы убедиться, что вы не реализуете код, уязвимый в одном из этих крайних случаев. Такое мышление и тестирование заставляют писать код дольше.
Вот почему в настоящее время рекомендуется использовать параметры запроса вместо экранирования строк.
$query = "SELECT user_id, password FROM users WHERE username = ? AND domain LIKE ?";
$stmt = mysqli_prepare($vuln_db, $query) or die(mysqli_error($vuln_db));
$stmt->bind_param('ss', $username, $domain);
$stmt->execute() or die(mysqli_error($vuln_db));
$result = $stmt->get_result() or die(mysqli_error($vuln_db));
P.S .: Это не связано с вашим вопросом об экранировании, но вам также следует научиться использовать password_hash () и password_verify () вместо хранения паролей в виде обычного текста.
Возможный дубликат SQL-инъекция, обходящая mysql_real_escape_string ()