Авторские статьи Советы и хитрости по безопасному оформлению скриптов

Discussion in 'Статьи' started by Twoster, 8 Nov 2008.

  1. Twoster

    Twoster Members of Antichat

    Joined:
    20 Aug 2008
    Messages:
    287
    Likes Received:
    402
    Reputations:
    159
    В этой статье я хочу рассказать о том, какие можно предпринять меры, чтобы увеличить время использование найденной злоумышленником уязвимости, и успеть предпринять меры! Тут показаны некоторые распространенные ошибки начинающий программистов! надеюсь эта статья им будет полезна! В общем приступаем!

    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
     
    4 people like this.
  2. Kakoytoxaker

    Kakoytoxaker Elder - Старейшина

    Joined:
    18 Feb 2008
    Messages:
    1,038
    Likes Received:
    1,139
    Reputations:
    350
    Отличное решение проблем :D

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

    Например вместо
    user--;lsdfhgsdc3456
    pass--7fm23sdcaskjt/ .

    Да , немного неудобно, скажете вы, но зато никто не догадается что это за таблицы и поля :D

    Админку тоже нужно спрятать очень хорошо, я думаю не менее 50 символов в урле, что-то вроде:

    http://site/74sdfkset45tdfgwe56kyj359fvbsdfllyu35her754hs/wuytw0ef98ewrlktjwbneodi.php

    А вдруг у хакера суперприватный сканер дирректорий? Да, опять-же некоторые неудобства есть, конечно, но ведь главное безопасность.

    Ну и т.д. Думаю мысль моя понятна. ТС , безопасности много не бывает , подходить к этому вопросу нужно очень серьёзно :D

    PS Ну а если серьёзно, то конечно так проблемы не решают. Это что-то вроде удаления гланд через задницу
     
    2 people like this.
  3. mr.The

    mr.The Elder - Старейшина

    Joined:
    30 Apr 2007
    Messages:
    1,080
    Likes Received:
    456
    Reputations:
    38
    Понравилось про фейковую админку)
    а остальное для меня не ново..

    я тоже так делаю -_-
    даже при том, что я 99% уверен в безопасности своего кода - админка находиться в глубокой опе)

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