R0 CREW

Malware Analysis Tutorial 15: Injecting Thread into a Running Process (Перевод: coldfire)

Перейти к содержанию

Цели урока:

  1. Понимание привилегий процесса\потока
  2. Понимание взаимодействия и дублирования объектов между процессами

1. Введение

В этом уроке мы покажем другое интересное поведение Мах++: он удаляет Max++Loader.exe с диска как только закончит операции инфицирования, такие как модификация реестра и инфицирование драйверов DLL файлов. Операции удаления совершаются серии интересных техник: изменение привилегий процесса, добавления потока в другой запущенный процесс, перехват событий таймера, и обратно ориентированное программирование (более точно возврат к атакам на libc).

В этом уроке мы будем анализировать код начиная с адреса 0x3C1193.

Ключом для анализа таких вредоносных действий является изучение системных вызовов, размещенные(используемые) Мах++. Мы ознакомлены с техниками и навыками необходимыми для подобного рода анализа в уроке 14.

2. Подготовка

(0) Запустите WinXP в режиме DEBUGGED. Теперь на вашей основной системе, запустите командную строку и перейдите “c:\Program Files\Debugging Tools for Windows (x86)”. Наберите “windbg -b -k com:pipe,port=\.\pipe\com_12” (проверьте, что com порт на вашем образе Vbox установлен). Когда WinDbg инициализирован, напишите «g»(go) дважды для того, что бы продолжить выполнение.

(1) Теперь запустите IMM в WinXP(на виртуальной машине), удалите все аппаратный и программные точки останова в IMM (View->Breakpoints и View->Hardware Breakpoints).

(2) Перейдите по адресу 0x4012DC и установите аппаратную точку останова.(почему не программную точку останова? Потому что эта область сама распаковывающийся и перезаписываемая — из-за этого программная точка останова будет потеряна). Обратите особое внимание, что как только вы перешли по адресу 0x4012DC, сразу сделайте правый клик на этой строчке и установите аппаратную точку останова(пока там находится мусорный код).

(3) Нажмите F9 несколько раз, что бы оказаться на адресе 0x4012DC. Вы столкнетесь с несколькими точками останова перед тем как окажетесь на 0x4012DC. Если вы уделите немного времени, то это происходит по причине трюка с int 2d (который объясняется в уроках 3-5). Просто игнорируйте их и продолжайте(используя F9) пока не окажетесь по адресу 0x4012DC.

Рис. 1 показывает код, который вы должны увидеть. Как вы можете заметить, сразу перед вызовом RtlAddVectoredException, где аппаратная точка останова установлена для прерывания вызова функции LdrLoadDll(смотри урок 11 для изучения деталей). В этот момент, код по адресу 0x3C24FB еще не был извлечен. Если вы перейдете по адресу 0x3C24FB в этот момент, IMM уведомит, что этот адрес — не доступный.

Рис. 1. код по адресу 0x4012DC

(4) Теперь прокрутите вниз около 2 экранов и установите программную точку останова на адрес 0x401417. Он идет сразу после вызова функции LdrLoadDll(“lz32.dll”), где Мах++ заканчивает загрузку lz32.dll. Затем нажмите несколько раз SHIFT+F9 для того, что бы достичь 0x401417 (вы дважды окажетесь на 0x7C90D500 — это где-то внутри ntdll.zwMapViewSection, которая вызывается в LdrLoadDll).

Рис. 2. Код по адресу 0x401407

(6) Теперь мы установим точку останова на адрес 0x3C1193. Перейдите по адресу 0x3C1193 и установите там программную точку останова. Нажмите SHIFT+F9 для того, что бы оказаться на адресе 0x3C1193. (Вы можете уведите предупреждение, что он находится за пределами сегмента кода, просто проигнорируйте предупреждение).

(Рис. 3 показывает код, который вы должны увидеть по адресу 0x3C1193. Первая инструкция должна быть PUSH EBP, за ней MOV EBP, ESP, а потом SUB EBP, 384.).

Рис. 3. Функция по адресу 0x3C1193

3. Немножко анализа функции по адресу 0x3C1193

Сейчас мы немножко опишем функциональность функции по адресу 0x3C1193 и мы оставим больше анализа для тебя в секции 4(задания).

