Skip to content
KitploitKITPLOIT
ИнструментыЭксплойтыБлог
Log in
Отправить
ИнструментыЭксплойтыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

ЛентыКонтактыКонфиденциальность© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
php2shell-deep-dive — Подробный технический разбор PHP2Shell: объединение двух уязвимостей ядра PHP — краха из-за нехватки памяти и use-after-free — в цепочку с heap grooming, утечками ASLR и удалённым выполнением кода. | Kitploit
Инструменты/GitHubGitHub/djad04/php2shell-deep-dive
Криминалистика памятиАнализ уязвимостейЭксплуатацияОбратная инженерияЭксплуатация веб-приложенийCTFСтатьи и ИсследованияОбучение и ОбразованиеЭксплуатация Бинарных Файлов
GitHubdjad04/php2shell-deep-dive

php2shell-deep-dive

Подробный технический разбор PHP2Shell: объединение двух уязвимостей ядра PHP — краха из-за нехватки памяти и use-after-free — в цепочку с heap grooming, утечками ASLR и удалённым выполнением кода.

634 дней назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться
РепозиторийСайт

Я начал писать это исследование 26 октября 2026 года и пока не совсем уверен, когда его закончу.

На момент написания этой работы информации о PHP2Shell по-прежнему очень мало, особенно когда речь идёт о детальном техническом анализе уязвимостей и процесса эксплуатации.

Честно говоря, мне надоело находить объяснения, которые лишь скользят по поверхности и не показывают, что на самом деле происходит внутри. Я хотел сделать нечто иное: полноценный, глубокий технический разбор, который исследует весь процесс, рассматривая каждую важную деталь и объясняя не только ЧТО происходит, но и ПОЧЕМУ и КАК это происходит.

Это исследование основано на моём собственном понимании исходного кода PHP, моих экспериментах и расследованиях, которые я проводил, пытаясь разобраться в этих уязвимостях. Я хотел собрать все эти фрагменты воедино, поделиться своими находками и, надеюсь, сделать некоторые из лежащих в основе концепций более понятными для других.

Одной из моих главных целей было сделать материал доступным, не жертвуя технической глубиной. Я хочу, чтобы человек с базовыми знаниями C и общим опытом программирования мог следить за изложением, даже не имея предыдущего опыта в низкоуровневой эксплуатации памяти.

Я также надеюсь, что это исследование поможет прояснить некоторые вещи, которые сейчас объяснены плохо или поняты неверно. Однако хочу быть откровенным: это моё собственное техническое понимание уязвимостей, а не официальный анализ и не безошибочный справочник. Я всё ещё учусь, исследую и сам соединяю точки. По пути могут встречаться ошибки, неточности или вещи, которые я понял неправильно.

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

В конце концов, весь смысл публикации этого материала — учиться вместе и помогать большему числу людей понять, что на самом деле происходит под капотом.


Быстрая навигация

Уже знакомы с основами? Переходите сразу к интересующей вас части:

  • Прежде чем начать: стек и куча, основы выделения памяти
  • Чем это опасно?: история устаревшего указателя, чтение и запись через UAF
  • Устаревший указатель: откуда он берётся: история происхождения UAF внутри взаимодействия сессий PHP и OOM
  • Построение атакующего запроса: фактический HTTP-запрос, который вызывает OOM
  • Цель: что нам нужно утечь и почему (указатель на кучу + указатель на код)
  • Целевая структура: zend_string: структура, которую PHP читает при построении cookie сессии
  • Возврат памяти: запрос №2 и целевая структура zend_string
  • Глубокое погружение в груминг кучи: как мы размещаем поддельные данные точно в нужном слоте памяти
  • Загадка multipart_buffer_read_body: скрытое выделение памяти, которое почти свело меня с ума
  • Две утечки, а не одна: почему утечка кучи и утечка кода требуют разных калибровок
  • Утечка кода (этап 3): утечка указателя на функцию для обхода ASLR
  • Фингерпринтинг: как мы узнаём, что получили правильный указатель
  • Разбор утечки кучи: поиск базы чанка в 256 байтах хаоса
  • Конвейер 1+8: как на самом деле доставляются обе утечки
  • Повторное использование аллокатора для подделки структуры: идея перехвата pDestructor
  • Триггер: PHP делает грязную работу, реальный код zend_hash_destroy
  • Три структуры в одной: ForgedArray + FakeExecuteData + FakeString в 384 байтах
  • Финальная полезная нагрузка (этап 4): подделка HashTable для перехвата pDestructor и получения RCE
  • Механизм праймера: как призрак освобождённого праймера в bucket[2] запускает цепочку уничтожения
  • Трюк с выводом команды: поиск собственного TCP-сокета в /proc
  • Полный конвейер: все четыре этапа от начала до конца
  • Калибровка для другой сборки: как каждое число получается из анализа кучи конкретной сборки PHP
  • Реальные трудности: почему эта атака гораздо сложнее на реальном производственном сервере
  • Steal My Bitcoin CTF: задача, с которой всё началось
  • Благодарности: авторы и ссылки

Если вы новичок в эксплуатации кучи или хотите получить полный опыт, просто продолжайте читать. Я писал это так, чтобы читать от начала до конца.


Прежде чем начать

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

Стек и куча

В типичной программе память организована в различные области, включая стек и кучу.

Например, в C++:

int main() {
    int a = 30;       // Typically stored on the stack
    int* b = new int(30);  // b is typically on the stack,
                           // but the integer it points to is on the heap
}

Здесь a — локальная переменная, содержащая значение 30. Указатель b также является локальной переменной, но он содержит адрес целого числа, выделенного в куче.

Как работает выделение памяти

PHP написан в основном на C, поэтому нам нужно понимать, как работает выделение памяти.

ОС предоставляет процессу собственное виртуальное адресное пространство. Затем распределитель памяти процесса управляет выделением памяти в пределах доступной ему памяти.

Например, в C++ у нас есть new, malloc() и другие способы выделения памяти.

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

Кроме того, когда время жизни объекта заканчивается, данные, хранившиеся в его памяти, не обязательно стираются немедленно. Эта память может быть просто помечена как доступная для повторного использования.


Чтобы лучше это понять, давайте кратко рассмотрим следующий код:

#include <cstdlib>
#include <iostream>

int main() {
    void* a = malloc(64);

    free(a);

    void* b = malloc(64);

    std::cout << a << "\n" << b << std::endl;

    free(b);
    return 0;
}

Здесь, когда мы выводим a и b, мы можем обнаружить, что они содержат один и тот же числовой адрес памяти.

Скачать инструмент