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

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

  1. nerezus

    nerezus Banned

    Joined:
    12 Aug 2004
    Messages:
    3,191
    Likes Received:
    729
    Reputations:
    266
    Pashkela, ну я думал, что понятно, что нельзя доверять любому вводу )

    Его уже не осталось, да и не нужен он - это было слабое подобие Zend_Db
     
    1 person likes this.
  2. nerezus

    nerezus Banned

    Joined:
    12 Aug 2004
    Messages:
    3,191
    Likes Received:
    729
    Reputations:
    266
    Чем же мануал по 0.1.5 версии актуальнее актуального 1.9.x на оффсайте?)))
     
  3. Explоit

    Explоit Banned

    Joined:
    21 Jul 2009
    Messages:
    19
    Likes Received:
    0
    Reputations:
    0
    Статья про анти sql-inj, а ачат - анти хак сайт,

    а и ещё осталось не писать сплоиты, а исправлять баги веб приложений
     
    #63 Explоit, 28 Sep 2009
    Last edited: 28 Sep 2009
  4. Gray_Wolf

    Gray_Wolf Active Member

    Joined:
    7 Mar 2009
    Messages:
    377
    Likes Received:
    135
    Reputations:
    10
    Вообщето ачат это сайт по аудиту безопасности.
    Так что всё верно...
     
  5. Forcer

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

    Joined:
    12 Apr 2007
    Messages:
    321
    Likes Received:
    98
    Reputations:
    12
    Ничего не сказано про prepared statement'ы. Именно из-за их использования ORM движки обладают побочным эффектом защиты от sql-inj.
     
    1 person likes this.
  6. nerezus

    nerezus Banned

    Joined:
    12 Aug 2004
    Messages:
    3,191
    Likes Received:
    729
    Reputations:
    266
    Ну это личные внутренности ОРМ, он может и по типу эскейпить просто. ;)
    НО про них надо в другом месте сказать, обновлю )
     
  7. Gray_Demon

    Gray_Demon New Member

    Joined:
    22 Feb 2007
    Messages:
    5
    Likes Received:
    0
    Reputations:
    0
    Уже на многих ру хостах юнион селект рубают , надежда ток на кавычку и знание движка(((
     
  8. nerezus

    nerezus Banned

    Joined:
    12 Aug 2004
    Messages:
    3,191
    Likes Received:
    729
    Reputations:
    266
    Не верю. Если и есть такие, то это единичные случаи за "2 бакса в год", т.к. юнион селект полезен и юзается активно.
     
  9. phpdreamer

    phpdreamer Member

    Joined:
    26 Jul 2009
    Messages:
    522
    Likes Received:
    86
    Reputations:
    19
    что думаете про такой подход?
    PHP:
    function antihack () {  
      
    $uri $_SERVER['REQUEST_URI']; //определяем адрес запрашиваемой страницы  
      
    $arr_u explode("?"$uri ); //разделяем адрес на массив  
    $url $arr_u[0];  //того что до знака ?   
    $p_url $arr_u[1]; // и того что после  
      
      
    $inj='/script|http|<|>|<|>|SELECT|UNION|UPDATE|AND|exe|exec|INSERT|tmp/i'//это паттерн возможных типов атак в адресе (их можно дополнить своими)  
      
      
    if (preg_match($inj$p_url )) { // ищем патерн в нашем адресе, в том что за знаком ?  
      
        
    die("Hacking attempt!"); //если находим - посылаем куда подальше :=)  
    }  
    }  
    взято с http://phpmaster.su/php-faq/8-kak-zashhititsya-ot-sql-inekcij-xss-atak-na-php.html
    много чего можно добавить к этому коду, но сам подход..?
     
  10. Qwazar

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

    Joined:
    2 Jun 2005
    Messages:
    989
    Likes Received:
    904
    Reputations:
    587
    phpdreamer, провальный подход. Первый пост читай, там ВСЁ описано.
     
  11. phpdreamer

    phpdreamer Member

    Joined:
    26 Jul 2009
    Messages:
    522
    Likes Received:
    86
    Reputations:
    19
    спасибо, теперь разобрался
     
  12. wolmer

    wolmer Member

    Joined:
    12 May 2009
    Messages:
    438
    Likes Received:
    97
    Reputations:
    9
    Не соглашусь, сейчас пробывал в опере 10 набрать в get параметре это => "SeLEcT" (без ковычек), итог => не проскочило слово

    Вообще да, плохая защита
     
    #72 wolmer, 18 Dec 2009
    Last edited: 18 Dec 2009
  13. cr0w

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

    Joined:
    11 Sep 2008
    Messages:
    92
    Likes Received:
    141
    Reputations:
    33
    Это ппц.
    Засунуть в коммент в скл-инъекции знак "?" - вот и весь обход "фильтрации":
    Code:
    ?lala=-1+/*?*/union+select+...
    (;

    Nightmarе

    Буква "i" в той регулярке - модификатор...
     
    #73 cr0w, 18 Dec 2009
    Last edited: 18 Dec 2009
    1 person likes this.
  14. phpdreamer

    phpdreamer Member

    Joined:
    26 Jul 2009
    Messages:
    522
    Likes Received:
    86
    Reputations:
    19
    я тоже сразу подумал что надо проверять еще count массива... вопрос был не о том, но больше вопросов нет =)
     
  15. imy681

    imy681 New Member

    Joined:
    16 Nov 2008
    Messages:
    6
    Likes Received:
    0
    Reputations:
    0
    Скули обречены на вымирание :)
    Юзайте mysqli и ничего фильтровать не надо и искейпить тоже не надо ничего.

    $mysqli = new mysqli();
    $mysqli->prepare("select * from data where id = ?");

    и далее по тексту :)
     
  16. Seravin

    Seravin Active Member

    Joined:
    25 Nov 2009
    Messages:
    475
    Likes Received:
    190
    Reputations:
    221
    А если так использовать можно избежать xss/sqli???
    Code:
    function secure($par) {
      $numb = array("1","2","3","4","5","6","7","8","9","0","-");
       if( get_magic_quotes_gpc())
    	   {
               $link = stripslashes($par);
    	   }
       $l=$par+1-1;
       if ((string)$l==(string)$par) {
    	   
         $par=(string)$par;
         $new_par="";
         for ($i=0;$i<>strlen($par);$i++) {
           if (in_array($par{$i},$numb)) {
           $new_par=$new_par.$par{$i};
    	   }
          if ($new_par<"-2147483648" || $new_par>"2147483647") $new_par="1";
    	 $new_par=(int)$new_par;
         }
       }
       else
       {
       $new_par=mysql_real_escape_string($par);
       }
       return $new_par;
    }
    
    Так вроде и раскрытия путей не будет
     
    #76 Seravin, 13 Feb 2010
    Last edited: 13 Feb 2010
  17. b3

    b3 Banned

    Joined:
    5 Dec 2004
    Messages:
    2,174
    Likes Received:
    1,157
    Reputations:
    202
    А где проверка на то что $par может быть массив?
     
  18. nerezus

    nerezus Banned

    Joined:
    12 Aug 2004
    Messages:
    3,191
    Likes Received:
    729
    Reputations:
    266
    Самый говнокодистый говнокод в этой теме.
     
  19. Seravin

    Seravin Active Member

    Joined:
    25 Nov 2009
    Messages:
    475
    Likes Received:
    190
    Reputations:
    221
    На самом деле это не просто самый говнокодистый говнокод, это код который не работает и не имеет смысла!
    И это меня заставило подумать о том что писал nerezus в первом посте.
    Когда я искал инъекции на различных сайтах меня смущало то, что когда я открываю страницу site.com/news.php?id=1 и добавляю к примеру +1+1+1, то у меня открывается та же страница, что и при id=1. Ну и что я надумал: если запрос вида SELECT * FROM TABLE WHERE id='.$id.', а в базе параматр id целочисленный, то наверно где то идёт конвертация значения id из строки в число. Единственное моё обьяснение так это конвертация процедурой похожей на процедуру val в Delphi( procedure Val ( const NumberString : string; var NumberVar : Number Type; var ErrorCode : Integer ) ), где ErrorCode - позиция с начиная с которой нельзя сконвертировать строку. Как я понял СУБД обрезает строку начиная с параметра ErrorCode и до конца, в итоге и получается id=1. nerezus сказал, что надо использовать mysql_real_escape_string() в текстовых полях и не изобретать какие-либо фильтры и т.д и т.п. Это нужно для того чтобы не нарушился синтаксис sql при добавлении '. По моему стоит эту функцию использовать и для числовых значений, и главное чтобы запрос был вида SELECT * FROM TABLE WHERE id='.$id.', потому что тогда параметр id передаётся строкой и субд ковертирует id в integer. Если будет запрос вида SELECT * FROM TABLE WHERE id=$id, тогда, как я понял не идёт проверка на принадлежность $id к числовому типу. Если я ошибаюсь, то поправьте, а то заведу кого-нибудь в заблуждение этим постом...
     
  20. draliokero

    draliokero Member

    Joined:
    14 Mar 2009
    Messages:
    83
    Likes Received:
    6
    Reputations:
    0
    Может пригодиться кому-нибудь использованный мной контрацептив моих проектов:
    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('/src=.*?|alert|script|javascript\:|\.js|charset\=|w  indow\.|document\.|\.cookie|<script|<xss|base64/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
    }
    ?>
     
    #80 draliokero, 4 Apr 2010
    Last edited: 16 Jun 2010