Первая часть кода показана на рис. 3.Сначала Max++ вызывает функцию getModuleHandleW, а затем он вызывает LdrFindEntryForAddress (его личный модуль). Далее идет большой цикл, начиная с адреса 0x3C11F1 и по адрес 0x3c1224,который проходится по списку модулей и проверяет информацию о процессах. Это делается используя zwQueryProcessInformation(это внутренний цикл, который регулирует размер буфера, если текущего места мало). После нескольких итераций, Max++ находит процесс, который удовлетворяет определенному критерию родительского потока и детей потоков. В нашем случаи, найденный процесс — smss.exe. Далее он открывает поток(подумайте, что это за поток) и назначает связку привилегий этому потоку. (смотри Рис. 4).

Рис. 4. Добавление привилегий потоку

Рис. 5 показывает следующую часть кода. Эта часть вполне интересная. Теперь давайте посмотрим на вызов функции по адресу 0x003C12DA. Вызов функции DosPathNameToNtPathName преобразовует строку “c:… …\Max++downloader.exe” в формат NtPath(смотри на вершину стека для того, что бы увидеть строку). Далее она открывает файл по адресу 0x0003C1331, и делает копию файла по адресу 0x003C1355. Отметим, что там где дубликат объекта создан, процесс «smss.exe» не размещается(этот процесс не есть процессом Мах++)!

Рис. 5. Объект дубликата файла

Последний участок кода очень искусный поэтому мы обсудим технику возвратно ориентированного программирования на следующем уроке. Тут мы опишем только общую идею. Рис. 6 показывает код последнего участка. По адресу 0x003C1393, Мах++ вызывает RtlCreateUserThread для создания нового потока(вопрос: кто является родителем? Мах++ или smss.exe?). Далее он устанавливает контекст только что созданного потока. С адреса 0x003C13CF по адрес 0x3C14FF, Мах++ тратит определенные усилия для установки содержимого участка памяти и потом копирует этот участок в специальную область в целевой процесс(smss.exe). Далее вызывается функция zwSetContextThread (по адресу 0x003C1481) для установки регистра EIP на новый поток. Обратите внимание, что мы не определили тело функции нового потока.Как новый поток выполняет работу? Мы тщательно разберем технику возвратно ориентированного программирования на следующем уроке.

Рис. 6. Создание нового потока в процессе smss.exe

4. Задания

[Внимание: для системный функция, который начинаются с zw", “nt” серии документацию можно часто встретить. Например, zwDuplicateObject имеет соответсвующую функцию “ntDuplicateObject”]

Задание 1. Проанализируйте смысл всех параметров и возвращающего значения функции getModuleHandleW, вызываемой по адресу 0x3C11A6 (рис. 3)

Задание 2. Проанализируйте смысл всех параметров и возвращающего значения функции LdrFindEntryForAddress, вызываемой по адресу 0x3C11AD (рис. 3)

Задание 3. Проанализируйте смысл всех параметров и возвращающего значения функции zwQuerySystemInformation, вызываемой по адресу 0x3C11F3 (рис. 3)

Задание 4. Подведите итоги функции цикла, начинающегося по адресу 0x3C1209 — 0x3C123F, который ищет процесс, в который внедрить поток. Есть несколько требований, которым процесс должен удовлетворять. Посмотрите на код и опишите эти желаемые требования(для родительского процесса и дочерних потоков).

Задание 5. На рис. 4, Мах++ добавляет ли привилегии потоку? Какой это поток( к какому процессу он относится)?. Попробуй описать этого и доказать, что ваши доводы корректны.

Задание 6. На рис. 4, Мах++ добавляет ли привилегии потоку? Проанализируйте вызов функции RtlAdjustPrivilege по адресам 0x003C1297, 0x003C12A3, 0x003C12AF, 0x003C12BB, т. д. Список привилегий добавлены.

Задание 7. Проанализируйте вызов функции DosPathNameToNtPathName по адресу 0x003C12DA (Рис. 5).

Задание 8. Проанализируйте вызов функции zwOpenFile по адресу 0x003C1331 (Рис. 5).

Задание 9. Проанализируйте вызов функции zwDuplicateObject по адресу 0x003C1355 (Рис. 5). Где новый объект ( дублированный объект) хранится?

Задание 10. Проанализируйте вызов функции zwDuplicateObject по адресу 0x003C136e (Рис. 5). Какой объект был дублирован?

Задание 11. Проанализируйте вызов функции RtlCreateUserThread по адресу 0x003C1390 (Рис. 6).

Задание 12. Проанализируйте вызов функции zwContextThread по адресу 0x003C13B5 (Рис. 6).

Задание 13. Проанализируйте вызов функции zwWriteVirtualMemory по адресу 0x003C145F (Рис. 6).

© Translated by coldfire from r0 Crew

UP