Загрузка...

#4. php object injection уязвимости.

Тема в разделе Веб уязвимости создана пользователем пользователь 29 апр 2023. (поднята 30 май 2024) 590 просмотров

Загрузка...
  1. пользователь
    https://t.me/+-myFKhrNkBowZjQy - моя беседа для любителей различного рода уязвимостей. прыгай к нам)

    дисклеймер:
    автор не несёт ответственности за ваши дальнейшие действия, всё нижеизложенное написано лишь в ознакомительных целях, все совпадения случайны, а всё то, что было написано, лишь вымысел автора, и не имеет связи с реальным миром.
    помни: любой взлом карается законом.


    вновь приветствую тебя, пользователь форума lolzteam :animewave:
    в этой статье ты узнаешь, что представляет из себя уязвимость php object injection, каким образом и как она работает. поехали!


    что это?

    php object injection (иньекция php обьектов) - это уязвимость, позволяющая внедрять произвольные php обьекты на сервер, что в некоторых случаях может привести к уязвимости вида RCE (удалённое выполнение кода).
    php object injection возникает, когда необработанный пользовательский ввод преобразуется (десериализуется) при помощи функции
    unserialize().


    о (де)сериализации в php
    для начала, терминология:
    сериализация - процесс преобразования объекта в текстовый или иной вид, для последующей передачи / хранения в файлах.
    десериализация - обратный процесс, когда объект создаётся из входных данных (например, из текста).

    сериализация и десериализация в php устроены следующим образом:

    PHP

    // сериализация
    $text = serialize($object);
    // десериализация
    $object = unserialize($text);


    синтаксис строки, полученной в результате десериализации, довольно прост (об этом поговорим чуть ниже):
    1. ; - разделитель данных.
    2. s - строка (пример: s:4:"text", где 4 - длина строки)
    3. a - массив (пример: a:2:{x;y;x;y;}, где x - ключ, а y - значение)
    4. i - целое число (от слова int, пример: i:1234)
    5. b - логическое значение, 0 (false) или 1 (true) (пример: b:1)
    6. d - число с плавающей точкой (пример: d:12.5)
    7. O - объект класса (пример: O:7:"myclass":1:{s:5:"value";i:123;})
    8. N - null (без понятия, как это выглядит, но оно есть)


    примеры десериализации


    после преобразования массива, состоящего из пяти чисел (
    100, 105, 200, 230 и 400), мы получим подобную строку:
    A:5:{i:0;i:100;i:1;i:105;i:2;i:200;i:3;i:230;i:4;i:400;}

    строка
    "hi lolz" в преобразованном виде будет выглядеть так:
    s:7:"hi lolz";

    PHP

    class MyClass {
    public $value = "hihi";
    function __construct() {
    echo "вызван метод __construct()\n";
    }
    }

    обьект класса MyClass в преобразованном виде будет выглядеть так:
    O:7:"MyClass":1:{s:5:"value";s:4:"hihi";}


    пример уязвимого кода

    допустим, у нас есть два класса - класс
    User и класс System.
    PHP

    class User {
    public $name = "";
    function func() {
    echo $name . "\n";
    }
    }
    class System {
    public $cmd = "";
    function func() {
    echo system($cmd);
    }
    }

    оба класса имеют функцию func(), при вызове которой выполняются следующие действия:
    - у класса
    User эта функция выводит никнейм пользователя.
    - у класса
    System эта функция выводит результат выполнения команды, указанной в переменной $cmd.


    чуть ниже мы имеем объект
    $obj, который конструируется из пользовательского ввода ($input) при помощи функции unserialize(), после чего у этого объекта вызывается метод func():
    PHP

    $input = $_GET['user_input'];
    $obj = unserialize($input);
    // ...
    $obj->func();


    по задумке разработчиков, в функцию
    unserialize() поступит примерно такая строка:
    O:4:"User":1:{s:4:"name";s:10:"RaysMorgan";}

    после чего сконструируется объект класса
    User, у которого будет вызван метод func(), который выведет на экран заданный пользователем никнейм.


    путь к XSS


    в данном случае мы имеем пользовательский ввод, отображаемый на странице.
    попробуем вместо
    "RaysMorgan" указать классический пейлоад:
    "><script>alert(1)</script>

    при отсутствии фильтрации (замены спец.символов
    ", < и > на соответствующие из таблицы HTML entities) браузер подумает, что это не текст, а полноценный HTML тег script, после чего выполнит код, т.е. его содержимое, и мы увидим окошко с нашей заветной цифрой:)


    путь к RCE


    хитрый пользователь, узнав о том, что существует некий класс
    System с переменной $cmd и функцией func(), обязательно додумается отправить следующий пейлоад:
    O:6:"System":1:{s:3:"cmd";s:2:"ls";}

    в этом случае на сервере произойдёт следующее:

    1. вместо объекта класса User сконструируется объект класса System.
    2. полю $cmd этого объекта будет присвоено значение "ls".
    2. у этого объекта будет вызвана функция func().
    ошибок не будет, потому что у класса System есть функция с таким-же именем.
    3. пользователь увидит следующий вывод:
    index.php config.php db.php // и прочие возможные файлы.

    следовательно, пользователь смог выполнить произвольный код на стороне сервера, и получил очень серьёзную RCE уязвимость из php object injection.


    итоги


    вы узнали, что такое php object injection, и каким образом можно раскрутить эту уязвимость до несерьёзной XSS и более серьёзной RCE. надеюсь, что вы смогли открыть что-то новое для себя)

    спасибо, что прочитали мою статью :love2:
     
    29 апр 2023 Изменено
  2. dsllviews
    dsllviews 30 апр 2023 208 17 авг 2022
    Статья классная, но не припомню случаев, когда б десериализовали строку пришедшею от пользователя.

    Вот ещё можно почитать про уязвимости PHP, если кому интересно, она конечно старая, но всё же статья интересная
    https://habr.com/ru/companies/vk/articles/308242/
     
Top