mysql_real_escape_string

Discussion in 'Песочница' started by Pirotexnik, 13 Dec 2011.

Thread Status:
Not open for further replies.
  1. Pirotexnik

    Pirotexnik Member

    Joined:
    13 Oct 2010
    Messages:
    376
    Likes Received:
    73
    Reputations:
    38
    Здравствуйте. Поставил DVWA, тренируюсь.
    На 2-х уровнях безопасности провел инъекцию, на 3-м стоит сабж.
    Как я понял обойти его можно, даже нужно. Только как?
    PHP:
    <?php     

    if (isset($_GET['Submit'])) { 

        
    // Retrieve data 

        
    $id $_GET['id']; 
        
    $id stripslashes($id); 
        
    $id mysql_real_escape_string($id); 

        if (
    is_numeric($id)){ 

            
    $getid "SELECT first_name, last_name FROM users WHERE user_id = '$id'"
            
    $result mysql_query($getid) or die('<pre>' mysql_error() . '</pre>' ); 

            
    $num mysql_numrows($result); 

            
    $i=0

            while (
    $i $num) { 

                
    $first mysql_result($result,$i,"first_name"); 
                
    $last mysql_result($result,$i,"last_name"); 
                 
                echo 
    '<pre>'
                echo 
    'ID: ' $id '<br>First name: ' $first '<br>Surname: ' $last
                echo 
    '</pre>'

                
    $i++; 
            } 
        } 

    ?>
     
    #1 Pirotexnik, 13 Dec 2011
    Last edited: 13 Dec 2011
  2. Чакэ

    Чакэ Elder - Старейшина

    Joined:
    15 Aug 2010
    Messages:
    260
    Likes Received:
    66
    Reputations:
    62
    тебя обманули.
     
  3. Pirotexnik

    Pirotexnik Member

    Joined:
    13 Oct 2010
    Messages:
    376
    Likes Received:
    73
    Reputations:
    38
    Таки нет. По твоему это не проходимый квест?)
     
  4. Чакэ

    Чакэ Elder - Старейшина

    Joined:
    15 Aug 2010
    Messages:
    260
    Likes Received:
    66
    Reputations:
    62
    по-моему тебя обманули.

    stripslashes($id); это шикарно
     
  5. phpdreamer

    phpdreamer Member

    Joined:
    26 Jul 2009
    Messages:
    522
    Likes Received:
    86
    Reputations:
    19
    http://php.net/manual/en/function.mysql-real-escape-string.php
    Если magic_quotes_gpc ON и сначала stripslashes, то получается 2-ой эскейп

    magic_quotes_gpc - это единственная проблема у mysql-real-escape-string и она уходит в прошлое, потому что никто не включает эту опцию
     
  6. KolosJey

    KolosJey Member

    Joined:
    21 Dec 2009
    Messages:
    45
    Likes Received:
    42
    Reputations:
    48
    phpdreamer

    Если ты считаешь что этот код уязвим, покажи реализацию плз.

    Та цитата, которую ты привёл, говорит о том, что при MQ=on НАДО убирать слеши, и тут они убираются.
    Но это не секурити проблема. Да, данные заэскейпяться дважды, но скуль ты не проведёшь, т.к. бекслеши тоже заэскейпятся.
    Это можно было-бы проделать при mysql_escape_string которая не учитывает кодировку, но тут...

    Да и это вобщем-то не всё. Даже если мы прорываем mysql_real_escape_string дальше идёт is_numeric, так что...

    Вобщем у кого есть реальзация баги, было-бы интересно взглянуть, но я склоняюсь к тому, что разрабы курнули
     
  7. Pirotexnik

    Pirotexnik Member

    Joined:
    13 Oct 2010
    Messages:
    376
    Likes Received:
    73
    Reputations:
    38
    http://www.dvwa.co.uk/
    Тренировачная площадка для хакера. 3 уровня сложности. Легкий и средний прошел, но тяжелый не выходит...
     
  8. Чакэ

    Чакэ Elder - Старейшина

    Joined:
    15 Aug 2010
    Messages:
    260
    Likes Received:
    66
    Reputations:
    62
    ohlol
     
  9. alias6969

    alias6969 Member

    Joined:
    3 Apr 2011
    Messages:
    27
    Likes Received:
    11
    Reputations:
    6
    ТС, верный ответ на твой вопрос - никак.
     
  10. Konqi

    Konqi Green member

    Joined:
    24 Jun 2009
    Messages:
    2,251
    Likes Received:
    1,149
    Reputations:
    886
    stripslashes и mysql_real_escape_string тут вообще никакой роли не играют, проверка входных данных осуществляется функцией is_numeric, а его ты не пройдешь никак
     
    _________________________
    #10 Konqi, 18 Dec 2011
    Last edited: 18 Dec 2011
  11. trololoman96

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

    Joined:
    1 Dec 2011
    Messages:
    120
    Likes Received:
    34
    Reputations:
    55
    Навряд ли конечно, но может будет полезно, is_numeric() пропускает хекс
    PHP:
    $test is_numeric('0x3a');
    var_dump($test);
    возвращает bool(true), хз как это можно использовать тут, но может наведет кого на мысли.
     
  12. Konqi

    Konqi Green member

    Joined:
    24 Jun 2009
    Messages:
    2,251
    Likes Received:
    1,149
    Reputations:
    886

    PHP:
    <?php
     
    //hex('union+select') -> 0x756e696f6e2b73656c656374
    $test is_numeric('0x756e696f6e2073656c656374'); 
    var_dump($test);
    ?>
    bool(false)


    откуда такая инфа ?
     
    _________________________
    #12 Konqi, 18 Dec 2011
    Last edited: 18 Dec 2011
  13. trololoman96

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

    Joined:
    1 Dec 2011
    Messages:
    120
    Likes Received:
    34
    Reputations:
    55
    У меня 0x756e696f6e2073656c656374 возвращает true.
    Тестилось на Apache/2.2.8 (Win32) PHP/5.2.6
    --------
    инфа взята с бложека разора, http://raz0r.name/mysli/phpids-za-i-protiv/
    вычитано в коментах
     
  14. M_script

    M_script Members of Antichat

    Joined:
    4 Nov 2004
    Messages:
    2,581
    Likes Received:
    1,317
    Reputations:
    1,557
    Допустим, is_numeric обошли. Как из кавычек в запросе выйти?
     
  15. Konqi

    Konqi Green member

    Joined:
    24 Jun 2009
    Messages:
    2,251
    Likes Received:
    1,149
    Reputations:
    886
    0x3a пропускает потому что оно число в hex (13) 0011 (2^0 + 2^1) + 1010 (2^1+2^3)

    а текст пропускать не может
     
    _________________________
  16. trololoman96

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

    Joined:
    1 Dec 2011
    Messages:
    120
    Likes Received:
    34
    Reputations:
    55
    Konqi, почему тогда 0x756e696f6e2073656c656374 у меня тоже возвращает true ?
    ---------
    Протестировал еще на PHP Version 5.2.17 (linux) тоже вернуло true
     
    #16 trololoman96, 18 Dec 2011
    Last edited: 19 Dec 2011
  17. Konqi

    Konqi Green member

    Joined:
    24 Jun 2009
    Messages:
    2,251
    Likes Received:
    1,149
    Reputations:
    886
    Windows NT/ php 5.1.6 - false
    Linux / 5.2.6 - true
    Linux / 5.2.17 - true

    хм =\


    p.s если вернемся к теме, то ясно становится, если даже is_numeric Поможет обойти фильтр, то вес запрос все равно в hex виде не отправишь в бд, база операторы в хекс виде не поймет, так что с этим все равно облом, но тему is_numeric стоит исследовать..
     
    _________________________
    #17 Konqi, 19 Dec 2011
    Last edited: 19 Dec 2011
  18. Expl0ited

    Expl0ited Members of Antichat

    Joined:
    16 Jul 2010
    Messages:
    1,035
    Likes Received:
    534
    Reputations:
    935
    PHP:
    <?php
    function conv($string$hex='')
    {
        for (
    $i=0;$i<strlen($string);$i++)$hex .= dechex(ord($string[$i]));
        return 
    '0x'.$hex;
    }
    $data = array('union select 1 from table#''$%^&*(Jkabhsdf''test''UniON/**/SELECT/**/1''-1/*!UnioN SELEct*/1,2,3');
    foreach(
    $data as $str) {
        
    ob_start();
        
    var_dump(is_numeric(conv($str)));
        
    $dump ob_get_contents();
        
    ob_end_clean();
        print 
    "Str: {$str}\nHex value:".conv($str)."\nis_numeric? - ".trim($dump)."\n";
        print 
    "\n--------------------\n\n";
    }
    ?>
    Code:
    Str: union select 1 from table#
    Hex value:0x756e696f6e2073656c65637420312066726f6d207461626c6523
    is_numeric? - bool(true)
    
    --------------------
    
    Str: $%^&*(Jkabhsdf
    Hex value:0x24255e262a284a6b616268736466
    is_numeric? - bool(true)
    
    --------------------
    
    Str: test
    Hex value:0x74657374
    is_numeric? - bool(true)
    
    --------------------
    
    Str: UniON/**/SELECT/**/1
    Hex value:0x556e694f4e2f2a2a2f53454c4543542f2a2a2f31
    is_numeric? - bool(true)
    
    --------------------
    
    Str: -1/*!UnioN SELEct*/1,2,3
    Hex value:0x2d312f2a21556e696f4e2053454c4563742a2f312c322c33
    is_numeric? - bool(true)
    Если же убрать 0x в хекс значении:
    PHP:
    <?php
    function conv($string$hex='')
    {
        for (
    $i=0;$i<strlen($string);$i++)$hex .= dechex(ord($string[$i]));
        return 
    $hex;
    }
    $data = array('union select 1 from table#''$%^&*(Jkabhsdf''test''UniON/**/SELECT/**/1''-1/*!UnioN SELEct*/1,2,3');
    foreach(
    $data as $str) {
        
    ob_start();
        
    var_dump(is_numeric(conv($str)));
        
    $dump ob_get_contents();
        
    ob_end_clean();
        print 
    "Str: {$str}\nHex value:".conv($str)."\nis_numeric? - ".trim($dump)."\n";
        print 
    "\n--------------------\n\n";
    }
    ?>
    Code:
    Str: union select 1 from table#
    Hex value:756e696f6e2073656c65637420312066726f6d207461626c6523
    is_numeric? - bool(false)
    
    --------------------
    
    Str: $%^&*(Jkabhsdf
    Hex value:24255e262a284a6b616268736466
    is_numeric? - bool(false)
    
    --------------------
    
    Str: test
    Hex value:74657374
    is_numeric? - bool(true)
    
    --------------------
    
    Str: UniON/**/SELECT/**/1
    Hex value:556e694f4e2f2a2a2f53454c4543542f2a2a2f31
    is_numeric? - bool(false)
    
    --------------------
    
    Str: -1/*!UnioN SELEct*/1,2,3
    Hex value:2d312f2a21556e696f4e2053454c4563742a2f312c322c33
    is_numeric? - bool(false)
    Хотя это понятно, он воспринимает хек значение без 0x как обычную строку.
     
    _________________________
  19. Expl0ited

    Expl0ited Members of Antichat

    Joined:
    16 Jul 2010
    Messages:
    1,035
    Likes Received:
    534
    Reputations:
    935
    а вообще если разобрать код из первого поста:
    PHP:
    <?php      

    if (isset($_GET['Submit'])) {  

        
    // Retrieve data  

        
    $id $_GET['id'];  
        
    $id stripslashes($id);  // в случае если MQ=ON, то убирается экранирование
        
    $id mysql_real_escape_string($id); // тут происходит экранирование по правилам функции mysql_real_escape_string, которая добавляет обратную косую черту к следующим символам: \x00, \n, \r, \, ', " и \x1a.

        // тут проходит проверка содержимого переменной $id, число это или нет, если нет, то ничего не происходит
        // если же в $id число (а именно функция is_numeric пропускает строки, содержащие числа, состоят из необязательного знака, любого количества цифр, 
        // необязательной десятичной части и необязательной экспоненциальной части. Так, +0123.45e6 является верным числовым значением. 
        // Шестнадцатеричная запись (0xFF) также допускается, но только без знака, десятичной и экспоненциальной части.)
        // то происходит запрос к БД
        
    if (is_numeric($id)){  

            
    // переменная $id обрамлена одинарной кавычкой, что заставляет соблюсти правильный синтаксис скул запроса, для проведения инъекции 
            // и прибегнуть к использованию одинарной кавычки на примере: 1' and false union select 1,2,3#
            // но так как, во-первых функция mysql_real_escape_string заэкранирует нашу кавычку
            // а is_numeric вообще не выполнит условие, то все попытки четны.
            
    $getid "SELECT first_name, last_name FROM users WHERE user_id = '$id'";  
            
    $result mysql_query($getid) or die('<pre>' mysql_error() . '</pre>' );  

            
    $num mysql_numrows($result);  

            
    $i=0;  

            while (
    $i $num) {  

                
    $first mysql_result($result,$i,"first_name");  
                
    $last mysql_result($result,$i,"last_name");  
                  
                echo 
    '<pre>';  
                echo 
    'ID: ' $id '<br>First name: ' $first '<br>Surname: ' $last;  
                echo 
    '</pre>';  

                
    $i++;  
            }  
        }  
    }  
    ?>
    Я так полагаю автор привел не полный код уязвимого скрипта. В данном коде, лично я, уязвимостей не наблюдаю.
     
    _________________________
    #19 Expl0ited, 19 Dec 2011
    Last edited: 19 Dec 2011
  20. KolosJey

    KolosJey Member

    Joined:
    21 Dec 2009
    Messages:
    45
    Likes Received:
    42
    Reputations:
    48
    is_numeric() разумеется пропускает 0xlalala, потому что это ЧИСЛО.
    И даже если переменная в запросе не будет обрамлена кавычками (id=$id)
    то всё равно инъекции не будет, база такое гавно не схавает :)

    А если бы это было возможно, то все WAFы сосали бы сразу, т.к. по этой логике можно сразу весь запрос переводить в HEX и не парится )

    PS Об этом свойстве is_numeric примерно раз в год все вспоминают\открывают заново и начинаются движения и исследования, которые ничем не кончаются, и снова забвение на год )
     
    1 person likes this.
Thread Status:
Not open for further replies.