Skip to content

Уцелевший терминал

Az404 edited this page May 19, 2018 · 5 revisions
  • Категория: Web
  • Стоимость: 300
  • Автор: Алексей Захаров
  • Репозиторий

Описание

Совсем недавно произошло нечто совсем не поддающееся объяснению.

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

Cамым удивительным было то, что когда мусор немного расчистили, из-под завалов начал пробиваться свет. Терминал продолжал работать даже спустя три года после катастрофы. На экране отображалась страница входа и её адрес:

terminal.contest.qctf.ru/365a9513fd97e3cdecf29094417c0103/.

В течение получаса мы тщетно пытались найти способ войти в систему, но всё было напрасно.

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

Решение

Перед нами форма логина:

Форма логина

Исходник сервера не выдаётся. В клиентском коде нет ничего интересного, кроме получения некоторого токена с сервера и вставки его в форму при отправке.
(Токены не играли существенной роли в таске и использовались только для защиты от автоматизированных сканеров.)

Проверим сайт на наличие SQL-инъекции, вставив кавычку в оба поля. Получаем сообщение об ошибке:

Результат при вводе кавычки

В сообщении выводится запрос:

SELECT * FROM `users` WHERE `login`=''' AND `password`='3590cb8af0bbb9e78c343b52b93773c9'

и сама ошибка, возвращаемая базой данных:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '3590cb8af0bbb9e78c343b52b93773c9'' at line 1

Из запроса видно, что логин подставляется как есть, а от пароля берётся md5-хэш. Попробуем классический вектор атаки: отправим в качестве логина строку ' 1=1 -- , после чего запрос будет иметь вид

SELECT * FROM `users`WHERE `login`='' OR 1=1 -- ' AND `password`='3590cb8af0bbb9e78c343b52b93773c9'

Часть строки после -- будет проигнорирована как комментарий, а условие WHERE будет верно для любой строки таблицы users. В результате запрос должен будет возвращать все записи из таблицы, вместо того, чтобы искать пользователя, который соответствует введённым логину и паролю.

Однако после попытки отправить форму с таким логином получаем новое сообщение: Hacking attempt detected. Forbidden sequence found: ' OR, из которого следует, что мы не можем использовать строку вида ' OR. Добавление пробелов и смена регистра символов ничего не меняет, следовательно, нужно искать другой вектор.

Заметим, что фильтр реагирует только на OR в сочетании с кавычкой (логин вида OR не вызывает ошибки). Построим инъекцию так, чтобы OR находился в середине запроса, а рядом с кавычкой стоял бы AND, например, так: ' AND 1=1 OR 1=1 -- . Некоторые участники вместо этого использовали || в качестве OR.

Вновь получаем ошибку от фильтра: нельзя использовать 1=1. Замена чисел не помогает, однако можно использовать другие тождественно верные логические выражения, такие как 1<2, TRUE, или просто добавить пробелы вокруг знака =, чтобы обойти фильтр.

Далее выясняется, что запрещены комментарии: не работают ни --, ни # и /*. Делаем вывод, что избавиться от окончания запроса нельзя, можно только изменить его середину.

Построим корректный запрос с учётом окончания и кавычек, которые добавляются вокруг логина:

SELECT * FROM `users`WHERE `login`='' AND 1<2 OR 1<2 OR ''='' AND `password`='3590cb8af0bbb9e78c343b52b93773c9'

Тогда нужное значение логина равно ' AND 1<2 OR 1<2 OR ''='. Запрос проходит все фильтры и корректно исполняется, получаем флаг:

Доступ разрешён

P.S.: Чтобы попрактиковаться в SQL-инъекциях, стоит пройти тренировочный квест от Хакердома: http://sql.training.hackerdom.ru/