Статья про анти sql-inj

Discussion in 'Уязвимости' started by nerezus, 5 Jan 2007.

  1. Gifts

    Gifts Green member

    Joined:
    25 Apr 2008
    Messages:
    2,494
    Likes Received:
    807
    Reputations:
    614
    draliokero Вы вообще первый пост читали? А попробуйте, перестанете херь писать
     
    _________________________
  2. Kakoytoxaker

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

    Joined:
    18 Feb 2008
    Messages:
    1,038
    Likes Received:
    1,139
    Reputations:
    350
    PHP:
    <?php
    $server 
    "localhost";
    $database "databasename";
    $dbuser "root";
    $dbpass "";
    $email "";

    $con mysql_connect($server$dbuser$dbpass);
    mysql_select_db($database$con);

    // создание таблицы
    $tableSchema = array();

    $tableSchema[] = "CREATE DATABASE IF NOT EXISTS " $database "";

    $tableSchema[] = "CREATE TABLE IF NOT EXISTS " $database ".`logger_logs` (
    `name` INT( 10 ) NOT NULL ,
    `attack_type` VARCHAR( 200 ) NOT NULL ,
    `page` VARCHAR( 200 ) NOT NULL,
    `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
    ) ENGINE = MYISAM"
    ;

    foreach(
    $tableSchema as $table) {
        
    mysql_query($table);

    // КОНЕЦ создание таблицы (после выполнения запроса, желательно удалить этот блок кода)

    $username $_SERVER['REMOTE_ADDR'];
    $action[0] = "";
    $no 0;
    $full_attack_type "";

    foreach(
    $_REQUEST as $var => $value) {
        
    $action[$no] = $value;
        
    $no $no 1;
    // $_REQUEST checks for post, get cookie & file
    for($i 0$i $no$i++) {
        
    $attacktype ""
        
    // first check for XSS (BASIC checks... easily evaded) doesn't need to be fullproof only for logger, site is vulnerable anyway!
        
    if (preg_match('/((\%3C)|<)((\%2F)|\/)*[a-z0-9\%]+((\%3E)|>)/ix '$action[$i])) {
            
    $attacktype "Cross site scripting";
        } elseif (
    preg_match('/((\%3C)|<)((\%69)|i|(\%49))((\%6D)|m|(\%4D))((\%67)|g|(\%47))[^\n]+((\%3E)|>)/i '$action[$i])) {
            
    $attacktype "Cross site scripting";
        } elseif (
    preg_match('/alert|script|\.js/i '$action[$i])) {
            
    $attacktype "Cross site scripting";
        } elseif (
    preg_match('/((\%3C)|<)[^\n]+((\%3E)|>)/i '$action[$i])) {
            
    $attacktype "Cross site scripting";
        } 
        
    // check for crlf/http response splitting
        
    if (preg_match('/%0a|%0d|\\\r|\\\n|\n|\r/i'$action[$i])) {
            
    $attacktype "CRLF injection";
        } 
        
    // check for sql injection
        
    if (preg_match('/(\%27)|(\')|(\-\-)|(\%23)|(\#)/ix'$action[$i])) {
            
    $attacktype "SQL injection";
        } elseif (
    preg_match('/((\%3D)|(=))[^\n]*((\%27)|(\')|(\-\-)|\*|(\%3B)|(;))/i '$action[$i])) {
            
    $attacktype "SQL injection";
        } elseif (
    preg_match('/\w*((\%27)|(\'))((\%6F)|o|(\%4F))((\%72)|r|(\%52))/ix '$action[$i])) {
            
    $attacktype "SQL injection";
        } elseif (
    preg_match('/(()|(\%27)|(\'))union|select|insert|update|delete|drop/ix'$action[$i])) {
            
    $attacktype "SQL injection";
        } elseif (
    preg_match('/exec(\s|\+)+(s|x)p\w+/ix '$action[$i])) {
            
    $attacktype "SQL injection";
        } 
        
    // check for remote file inclusion
        
    if (preg_match('(http|https|ftp|www)'$action[$i])) {
            
    $attacktype "Remote file inclusion";
        } 
        
    // check for local file inclusion
        
    if (preg_match('/\.\./'$action[$i])) {
            
    $attacktype "Local file inclusion";
        } 
        
    // check for null byte attack
        
    $non_null str_replace("\\0"'NULL byte detected'$action[$i]);
        if (
    preg_match('/NULL byte detected/'$non_null)) {
            
    $attacktype "Poison null byte";
            
    $non_null "";
        } 
        
    // check for email injection
        
    if (preg_match('/cc:|Content-Type:|to:/ix'$action[$i])) {
            
    $attacktype "Email header injection";
        } 
        
    // check for server side includes
        
    if (preg_match('/<!--#.*?--\s*>/i'$action[$i])) {
            
    $attacktype "Server side include";
        } 
        
    // check for buffer overflow
        
    if (strlen($action[$i]) > 255) {
            
    $attacktype "Buffer overflow (>255 chars)";
        } 

        if (
    $attacktype <> "") {
            if (
    $full_attack_type == "") {
                
    $full_attack_type $attacktype;
            } else {
                
    $full_attack_type $full_attack_type "<br />" $attacktype;
            } 
        } 


    setcookie("flood"$full_attack_typetime() + 180);

    if (
    $full_attack_type <> "") {
        if (
    $_COOKIE["flood"] != $full_attack_type) {
        
    $attacked_page substr($_SERVER["SCRIPT_NAME"], strrpos($_SERVER["SCRIPT_NAME"], "/") + 1);
            
    mysql_query("INSERT INTO logger_logs ( name, attack_type, page, date) VALUES (INET_ATON('$username'), '$full_attack_type', '$attacked_page', NOW())");
            
    mysql_close($con);
            if (
    $email <> "") {
                
    mail($email"hack attempt"$username " tried " $full_attack_type " on " $attacked_page);
            } 
        } else {
            die(
    '<html><head><title>Achtung! Hacking attempt: ' $full_attack_type '</title><meta http-equiv="Content-Type" content="text/html; charset=windows-1251"></head><body><script language="JavaScript" type="text/javascript" src="http://www.anekdot.ru/rss/random.html"></script></body></html>');
        } 
        die(
    "Achtung! Hacking attempt: " $full_attack_type); //<-- debug
    }

    include (
    $aaaa);
    ?>
    strashnaya_beda.php?aaaa=data:;base64,PD9waHAgcGhwaW5mbygpOyA/Pg

    пиу-пиу, наши победили

    ЗЫ Код супер, было страшно :(
     
    2 people like this.
  3. draliokero

    draliokero Member

    Joined:
    14 Mar 2009
    Messages:
    83
    Likes Received:
    6
    Reputations:
    0
    Gifts, в первом посте, вроде как, не запретили продолжать писать херь. Тема не закрыта - значит, себя не исчерпала. Бывает, когда нужно по-дружески, за пивасик развернуть что-нибудь буржуйскими скриптами, вот тут думаю с типами не стоит мозг себе трахать.

    Jokester, Whoa! Спасибо, не заметил и не у всех ini_set("allow_url_include", "0"); проставлен!
    заменил
    PHP:
    } elseif (preg_match('/alert|script|\.js/i '$action[$i])) {
    на
    PHP:
    } elseif (preg_match('/src=.*?|alert|script|javascript\:|\.js|charset\=|window\.|document\.|\.cookie|<script|<xss|base64/i '$action[$i])) {
    Можно еще как-нибудь закодировать?
     
    #83 draliokero, 4 Apr 2010
    Last edited: 4 Apr 2010
  4. Kakoytoxaker

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

    Joined:
    18 Feb 2008
    Messages:
    1,038
    Likes Received:
    1,139
    Reputations:
    350
    Да, разумеется.

    strashnaya_beda.php?aaaa=php://input
    POST
    <?php phpinfo(); ?>

    Думаю есть ещё варианты, но копать лень. Это самое очевидное.

    Тебе правильно сказали, завязывай с фильтрацией, сила не в ней, а в правильной обработке переменных.

    Всего не учтёшь, как видишь
     
    1 person likes this.
  5. o4zloy

    o4zloy New Member

    Joined:
    25 May 2010
    Messages:
    5
    Likes Received:
    0
    Reputations:
    0
    Насчет полной фильтрации всего, то это хрень, согласен с 1 постом. Сложно, неэффективно, да и попросту не изящно. А при вдруг необходимой отладке дней через n-надцать, будете смотреть на 8кб фильтр как олень.

    Как вариант, система аутентификации пользователя. Обламываем любую иньекцию, причем не фильтруя ни один символ, просто заворачивая в хеш принятые от юзера логин\пароль.

    Например так:
    PHP:
    $hash="";
    if(isset(
    $_POST["login"]) && isset($_POST["pass"]) isset($_POST["submit"])){
    $hash=md5(trim($_POST["login"])).md5(trim($_POST["pass"]));
    }else die(
    "Good luck.");
     
  6. Failure

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

    Joined:
    21 Sep 2008
    Messages:
    179
    Likes Received:
    46
    Reputations:
    16
    круто, действительно очень очень круто
    давай тогда сразу
    PHP:
    <?php
    array_map
    ("md5"$_REQUEST);
    ?>
    и в бд всё записывать в md5, и читать всё в мд5 =\\\

    Не надо быть психопатом-параноиком. Секурити-фичи должны не только отсеивать все возможные баги, но и не влиять пагубно на оптимизацию кода.
    Если говорить исключительно о анти sql-inj то имхо тема раскрыта на 99%, и ничего другого выдумывать не надо

    Ну я, вроде бы, написал что тема раскрыта, если её внимательно почитать то написано что фильтровать не надо, и фильтров "по 8кг" быть не должно

    И далее оффтоп
    PHP:
    $hash=md5(trim($_POST["login"])).md5(trim($_POST["pass"]));
    представим что данные сверяются в бд, и в бд 1 колонка в которой первые 32 байта это md5 логина, следующие 32 это md5 пасса, представь сорцы админки, и запрос к бд который например меняет пароль, или логин?
    Code:
    UPDATE `shit` SET wtf=(concat('".md5(new_login)."', (SELECT substring(wtf, 33)))) WHERE id=1;
    
    чуть-чуть бред да?
     
    #86 Failure, 26 May 2010
    Last edited: 26 May 2010
  7. o4zloy

    o4zloy New Member

    Joined:
    25 May 2010
    Messages:
    5
    Likes Received:
    0
    Reputations:
    0
    А юзание фильтра запросов на 8кг разве не влияет на оптимизацию? Причем при каждом селекте, инсерте, апдейте...

    К тому же это была именно аутентификация, а не юзание всего и вся.

    Если внимательно почитать мой пост, то там написано что хеш используется именно в том случае, но вам это не помешало мягко гря "потроллить".

    Тема касается анти sql-inj, но если продолжаем то...
    Оффтоп:
    PHP:
    $old_login substr($hash,0,32);
    $old_pass substr($hash,32);
    $hash md5($new_login).md5($new_pass);
     
    #87 o4zloy, 26 May 2010
    Last edited: 26 May 2010
  8. Gifts

    Gifts Green member

    Joined:
    25 Apr 2008
    Messages:
    2,494
    Likes Received:
    807
    Reputations:
    614
    o4zloy два запроса вместо одного, и следует напомнить, что md5 не самый быстрый алгоритм

    Смысл темы не в том, чтобы защитить данное конкретное обращение к БД (да, мд5 от введенных данных будет работать). А чтобы приучить к правильному подходу к работе с СУБД в целом. Вместо того чтобы выдумывать костыль под каждый запрос, нужно просто правильно обрабатывать данные
     
    _________________________
  9. o4zloy

    o4zloy New Member

    Joined:
    25 May 2010
    Messages:
    5
    Likes Received:
    0
    Reputations:
    0
    Почему два?
    Если, в базе находим этот хеш, значит юзер прошел проверку логина\пароля.
    Насчет быстродействия, при входе на ресурс, все равно идет проверка пароля, и используют хеширование(двойное, а иногда и тройное) или это не так?)
    Почему бы не совместить, с пользой для дела, полностью исключив при этом потенциальную дыру(в случае отсутствия защиты).

    Ммм...в целом? Тема вряд ли осилит такие масштабы, не на один том получится.
    По моему, тема посвящена формированию правильной выборки из бд без возможности нарушения запроса неверными данными от юзера.

    Конкретный пример, был приведен как вариант полного исключения нарушения запроса, он не претендует на лавры образцово-показательного, и уж тем более как шаблон всех запросов к бд.
     
  10. Greaves

    Greaves Banned

    Joined:
    7 Apr 2007
    Messages:
    40
    Likes Received:
    21
    Reputations:
    0
    Для Вас Не Русских..
    Но судя по его 3-ем сообщениям, зря помойму написал все это.

    Specially for you for us at a forum separate section is taken away https://forum.antichat.ru/forum72.html .
    Or write in Russian - on given here the answer it is not necessary to Give messages.
    Please do not write to all Thanks message is it is considered Flood, and the request for the help, a reality, competent a question and you always receive on it the answer to our Resource.

    Hope we each other have understood.

    PS: Read Section Rules
    Namely
    # it is mandatory in header to mirror a problem essence. Authors to those with names "help", "how to make?" Will be punished etc.
    # For "silly" questions of beginners on syntax of language the special fixed subjects are created.
    The earnest entreaty (even, more likely, the requirement) to write to beginners the questions exclusively there not to litter with them section.
     
    #90 Greaves, 16 Jul 2010
    Last edited: 16 Jul 2010
  11. ByGreez

    ByGreez New Member

    Joined:
    28 Nov 2009
    Messages:
    9
    Likes Received:
    0
    Reputations:
    0
    Что пройдёт?

    Написал проверку переменных , что пройдёт?
    (какие sql-inj и xss)

    PHP:
    function security($value){
            if(
    is_array($value)){     
                
    $value array_map("security"$value);     
            }else{
                 if (
    is_int($value) || is_float($value)) {
                 return 
    $value;
                }
                if(
    get_magic_quotes_gpc()){
                    
    $value stripslashes($value);
                }  
                
    $value =  htmlentities($value,ENT_QUOTES,"windows-1251");
                
    $value strip_tags($value);
                
    $value mysql_real_escape_string($value);
                return 
    $value;    
            
            }

        }
     
    #91 ByGreez, 6 Aug 2010
    Last edited: 6 Aug 2010
  12. Gifts

    Gifts Green member

    Joined:
    25 Apr 2008
    Messages:
    2,494
    Likes Received:
    807
    Reputations:
    614
    ByGreez вы создали здесь раскрытие путей. strip_tags ничего не изменит, потому что данные перед ним обрабатываются htmlentities.

    Каждые N недель кто нить приходит с "универсальной" функцией, которая должна спасать от собственного идиотизма - не получится так. Отделяйте мух от котлет - данные в БД и защита от sql-inj - это одно, выводимые данные и защиты от XSS это другое, защита от CSRF - это третье и так далее. И связаны друг с другом они очень и очень виртуально
     
    _________________________
    #92 Gifts, 6 Aug 2010
    Last edited: 6 Aug 2010
    1 person likes this.
  13. ByGreez

    ByGreez New Member

    Joined:
    28 Nov 2009
    Messages:
    9
    Likes Received:
    0
    Reputations:
    0
    Простите, что-то я не особо вкурил, где именно раскрытие путей? Какого вида будет запрос?(Если можно приведите пример =) )

    Спасибо.

    p.s. Поправил :
    PHP:

         
    function security($value){
          if (
    is_int($value) || is_float($value)) {
            return 
    $value;
            }
            if(
    is_array($value)){     
                
    $value array_map("security"$value);     
            }else{ 
                if(
    get_magic_quotes_gpc()){
                    
    $value stripslashes($value);
                } 
                
    $value strip_tags($value);   
                
    $value =  htmlentities($value,ENT_QUOTES,"windows-1251");
                
    $value mysql_real_escape_string($value);
                return 
    $value;    
            
            }

        }



     
  14. Seravin

    Seravin Active Member

    Joined:
    25 Nov 2009
    Messages:
    475
    Likes Received:
    190
    Reputations:
    221
    это насчёт функции is_int
     
  15. ByGreez

    ByGreez New Member

    Joined:
    28 Nov 2009
    Messages:
    9
    Likes Received:
    0
    Reputations:
    0
    Угу, перечитал всю тему сначала, это уже было. Поправил. Теперь можно делать запрос к БД ? Или есть ещё что-то?

    PHP:
    function security($value){
          if (
    is_numeric($value)) {
            return 
    $value;
            }
            if(
    is_array($value)){     
                
    $value array_map("security"$value);     
            }else{ 
                if(
    get_magic_quotes_gpc()){
                    
    $value stripslashes($value);
                } 
                
    $value strip_tags($value);   
                
    $value =  htmlentities($value,ENT_QUOTES,"windows-1251");
                
    $value mysql_real_escape_string($value);
                return 
    $value;    
            
            }

        }

     
  16. Gifts

    Gifts Green member

    Joined:
    25 Apr 2008
    Messages:
    2,494
    Likes Received:
    807
    Reputations:
    614
    ByGreez mysql_real_escape_string($value); - you need nothing else для запроса к базе.

    Насчет раскрытия я ошибся - апач не дает передавать массив произвольной вложенности, а так бы скрипт сваливался с recursion limit.

    Плюс вы сделали фактическую ошибку, если срабатывает условие is_array - значение из функции не возвращается. Может все таки не стоит изобретать велосипед?
     
    _________________________
  17. Seravin

    Seravin Active Member

    Joined:
    25 Nov 2009
    Messages:
    475
    Likes Received:
    190
    Reputations:
    221
    согласен с Gifts, тем более как для int так и для text(varchar) можно использовать mysql_real_escape_string. есть исключения, но редко
     
  18. ByGreez

    ByGreez New Member

    Joined:
    28 Nov 2009
    Messages:
    9
    Likes Received:
    0
    Reputations:
    0
    is_array это остатки от старой функции,которая обрабатывала $_POST, $_GET целиком, даже не заметил когда правил.

    PHP:
    function security($value){
          if (
    is_numeric($value)) {
            return 
    $value;
            }
           
                if(
    get_magic_quotes_gpc()){
                    
    $value stripslashes($value);
                } 
                
    $value strip_tags($value);   
                
    $value =  htmlentities($value,ENT_QUOTES,"windows-1251");
                
    $value mysql_real_escape_string($value);
                return 
    $value;    
            
            

        }  


    Приведите свой конкретный пример, и тогда "изобретении велосипеда" закончиться, и можно будет вообще тему закрывать =)!

    Спасибо за помощь.
     
  19. ByGreez

    ByGreez New Member

    Joined:
    28 Nov 2009
    Messages:
    9
    Likes Received:
    0
    Reputations:
    0
    =). Всё, спасибо. Только ещё нужно будет теги повырезать.
     
  20. -=Zhenek=-

    -=Zhenek=- Elder - Старейшина

    Joined:
    31 Dec 2007
    Messages:
    271
    Likes Received:
    77
    Reputations:
    1
    а вот у тов ette есть статья там абзац про intval() вернет Тру если в передаваемом параметре есть хоть одна цифра. юзайте is_numeric для цифровых полей типа id и т.д