Отличный фазер, он поддерживает
различные кодировки и паттерны для обхода фильтров. Огорчило то, что фазер не
поддерживает многопоточность. Сложно пользоваться однопоточным фазером.
Предлагаю следующее решение проблемы.
Dotdotpwnподдерживает разные модули:
http, http-url, ftp, tftp, payload, stdout. Модули задаются опцией –m. Модуль stdoutпозволяет
сгенерировать traversalстроки для фазинга в поток stdout.
Генерируем traversalстроки
в файл fuzz.txt следующей командой.
Непосредственно для фазинга
используем многопоточный фазер Patator,
он входит в состав KaliLinux
(и BacktrackLinux).
На вход подаем файл fuzz.txtсо
строками. Примеры использования фазера лучше всего смотреть в тексте скрипта Patator.py.
Для фазинга веб-приложения запускаем Patatorсо
следующими параметрами.
В этом посте я хочу рассказать,
как эксплуатировать SQL
инъекции в веб-приложенях на платформе PHP-MySQL.
Как обходить фильтры addslashesи mysql_real_escape_string. И как полностью скомпрометировать
хост через SQLинъекцию.
Для демонстрации я использую bWAPP. Это уязвимое PHP приложение. Оно создано
бельгийским разработчиком Malik Mesellem для обучения веб-безопасности. Это
довольно свежий проект – появился в августе 2013 года. Приложение содержит
более 60 различных уязвимостей. Как классические SQL, LDAP, XML
инъекции, инъекции команд ОС, XSS,
RFI, LFI, так и, например, SlowHTTPPOSTDoS. Для каждой уязвимости
есть три уровня сложности ее эксплуатации (low, medium,
high). Сайт проекта
находится здесь http://www.mmeit.be/bwapp/,
скачать приложение можно здесь http://sourceforge.net/projects/bwapp/.
Приложение распространяется в двух вариантах: виртуальная машина - уязвимая Ubuntu с установленным bwapp (вообщем, boot-to-root) или отдельно bwapp. Я выбрал второй вариант.
Конфигурация атакуемой машины: Windows 2008 R2 ServerRussian, XAMPP, bWAPP. Для атак я использовал Backtrack 5r3 – еще в процессе перехода на Kali))
Мой выбор Windowsи
XAMPPв
качестве платформы для bWAPPсвязан с тем, что по умолчанию сервис MySQLзапущен с
правами LocalSystem и
эксплуатация SQL
инъекции позволяет скомпрометировать весь хост.
Немного о том, что из себя
представляет bWAPPс точки зрения SQLинъекций.
bWAPPсодержит
четыре страницы с SQLинъекцией sqli_1.php, sqli_2.php, sqli_3.php,
sqli_4.php. Первая страница sqli_1.phpосуществляет
поиск в базе по GET-параметру
title. Вторая страница sqli_2.phpсодержит
поле selectи осуществляет поиск в базе по числовому GET-параметру movie. Третья страница sqli_3.php – это страница аутентификации, POST-параметры loginи
passwordиспользуются для поиска нужного пользователя в базе.
Четвертая страница sqli_4.phpсодержит
поле для ввода, значение которого передается как POST-параметр titleи
используется для поиска в базе. На основе передаваемых параметров (GETили
POST) строится SQL-запрос путем конкатенации строк. Для трех первых страниц
результаты выполнения SQL-запроса
возвращаются сервером и отображаются на странице. Для четвертой страницы
результаты запроса не отображаются, но в зависимости от результата выводится
сообщение «Themovieexists»
либо «Themoviedoesnotexists».
Перед построением SQL-запроса передаваемые
параметры (GETили POST)
попадают в функцию sqli,
которая в зависимости от уровня сложности выполняет те или иные проверки.
Вот
как выглядит эта функция:
function sqli($data)
{
switch($_COOKIE["security_level"])
{
case "0" :
$data = no_check($data);
break;
case "1" :
$data = sqli_check_1($data);
break;
case "2" :
$data = sqli_check_2($data);
break;
default :
$data = no_check($data);
break;
}
}
Все
функции проверок содержаться в файле function_external.php.
function no_check($data)
{
return $data;
}
function sqli_check_1($data)
{
return addslashes($data);
}
function sqli_check_2($data)
{
return mysql_real_escape_string($data);
}
Как видно. В случае уровня low, с данным ничего не
происходит. В случае уровня medium,
применяется функция addslashes,
которая экранирует специальные символы (‘, “, \, \x00) при помощи бэкслэша (\). В случае
уровня highиспользуется функция mysql_real_escape_string, которая экранирует специальные
символы (\x00, \n, \r, \, ', " и \x1a)
также при помощи бэкслэша (\).Еще важный момент. bWAPPработает с
MySQLиз
под пользователя rootСУБД.
Понимая, как работает приложение,
можно перейти к интересным вещам.
На уровне lowэксплуатация
SQL-инъекции в моей
конфигурации (Windows+XAMPP+bWAPP) для всех страниц приводит к
полной компрометации хоста. Атакующий получает доступ к выполнению команд
операционной системы с правами LocalSystem.
Как это происходит. SQL-инъекция дает возможность
атакующему выполнять SQL-команды
с правами пользователя rootCУБД.
Пользователь rootимеет привилегии File_priv,
которые позволяют ему читать и писать файлы с правами учетной записи процесса MySQL (т.е. LocalSystem). Для чтения файлов в MySQLиспользуется
конструкция load_file. Для записи файлов в MySQLиспользуется
конструкция intodumpfileили intooutfile.
Атакующий просто забрасывает PHPшелл в директорию Web-сервера и получает доступ к операционной системе через шелл.
Все просто.
Смотрите первый скринкаст, в
котором показано как получить доступ к ОС через SQL-инъекцию в sqli_3.php.
На уровнях mediumи hard, когда данные проходят
через addslashesили mysql_real_escape_string, а затем попадают в SQL-запрос, полностью
скомпрометировать хост уже не получиться. Причина в том, что конструкции intodumpfile (outfile) нужно обязательно передавать
имя файла в кавычках, а кавычки экранируются функциями addslashesи mysql_real_escape_string.
Записать шелл на сервер уже не получиться(
Чтение файлов возможно, так как load_file может принимать строку в бинарном
виде (например, 0x633a2f78616d70702f6874646f63732f62776170702f73716c695f312e706870 то же самое что ‘c:/xampp/htdocs/bwapp/sqli_1.php’). В нашей конфигурации (Windows+XAMPP+bWAPP) можно получить доступ на чтение к любым файлам ОС, если
конечно известен полный путь к файлам.
Если инъекция в числовом
параметре (как в случае с sqli_2.php), мы легко обходим
фильтры addslashes и mysql_real_escape_string.
Если инъекция в строковом
параметре, тогда необходима кавычка, чтобы закрыть строку и вставить наши SQL-операторы. Казалось бы, addslashes и mysql_real_escape_string
экранируют кавычку и у атакующего нет возможности терминировать строку в
оригинальном запросе. Но из-за особенностей работы функций addslashes и mysql_real_escape_string в PHP при определенных условиях у атакующего
есть возможность обойти фильтрацию одинарной кавычки.
Дело в том, что функция addslashesвообще
не различает разные кодировки символов и экранирует символы побайтно. В
документации на mysql_real_escape_string написано, что она принимает
кодировку соединения, но на практике она работает аналогично addslashes. СУБД MySQLподдерживает
разные кодировки. На моей машине, где стоит bWAPPкоманда showcharactersetпоказала
39 различных кодировок. Техника обхода как раз основана различии в обработке
символов функциями addslashesили mysql_real_escape_string и самой MySQL. Есть такие кодировки, например big5 (китайская кодировка),
которая содержит как однобайтные символы (нормальные asciiсимволы),
так и двухбайтные символы (обозначают иероглифы). В таких кодировках есть
символы, второй байт которых равен \x5c (бэкслэш
в hex). Если MySQL в такой странной кодировке, получается следующее. Если мы передаем
веб-приложению что-то вроде %e5%27,
функция addslashes или mysql_real_escape_string
преобразует это в %e5%5с%27.
Далее это передается в MySQL,
который интерпретирует это как два символа иероглиф %e5%5cи одинарную кавычку %27. Тада…мы
обходим фильтрацию)
Мне стало интересно, какие
кодировки и какие символы позволяют обойти addslashesи mysql_real_escape_string. Я написал фаззер на
питоне, который проверяет, есть ли в кодировке однобайтовый символ \x27 и ищет в кодировке все
двухбайтовые символы, у которых второй байт оканчивается на \x5c.
#!/usr/bin/python
import sys
import binascii
import struct
encoding = sys.argv[1]
sb = b'\x5c'
print "[-] Valid symbols for %s encoding ended with 5c:"%encoding
try:
"\x27".decode(encoding)
except Exception,e:
sys.exit(0)
for i in range(128,255):
symb = ""
try:
symb = (struct.pack("B",i)+sb).decode(encoding)
if len(symb) > 1:
continue
except Exception,e:
continue
s = binascii.hexlify(struct.pack("B",i)+sb)
print '%'+s[:2]+'%'+s[2:]+",",
Далее я запустил фаззер для все
кодировок, поддерживаемых MySQL.
В файл encoding.txt я скопировал вывод
команды showcharactersetбез заголовка таблицы.
В итоге получается, что четыре кодировки big5, sjis, gbk, cp932 удовлетворяют условиям и позволяют обойти фильтры addslashes и mysql_real_escape_string.
[-] Valid symbols for big5 encoding ended with 5c:
%a1%5c, %a2%5c, %a3%5c, %a4%5c, %a5%5c, %a6%5c, %a7%5c, %a8%5c, %a9%5c, %aa%5c, %ab%5c, %ac%5c, %ad%5c, %ae%5c, %af%5c, %b0%5c, %b1%5c, %b2%5c, %b3%5c, %b4%5c, %b5%5c, %b6%5c, %b7%5c, %b8%5c, %b9%5c, %ba%5c, %bb%5c, %bc%5c, %bd%5c, %be%5c, %bf%5c, %c0%5c, %c1%5c, %c2%5c, %c3%5c, %c4%5c, %c5%5c, %c6%5c, %c7%5c, %c9%5c, %ca%5c, %cb%5c, %cc%5c, %cd%5c, %ce%5c, %cf%5c, %d0%5c, %d1%5c, %d2%5c, %d3%5c, %d4%5c, %d5%5c, %d6%5c, %d7%5c, %d8%5c, %d9%5c, %da%5c, %db%5c, %dc%5c, %dd%5c, %de%5c, %df%5c, %e0%5c, %e1%5c, %e2%5c, %e3%5c, %e4%5c, %e5%5c, %e6%5c, %e7%5c, %e8%5c, %e9%5c, %ea%5c, %eb%5c, %ec%5c, %ed%5c, %ee%5c, %ef%5c, %f0%5c, %f1%5c, %f2%5c, %f3%5c, %f4%5c, %f5%5c, %f6%5c, %f7%5c, %f8%5c, %f9%5c,
[-] Valid symbols for dec8 encoding ended with 5c:
[-] Valid symbols for cp850 encoding ended with 5c:
[-] Valid symbols for hp8 encoding ended with 5c:
[-] Valid symbols for koi8r encoding ended with 5c:
[-] Valid symbols for latin1 encoding ended with 5c:
[-] Valid symbols for latin2 encoding ended with 5c:
[-] Valid symbols for swe7 encoding ended with 5c:
[-] Valid symbols for ascii encoding ended with 5c:
[-] Valid symbols for ujis encoding ended with 5c:
[-] Valid symbols for sjis encoding ended with 5c:
%81%5c, %83%5c, %84%5c, %89%5c, %8a%5c, %8b%5c, %8c%5c, %8d%5c, %8e%5c, %8f%5c, %90%5c, %91%5c, %92%5c, %93%5c, %94%5c, %95%5c, %96%5c, %97%5c, %98%5c, %99%5c, %9a%5c, %9b%5c, %9c%5c, %9d%5c, %9e%5c, %9f%5c, %e0%5c, %e1%5c, %e2%5c, %e3%5c, %e4%5c, %e5%5c, %e6%5c, %e7%5c, %e8%5c, %e9%5c, %ea%5c,
[-] Valid symbols for hebrew encoding ended with 5c:
[-] Valid symbols for tis620 encoding ended with 5c:
[-] Valid symbols for euckr encoding ended with 5c:
[-] Valid symbols for koi8u encoding ended with 5c:
[-] Valid symbols for gb2312 encoding ended with 5c:
[-] Valid symbols for greek encoding ended with 5c:
[-] Valid symbols for cp1250 encoding ended with 5c:
[-] Valid symbols for gbk encoding ended with 5c:
%81%5c, %82%5c, %83%5c, %84%5c, %85%5c, %86%5c, %87%5c, %88%5c, %89%5c, %8a%5c, %8b%5c, %8c%5c, %8d%5c, %8e%5c, %8f%5c, %90%5c, %91%5c, %92%5c, %93%5c, %94%5c, %95%5c, %96%5c, %97%5c, %98%5c, %99%5c, %9a%5c, %9b%5c, %9c%5c, %9d%5c, %9e%5c, %9f%5c, %a0%5c, %a8%5c, %a9%5c, %aa%5c, %ab%5c, %ac%5c, %ad%5c, %ae%5c, %af%5c, %b0%5c, %b1%5c, %b2%5c, %b3%5c, %b4%5c, %b5%5c, %b6%5c, %b7%5c, %b8%5c, %b9%5c, %ba%5c, %bb%5c, %bc%5c, %bd%5c, %be%5c, %bf%5c, %c0%5c, %c1%5c, %c2%5c, %c3%5c, %c4%5c, %c5%5c, %c6%5c, %c7%5c, %c8%5c, %c9%5c, %ca%5c, %cb%5c, %cc%5c, %cd%5c, %ce%5c, %cf%5c, %d0%5c, %d1%5c, %d2%5c, %d3%5c, %d4%5c, %d5%5c, %d6%5c, %d7%5c, %d8%5c, %d9%5c, %da%5c, %db%5c, %dc%5c, %dd%5c, %de%5c, %df%5c, %e0%5c, %e1%5c, %e2%5c, %e3%5c, %e4%5c, %e5%5c, %e6%5c, %e7%5c, %e8%5c, %e9%5c, %ea%5c, %eb%5c, %ec%5c, %ed%5c, %ee%5c, %ef%5c, %f0%5c, %f1%5c, %f2%5c, %f3%5c, %f4%5c, %f5%5c, %f6%5c, %f7%5c, %f8%5c, %f9%5c, %fa%5c, %fb%5c, %fc%5c, %fd%5c,
[-] Valid symbols for latin5 encoding ended with 5c:
[-] Valid symbols for armscii8 encoding ended with 5c:
[-] Valid symbols for utf8 encoding ended with 5c:
[-] Valid symbols for ucs2 encoding ended with 5c:
[-] Valid symbols for cp866 encoding ended with 5c:
[-] Valid symbols for keybcs2 encoding ended with 5c:
[-] Valid symbols for macce encoding ended with 5c:
[-] Valid symbols for macroman encoding ended with 5c:
[-] Valid symbols for cp852 encoding ended with 5c:
[-] Valid symbols for latin7 encoding ended with 5c:
[-] Valid symbols for cp1251 encoding ended with 5c:
[-] Valid symbols for cp1256 encoding ended with 5c:
[-] Valid symbols for cp1257 encoding ended with 5c:
[-] Valid symbols for binary encoding ended with 5c:
[-] Valid symbols for geostd8 encoding ended with 5c:
[-] Valid symbols for cp932 encoding ended with 5c:
%81%5c, %83%5c, %84%5c, %87%5c, %89%5c, %8a%5c, %8b%5c, %8c%5c, %8d%5c, %8e%5c, %8f%5c, %90%5c, %91%5c, %92%5c, %93%5c, %94%5c, %95%5c, %96%5c, %97%5c, %98%5c, %99%5c, %9a%5c, %9b%5c, %9c%5c, %9d%5c, %9e%5c, %9f%5c, %e0%5c, %e1%5c, %e2%5c, %e3%5c, %e4%5c, %e5%5c, %e6%5c, %e7%5c, %e8%5c, %e9%5c, %ea%5c, %ed%5c, %ee%5c, %f0%5c, %f1%5c, %f2%5c, %f3%5c, %f4%5c, %f5%5c, %f6%5c, %f7%5c, %f8%5c, %f9%5c, %fa%5c, %fb%5c,
[-] Valid symbols for eucjpms encoding ended with 5c:
Таким образом. Для того, чтобы
завершить строку в оригинальном SQL-запросе,
вместо одинарной кавычки мы должны передавать символ %e5%5c, %af%5c или %bf%5c (эти символы валидны для всех четырех кодировок).
Можно подумать, что для обхода
функций фильтрации в случае строкового параметра MySQLдолжен
обязательно быть настроен на работу с одной из перечисленных кодировок. Это не
всегда так. В PHPесть функция mysql_set_charset или мы можем вызвать mysql_query(‘SETNAMESbig5’). Таким образом мы
установим нужную нам кодировку. Веб-приложение уязвимо, если содержит вызов указанных
функций, позволяя пользователю задавать кодировку для работы с MySQL.
Еще раз повторюсь, заливать файлы
через SQL-инъекцию при
использовании addslashes
или mysql_real_escape_string не получиться, так как функции не
позволяют передать одинарную кавычку в чистом виде.
Смотрите второй скринкасте к
этому посту. В нем показано как эксплуатировать слепую SQLинъекцию в sqli_4.php на уровне hard (обходить фильтрацию mysql_real_escape_string). Скринкаст 1.