Возможна ли SQL-инъекция в этом коде? - PullRequest
4 голосов
/ 13 февраля 2011

Введение

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

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

tl; dr (или: актуальный вопрос)

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

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

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

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

Ответы [ 6 ]

2 голосов
/ 13 февраля 2011

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

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

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

0 голосов
/ 13 февраля 2011

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

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

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

0 голосов
/ 13 февраля 2011

EDIT

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

http://www.erich -kachel.de /? Тег = addslashes

Техника, подобная приведенной ниже, может быть построена. Как бы то ни было, команда MySQL посчитала целесообразным удалить magic_quotes, а также настоятельно рекомендовала не притворяться, что addlashes () является реальной формой защиты. Может быть, вы знаете, что команда 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'"

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

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

0 голосов
/ 13 февраля 2011

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

0 голосов
/ 13 февраля 2011

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

Конечно, вы можете проверить свой код с помощью sqlmap.

0 голосов
/ 13 февраля 2011

При включенных магических кавычках это будет невозможно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...