Потомок «нецензурного» трояна или как воруют пароли на FTP.

    Вчера я разбирал «нецензурный» троян (http://vilgeforce.habrahabr.ru/blog/44130.html), а сегодня разделываю его потомка — ftp34.dll. Эта тваринка, кстати, куда как интереснее подавляющего большинства троянов. Хотя бы тем, что ворует информацию не с диска, а прямо из сетевого траффика. Как? Смотрите под кат.


    В первой серии был почти до конца разобран один из компонентов комплекса «Троян Залупко». Он дропал на диск файл ftp34.dll и загружал его при помощи LoadLibrary. Причем это происходило при каждой активации трояна.

    ftp34.dll — файл размером 4608 байт, упакован UPX, поэтому в Linux (я дома в линухе) распаковывается за 5 секунд. Распакованный файл весит 7608 байт. DLL, как и ее дроппер, использует тот же принципи шифрования строк — XOR одним байтом, код функции тот же. Скрипт для IDA пишется за минуту.
    IDA заботливо свернула код точки входа, переместив курсор на DllMain. В DllMain проверяется причина вызова: если производится загрузка библиотеки выполняются одни действия, если выгрузка — другие. Так как call'ов для выгрузки было меньше, начал с этого куска. В продуре Detach (назовем ее так) — странный код:

    .text:10001D2F push eax; lpNumberOfBytesWritten
    .text:10001D30 push 6; nSize
    .text:10001D32 push offset unk_1001213C; lpBuffer
    .text:10001D37 push lpBaseAddress; lpBaseAddress
    .text:10001D3D push 0FFFFFFFFh; hProcess
    .text:10001D3F call ds:WriteProcessMemory

    и повторяется он 4 раза. Если я ничего не путаю, то hProcess равный -1 означает запись в свое же собственное адресное пространство. Беглый анализ ссылок на адреса буфера для чтения и для записи показал, что DLL довольно активно читает/пишет в них при помощи Read/WriteProcessMemory. Открытый вопрос «Зачем?» оставлю на потом.

    Действия при загрузке
    Как и свой «родитель», эта библиотека подготавливает строки, содержащие пути к нужным файлам: %TEMP%\r43q34.tmp и %TEMP%\mpz.tmp. Присутствие в системе других экземпляров библиотеки определяется при помощь мьютекса, и если его нет, создается поток Thread1. Имена мьютексов я не привожу, ибо сомневаюсь, что кто-то будет проверять систему на их наличие :-) Теперь — самое интересное! Библиотека ПАТЧИТ функции Windows Sockets в памяти. Как это происходит? Вот код:

    .text:10001B72 push 4; int
    .text:10001B74 push offset aSw676Hh; «ws2_32.dll»
    .text:10001B79 call decryptXor
    .text:10001B7E pop ecx
    .text:10001B7F pop ecx
    .text:10001B80 push eax; lpModuleName
    .text:10001B81 call ds:GetModuleHandleA; Получаем хэнд ws2_32.dll
    .text:10001B87 mov [ebp+ws2_32handle], eax
    .text:10001B8A push 5; int
    .text:10001B8C push offset aWFs; «recv»
    .text:10001B91 call decryptXor
    .text:10001B96 pop ecx
    .text:10001B97 pop ecx
    .text:10001B98 push eax; lpProcName
    .text:10001B99 push [ebp+ws2_32handle]; hModule
    .text:10001B9C call ds:GetProcAddress; Получаем адрес функции recv
    .text:10001BA2 mov recvAddr, eax
    .text:10001BA7 lea eax, [ebp+NumberOfBytesWritten]
    .text:10001BAA push eax; lpNumberOfBytesRead
    .text:10001BAB push 6; nSize
    .text:10001BAD push offset originalCode; lpBuffer
    .text:10001BB2 push recvAddr; lpBaseAddress
    .text:10001BB8 push 0FFFFFFFFh; hProcess
    .text:10001BBA call ds:ReadProcessMemory; Читаем в буфер originalCode первые 6 байт функции recv
    .text:10001BC0 mov HookCode, 68h; В буфер, записываемый в начало recv() помещаем опкод команды push
    .text:10001BC7 mov dword ptr HookCode+1, offset newRecv; Следом за push — адрес нашего нового обработчика
    .text:10001BD1 mov HookCode+5, 0C3h; И теперь RET
    .text:10001BD8 lea eax, [ebp+NumberOfBytesWritten]
    .text:10001BDB push eax; lpNumberOfBytesWritten
    .text:10001BDC push 6; nSize
    .text:10001BDE push offset HookCode; lpBuffer
    .text:10001BE3 push recvAddr; lpBaseAddress
    .text:10001BE9 push 0FFFFFFFFh; hProcess
    .text:10001BEB call ds:WriteProcessMemory; Пишем нашу вставку на начало recv(). Дело сделано!

    Увы, получился он куда как менее читаемым, нежели в IDA :-( Вкратце: получили адрес нужной функции. Считали с этого адреса 6 байт, подготовили буфер с кодом

    push offset myRecv
    ret

    и записали его в начало перехватываемой процедуры. Комбинация push-ret — переход на нужный нам адрес не совсем очевидным способом. Перехватываются следующие функции: recv(), WSARecv(), WSASend(), send(). Теперь стало ясно, что такое пишется в память при выгрузке DLLки: это восстанавливается оригинальный код перехватываемых функций. Остался главный вопрос — как передается управление на оригинальные функции? И что же с Thread1? Она устанавливает свой обработчик (который, кстати, ничего криминального не далет) при помощи SetWindowsHookEx. Зачем? Точно не знаю… Но да это, думаю, не важно.

    Функции перехватчиков
    У всех перехватчиков много общего: это короткие процедуры, содержащие, грубо говоря, только 2 вызова. Первый вызов одинаков для перехватчиков send() и WSASend(), а второй — для recv() и WSARecv(), то есть разделение по функционалу. Назову эти две функции HookSend и HookRecv соответственно. Второй вызов в перехватчиках разный, это вызов функции, которая патчит перехватываемые функции до исходного состояния, вызывает их, а потом патчит в вариант с перехватчиком.
    Функции HookSend() и HookRecv() получают три параметра — сокет, буфер и длину. Начальный код тоже совпадает: получаем адрес, к которому подключен сокет, преобразовываем этот адрес в строку, а также переводит адрес из сетевого порядка следования байт в хостовый. Тут возникает не совсем понятный мне момент:

    .text:100015CA push [ebp+s]; s
    .text:100015CD call ds:getpeername
    .text:100015D3 push dword ptr [ebp+name.sa_data+2]; in
    .text:100015D6 call ds:inet_ntoa
    .text:100015DC push eax; Source
    .text:100015DD push offset byte_10011C10; Dest
    .text:100015E2 call strcpy
    .text:100015E7 pop ecx
    .text:100015E8 pop ecx
    .text:100015E9 push dword ptr [ebp-12h]; netshort
    .text:100015EC call ds:ntohs
    .text:100015F2 movzx eax, ax
    .text:100015F5 cmp eax, 25
    .text:100015F8 jnz short loc_10001607

    s — сокет. Не понимаю, как мы после вызова ntohs в ax получаем порт? Или там действительно порт будет и я плохо доки читал? В общем, интуиция и знакомые числа (25, 80, 110 :-) подсказали, что идет проверка порта, к которому осуществлен коннект. Для приема перехватывается траффик по следующим портам: 25, 80, 110. Для передачи: 25, 80, 21. Причем траффик 21-го порта обрабатывается как-то хитро. Передача по 80-му порту, похоже, вносит некоторые изменения в траффик: если в передаваемых данных встречается строка «gzip,», то она будет заменена на 5 байт с кодом 0x6E («n»). Зачем? Не знаю… На этот момент не разобранными остались только процедуры поиска в передаваемых данных паролей на FTP и почтовых адресов, а также записи этого добра в файлы. Строк для воровства почтовых паролей не видно, равно как и кода, отправлящего собранную информацию по сети. Для этого, наверное, есть свои компоненты.

    Если такая зараза получит распространение, то никакие рекомендации от Пинча типа «Не хранить пароли на дисках» не помогут. Остается только переход на шифрованные каналы связи. Но учитывая перехват всего траффика это, думаю, слабо поможет :-(

    Что мне во всем этом не ясно и странно:
    1) WriteProcessMemory использует в качестве хэндла -1. Почему сомневаюсь, что перехвачены будут вызовы для всех приложений.
    2) Зачем применяется SetWindowsHookEx?
    3) Обнаруживается ли активность трояна поведенческими анализаторами? И вообще хоть каким-нибудь софтом (кроме сигнатурного поиска).
    4) Откуда столько людей узнают про мой пост? Меня читает, насколько я знаю, меньше 10 человек :-D

    Время на анализ — около 2 часов (попутно отвечая на комменты). Инструменты — UPX + IDA Pro + OllyDbg (можно было и без него), голова с мозгами.
    Поделиться публикацией
    Похожие публикации
    Ой, у вас баннер убежал!

    Ну. И что?
    Реклама
    Комментарии 49
    • +3
      vilgeforce, вами уже наверняка заинтересовались хакеры, антивирусные компании ну или как минимум — спецслужбы)
      • +24
        DrWeb мною заинтересовался месяца этак 4 назад, в итоге я у них работаю. Спецслужбами я и сам интересуюсь немного. А хакеры... Посмотрим :-)
      • +10
        > Передача по 80-му порту, похоже, вносит некоторые изменения в траффик: если в передаваемых данных встречается строка "gzip,", то она будет заменена на 5 байт с кодом 0x6E ("n"). Зачем? Не знаю...

        Если браузер поддерживает сжатие трафика, он шлет заголовок Accept-Encoding: gzip или что-то в таком духе. Значит троян хочет, чтобы трафик передавался незапакованным.
        • +3
          О! Спасибо!!!
          Экая хитрая зараза, оказывается :-)
        • +4
          Дык это, прием с SetWindowsHookEx стар как говно мамонта: ставится system-wide хук, если не ошибаюсь, на оконные сообщения. Чтобы можно было вызвать процедуру-хук, винда грузит указанную библиотечку во все процессы, которые посылают эти сообщения, таким образом ваша дллка оказывается загружена везде где нужно, и при загрузке WriteProcessMemory патчит нужные адреса для текущего процесса.
          • 0
            Хм, вот оно как. Спасибо, буду теперь знать :-)
          • 0
            помоему пора тематический блог создавать
            • 0
              Дык есть он, оказывается. ЭВирусы и антивирусы" или как-то так. Это просто я по дурости да с непривычки в персональный пишу.
              • 0
                так Вы можете перенести без проблем
                • 0
                  Хм... Как переносить, вроде, нашел... Перенесенные посты будут и в моем личном блоге?
                  • 0
                    Нет. Либо там, либо там. Но если очень хочется можно задублировать. В любом случае они будут отображаться в разделе "Моё"
            • 0
              я бы упразднил функции типа WriteProcessMemory %)
              любое их использование надо считать подозрительным..
              • 0
                Ну в общем да, WriteProcessMemory, особенно не в себя - за это надо убивать процесс. Но есть способы и без них сделать то же самое, да и легальный софт иногда инжектится.
                • 0
                  Кхм. И нелегальные антивирусы и файрволлы =)
                • НЛО прилетело и опубликовало эту надпись здесь
                  • +1
                    Хм... Интересная мысль! Надо будет попробовать :-)
                    Поиском прошелся по системному каталогу винды - очень немного файлов содерджат название этой функции.
                  • +1
                    Read/WriteProcessMemory это Debugging API и требует определённых привелегий. Если работать под обычным пользователем (не членом групп Administrators и Debuggers), то Read/WriteProcessMemory для произвольных процессов не будут срабатывать.
                    • 0
                      С другой стороны, в данном случае запись идет в самого себя (хэндл везде -1)... Прокатит не из под админа?
                      • 0
                        В себя покатит, также как и в процессы, собой запущенные.
                        • 0
                          Хм, ничего про привилегии для SetWindowsHookEx в MSDN нет :-D
                  • НЛО прилетело и опубликовало эту надпись здесь
                    • 0
                      Продолжение будет обязательно. Возможно, про это семейство троянов, но скорее всего про ложные "антивирусы". И не раньше чем через пару дней :-)
                    • 0
                      Я понимаю что это - круто.И что сам бы хотел в этом разбираться. Но это так долеко до моих представлениях о жизни.
                      • 0
                        Сильно!
                        Респект!
                        • 0
                          Боже, ассемблер, пора его изучить... :-)
                          • 0
                            Что ж сразу "Боже"? Язык как язык. К сожалению, исходники заразы попадаются крайне редко (но была пара случаев), а интерпретируемые вирусы обычно не заслуживают такого внимания.
                          • +1
                            А зря Вы не даёте имя мьютекса, так как на его основе можно быстренько написать лечилку (хотя, если правила компании этого не позволяют, то вопросов, конечно, нет).
                            Относитльно Вашего третьего вопроса: я думаю, что троян распознают все комплексы, имеющие контроль над установкой хука, либо контролирующие запись в память процесса (имеющие свой хук на WriteProcessMemory).
                            P.S. Чтож, этот вирус - яркий пример, что большинство старых протоколов, где информация передаётся открытым текстом устарели. Правда смерть этим протоколам обещали ещё во времена появления первых снифферов и кейлоггеров, однако они живы... Поживём увидим.
                            • 0
                              Правила, насколько я знаю, не запрещают. Но лечилка не получится - проверка наличия мьютекса производится только при старте трояна. Убить существующий не выйдет, разве что препятствовать запуску новых экземпляров. Для "родителя" условия завершения я расписал, так что все ОК. Да и не препятствует тваринка своей остановке.
                            • 0
                              упакован UPX, поэтому в Linux (я дома в линухе) распаковывается за 5 секунд

                              Да и под Виндовс не медленнее, upx везде одинаковый.
                              • 0
                                а чего так долго 7кб распаковываются? *_*

                                и чтобы пять минут не ждать:
                                >Эта тваринка, кстати, куда как интереснее подавляющего большинства >троянов. Хотя бы тем, что ворует информацию не с диска, а прямо из >сетевого траффика.
                                Подавляющее большинство троянов именно трафик слушают, отправляя введенные в формы данные злоумышленникам.
                                • 0
                                  Они не так работают ;-) Перехват сообщений, перехват ввода - это да. А вот перехват функций WS - не частая штука.
                              • 0
                                Спасибо автору! Очень интересно.
                                • 0
                                  Прочитал оба поста от автора. Очень понравилось! Надеюсь в будущем хоть на половину также разбиратся в программах.
                                  • 0
                                    Перехват send() и recv() на локальном компьютере – еще цветочки. Есть интересный троянец, который с помощью arp-spoofing перехватывает трафик в локальной сети между остальными компьютерами и основным шлюзом – Trojan-Spy.Win32.FtpSend.a. Теоретически возможен перехват нешифрованных паролей или man-in-the-middle атака на шифрованные соединения. Встречается в виде связки: Trojan-Spy.Win32.FtpSend.a, Virus.Win32.Alman.b, много разных версий Trojan-PSW.Win32.OnlineGames.a*** и Trojan.Win32.Agent.rcp – что указывает на любовь к паролям от онлайн игр ;-).
                                    Если буде интересно – могу выслать семпл.
                                    • 0
                                      Интересно, конечно. Но времени на все не хватит, это точно :-)
                                    • 0
                                      Спасибо за пост!
                                      Вспомнил времена когда ковырялся идой в защищенных прогах наприедмет написания крака just for fun так сказать. Потом наоборот писал защиту под линуха ;) Задумался, может вирусами заняться ;)
                                      Вопрос, а почему ollyDbg ? SoftIce нынче не рулит ?
                                      • 0
                                        Да я уже привык к Олли - на работе она. Для юзермоды ее хватает. И сайс у меня что-то не ставится или не работает - очень я об этом жалею :-(
                                        • 0
                                          Ясно, надо будет поковырять этот olly
                                          • 0
                                            Советую сразу к нему ставить CommandBar и OllyDump. Про этот отлачик на wasm.ru был цикл статей.
                                      • 0
                                        спасибо за пост
                                        очень интересно
                                        • 0
                                          Владимир, очередное вам спасибо за интересный (и непонятный :-) материал.
                                          интересно было бы увидеть комментарии авторов кода: точно ли вы угадали поведение вируса, сколько они писали его и думали что никто сломает и, тем более, полное разоблачение их творения не всплывёт на хабре ну так далее.
                                          • 0
                                            Комментарии авторы дали в рекламном проспекте к своему творению, которое гуглится с пол-пинка. А вот остальные вопросы мне тоже интересны. Но не думаю, что когда-нибудь на них будут получены ответы.
                                          • 0
                                            Спасибо за пост, а антивирус ДрВеб я так понимаю?
                                            А то кормить у себя этого карманника фтп-паролей не хочется :( много сайтов на подхвате...
                                          • 0
                                            интересно было читать

                                            >4) Откуда столько людей узнают про мой пост? Меня читает, насколько я знаю, меньше 10 человек :-D
                                            твой блог прорекламировали на одном серьезном форуме ;)
                                            • +1
                                              Увы, получился он куда как менее читаемым, нежели в IDA
                                              э.. коллега (как бы:) - попробуйте File - Produce file - Create html file. Вставляет на ура.
                                              • 0
                                                Не знал :-) Век живи - век учись! Спасибо.
                                              • +2
                                                1) WriteProcessMemory использует в качестве хэндла -1. Почему сомневаюсь, что перехвачены будут вызовы для всех приложений.
                                                2) Зачем применяется SetWindowsHookEx?



                                                Это на самом деле один вопрос, разбитый на две части.
                                                2 - МСДН: SetWindowsHookEx can be used to inject a DLL into another process. Собственно, это самый распространенный и простой вариант инъекции. Хорошая новость тут в том, что это работает только на активный десктоп. Плохая новость - в винде обычно используют один десктоп (

                                                1 - Раз после вызова SetWindowsHookEx дллка у нас находится во всех нужных процессах, то надо значть только хэндл текущего процесса, -1.

                                                Где-то так.

                                                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                Самое читаемое