Всем привет, сегодня я попытаюсь объяснить, как работают уязвимости сериализации.
Прежде чем разрушить пирамиды, нам нужно узнать, как они их строили.
Итак, первый вопрос: что такое сериализация и десериализация?
Сериализация:
Сериализация — это механизм преобразования состояния объекта в поток байтов.
Итак, в основном это работает так:
Сериализация означает преобразование чего-либо (например, собаки Рекса) в серию единиц и нулей, которые можно передавать по телефонной линии и хранить в памяти. Мои друзья за границей могут затем преобразовать эти 1 и 0 обратно в идеальное представление щенка (десериализация), чтобы они могли наслаждаться обществом Рекса.
Зачем нам это нужно?
Вот простая аналогия, чтобы понять, почему нам нужно сериализовать данные в определенных ситуациях: скажем, у вас есть идея, и вы хотите описать ее своему другу. К сожалению, вы находитесь дома, а ваш друг где-то еще, поэтому вы решаете написать письмо, описав свою идею. Видишь, что ты только что сделал? Вы сериализуете материал в своей голове в письмо, что-то, что может быть передано, сохранено, отображено и, наконец, прочитано вашим другом. Читая эту почту и выстраивая в мозгу внутреннюю модель идеи удивляешься, потом процессу десериализации. Итак, компьютеры на самом деле всего лишь подражатели естественных процессов
Десериализация:
Десериализация — это обратный процесс, при котором поток байтов используется для воссоздания фактического объекта в памяти.
В общем
Сериализация данных на PHP:
Левая панель (описание кода):
Мы создаем класс User и назначаем $username и $password в этом классе.
Мы установили нового пользователя для нашего объекта и, по сути:
$username принадлежит $obj
$password так же принадлежит $obj
В последний момент мы вызываем нашу функцию сериализации с $obj для сериализации нашего объекта.
Правая панель (время выполнения):
На правой панели мы видим наш объект как сериализованную версию.
Что бы это могло значить?
Десериализация данных на PHP:
На стороне серверакот ловит мышь код, подобный приведенному выше, десериализует полученные сериализованные объекты. Я знаю, что это немного сбивает с толку.
Попробуем понять процесс.
1- Сервер приложений сериализует объект для отправки, а затем отправляет его в клиентский браузер.
2- Злоумышленник находит сериализованный объект, допустим, это был файл cookie.
3- Если файл cookie был закодирован как base64, прежде всего, злоумышленнику необходимо его декодировать, чтобы увидеть строку. После этого это сериализованный объект, поэтому ему нужно его десериализовать, чтобы увидеть, что находится в объекте. В этот момент объект, вероятно, хранит такие переменные, как имя пользователя, isAdmin и т. д.
Есть две вещи, с которыми вам нужно быть осторожным, когда вы выполняете атаку сериализации.
После того, как мы внедрили нашу полезную нагрузку, мы можем сериализовать ее и отправить обратно.
Магические методы PHP — это специальные методы в классе . Магические методы переопределяют действия по умолчанию, когда объект выполняет действия.
По соглашению имена магических методов начинаются с двойного подчеркивания ( __). И PHP резервирует методы, имена которых начинаются с двойного подчеркивания ( __) для магических методов.
Каждый магический метод следует определенным правилам:
-Каждый магический метод начинается с двойного подчеркивания ( __ ).
-Они предопределены и не могут быть созданы или удалены.
-Магические методы имеют зарезервированные имена, и их имена не должны использоваться для других целей.
-Магические методы вызываются автоматически при выполнении определенных условий.
Этот метод вызывается автоматически каждый раз, когда создается объект определенного класса.
Функция этого волшебного метода такая же, как у конструктора в любом ООП-языке.
В атаке часть сериализации похожа на дверь, поэтому, если они не проверяли наш ввод во время сериализации, это означает, что дверь открыта. Но чтобы украсть золото, нужно открыть ящик. В кодах ящик имеет магические функции.
Итак, дело только в том, что сериализация на самом деле не опасна, нам нужно перейти к магическим методам, чтобы навредить системе сериализацией. В противном случае наша полезная нагрузка будет десериализована, но ее нельзя будет выполнить в системе.
В заключение двух вышеперечисленных вещей, хитрость заключается в том, что вам нужно найти значение, которое не является строкой, и вам нужно перейти к уязвимым функциям (магическим методам), используя нестроковые значения для успешной атаки сериализации. Вы увидите больше деталей в симуляции атаки.
4- Браузер отправляет этот запрос на внутренний сервер.
5- Приложение десериализует его, чтобы увидеть, что находится в сериализованных данных. На этом шаге наша полезная нагрузка вызывает функцию с вредными пожеланиями
.
6- Оболочка выполнена.
Моделирование атаки:
Во-первых, давайте посмотрим на серверные коды:
Поскольку это симуляция, код на самом деле не работает, но давайте подумаем, что разработчики пытаются получить имена пользователей от клиентов с помощью метода post, а затем десериализовать его. Кроме того, в разных частях кода используется магический метод __tostring для получения содержимого файла. В этот момент, если мы десериализуем объект и сериализуем его злонамеренным образом, мы можем выполнить наши опасные желания, перейдя к магическому методу.
Сторона атакующего:
Мы пишем наш PHP-скрипт для сериализации той же формы данных с __construct для чтения файлов из системы. Этот сценарий создает вредоносные сериализованные данные.
Как вы можете видеть в выводе, s:8:username — это строковое значение, указывающее на объект ReadFile, поэтому с этими данными мы можем отправить их на сервер через браузер и запустить магические методы с нашим вводом на сервере. сторона. Итак, давайте скопируем его, чтобы отправить через curl.
Мы отправили почтовый запрос на сервер с сериализованными вредоносными данными.
БУМ! Мы можем прочитать proof.txt, который выделен на изображении выше.
Прежде чем разрушить пирамиды, нам нужно узнать, как они их строили.
Итак, первый вопрос: что такое сериализация и десериализация?
Сериализация:
Сериализация — это механизм преобразования состояния объекта в поток байтов.
Итак, в основном это работает так:
Сериализация означает преобразование чего-либо (например, собаки Рекса) в серию единиц и нулей, которые можно передавать по телефонной линии и хранить в памяти. Мои друзья за границей могут затем преобразовать эти 1 и 0 обратно в идеальное представление щенка (десериализация), чтобы они могли наслаждаться обществом Рекса.
Зачем нам это нужно?
Вот простая аналогия, чтобы понять, почему нам нужно сериализовать данные в определенных ситуациях: скажем, у вас есть идея, и вы хотите описать ее своему другу. К сожалению, вы находитесь дома, а ваш друг где-то еще, поэтому вы решаете написать письмо, описав свою идею. Видишь, что ты только что сделал? Вы сериализуете материал в своей голове в письмо, что-то, что может быть передано, сохранено, отображено и, наконец, прочитано вашим другом. Читая эту почту и выстраивая в мозгу внутреннюю модель идеи удивляешься, потом процессу десериализации. Итак, компьютеры на самом деле всего лишь подражатели естественных процессов
Десериализация:
Десериализация — это обратный процесс, при котором поток байтов используется для воссоздания фактического объекта в памяти.
В общем
Сериализация данных на PHP:
Левая панель (описание кода):
Код:
class User{public $username;
public $password;
}
Мы создаем класс User и назначаем $username и $password в этом классе.
[I]$obj = new User();[/I] Мы установили нового пользователя для нашего объекта и, по сути:
Код:
$obj->username=’zer0d’;
$obj->password=’mypass123';
$username принадлежит $obj
$password так же принадлежит $obj
Код:
echo serialize($obj);
В последний момент мы вызываем нашу функцию сериализации с $obj для сериализации нашего объекта.
Правая панель (время выполнения):
На правой панели мы видим наш объект как сериализованную версию.
Код:
O:4:”User”:2:{s:8:”username”;s:5:”zer0d”;s:8:”password”;s:9:”mypass123";}
Что бы это могло значить?
Код:
Ex: (Type:object):(4 character):( “It is User”): (it has 2 variable)
Десериализация данных на PHP:
Код:
$obj = unserialize($_POST['cmd']);
На стороне сервера
1- Сервер приложений сериализует объект для отправки, а затем отправляет его в клиентский браузер.
2- Злоумышленник находит сериализованный объект, допустим, это был файл cookie.
3- Если файл cookie был закодирован как base64, прежде всего, злоумышленнику необходимо его декодировать, чтобы увидеть строку. После этого это сериализованный объект, поэтому ему нужно его десериализовать, чтобы увидеть, что находится в объекте. В этот момент объект, вероятно, хранит такие переменные, как имя пользователя, isAdmin и т. д.
Есть две вещи, с которыми вам нужно быть осторожным, когда вы выполняете атаку сериализации.
- Нестроковые значения:
После того, как мы внедрили нашу полезную нагрузку, мы можем сериализовать ее и отправить обратно.
- Магические методы:
Магические методы PHP — это специальные методы в классе . Магические методы переопределяют действия по умолчанию, когда объект выполняет действия.
По соглашению имена магических методов начинаются с двойного подчеркивания ( __). И PHP резервирует методы, имена которых начинаются с двойного подчеркивания ( __) для магических методов.
Каждый магический метод следует определенным правилам:
-Каждый магический метод начинается с двойного подчеркивания ( __ ).
-Они предопределены и не могут быть созданы или удалены.
-Магические методы имеют зарезервированные имена, и их имена не должны использоваться для других целей.
-Магические методы вызываются автоматически при выполнении определенных условий.
Код:
__construct()
Этот метод вызывается автоматически каждый раз, когда создается объект определенного класса.
Функция этого волшебного метода такая же, как у конструктора в любом ООП-языке.
В атаке часть сериализации похожа на дверь, поэтому, если они не проверяли наш ввод во время сериализации, это означает, что дверь открыта. Но чтобы украсть золото, нужно открыть ящик. В кодах ящик имеет магические функции.
Итак, дело только в том, что сериализация на самом деле не опасна, нам нужно перейти к магическим методам, чтобы навредить системе сериализацией. В противном случае наша полезная нагрузка будет десериализована, но ее нельзя будет выполнить в системе.
В заключение двух вышеперечисленных вещей, хитрость заключается в том, что вам нужно найти значение, которое не является строкой, и вам нужно перейти к уязвимым функциям (магическим методам), используя нестроковые значения для успешной атаки сериализации. Вы увидите больше деталей в симуляции атаки.
4- Браузер отправляет этот запрос на внутренний сервер.
5- Приложение десериализует его, чтобы увидеть, что находится в сериализованных данных. На этом шаге наша полезная нагрузка вызывает функцию с вредными пожеланиями
6- Оболочка выполнена.
Моделирование атаки:
Во-первых, давайте посмотрим на серверные коды:
Поскольку это симуляция, код на самом деле не работает, но давайте подумаем, что разработчики пытаются получить имена пользователей от клиентов с помощью метода post, а затем десериализовать его. Кроме того, в разных частях кода используется магический метод __tostring для получения содержимого файла. В этот момент, если мы десериализуем объект и сериализуем его злонамеренным образом, мы можем выполнить наши опасные желания, перейдя к магическому методу.
Сторона атакующего:
Мы пишем наш PHP-скрипт для сериализации той же формы данных с __construct для чтения файлов из системы. Этот сценарий создает вредоносные сериализованные данные.
Как вы можете видеть в выводе, s:8:username — это строковое значение, указывающее на объект ReadFile, поэтому с этими данными мы можем отправить их на сервер через браузер и запустить магические методы с нашим вводом на сервере. сторона. Итак, давайте скопируем его, чтобы отправить через curl.
Мы отправили почтовый запрос на сервер с сериализованными вредоносными данными.
БУМ! Мы можем прочитать proof.txt, который выделен на изображении выше.