Возможна ли в этом коде SQL-инъекция?


Введение

Я взял на себя обслуживание действительно грязной страницы PHP, которая является платформой бронирования апартаментов для отдыха, но это не важно. Код изначально был написан дизайнером (а не программистом), и он действительно плох. Передача логических переменных строками "true" и "false" является одним из второстепенных WTF. Я хочу убедить владельца страницы, дать мне время (и деньги, конечно), чтобы очистить его код (или переписать его).

По-видимому, оригинал "разработчик" никогда не слышал о SQL-инъекции, потому что он использует переменные POST и GET непосредственно в своих SQL-операторах. Чтобы убедить владельца, я хочу немного шокировать его, войдя в систему как администратор без использования его пароля.

Tl;dr (или: Фактический вопрос)

Это утверждение (где $p_username - это переменная POST, которая содержит содержимое поля ввода "Имя пользователя"):

"SELECT password FROM user WHERE username = '$p_username'"

Возвращенная строка (которая является несоленым MD5-хэшем пароля, который был сохранен в база данных) затем сравнивается с (также хэшированной) строкой, которая была введена в поле "Пароль", и если обе строки совпадают, пользователь входит в систему как введенный пользователь. Можно ли ввести что-то в поле имени пользователя, чтобы войти в систему как "поддельный" администратор?

Примечание: Сервер БД - MySQL, PHP находится в версии 5 и magic_quotes включен.

Author: hakre, 2011-02-13

6 answers

Как отметил полковник Дж. Шрапнель, magic_quotes делает это невозможным, если только вы не бежите в каких-то очень особых обстоятельствах.

Однако, если то, что вы говорите, правда, вполне вероятно, что первоначальный разработчик мало что знал о magic_quotes, поэтому, скорее всего, он ошибся, если когда-либо сохранял значения GET/POST/COOKIE где-либо еще, кроме операторов SQL. Короче говоря, ищите места, где ' и " были бы законными, и проверьте, не перепутались ли они.

Также - знал ли он о htmlspecialchars(), или инъекция HTML/Javascript все еще возможна?:)

 2
Author: Vilx-, 2011-02-13 08:35:42

С включенными магическими кавычками это было бы невозможно.

 0
Author: Your Common Sense, 2011-02-13 08:27:52

Если это полный запрос и проверка пароля выполняется на стороне PHP, вы не сможете войти в систему как администратор (даже если magic_quotes отключен), потому что вам все равно придется сопоставлять хэш пароля.

 0
Author: Alix Axel, 2011-02-13 09:44:37

Как отмечали другие, получить одинарную кавычку после магических кавычек сложно, но если это можно сделать, запрос является тостом. Подумайте, не могли бы мы ввести следующее:

SELECT password FROM user WHERE username = 'unlikely' 
UNION ALL SELECT CHAR(102,111,111); #'

Это вернет строку "foo" в PHP в качестве пароля, поэтому все, что нам нужно сделать, это убедиться, что наша форма отправляет нашу инъекцию для имени пользователя $ и "foo" для пароля $.

 0
Author: Paul Dixon, 2011-02-13 10:16:48

РЕДАКТИРОВАТЬ

Существует несколько векторов атаки с addslashes(). Первый, который я выбрал ниже, был основан на статье, ранее приведенной в ответе, в котором она цитировалась в поддержку противоположный претензия. По крайней мере, еще один - с слишком длинными строками, использующими кодировку не ниже UTF-8.

Http://www.erich-kachel.de/?tag=addslashes

Можно было бы построить аналогичную технику, описанную ниже. Короче говоря, команда MySQL сочла нужным уйти в отставку magic_quotes, а также настоятельно не рекомендуется притворяться, что addslashes() - это реальная форма защиты. Может быть, вы знаете, что команда MySQL знала бы лучше? Как бы то ни было, mysql_real_escape_string также имеет некоторые уязвимости в крайнем случае, но, поскольку он специфичен для MySQL, а не только для PHP, он делает еще один шаг вперед. Лучшим решением было бы использовать параметры запроса.

Следует оригинальный ответ

Да, можно войти в систему как администратор. Ни в одном иди, но двух проходов будет достаточно.

Ссылка - http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string (Да, это та же ссылка из другого ответа, но вместо этого моя интерпретация заключается в том, что это обычно возможно для любого многобайтового набора символов, кроме utf8)

Вы не указали, является ли ваша система многобайтовой, но, поскольку вопрос открыт, я буду считать, что это так.

$p_username = chr(0xbf) . chr(0x27) . ';' .
    "update user set password='password', '.
    "username='" . chr(0xbf) . "' where username='admin' /*';

"SELECT password FROM user WHERE username = '$p_username'"

Я изменил имя пользователя И пароль "администратора" пользователь

Этот тип атаки возможен с любой кодировкой символов, где есть допустимый многобайтовый символ, заканчивающийся на 0x5c

 0
Author: RichardTheKiwi, 2011-02-13 12:40:46

Я думаю, что важно проверить все входные переменные и экранировать все специальные символы, даже если включена функция magic_quotes.

Чтобы быть уверенным, вы можете протестировать свой код с помощью sqlmap.

 -2
Author: kdani, 2011-02-13 09:36:12