Содержание статьи
- Готовимся к эксплуатации
- Уязвимость
- Демонстрация уязвимости (видео)
- Заключение
Все любят забавные гифки, но особый юмор — это повесить сервер на PHP при помощи специально сформированного файла GIF. Успешная эксплуатация бага, который мы разберем, приводит процесс в состояние бесконечного цикла. Создав множество таких процессов, атакующий исчерпает ресурсы системы. Жертвой может стать любой сервис, который производит манипуляции с картинками, написан на PHP и использует библиотеку gd или libgd.
Уязвимость получила идентификатор CVE-2018-5711, а обнаружил ее исследователь Orange Tsai (@orange_8361) из тайваньской компании Devcore. О деталях он написал в своем блоге.
WARNING
Вся информация предоставлена исключительно в ознакомительных целях. Ни редакция, ни автор не несут ответственности за любой возможный вред, причиненный материалами данной статьи.
Готовимся к эксплуатации
Главное, что нам понадобится, чтобы испытать баг, — это уязвимая версия PHP. Их у нас целый пучок:
- PHP 5 < 5.6.33,
- PHP 7.0 < 7.0.27,
- PHP 7.1 < 7.1.13,
- PHP 7.2 < 7.2.1.
Выбирай любую, как говорится. Если хочешь контролировать процесс эксплуатации и рассмотреть уязвимость поближе, то тебе понадобится версия, которая содержит дополнительную отладочную информацию (dbg-версия). Большинство дистрибутивов Linux позволяют установить dbg-версию с помощью пакетного менеджера. Я буду использовать Debian 8 в контейнере Docker.
docker run --rm -ti --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --name=phpgd --hostname=phpgd debian:jessie-20171210 /bin/bash apt-get update
В моем случае в репозитории имелись две версии дистрибутива: 5.6.33 и 5.6.30.
apt-cache policy php5-dbg

Версия PHP 5.6.30 точно уязвима, поэтому ее и установим.
apt-get install -y php5-dbg=5.6.30+dfsg-0+deb8u1 php5-common=5.6.30+dfsg-0+deb8u1 libapache2-mod-php5=5.6.30+dfsg-0+deb8u1 php5-cgi=5.6.30+dfsg-0+deb8u1 php5-cli=5.6.30+dfsg-0+deb8u1 php5-fpm=5.6.30+dfsg-0+deb8u1 libphp5-embed=5.6.30+dfsg-0+deb8u1 php5-curl=5.6.30+dfsg-0+deb8u1 php5-enchant=5.6.30+dfsg-0+deb8u1 php5-gd=5.6.30+dfsg-0+deb8u1 php5-gmp=5.6.30+dfsg-0+deb8u1 php5-imap=5.6.30+dfsg-0+deb8u1 php5-interbase=5.6.30+dfsg-0+deb8u1 php5-intl=5.6.30+dfsg-0+deb8u1 php5-ldap=5.6.30+dfsg-0+deb8u1 php5-mcrypt=5.6.30+dfsg-0+deb8u1 php5-readline=5.6.30+dfsg-0+deb8u1 php5-mysql=5.6.30+dfsg-0+deb8u1 php5-odbc=5.6.30+dfsg-0+deb8u1 php5-pgsql=5.6.30+dfsg-0+deb8u1 php5-pspell=5.6.30+dfsg-0+deb8u1 php5-recode=5.6.30+dfsg-0+deb8u1 php5-snmp=5.6.30+dfsg-0+deb8u1 php5-sqlite=5.6.30+dfsg-0+deb8u1 php5-sybase=5.6.30+dfsg-0+deb8u1 php5-tidy=5.6.30+dfsg-0+deb8u1 php5-xmlrpc=5.6.30+dfsg-0+deb8u1 php5-xsl=5.6.30+dfsg-0+deb8u1 curl vim nano

Такая огромная портянка получилась, потому что дистрибутив отказывался устанавливаться, ссылаясь на то, что я пытаюсь установить версию PHP ниже, чем версии его зависимостей. Это показалось мне самым простым решением, не исключено, что есть и более элегантный способ.
Возможно, на тот момент, когда ты будешь читать эту статью, в репозиториях появятся пропатченные версии дистрибутива. Тогда ничего не останется, кроме как скомпилировать PHP из исходников вручную. Для этого можно воспользоваться тем же контейнером, только теперь нужно установить среду для компиляции и все необходимые зависимости.
apt-get install -y build-essential git autoconf automake libtool re2c bison libxml2-dev libgd-dev curl vim nano gdb
Для разнообразия теперь возьмем версию 7.0.26.
git clone --branch PHP-7.0.26 --depth 1 https://github.com/php/php-src.git
Осталось только сконфигурировать. По сути, из расширений нам нужен только gd.
cd php-src ./buildconf --force ./configure --with-gd --enable-debug
Ну а затем стандартное:
make make install

Продолжение статьи доступно только подписчикам
Cтатьи из последних выпусков журнала можно покупать отдельно только через два месяца после публикации. Чтобы читать эту статью, необходимо купить подписку.
Подпишись на журнал «Хакер» по выгодной цене!
Подписка позволит тебе в течение указанного срока читать ВСЕ платные материалы сайта, включая эту статью. Мы принимаем оплату банковскими картами, электронными деньгами и переводами со счетов мобильных операторов. Подробнее о подписке
1 год3990 р. Экономия 1400 рублей! |
1 месяц720 р. 25-30 статей в месяц |
Уже подписан?