В этой статье я хочу рассказать о том, какие можно предпринять меры, чтобы увеличить время использование найденной злоумышленником уязвимости, и успеть предпринять меры! Тут показаны некоторые распространенные ошибки начинающий программистов! надеюсь эта статья им будет полезна! В общем приступаем! 1. Болтун - находка для шпиона! Первый совет касается манеры оформления форм скрипта и взаимодействия с базой данных! Я начал замечать, что очень часто программисты используют одинаковые имена для полей в html-форме и столбцов в базе данных. Это с одной стороны удобно для самого программиста, однако этим программисты делают великую услугу злоумышленникам. Приведу пример, злоумышленник обнаружил уязвимость типа "SQL-injection" на сайте, и нашел таблицу с юзерами. Первое что он попытается сделать? (сужу по себе) Он сначала попытается проверить наличие столбцов типа "username", "password" и т.п, а уже в случае неудачи анализирует сайт для поиска названия столбца. Я например постоянно смотрю исходный код страницы авторизации. Вот плохой пример: Вот более-менее приемлимый пример: Вот такая вот с первого взгляда не шибко то и опасная оплошность помогала определять имена столбцов на некоторых "не нашенских" сайтах (итальянские, бразильские, французские) где программисты используют в качестве имен зачастую слова своего языка, а не английского, причем иногда и на сленге, т.е. даже с переводчиком было трудно подобрать поле. 2. Молчание - золото! (Продолжение пункта "Болтун - находка для шпиона!") Итак, практически похожая оплошность программистов. Зачастую бывает, что программисты присваиваивают обычной переменной либо аргументу функции прямое, "человеко-читаемое" значение (т.е. значения типа insert, update, view, show, add и т.п.), опять же делается для удобства самого программиста, и читаемости кода. Это конечно со стороны культуры кода отлично, однако со стороны безопасности этого лучше не делать. А например сделать для самого себя условие наподобие "insert"==1, "show"==2 и т.д. а передавать уже целочисленное значение, которое не отображает действие. И написать в коде комментарий с расшифровкой этих манипуляций рядом с функцией, дабы после выходных не забыть чего наделали! =) Это конечно не очень удобно, зато осложнит злоумышленнику изучение алгоритма выполнения скрипта. 3. Семь раз отмерь... Также многие программисты совершают ошибку описанную ниже либо из-за лени, либо из-за каких-то природных катаклизмов, ничем другим это не обьясняется! Встречаются такие случаи, когда перед записью в базу ограничивают ввод в поле формы "maxlength", потом обрезают переменную (на всякий случай! =) ) "substr" и ей подобными, в это же время абсолютно не устанавливая тип и длину данных в самой базе (например все поля без разбора имеют тип "text") Естественно делая подобное, программисты не задумываются, что злоумышленник имея некую уязвимость не в 100% случаях произведет запись в базу именно из любезно предоставленной программистом переменной, а из какой либо другой, причем без проверок! =) Ведь гораздо лучше совместить вышеуказанные ограничения по размеру с ограничением в структуре базы. Например для MD5 хеша пароля подойдет тип varchar(32) , а для столбца с номером ICQ тип tinyint(9) и т.д. Дальше интереснее! =) Читаем! 4. Глумимся над злоумышленником 4.1 Админка Итак, опять давайте попробуем размышлять как злоумышленник! =) Представим, что злоумышленник обнаружил уже упомянутую уязвимость типа "SQL-injection", удачно вытянул из базы логин и хеш админа, что он делает дальше? А? Именно! Пойдет искать админку! и даю 99% будет искать в начале частые имена (не рассматриваем случаи с robots.txt и общей формой входа) - admin, login, webadmin, cpanel, и т.п. Но, мы же добрые, и хитрые программисты! =) Давайте создадим папочку (или просто файлик) с именем /admin/ закинем туда один файлик index.php с подобным содержанием: PHP: <html> <head> <title>Admin Panel</title> </head> <body> <? if(empty($_POST['login'])) { print '<form action="" method="post">'; print 'Login <br>'; print '<input name="login" type="text"> <br>'; print 'Password <br>'; print '<input name="password" type="password"> <br>'; print '<input type="submit" value="enter">'; print '</form>'; } else { print 'Login and/or Password is not correct! Please re-enter!'; } ?> </body> </html> Вот у нас и получился фейк нашей настоящей админки! (для пущей уверенности можно сделать еще вывод ошибок при вводе запрещенных символов, проверку на пустоту переменной, если хекер не ввел данные и т.п. в общем максимально приблизить к реальности) Как видите это просто произвол! =) При любом вводе логина и пароля будет выводится ошибка! А реальная админка будет находится в какой-нибудь папочке типа "good_cpanel_for_best_user" 4.2. Ошибки 404 и 403 Продолжаем обманывать нашего гостя! Для начала создадим файл .htaccess в корне сайта со следующим содержанием Далее в указанном файле index.php добавим несколько строк подобного содержания PHP: if(@$_GET['error']==404) { print ‘Not Found <br>’; } if(@$_GET['error']==403) { print ‘Forbidden<br>’; } Разберем написаное! В файле .htaccess мы заменили дефолтные страницы ошибок на свою, причем мы заменили не просто на index.php, а еще и присвоили переменной error код ошибки! Зачем? Дальше расскажу! А в индексном файле сделали вывод этих ошибок. Кажется ничего сверхъестественного не сделали… Продолжаем. Теперь давайте снова пофантазируем! Допустим у нас есть директория на сайте под именем files, в ней хранятся какие то наши файлы, мы естественно закрыли к ней доступ в файле .htaccess, а при заходе по адресу http://your_site.ru/files/ нам выдает ошибку 403, причем не простую, а редиректит на http://your_site.ru/index.php?error=403, где нас и оповещают об ошибке. Надеюсь тут все понятно! Это будет наш отвлекающий маневр! Злоумышленник увидит, что при запросе несуществующего файла/директории выдается ошибка 404, а при отсутствии доступа 403. Теперь подумаем что можно сделать с этим… Точно! Можно еще лучше спрятать админку! Ранее мы сделали подставную, фейковую админку, а своей присвоили сложное имя, а все же если хакер узнает название админки? Будет плохо… Прячем админку! Создадим в папке с админкой индексный файл index.php следующего содержания PHP: <?php header("Location: http://your_site.ru/index.php?error=404"); ?> Т.е.при заходе в директорию с админкой /good_cpanel_for_best_user/ сработает индексный файл и редиректит хакера на ту же страницу, что и при отсутствии директории, т.е. 404. (надеюсь понятно выразился, просто красноречия не хватает…) Таким образом создастся зрительное впечатление, что директории /good_cpanel_for_best_user/ не существует. Естественно в этой папке придется сделать нужные (для администрирования) файлы с названиями отличными от index.php. 5. Только жесткий контроль!!! Теперь давайте подумаем над тем, как же мы будем обрабатывать все остальные ошибки которые провоцируются в основном пользователем. Я предлагаю следующую схему: Создать функцию наподобие этой: PHP: function get_error($int) { $int = intval($int); // Мелкие ошибки $error[0] = 'Вы неверно ввели проверочный код, пожалуйста попробуйте еще раз! <br>'; $error[1] = 'Вы не ввели логин, повторите ввод! <br>'; $error[2] = 'Вы не ввели пароль, повторите ввод! <br>'; // ошибки средней важности $error[20] = 'Авторизация провалена!<br>'; $error[21] = 'Неверный идентификатор сессии!<br>'; // Важные ошибки $error[30] = 'Файл не найден!<br>'; $error[31] = 'Запрашивался недоступный файл!<br>'; // Весьма важные, либо критические ошибки $error[50] = 'Попытка доступа к закрытым разделам сайта!<br>'; $error[51] = 'Введен неверный пароль доступа к панели администрирования!<br>'; if($int>=50) { echo send_mail('admin@your_site.ru',$int); } return $error[$int]; } Суть функции в том, что каждой ошибке присваивается свой номер в зависимости от важности. Выводить ошибку в скрипт следующим образом вместо обычного print 'Error'; написать print get_error(number_of_error); Подобная функция позволяет вести контроль за ошибками! Например в этой функции показан пример, что при вызове ошибки номер которой больше 50 (т.е. критические ошибки) отсылается админу письмо с нужными данными. Также можно сделать ранжирование, например Принцип работы простой, зато очень удобный! Ну, вот как бы и все пока! Надеюсь, что это кому-нибудь, да будет полезно! С Ув. Twoster
Отличное решение проблем Тоесть вместо читаемого кода получаем хрен знает что, зато никто не догадается о именах столбцов и таблиц. Можно и в базе их поменять, что-бы вообще всё серьёзно было. Например вместо user--;lsdfhgsdc3456 pass--7fm23sdcaskjt/ . Да , немного неудобно, скажете вы, но зато никто не догадается что это за таблицы и поля Админку тоже нужно спрятать очень хорошо, я думаю не менее 50 символов в урле, что-то вроде: http://site/74sdfkset45tdfgwe56kyj359fvbsdfllyu35her754hs/wuytw0ef98ewrlktjwbneodi.php А вдруг у хакера суперприватный сканер дирректорий? Да, опять-же некоторые неудобства есть, конечно, но ведь главное безопасность. Ну и т.д. Думаю мысль моя понятна. ТС , безопасности много не бывает , подходить к этому вопросу нужно очень серьёзно PS Ну а если серьёзно, то конечно так проблемы не решают. Это что-то вроде удаления гланд через задницу
Понравилось про фейковую админку) а остальное для меня не ново.. я тоже так делаю -_- даже при том, что я 99% уверен в безопасности своего кода - админка находиться в глубокой опе) а в базе можно просто добавить индексы. для любого проэкта несложно придумать логичный инекс. а хеккер недогадаеться..