+ Reply to Thread
Results 1 to 11 of 11

Thread: (Phrack 65): phook - The PEB Hooker

  1. #1
    root's Avatar

    Default (Phrack 65): phook - The PEB Hooker

    Авторы: Shearer и Dreg
    Переводчик: Izg0y
    Оригинал (EN): www.phrack.org
    phook - The PEB Hooker


    ------[ 0.- Предисловие

    Номенклатуры:
    • [T.Index]: соответствующих работ (section 10).
    • [R.Index]: ссылки (section 11).
    Индекс это идентификатор из номенклатуры.

    Для понимания документа требуются знания по win32:
    • Форматы исполняемых файлов:
      • PE32 [R.3]: DLLs, EXE...
    • Программирование:
      • Использование APIs [R.20]: LoadLibrary, GetModuleHandle ...
      • Hooks [R.10] [R.8] [...]
    • Win32 ASM [R.21].

    Термины которые часто используются в документе:
    1. DLL_FAKE: DLL которая будет подменять системную DLL (DLL_REAL).
    2. DLL_REAL: DLL которая будет подменяться DLL_FAKE.

    Если неуказанно иначе, hook/s будет всегда ссылаться на hook/s в win32.

    ------[ 1.- Введение

    Перехват в win32 обычно используются для обратного проектирования, обычно для анализа работы malware и пакеров, систем защиты программного обеспечения.

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

    Большинство известных методов реализации перехвата под ring3 (см. пункт 2.5) имеют различные проблемы (см. пункт 2.5.1). Наиболее актуальная для нас заключается в том, что специальные программы могут обнаружить их...

    Некоторые защитные программы (фаерволы, антивирусы, антируткиты и т. д.), в состоянии приостановить поток, снять неизвестные ей перхваты и продолжить нормальное выполнение потока.

    Другая проблема возникает при попытке реализовать перехват в вирусе, который отслеживает API адреса в памяти, отключая такие типы перехвата, как IAT HOOKING (см. пункт 2.5). Есть так же защитное ПО использующие вирусные
    технологии и наоборот.

    Из-за этих проблем мы создали phook, который использует несколько документированных методов при реализации перехвата в ring3 и даже реализует некоторые вирусные технологи используя наш перехват.

    Этот документ объясняет как работает phook и PEB HOOKING [T.1].

    phook - это инструмент, который использует PEB PEB HOOKING [T.1] для реализации перехвата в DLL, он также позволяет реализовать другие задачи в интерактивном режиме:
    • Показать список загружаемых модулей.
    • Загрузить DLL.
    • Скачать DLL.
    • ...
    PEB HOOKING [T.1] выполняет замену DLL_REAL в памяти на DLL_FAKE, поэтому все модули процесса, которые используют DLL_REAL теперь будут использовать DLL_FAKE.

    ------[ 2 - Предыдущая концепций

    Для понимания работы PEB HOOKING [T.1] метода и phook, необходимо четко понимать некоторые понятия.

    ------[ 2.1 - Process Environment Block

    Process Environment Block (PEB) это структура [R.1] расположенная в пользовательском пространстве, которая содержит данные окружающей среды процесса : [R.2]:
    • Переменные среды.
    • Список загруженных модулей.
    • Адреса в памяти Heap.
    • If the process is being depurated.
    • ...
    Code:
       
        typedef struct _PEB
        {   
            BOOLEAN InheritedAddressSpace;
            BOOLEAN ReadImageFileExecOptions;
            BOOLEAN BeingDebugged;
            BOOLEAN Spare;
            HANDLE  Mutant;
            PVOID ImageBaseAddress;
            PPEB_LDR_DATA LoaderData;
            PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
            PVOID SubSystemData;
            PVOID ProcessHeap;
            PVOID FastPebLock;
            PPEBLOCKROUTINE FastPebLockRoutine;
            PPEBLOCKROUTINE FastPebUnlockRoutine;
            ...
           
        } PEB, *PPEB;
    Для реализации PEB HOOKING, нужно использовать поле LoaderData [T.1].

    ------[ 2.1.1 - LoaderData

    Оно представляет собой структуру [R.1], в которой есть данные о модулях в процессе. Это двойной связанный список, и он может быть отсортированы по трём критериям [R.2]:
    • Порядок загрузки
    • Порядок в памяти
    • Порядок инициализации
    Code:
        typedef struct _PEB_LDR_DATA
        {
            ULONG Length;
            BOOLEAN Initialized;
            PVOID SsHandle;
            LIST_ENTRY InLoadOrderModuleList;
            LIST_ENTRY InMemoryOrderModuleList;
            LIST_ENTRY InInitializationOrderModuleList;
       
    
        } PEB_LDR_DATA, *PPEB_LDR_DATA;
    Все flink и blink поля в LIST_ENTRY указывает на LDR_MODULE.

    Code:
        typedef struct _LIST_ENTRY {
            struct _LIST_ENTRY * Flink;
            struct _LIST_ENTRY * Blink;
           
        } LIST_ENTRY,*PLIST_ENTRY;
    Данные, которые нам понадобятся из LDR_MODULE, реализовывая PEB HOOKING это [T.1]:
    • BaseAddress: Адрес модуля в памяти..
    • EntryPoint : Адрес где содержится первая инструкция для выполнения модуля.
    • SizeOfImage: Размер модуля в памяти.
    Code:
        typedef struct _LDR_MODULE
        {
            LIST_ENTRY InLoadOrderModuleList;
            LIST_ENTRY InMemoryOrderModuleList;
            LIST_ENTRY InInitializationOrderModuleList;
            PVOID BaseAddress;
            PVOID EntryPoint;
            ULONG SizeOfImage;
            UNICODE_STRING FullDllName;
            UNICODE_STRING BaseDllName;
            ULONG Flags;
            SHORT LoadCount;
            SHORT TlsIndex;
            LIST_ENTRY HashTableEntry;
            ULONG TimeDateStamp;
    
        } LDR_MODULE, *PLDR_MODULE;
    ------[ 2.2 - Import Address Table

    Import Address Table (IAT) это таблица где содержится PE32 [R.3], который заполняет win32 загрузчик, когда модуль[R.4] загружен и также на дальнейшей загрузке, используя stub в IAT.

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

    В IAT [R.3] модуля есть адрес его импорта, это значит, что в IAT [R.3] модуля есть адрес экспорта используемых из других модулей.

    ------[ 2.2.1 - Загрузка из Import Address Table

    Для win32 загрузчика, который может получить экспорт, нужно узнать: модуль в котором он расположен, имя экспорта и/или ordinal [R.3].

    В PE32 имеет структура IMAGE_IMPORT_DESCRIPTOR [R.5], где мы можем выделить 3 области:

    Code:
        - Name                    : Имя модуля где находится экспорт.
        - OriginalFirstThunk  : Адрес таблицы импорта
        - FirstThunk             : Адрес таблицы, идентичной OriginalFirstThunk,
                                        куда win32 загрузчик помещает адреса импорта.
               
       
        typedef struct _IMAGE_IMPORT_DESCRIPTOR {
            DWORD OriginalFirstThunk;
            DWORD TimeDateStamp;
            DWORD ForwarderChain;
            DWORD Name;
            DWORD FirstThunk;
           
        } IMAGE_IMPORT_DESCRIPTOR,*PIMAGE_IMPORT_DESCRIPTOR;
    Каждая запись в таблице FirstThunk и OriginalFirstThunk имеет 2 поля[R.3]:

    Code:
        - Hint: если первые 31/63 bits составляют 0x80000000, то импорт будет
                  произведён по ordinal, в противном случаи нет.
                  Биты 15-0 это ordinal.
        - Name: Адрес, где хранятся имена экспорта.
       
        typedef struct _IMAGE_IMPORT_BY_NAME {
            WORD Hint;
            BYTE Name[1];
           
        } IMAGE_IMPORT_BY_NAME,*PIMAGE_IMPORT_BY_NAME;
    ------[ 2.3 - Запуск процесса в приостановленном состоянии

    Когда мы хотим создать процесс в приостановленном состоянии, то нам необходимо знать, какого типа он [R.6]:
    • Console
    • GUI
    Консольные тип процесса могут быть созданы с помощью API CreateProcess и флага CREATE_SUSPENDED.

    Если GUI процесс открывается с флагом CREATE_SUSPENDED, то он может работать не корректно, поэтому он должен быть создан с помощью API:

    Code:
        1.- CreateProcess   : Процесс создаётся без флага CREATE_SUSPENDED.
        2.- WaitForInputIdle: Дождаться корректной загрузки [R.6] процесса.
        3.- SuspendThread   : Приостановить главный поток.
    ------[ 2.4 - Инъекция DLL в процесс

    Существует много способов внедрения DLL в процесс [R.7], самый простой это использовать связку API:
    Code:
        1.- VirtualAllocEx    : Зарезервировать память в процессе.
        2.- WriteProcessMemory: Записать в зарезервированное место код
        который загрузит DLL.
        3.- CreateRemoteThread: Создать поток в процессе каторый выполнит
        записанный код.
        4.- VirtualFreeEx     : Освободить зарезервированную память после
        подгрузки DLL.
    ------[ 2.5 - Hooks в ring3

    Всегда существует куча форм для реализации перехвата в win32 как в ринг0 так и в ринг3. Проблема при работе в ring0 заключается в том, что если код работает не стабильно, то это отразиться на всей ОС. Самый стабильный метод для OS реализовать перехват из ring3.

    Самые известные методы:
    • IAT HOOKING: Запись IAT [R.3] изменяется, так чтоб загрузчик win32, указывал на другую область [R.8].
    • PUSH + RET: В область кода PUSH DIRECTION и RET вставляется jump, чтоб передать управление своему коду, но приходится восстанавливать оригинальный код в определённый момент [R.9].
    • SetWindowHook...: С помощью этих API, вызов своего кода может быть зарегистрирован для различных событий в системе.
    ------[ 2.5.1 - Проблемы

    Некоторые проблемы при реализации перехвата в ring3:

    Code:
    +-------------------------------------------------------------------------+
    | Метод                  | Проблема                                       |
    +------------------------+------------------------------------------------+
    | IAT HOOKING [R.8]      | 1.- IAT [R.3] для всех загружаемых модулей     |
    |                        |     должен быть изменён.                       |
    |                        | 2.- Модулю не нужен IAT [R.3] для              |
    |                        |     использования символов экспортируемых      |
    |                        |     другими.                                   |
    |                        | 3.- Это всем хорошо известно.                  |
    |                        | 4.- Легко восстановить.                        |                   
    |                        | 5.- Можно обнаружить.                          |   
    |                        | 6.- Не даёт полный контроль сразу после старта.|                   
    |------------------------+------------------------------------------------|
    | PUSH + RET [R.9]       | 1.- Метод не универсален.                      |
    |                        | 2.- Сложно в применении.                       |
    |                        | 3.- Легко восстановить.                        |
    |                        | 4.- Можно обнаружить.                          |
    |                        | 5.- Не даёт полный контроль сразу после старта.|
    |------------------------+------------------------------------------------|    
    | Otros "hooks":         | 1.- Не даёт полного контроля.                  |
    | SetWindowHook... [R.10]| 2.- Легко восстановить.                        |
    |                        | 3.- Можно обнаружить.                          |
    |------------------------+------------------------------------------------|    
    | PEB HOOKING [T.1]      | 1.- Сложно в применении.                       |
    |                        | 2.- Оригинальная DLL и внедрённая, должна      |
    |                        |     экспортировать теже символы в том же       |
    |                        |     объеме (как минимум).                      |
    |                        | 3.- Можно обнаружить.                          | 
    |                        | 4.- Не даёт полный контроль сразу после старта.| 
    +------------------------+------------------------------------------------+
    Примечание: Эта таблица только мнение авторов.

    Вызовы из ring3 в ring0 используя SYSENTER не могут управляться только с помощью предыдущих методов. Системны вызов из ring3 могут быть реализованы SYSENTER [R.11] без каких либо других DLL, таких образом, предыдущие методы сделались непригодным для использования, это довольно редкая ситуация.

    Из-за предыдущих проблем, мы решили использовать PEB HOOKING [T.1], чтобы создать механизм, который делает больше чем хук : phook - The PEB Hooker.

    Примечание: Преимущества и недостатки PEB HOOKING [T.1] разъясняются в section 7.

    ------[ 3.- Разработка

    В этом разделе будет говориться о базовой концепции и реализации PEB HOOKING [T.1]. Реализация не сложная, но только тогда, когда понимаешь для чего и зачем применяется тот или иной код.

    Шаги:
    • Загрузить DLL_FAKE и DLL_REAL.
    • В списке, используемым загрузчиком вин32, в котором перечислены все загруженные в данный момент модули, нужно поменять поля между DLL_FAKE и DLL_REAL
    • Необходимо чтобы IAT [R.3] всех загруженных модулей, кроме DLL_REAL и возможно DLL_FAKE указывали функциям, что DLL_FAKE экспорт.

    ------[ 3.1 - Первый шаг к PEB HOOKING

    Прежде чем что-то сделать, необходимо загрузить DLL_FAKE в память процесса, к которому это требуется что-бы использовать PEB HOOKING [T.1]. DLL_FAKE должен иметь по крайней мере тот же самый экспорт что и DLL_REAL.

    ------[ 3.2 - Обмен данными в LoaderData

    Необходимо найти в DLL_FAKE и DLL_REAL некоторые идентификаторы LDR_MODULE, после чего обменяться следующей информацией:
    • EntryPoint
    • BaseAddress
    • SizeOfImage (почти всегда)

    Поиск с использованием поля BaseDllName будет получать данные о "LDR_MODULE", относящиеся к DLL_FAKE. Некоторые вирусы, упаковщики и API используют эту форму поиска, чтобы найти BaseAddress или EntryPoint для модуля.

    Необходимо изменить поле SizeOfImage если DLL_FAKE и DLL_REAL, не имеют равный размера в памяти.

    Поиск BaseAddress из kernel32.dll без "PEB HOOKING":

    Code:
                         0     +---------------------------------+
       [ process ] ---------+  | Process Environment Block (PEB) |
                            |  |---------------------------------|
                            |  | InheritedAddressSpace           |
                            |  | ReadImageFileExecOptions        |
                            |  | BeingDebugged                   |
                            |  | Spare                           |
                            |  | Mutant                          |
                            |  | ImageBaseAddress                |
                            +->| LoaderData                      |--+
                               | ...                             |  |                      
                               +---------------------------------+  | 1
                                                                    |
                                                                    |
     +--------------------------------------------------------------+
     |  +----------------------------+     +----------------------------+  
     |  |          LoaderData        |     |         LDR_MODULE         |
     |  +----------------------------+     |----------------------------| flink
     |  | Length                     |     | InLoadOrderModList         |-----+
     |  | Initialized                |     | InMemoryOrderModList       |     |
     |  | SsHandle                   |     | InInitOrderModList         |     |
     +->| InLoadOrderModList         |  2  | ...                        |     |
        | InMemoryOrderModList       |---->| BaseDllName   "ntdll.dll"  |---+ |   
        | InInitOrderModList - Flink |     +----------------------------+   | |
        +----------------------------+ +------------------------------------+ |
                                       |   +----------------------------+     |
                                       |   |   LDR_MODULE (DLL_REAL)    |     |
                                       |   |----------------------------|     |
                                       |   | InLoadOrderModList         |   6 |
        +---------------------+     3  |   | InMemoryOrderModList       |     |
        | ¿Es "kernel32.dll"? |<-------+   | InInitOrderModList         |     |
        +---------------------+            | BaseAddress  7C801000      |     |
            8 |     |4       ^        7    | ...                        |     |
         Si <-+     +-> No   +-------------| BaseDllName "kernel32.dll" |<----+
         |               | 5               | ...                        | 
       9 |               v                 +----------------------------+  
         |            NextLdrModule(); 
         v     
     kernel32.dll = 7C801000

    Поиск BaseAddress из kernel32.dll с использованием PEB HOOKING [T.1]:

    Code:
                         0     +---------------------------------+
       [ process ] ---------+  | Process Environment Block (PEB) |
                            |  |---------------------------------|
                            |  | InheritedAddressSpace           |
                            |  | ReadImageFileExecOptions        |
                            |  | BeingDebugged                   |
                            |  | Spare                           |
                            |  | Mutant                          |
                            |  | ImageBaseAddress                |
                            +->| LoaderData                      |--+
                               | ...                             |  |                      
                               +---------------------------------+  | 1
                                                                    |
                                                                    |
     +--------------------------------------------------------------+
     |  +----------------------------+     +----------------------------+  
     |  |          LoaderData        |     |         LDR_MODULE         |
     |  +----------------------------+     |----------------------------| flink 
     |  | Length                     |     | InLoadOrderModList         |-----+
     |  | Initialized                |     | InMemoryOrderModList       |     |
     |  | SsHandle                   |     | InInitOrderModList         |     |
     +->| InLoadOrderModList         |  2  | ...                        |     |
        | InMemoryOrderModList       |---->| BaseDllName   "ntdll.dll"  |---+ |   
        | InInitOrderModList - Flink |     +----------------------------+   | |
        +----------------------------+ +------------------------------------+ |
                                       |   +----------------------------+     |
                                       |   |   LDR_MODULE (DLL_REAL)    |     |
                                       |   |----------------------------|   6 |
                                       |   | InLoadOrderModList         |     |
        +---------------------+     3  |   | InMemoryOrderModList       |flink|
        | ¿Es "kernel32.dll"? |<-------+   | InInitOrderModList         |--+  |
        +---------------------+            | BaseAddress 7C801000       |  |  |
           12 |     |4-8   ^ ^        7    | ...                        |  |  |
         Si <-+     +-> No | +-------------| BaseDllName "old_k32.dll"  |<-|--+
         |           5-9 | +------------+  | ...                        |  |
      13 |               v              |  +----------------------------+  |
         |            NextLdrModule();  +-+                                |
         v                                | +----------------------------+ |
     kernel32.dll = 005C5000              | |   LDR_MODULE (DLL_FAKE)    | | 10
                                          | |----------------------------| |
                                      11  | | InLoadOrderModList         | |
                                          | | InMemoryOrderModList       | |
                                          | | InInitOrderModList         | |
                                          | | BaseAddress 005C5000       | |
                                          | | ...                        | |
                                          +-| BaseDllName "kernel32.dll" |<+
                                            | ...                        |
                                            +----------------------------+
    Результаты поиска:
    1. BaseAddress без использования PEB HOOKING [T.1]: 7C801000 (DLL_REAL)
    2. BaseAddress с использованием PEB HOOKING [T.1]: 005C5000 (DLL_FAKE)

    PD: В поиске по InLoadOrderModList, первое поле показывает, что LDR_MODULE соответствует основному модулю. В примере он был опущен для ясности.

    ------[ 3.3 - Динамическая загрузка модулей

    Кoгда процесс, PEB HOOKING [T.1] будет выполнен, динамически [R.12] загруженные модули будут иметь импорт DLL_REAL, его IAT [R.3] будет автоматически загружен с необходимым экспортом DLL_FAKE.

    ------[ 3.4 - Восстановление IAT

    Кроме модулей DLL_FAKE и DLL_REAL, все IAT [R.3] экспортирующие DLL_REAL, должны быть заменены DLL_FAKE. IAT [R.3] DLL_FAKE не должен изменяться в случаи если DLL_REAL необходимо использовать.

    Если IAT из DLL_FAKE модифицирована таким образом, что экспорты DLL_REAL совпадают с DLL_FAKE, вызов экспорта из DLL_REAL из такого же экспорта DLL_FAKE войдет в непрерывный бесконечный цикл, вызывающий переполнение стека.

    Code:
        +--------------------------+     +--------------------------------+
        |      .text DLL_FAKE      |     |               IAT              |
        |--------------------------|     |--------------------------------|                                
        | ...                      |     | LocalAlloc  1 (Nr_LocalAlloc)  |         
        | PUSH EBP                 |  +->| LoadLibrary 2 (Nr_LoadLibrary) |--+        
        | MOV EBP, ESP             |  |  |  ....                          |  |
        | ...                      |  |  +--------------------------------+  |
        | LoadLibrary_FAKE:        |  |                                      |
     +->| PUSH original_lib_name   |  | 0                                    |
     |  | CALL IAT[Nr_LoadLibrary] |--+                                      |
     |  | ...                      |                                         |
     |  | POP EBP                  |                                         |
     |  | RET                      |                                         |
     |  | ...                      |                                         |
     |  +--------------------------+                                         |
     |                                          1                            |
     +-----------------------------------------------------------------------+
    Реальную проблему составляет то, что мы обращаемся сами к себе или одной из других DLL. Это не должно восстанавливать IAT [R.3] любого другова модуля (DLL_ANY), когда DLL_FAKE вызывает экспорт DLL_ANY который в свою очередь обращается к экспорту DLL_FAKE, который снова обращается к экспорту DLL_ANY.

    Вызов RtlHeapAlloc, когда PEB HOOKING [T.1] выполнен через NTDLL.DLL и IAT kernel32.dll был изменён:

    Пример:

    Code:
    [ proceso ]
     |
     | CALL RtlHeapAlloc                         CALL LoadLibrary
     +-------------------> [DLL_FAKE ntdll.dll] ------------------+  
                  0         ^                           1         |
                            | CALL RtlInitUnicodeString           v
                            +--------------------------- [DLL_ANY kernel32.dll]
                                              2
    Вызов RtlHeapAlloc, когда PEB HOOKING [T.1] выполнен через NTDLL.DLL и IAT [R.3] kernel32.dll не был изменен:

    Code:
    [ proceso ]<----------------+ 
     |                       4  |
     | CALL RtlHeapAlloc        |                 CALL LoadLibrary
     +-------------------> [ DLL_FAKE ntdll.dll] ------------------+  
        0                       ^                       1          |
             +------------------+                                  |
             |    3                                                |
             |                CALL RtlInitUnicodeString            v
    [DLL_REAL old_nt.dll] <--------------------------- [DLL_ANY kernel32.dll]
                                              2
    Примечание: Схема была упрощенна, исключив другие вызовы DLL_FAKE.


    Нормальный вызов LoadLibrary из процесса (без PEB HOOKING [T.1]):

    Code:
                CALL IAT[Nr_LoadLibrary]  +--------------------------------+
    [process] -------------------------+  |                IAT             |
       ^                0              |  |--------------------------------|
       |                               |  | LocalAlloc  1 (Nr_LocalAlloc)  |
       |    +-----------------------+  +->| LoadLibrary 2 (Nr_LoadLibrary) |-+
       |    | DLL_REAL kernel32.dll |     |  ....                          | |
       |    |-----------------------|     +--------------------------------+ |
       |    | ...                   |                  1                     |
       |    | LoadLibrary:          | <--------------------------------------+
       | 2  | PUSH EBP              |                       
       |    | MOV EBP, ESP          |
       |    | ...                   |
       |    | POP EBP               |
       +----| RET                   | 
            | ...                   |
            +-----------------------+
    Вызов проходит нормально без захода в DLL_REAL.


    Вызов LoadLibrary в процессе с PEB HOOKING [T.1]:

    Code:
                CALL IAT[Nr_LoadLibrary]  +--------------------------------+
    [process] -------------------------+  |                IAT             |
       ^                0              |  |--------------------------------|
       |                               |  | LocalAlloc  1 (Nr_LocalAlloc)  |
       |  +-------------------------+  +->| LoadLibrary 2 (Nr_LoadLibrary) |-+
       |  | DLL_FAKE  kernel32.dll  |     |  ....                          | |
       |  |-------------------------|     +--------------------------------+ |
     4 |  | ...                     |                     1                  |
       |  | Own_LoadLibrary:        | <--------------------------------------+
       |  | PUSH EBP                |                       
       |  | MOV EBP, ESP            |       +-----------------------------+
       |  | // Own functions...     |   2   | DLL_REAL  old_k32.dll       |
       |  | CALL IAT[Nr_LoadLibrary]|----+  |-----------------------------|
       |  | POP EBP                 |<-+ |  | ...                         | 
       +--| RET                     |  | +->| LoadLibrary:                |
          |   ...                   |  |    | PUSH EBP                    |
          +-------------------------+  |    | MOV EBP, ESP                |
                                       |    | ...                         |
                                     3 |    | POP EBP                     |
                                       |    | RET                         |--+
                                       |    | ...                         |  |
                                       |    +-----------------------------+  |
                                       +-------------------------------------+
    Рассмотрев схему можно увидеть, что вызов проходит сначало через DLL_FAKE. Затем DLL_FAKE вызывает оригинальную LoadLibrary (DLL_REAL).

    ------[ 3.5 - Начало выполнения

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

    ------[ 3.6 - API для работы с модулями

    API - LoadLibrary, GetModuleHandle, EnumProcessModules [R.12] ... используют поле LoaderData из PEB [T.1]. Это означает, что каждый раз, они вызывают что-то из DLL_REAL, которая вызывает что-то из DLL_FAKE, например:

    Code:
    PEB HOOKING [T.1] был выполнен для USER32.DLL:
        - DLL_FAKE
            - Name in memory:    USER32.DLL
            - BaseAddress:       00435622
        - DLL_REAL
            - Name in memory:    OLD_U32.DLL
            - BaseAddress:       77D10000
    
    Процесс пытается получить базу USER32.DLL:
        - HMODULE user32 = GetModuleHandle( "user32.dll" );
    После выполнения GetModuleHandle [R.12] в переменной user32 будет: 00435622 (BaseAddress из DLL_FAKE). Если процесс выполнен позже GetProcAddress [R.12] на некоторые функции экспорта USER32.DLL, они получат функции из DLL_FAKE.

    Блогадоря PEB HOOKING [T.1] больше нет необходимости изменять API, которые работают с модулями, так чтоб они использовали DLL_FAKE.

    ------[ 3.7 - Новая разработка: DLL MINIFILTER

    DLL MINIFILTER это название, которые мы дали способности, вызывать экспорт проходя через несколько DLL_FAKE. Одной из самых важных особностей метода является, ограничение или расширение функциональных возможностей к запросу на экспорт.

    Когда PEB HOOKING [T.1] выполнен с DLL_FAKE, то термин DLL_REAL для новых DLL_FAKE становится предыдущий DLL_FAKE. Поток пойдёт по форме последней DLL_FAKE, над которым взял контроль PEB HOOKING [T.1] по отношению к DLL_REAL, в случаи если все DLL_FAKEs приводят к оригинальному экспорту.

    Поток запроса процесса, с PEB HOOKING [T.1], только с одним DLL_FAKE:
    Code:
               0              1
    [proceso] --> [DLL_FAKE] --> [DLL_REAL]
        ^                            |
        |             2              |
        +----------------------------+
    Поток запроса процесса, с PEB HOOKING [T.1], с тремя DLL_FAKEs:
    Code:
               0                1                2                3
    [proceso] --> [DLL_FAKE 3] --> [DLL_FAKE 2] --> [DLL_FAKE 1] --> [DLL_REAL]
        ^                                                               |
        |                               4                               |
        +---------------------------------------------------------------+
    В предыдущем примере все DLL_FAKEs получают контроль соответствующий DLL_REAL.

    ------[ 3.8 - Частые проблемы

    На данный момент при реализации PEB HOOKING [T.1] выявлены, следующие проблемы:

    Code:
    +-------------------------------------------------------------------------+
    | Проблема                      | Возможные решения                       |
    |-------------------------------+-----------------------------------------|
    | - PEB HOOKING [T.1] fails     | - Проверьте, могут ли необходимые поля  | 
    |                               |   PEB [T.1] обмениваться.               |
    |                               | - Проверьте, есть ли доступ             |
    |                               |   для изменения в IATs [R.3]            |
    |-------------------------------+-----------------------------------------|
    | - Выполнение процесса не      | - Проверьте корректность PEB [R.1]      |
    |   происходит                  | - Проверьте значения IATs [R.3]         |
    |                               |   модуля во всех процессах              |  
    |                               | - Проверьте были ли восстановлены       |
    |                               |   изменения в памяти PEB HOOKING [T.1]  |  
    +-------------------------------------------------------------------------+
    ------[ 4.- phook

    phook способен реализовать PEB HOOKING [T.1] (и кое что ещё). phook это проект из различных модулей:

    - InjectorDLL: Создаёт приостановленный процесс и внедряет в него DLL.
    - Console Control: Внедрённая DLL позволяет выполнит PEB HOOKING [T.1]. и другие задачи в интерактивном режиме посредством команд консоли через sockets.
    - CreateExp: Программа создающая из DLL_REAL код, нужный для DLL_FAKE.
    - ph_ker32.dll: DLL_FAKE из kernel32.dll. ph_ker32.dll смотрит за доступом к API: CreateFileA and CreateFileW [R.14].

    ------[ 4.1 - InjectorDLL

    Программа создаёт приостановленный процесс и внедряет в него DLL. Для внедрения DLL C:\console.dll в процесс C:\poc.exe:
    • - Тип процесса:
      • - CONSOLE:
        • - InjectorDLL.exe C:\console.dll -c C:\poc.exe
      • - GUI:
        • - InjectorDLL.exe C:\console.dll -g C:\poc.exe
    • - Неизвестный тип:
      • - InjectorDLL.exe C:\console.dll -u C:\poc.exe

    InjectorDLL, с параметром -u, пытается обнаружить GUI или Console чтобы знать как создавать приостановленный поток (см пунтк 2.3). Этот метод создаёт процесс при помощи API CreateProcess и флага CREATE_SUSPENDED [R.6]. Потом вызывает WaitForInputIdle, если это не приносит результата то это консольный процесс, иначе GUI.

    Code:
        CreateProcess
        ( 
            program_name                          ,
            NULL                                  ,
            NULL                                  ,
            NULL                                  ,
            FALSE                                 ,
            CREATE_SUSPENDED | CREATE_NEW_CONSOLE ,
            NULL                                  ,
            NULL                                  ,
            pstart_inf                            ,
            ppro_inf
        )
       
        // Необходимо проверить тип созданного процесса
       
        if ( WaitForInputIdle( ppro_inf->hProcess, 0 ) == WAIT_FAILED )
            // "Console процесс"
        else
            // "GUI процесс"
    Если известен тип процесса мы знаем как его правельно остановить (см. пункт 2.3).

    Примечание: метод не всегда работает, например если "Console процесс" будет опознан как "GUI процесс".

    Код который загружает DLL помещён в структуру под названием LOADER_DLL_s (см. пункт 2.3). LOADER_DLL_s состоит из команд на ассемблере и всеми необходимыми данными. В созданном процессе необходимо описать структуру LOADER_DLL_s и объявить CreateRemoteThread, как точку запуска структуры. Она будет выполняться в коде LOADER_DLL_s.

    Как только DLL загружена и поток приостановлен, LOADER_DLL_s начинает выполнение и устанавливает флаг для "опознания".

    Code:
        typedef struct LOADER_DLL_s
        {
            /* - CODE ------------------------------------------------------ */
            PUSH_ASM_t      push_name_dll;           /* PUSH "DLL_INJECT.DLL"*/
            CALL_ASM_t      call_load_library;       /* CALL  LoadLibraryA   */
           
            CALL_ASM_t      call_get_current_thread; /* CALL GetCurrentThread*/
            INC_BYTE_MEM_t  inc_flag;                /* INC [FLAG]           */
            char            PUSH_EAX;                /* PUSH EAX             */
            CALL_ASM_t      call_suspendthread;      /* CALL SuspendThread   */
           
            /* - DATA ------------------------------------------------------ */
            char            name_dll[MAX_PATH];      /* DLL_INJECT.DLL'\0'   */
            char            flag;                    /* [FLAG]               */
           
        } LOADER_DLL_t;
    ------[ 4.2 - Консоль управления

    Консолью управления является DLL, которая внедрена в процессе, в котором вы хотели бы реализовать PEB HOOKING [T.1]. Это позволяет сделать PEB HOOKING [T.1] и другие задачи в интерактивном режиме с помощью команд консоли через sockets. Через прослушиваемый порт, в файл C:\ph_listen_ports.log записывается, PID - PORT. Например процесс с PID 2456, прослушивать на 1234 порт: 2456 - 1234.

    На данный момент поддерживаются следующие команды:
    Code:
        help                      - Показать справку
        exit                      - Закрыть и выгрузить консоль
        suspend                   - Приостановить выполнение программы
        resume                    - Возобновить выполнение программы
        showmodules               - Показать список модулей
        load [param1]             - Загрузить в память библиотеку указанную
                                    в [param1]
        unload [param1]           - Выгрузить из памяти библиотеку указанную
                                    в [param1]
        pebhook [param1] [param2] - Реализовать PEB HOOKING [T.1] над dll
                                    [param1]: Имя оригинальной dll
                                    [param2]: путь до DLL_FAKE
    Эти команды легки для понимания, но мы обьясним как работают "showmodules", "pebhook" и "suspend".

    Команда "showmodules" выполняет поиск по PEB [R.1] из загружаемых модулей, без использования API.

    pebhook которая реализовывает весь процесс PEB HOOKING (см. пункт 3).

    Если требуется выполнить PEB HOOKING [T.1] для kernel32.dll , используйте DLL_FAKE "C:\phook\bin\windows_xp_sp2\ph_ker32.dll", для ОС Windows XP SP2, требуется только отправить команду:
    • pebhook kernel32.dll c:\phook\bin\windows_xp_sp2\ph_ker32.dll

    Команда "suspend" способна приостановить выполнение главного потока процесса. TID основного потока получен, просматривая THREADENTRY32 [R.13] этой системы, можно достигнуть первого из процесса:

    Code:
        BOOL GetMainThreadId( DWORD * thread_id )
        {
            HANDLE        hThreadSnap;
            THREADENTRY32 th32;
            BOOL          return_function;
            DWORD         process_id;
           
            process_id      = GetCurrentProcessId();
            hThreadSnap     = INVALID_HANDLE_VALUE;
            return_function = FALSE;
       
            hThreadSnap = \
                CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, process_id );
           
            if( hThreadSnap == INVALID_HANDLE_VALUE )
            {
                ShowGetLastErrorString
                    ( " GetMainThreadId() - CreateToolhelp32Snapshot()" );
                return FALSE;
            }
           
            th32.dwSize = sizeof( THREADENTRY32 );
            if( !Thread32First( hThreadSnap, & th32 ) )
                ShowGetLastErrorString( "GetMainThreadId() - Thread32First()");
           
            do
            {
                if ( th32.th32OwnerProcessID == process_id )
                {
                    * thread_id     = th32.th32ThreadID;
                    return_function = TRUE;
                }
               
            }
            while
            (
                Thread32Next( hThreadSnap, & th32 ) && return_function != TRUE
            );
           
            CloseHandle( hThreadSnap );
           
            return return_function;
        }
    ------[ 4.3 - CreateExp

    CreateExp это программа создает исходный код, необходимый для реализации DLL_FAKE из a DLL_REAL. На данный момент она способна создавать .c и .def, для использования с mingw.

    Для создания DLL_FAKE для kernel32.dll необходимо выполнить:
    • CreateExp C:\WINDOWS\SYSTEM32\KERNEL32.DLL C:\ph_ker32

    После успешного выполнения создадутся C:\ph_ker32.c и C:\ph_ker32.def.

    ph_ker32.c содержит в себе экспорт из kernel32.dll и автоматически jumps для оригиналов.

    ph_ker32.def содержит псевдонимы и имена из экспорта kernel32.dll.

    По умолчанию экспорт из DLL_FAKE приведёт к экспорту из DLL_REAL.

    ------[ 4.3.1 - Forwarder DLL

    CreateExp преобразовывает Forwarder DLL [R.3] в экспорт PEB HOOKING таким образом функция Forwarder может быть создана.

    Пример: kernel32.dll имеет Forwarder HeapAlloc который идет в экспорте RtlAllocateHeap of NTDL.DLL. Когда модуль импортирует HeapAlloc из kernel32.dll, загрузчик win32 автоматически помещает адрес экспорта NTDLL.DLL и никогда не проходит через kernel32.dll:

    Code:
                        CALL HeapAlloc
            [proceso] ------------------> [NTDLL.DLL]
                ^               0               | 
                +-------------------------------+      
                                1
    Если DLL_FAKE из kernel32.dll создается с CreateExp, то поток будет:

    Code:
                CALL HeapAlloc      (DLL_FAKE)
    [proceso] ------------------> [KERNEL32.DLL] --------> [NTDLL.DLL]
        ^              0                            1         | 
        +-----------------------------------------------------+                
                                 2
    В такой форме мы можем осуществить хук HeapAlloc (kernel32.dll).

    ------[ 4.4 - ph_ker32.dll

    ph_ker32.dll была создана для реализации PEB HOOKING [T.1] из kernel32.dll; Наблюдает за APIs "CreateFileA" и "CreateFileW" [R.14], и когда их вызывают, их ( или любые другие ) перенаправляют на оригинальные.

    Чтобы ослаблять прыжок к API, бал создан макрос JMP, он должно передать название DLL и оригинальный экспорт (см. пункт 4.4.2).

    ph_ker32.c созданный с CreateExp (JMP макрос был пропущен):

    Code:
        #define FAKE_LIB "ph_ker32.dll"
    
        DLLEXPORT void _ActivateActCtx ( void )
        {
            JMP( FAKE_LIB, 1 );
        }
       
        DLLEXPORT void _AddAtomA ( void )
        {
            JMP( FAKE_LIB, 2 );
        }
       
        DLLEXPORT void _AddAtomW ( void )
        {
            JMP( FAKE_LIB, 3 );
        }
       
        DLLEXPORT void _AddConsoleAliasA ( void )
        {
            JMP( FAKE_LIB, 4 );
        }
        ....

    Необходимо помнить, что после выполнения PEB HOOKING [T.1], kernel32.dll будет называться ph_ker32.dll, поэтому ph_ker32.dll обозначен как константа FAKE_LIB.

    ph_ker32.def созданный с CreateExp:

    Code:
        LIBRARY    default
        EXPORTS   
        ActivateActCtx=_ActivateActCtx           @ 1
        AddAtomA=_AddAtomA                       @ 2
        AddAtomW=_AddAtomW                       @ 3
        ...

    Причинами ясности выполнение APIs CreateFileA и CreateFileW [R.14] были помещены в файл owns.c. Когда сделан запрос к CreateFileA, и к CreateFileW [R.14] то записывается параметр lpFileName в файле C:\CreateFile.log

    Code:
        owns.c:
               
        #define FILE_LOG C:\CreateFile.log
       
        DLLEXPORT
        HANDLE _stdcall _CreateFileW
        (
            LPCWSTR lpFileName,
            DWORD dwDesiredAccess,
            DWORD dwShareMode,
            LPSECURITY_ATTRIBUTES lpSecurityAttributes,
            DWORD dwCreationDistribution,
            DWORD dwFlagsAndAttributes,
            HANDLE hTemplateFile
        )
        {
            char   asc_str[MAX_PATH];
           
            if ( UnicodeToANSI( (WCHAR *) lpFileName, asc_str ) == 0 )
                CreateFileLogger( asc_str );
           
            return CreateFileW(
                lpFileName,
                dwDesiredAccess,
                dwShareMode,
                lpSecurityAttributes,
                dwCreationDistribution,
                dwFlagsAndAttributes,
                hTemplateFile );
        }
       
        DLLEXPORT
        HANDLE _stdcall _CreateFileA
        (
            LPCSTR lpFileName,
            DWORD dwDesiredAccess,
            DWORD dwShareMode,
            LPSECURITY_ATTRIBUTES lpSecurityAttributes,
            DWORD dwCreationDistribution,
            DWORD dwFlagsAndAttributes,
            HANDLE hTemplateFile
        )
        {
            char   asc_str[MAX_PATH];
           
            CreateFileLogger( lpFileName );
           
            return CreateFileA(
                lpFileName,
                dwDesiredAccess,
                dwShareMode,
                lpSecurityAttributes,
                dwCreationDistribution,
                dwFlagsAndAttributes,
                hTemplateFile );
        }
       
        static void
        CreateFileLogger( const char * file_to_log )
        {
            HANDLE file;
            DWORD  chars;
           
            file = \
                CreateFileA
                (
                    FILE_LOG                            ,
                    GENERIC_WRITE    | GENERIC_READ     ,
                    0                                   ,
                    NULL                                ,
                    OPEN_ALWAYS                         ,
                    0                                   ,
                    NULL
                );
               
            if ( file != INVALID_HANDLE_VALUE )
            {       
                if ( SetFilePointer( file, 0, NULL, FILE_END ) != -1 )
                {
                    WriteFile
                    (
                        file, file_to_log, strlen( file_to_log ), &chars, NULL
                    );
                    WriteFile( file, "\x0D\x0A", 2, &chars, NULL );
                }
                CloseHandle( file );
            }
        }
    ------[ 4.4.1 - Проблемы стэка

    Когда требуется непосредственно передать контроль к API, необходимо передать его неповрежденный стек оригиналу API. Нужно в mingw выбрать compilator-fomit-frame-pointer [R.15] и JMP (ASM) к оригиналу API.

    Функции, которые были осуществлены, должны быть помещены образец и должны иметь тип _stdcall. Функции типа _stdcall имеют различный синтаксис в файле .def:
    • Name_exportation=Alias@arguments * 4 @ Ordinal

    Пример файла .def с APIs типа _stdcall CreateFileA и CreateFileW [R.14] (оба имеют семь аргументов):

    Code:
        LIBRARY    ph_ker32
        EXPORTS
       
        ; Name Exp | Alias      | No Args * 4    | Ordinal Windows XP SP2
        CreateFileW=_CreateFileW@28              @ 83
        CreateFileA=_CreateFileA@28              @ 80
    Функции типа _stdcall не должны быть скомпилированы с опцией с-fomit-frame-pointer [R.15].

    ------[ 4.4.2 - Проблемы регистра

    Не только необходимо передать стек с неповреждённым экспортом, экспортирование должно быть с целостностью регистраторов. Перед прохождением контроля к оригинальному экспортированию, необходимо чтобы регистры не были повреждены, это достигается использованием в коде инструкции PUSHAD и POPAD:
    • [PUSHAD] [ CODE NEEDED TO JUMP TO THE EXPORTATION ] [POPAD]

    Пример экспортирования с использованием регистров _chkstk в NTDLL.DLL:

    Code:
    _chkstk in NTDLL.DLL (WINDOWS XP SP2):
       
        7C911A09 >/$ 3D 00100000    CMP EAX,1000
        7C911A0E  |. 73 0E          JNB SHORT ntdll.7C911A1E
        7C911A10  |. F7D8           NEG EAX
        7C911A12  |. 03C4           ADD EAX,ESP
        7C911A14  |. 83C0 04        ADD EAX,4
        7C911A17  |. 8500           TEST DWORD PTR DS:[EAX],EAX
        7C911A19  |. 94             XCHG EAX,ESP
        7C911A1A  |. 8B00           MOV EAX,DWORD PTR DS:[EAX]
        7C911A1C  |. 50             PUSH EAX
        7C911A1D  |. C3             RETN
        7C911A1E  |> 51             PUSH ECX
        7C911A1F  |. 8D4C24 08      LEA ECX,DWORD PTR SS:[ESP+8]
        7C911A23  |> 81E9 00100000  /SUB ECX,1000
        7C911A29  |. 2D 00100000    |SUB EAX,1000
        7C911A2E  |. 8501           |TEST DWORD PTR DS:[ECX],EAX
        7C911A30  |. 3D 00100000    |CMP EAX,1000
        7C911A35  |.^73 EC          \JNB SHORT ntdll.7C911A23
        7C911A37  |. 2BC8           SUB ECX,EAX
        7C911A39  |. 8BC4           MOV EAX,ESP
        7C911A3B  |. 8501           TEST DWORD PTR DS:[ECX],EAX
        7C911A3D  |. 8BE1           MOV ESP,ECX
        7C911A3F  |. 8B08           MOV ECX,DWORD PTR DS:[EAX]
        7C911A41  |. 8B40 04        MOV EAX,DWORD PTR DS:[EAX+4]
        7C911A44  |. 50             PUSH EAX
        7C911A45  \. C3             RETN
    ------[ 4.4.3 - JMP макрос

    Макрос JMP необходим так, как не всегда весь DLL (файл .h) имеются в его header'e. С макросом JMP адрес экспорта получается с GetProcAddress [R.12] во времени выполнения.

    Code:
        unsigned long tmp;
       
        #define JMP( lib, func )        \
           asm ( "pushad" );           \
           asm                           \
           (                             \
               " push edx             \n"      \
               " push %1              \n"      \
               " call eax             \n"      \
               " pop edx              \n"      \
               " push %2              \n"      \
               " push eax             \n"      \
               " call edx             \n"      \
               " mov %4, eax          \n"      \
               " popad                \n"      \
                                                  \
               : :                                \
               "a" (GetModuleHandle) ,         \
               "g" (lib)             ,         \
               "g" (func)            ,         \
               "d" (GetProcAddress)  ,         \
               "g" (tmp)                       \
            );                                   \
           asm ( "jmp %0" : : "g" (tmp) );
    Это код для mingw [R.16], компилировать с опцией -masm=intel.

    ------[ 4.4.4 - Версии

    Мы включили в phook различные версии ph_ker32 для систем:
    Code:
        - Windows XP SP2                 v5.1.2600
        - Windows Server 2003 R2         v5.2.3790
        - Windows Vista                  v6.0.6000
    Исходный код в ph_ker32/SO и бинарники в bin/OS.

    ------[ 4.5 - Использование phook

    Далее рассмотрено что можно делать с PEB HOOKING [T.1] для kernel32.dll к ph_ker32.dll, программа poc.exe была выбрана для примера (лежит в папке bin\ of phook).

    Шаги для следования:

    1.- Запустите InjectorDLL с указанием программы для инжекта DLL, для для этого введите в консоли:
    • InjectorDLL.exe console.dll -u poc.exe

    Процесс будет в приостановленном виде и будет возможность для прослушки порта, записанном в файле C:\ph_listen_ports.log

    Code:
            C:\phook\bin>InjectorDll.exe console.dll -u poc.exe 
              ________________________________________________________________
             |                       InjectorDLL v1.0                         |
             |                                                                |
             | Juan Carlos Montes   eunimedes@hotmail.com                     |
             | David Reguera Garcia Dreg@fr33project.org / Dreg@7a69ezine.org |
             | -------------------------------------------------------------- |
             |                   http://www.fr33project.org                   |
             |________________________________________________________________|
            
             Showing injection data .....
                 Program to inject : poc.exe
                 Library to inject: console.dll
            
             [OK]   - CONSOLE.
             [OK]   - Create process:
                 [INFO] PID:       0x0960
                 [INFO] P. HANDLE: 0x000007B8
                 [INFO] TID:       0x0AE0
                 [INFO] T. HANDLE: 0x000007B0
             [INFO] - Injecting DLL...
                 [OK]   - Allocate memory in the extern process.
                 [INFO] - Address reserved on the other process: 0x00240000
                 [INFO] - Space requested: 306
                 [OK]   - Creating structure for the dll load.
                 [OK]   - Writing structure for the dll load.
                 [OK]   - Creating remote thread.
                 [INFO] - Thread created with TID: 0x0B28
                 [INFO] - Attempt: 1
                 [INFO] - Thread has entered suspension mode.
                 [OK]   - Injection thread ended.
                 [OK]   - Memory in remote thread freed.
             [OK]   -  DLL injected.
            
             [OK]   -  Injection ended.
    2.- Необходимо соединиться с клиентом через netcat к открытому порту, в нашем случаи: 1234.

    Code:
        C:\>nc 127.0.0.1 1234
          ________________________________________________________________
         |                        Phook Prompt v1.0                       |
         | Juan Carlos Montes   eunimedes@hotmail.com                     |
         | David Reguera Garcia Dreg@fr33project.org / Dreg@7a69ezine.org |
         | -------------------------------------------------------------- |
         |                   http://www.fr33project.org                   |
         |________________________________________________________________|
        
        
         ph > help
          _________________________________________________________________
         |                       Phook Prompt v1.0                         |
         |                                                                 |
         | Command list:                                                   |
         | --------------------------------------------------------------- |
         | help                      - Shows this screen                   |
         | exit                      - Closes and unloads the console      |
         | suspend                   - Pauses the programs execution       |
         | resume                    - Resumes the programs execution      |
         | showmodules               - Shows the modules list              |
         | load [param1]             - Loads in memory the library         |
         |                             especified in [param1]              |
         | unload [param1]           - Unloads a librery in memory         |
         |                             especified in [param1]              |
         | pebhook [param1] [param2] - Performs PEB Hook over a dll        |
         |                             [param1]: Name of the original dll  |
         |                             [param2]: Path to the DLL hook      |
         |_________________________________________________________________|
    3.- PEB HOOKING [T.1] для kernel32.dll осуществляется с ph_ker32.dll:

    Code:
        ph > pebhook kernel32.dll C:\phook\bin\windows_xp_sp2\ph_ker32.dll
    4.- Команда resume продолжает выполнение процесса.

    Code:
    ph > resume
        ph >    
        C:\phook\bin>
    5.- poc.exe creates the files in C:\
    Code:
        - file
        - file2
        - file3
    6.- ph_ker32.dll регистрирует успешные API вызовы CreateFileA и CreateFileW [R.14] в файле C:\CreateFile.log

    7.- C:\>more CreateFile.log

    Code:
        C:\file1
        C:\file2
        C:\file3
    ------[ 4.5.1 - DLL MINIFILTER

    phook позволяет также реализовать и DLL MINIFILTER (см. пункт 3.7). Он только должен выполнить PEB HOOKING [T.1], с помощью команды pebhook, с необходимым именем DLL_FAKE, тоесть той что была DLL_REAL.

    Предположим что у нас есть две DLL_FAKE:
    • ph_ker32_1.dll: Следит за доступом к API CreateFile [R.14].
    • ph_ker32_2.dll: Следит за доступом к API ReadFile [R.17].
    Выполнения DLL MINIFILTER очень просто:

    Code:
        C:\>nc 127.0.0.1 1234
          ________________________________________________________________
         |                        Phook Prompt v1.0                       |
         | Juan Carlos Montes   eunimedes@hotmail.com                     |
         | David Reguera Garcia Dreg@fr33project.org / Dreg@7a69ezine.org |
         | -------------------------------------------------------------- |
         |                   http://www.fr33project.org                   |
         |________________________________________________________________|
        
        
         ph > pebhook kernel32.dll C:\phook\bin\windows_xp_sp2\ph_ker32_1.dll
         ph > pebhook kernel32.dll C:\phook\bin\windows_xp_sp2\ph_ker32_2.dll
    Поступает вызов от процесса к kernel32.dll:
    Code:
                   0                    1                   2
        [proceso] --> [ph_ker32_2.dll] --> [ph_ker32_2.dll] -> [kernel32.dll]
            ^                                                      |
            |                          3                           |
            +------------------------------------------------------+
    ------[ 4.6 - Частые проблемы

    Помимо проблем описанных в section 3.8, есть и другие:

    Code:
    +------------------------------------------------------------------------+
    |           Problem            |                 Possible/s Solution/s   |
    |------------------------------+-----------------------------------------|
    | - DLL_FAKE ошибка компиляции | - Проверьте, что функции, которые       |
    |                              |   выходят непосредственно на DLL_REAL   |
    |                              |   не повторялись, и реализуются.        |
    |                              | - Проверьте, что выполнены функций      |
    |                              |   (которые должны быть _stdcall типа)   |
    |                              |   хорошо определено в .def файле        |
    |                              |   (см. пункт 4.4.1).                    |
    |------------------------------+-----------------------------------------|
    | - Выполнение процесса        | - Проверьте, что функции, которые       |
    |   не происходит              |   выходят непосредственно на DLL_REAL   |
    |                              |   были составлены с помощью опции       |
    |                              |   -fomit-frame-pointer (см. пункт       |
    |                              |    4.4.1).                              |
    |                              | - Проверьте, что выполнены функции      |
    |                              |   имеют _stdcall типа.                  |
    |                              | - Проверьте, что DLL_FAKE были созданы  |
    |                              |   от DLL_REAL, а не от другой.          |
    |                              | - Проверьте, если InjectorDLL правильно |
    |                              |   обнаружен реальный тип процесса       |
    |                              |   (GUI или CONSOLE).                    |
    |------------------------------+-----------------------------------------|
    | - Не удалось подключиться    | - Проверьте что порт 1234 открыт        |
    |   к консоли                  |   перед вызовом PEB HOOKING [T.1].      |
    |                              | - Проверьте что фаервол не блокирует... |
    |                              | - Убедитесь в том, что полный путь      |
    |                              |   console.dll было указано              |
    |                              |   в InjectorDLL.                        |
    |------------------------------+-----------------------------------------|
    | - InjectorDLL не работает    | - Проверьте что есть привилегии для     |
    |                              |   внедрения DLL (CreateRemoteThread..)  |
    |                              |                                         |
    |                              | - Проверьте не блокирует ли антивирус.. |
    |------------------------------+-----------------------------------------|
    | - CreateExp не работает      |- Проверьте DLL_REAL на правильность     |
    |                              |  PE32 и EXPORT DIRECTORY [R.3].         |
    +------------------------------------------------------------------------+
    Некоторые другие проблемы могут возникнуть из-за проектирования или других несвязанных с phook ошибок программиста.

    ------[ 5.- Что делаем

    На данный момент мы работаем над:
    • - Реализацией PEB HOOKING [T.1] до выполнения:
      • TLS Table и DLLMain [R.3].
      • Создать отладочные файлы конфигурации и для консоли.
      • Правила для восстановления IATs [R.4].
      • Список прослушивающих портов.
      • ...
    • - Улучшить InjectorDLL:
      • Автоматическое распознавание "GUI процессов" и "Console процессов".

    ------[ 6.- Тестирование

    Тестирование phook было произведено в различных версиях Windows и программах.

    Code:
    Windows:
        - Windows XP SP2              v5.1.2600
        - Windows Server 2003 R2      v5.2.3790
        - Windows Vista               v6.0.6000
    Теоретически должно работать и в Windows 2000, но мы не можем подтвердить это.

    Code:
    Программы:
        - Microsoft Word        10.0.2627.0
        - Regedit               5.1.2600.2180
        - Notepad               5.1.2600.2180
        - Calc                  5.1.2600.0
        - CMD                   5.1.2600.2180
        - piathook              1.4
        - pebtry                Beta 5
        - pe32analyzer          Beta 2
    ------[ 7.- Преимущества и возможности

    Главное преимущества PEB HOOKING перед другими в том что, он применяется только 1 раз.К моменту когда выполнен хук длл, любой загружаемый модуль автоматически получает в своей IAT экспорт DLL_FAKE. Остальные модули должны применять хук каждый раз когда модуль загружается.

    Другие преимущества PEB HOOKING [T.1]:
    • Поиск PEB (используя BaseDllName) чтоб найти DLL_REAL, будет находится в DLL_FAKE.
    • PEB HOOKING является более стабильным для ОС чем использование ring0.
    • Некоторые упаковщики не обнаруживают PEB HOOKING [T.1] так как это не документированный способ.
    • Нет необходимости менять поведение работы API с модулями. Когда модуль обращается к DLL_REAL, то он автоматически обращается к DLL_FAKE.
    • Возможность реализовать DLL MINIFILTER (см. пункт 3.7).
    • PEB HOOKING может экспортировать Forwarder [R.3] не делая PEB HOOKING к Forwarder DLL.

    Спектр возможностей PEB HOOKING [T.1] и phook достаточно большой, вот несколько примеров применения:

    Code:
        - Мониторинг/виртуализация доступа процесса к реестру:
            - POC [R.18]:
                1.- Запустите CreateExp (см. пункт 4.3) с
                    "advapi32.dll".
                2.- Взависимости от того, что вы хотите сделать необходимо
            наблюдать/виртуализовать следующие API:
                    - RegCloseKey
                    - RegCreateKeyA/RegCreateKeyW
                    - RegCreateKeyExA/RegCreateKeyExW
                    - RegDeleteKeyA/RegDeleteKeyW
                    - RegLoadKeyA/RegLoadKeyW
                    - RegOpenKeyA/RegOpenKeyW
                    - RegOpenKeyExA/RegOpenKeyExW
                    - RegQueryValueA/RegQueryValueW
                    - RegQueryValueExA/RegQueryValueExW
                    - RegReplaceKeyA/RegReplaceKeyW
                    - RegRestoreKeyA/RegRestoreKeyW
                    - RegSaveKeyA/RegSaveKeyW
                    - RegSaveKeyExA/RegSaveKeyExW
                    - RegSetValueA/RegSetValueW
                    - RegSetValueExA/RegSetValueExW
                    - RegUnLoadKeyA/RegUnLoadKeyW
                    ...
       
        - Наблюдение/виртуализация подключений.
            - POC [R.20]:
                1.- Запустите CreateExp (см. пункт 4.3) с "ws2_32.dll".
                2.- Взависимости от того, что вы хотите сделать необходимо наблюдать/виртуализовать следующие API:
                    - accept
                    - bind
                    - closesocket
                    - connect
                    - listen
                    - recv
                    - recvfrom
                    - send
                    - sendto
                    - socket
                    - WSAAccept
                    - WSAConnect
                    - WSARecv
                    - WSARecvFrom
                    - WSASend
                    - WSASendTo
                    - WSASocketA/W
                    ...
       
        - Syscall Proxy of files:
            - POC [R.19]:
                1.- Запустите CreateExp (см. пункт 4.3) с "kernel32.dll".
                2.- Взависимоти от того, что вы хотите сделать необходимо перенаправлять следующие API:
                    - CreateFileA/CreateFileW
                    - CreateFileExA/CreateFileExW
                    - ReadFile
                    - ReadFileEx
                    - WriteFile
                    - WriteFileEx
                    ...
       
        - ... и конечно ваши идеи ;-)
    ------[ 8.- Заключение

    Если необходимо выполнить hook на API/экспорта, можно использовать любые методы. Но если необходимо наблюдать или виртуализировать доступ к различным API/экспорту, то с phook это намного проще осуществить.

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

    ------[ 9.- Благодарности

    Recommendations for the paper:
    • phrack staff
    • Tarako

    Translation to English of the chains of phook:
    • Southern
    • LogicMan
    • XENMAX

    Translations of the paper to English:
    • BETA : Ana Hijosa
    • BETA 2: delcoyote
    • ACTUAL: LogicMan

    Virii scene:
    • GriYo, zert, Slow, pluf, xezaw, sha0 ...

    Reversing scene:
    • pOpE, JKD, ilo, Ripe, int27h, at4r, uri, numitor, vikt0ry, kania, remains, S-P-A-R-K ...

    Other scene:
    • sync, ryden, xenmax, ozone/membrive, \^snake^\, topo, fixgrain, ia64, overdrive, success, scorpionn, oyzzo, simkin, !dSR ...
    ALL vx.7a69ezine.org and 7a69ezine.org people

    And specially thanks to YJesus - http://www.security-projects.com

    ------[ 10.- Похожие работы
    • [T.1] .- Нам неизвестно о каких-то других работах с использованием phook, но есть статья с упоминанием PEB HOOKING написанная Deroko: "PEB DLL Hooking Novel method to Hook DLLs". Статья была опубликованна в ARTeam-Ezine выпуск 2.

    ------[ 11.- Ссылки

    ------[ 12.- Исходный код


    Download "Source Code phook"


    Izg0y © CORU, r0 Crew
    Успех – это путь от провала до провала без потери энтузиазма. (В. Черчиль)

    Не бойся идти медленно, бойся остановиться. (Китайская пословица)

    When you lose fun and start doing things only for the payback, you're dead. (c) TCLH (Phrack 65, Intro)

  2. 5 пользователя(ей) сказали cпасибо:
    AbreC (18-10-2010) Heroin (18-10-2010) Scorpius (22-10-2010) dahaka (18-10-2010) ximera (22-10-2010)
  3. #2
    ARCHANGEL's Avatar

    Default Re: (Phrack 65): phook - The PEB Hooker

    Товарищи, у кого-то получилось удачно перехватить какие-то функции с помощью скомпиленных бинарников этого чуда? Я вчера проводил опыты - вначале на одной своей консольной программе, потом на стандартном гуишном блокноте - эффекта ноль: и то, и то так и остаётся в замороженном состоянии, т.е. главный поток либо так и остаётся в SUSPENDED состоянии, либо WaitForInputIdle используется неправильно - я не знаю, но лог перехвата получить мне не удалось.
    Добрым быть просто - достаточно обратить свой гнев на негодяев...

  4. #3
    root's Avatar

    Default Re: (Phrack 65): phook - The PEB Hooker

    На Windows SP2 у меня работало.
    Успех – это путь от провала до провала без потери энтузиазма. (В. Черчиль)

    Не бойся идти медленно, бойся остановиться. (Китайская пословица)

    When you lose fun and start doing things only for the payback, you're dead. (c) TCLH (Phrack 65, Intro)

  5. #4
    ARCHANGEL's Avatar

    Default Re: (Phrack 65): phook - The PEB Hooker

    А можно подробнее? Работало, когда применял netcat для управления? Если да, то как? Я просто хочу на основе этого творения статейку замутить до начала челенджа - потом некогда будет.
    Добрым быть просто - достаточно обратить свой гнев на негодяев...

  6. #5
    root's Avatar

    Default Re: (Phrack 65): phook - The PEB Hooker

    Выполнял все шаги описанные в статье. Может ты забыл продолжить выполнение процесса (команда "resume")? Или запустить еще одну консоль (cmd.exe), для запуска "nc.exe"?

    Как делал я:
    • Взял папку "bin", забросил на "Рабочий стол";
    • Скопировал туда "cmd.exe", "nc.exe", ph_ker32.dll;
    • Запустил cmd.exe;
    • Ввел: injectordll console.dll -c poc
    • Получил:
      C:\ ... \bin>injectordll console.dll -u poc
      __________________________________________________ ______________
      | InjectorDLL v1.0 |
      | |
      | Juan Carlos Montes eunimedes@hotmail.com |
      | David Reguera Garcia Dreg@fr33project.org / Dreg@7a69ezine.org |
      | -------------------------------------------------------------- |
      | http://www.fr33project.org |
      |_________________________________________________ _______________|

      Showing injection data .....
      Program to inject : poc.exe
      Library to inject: console.dll

      [OK] - CONSOLE.
      [OK] - Create process:
      [INFO] PID: 0x0960
      [INFO] P. HANDLE: 0x000007B8
      [INFO] TID: 0x0AE0
      [INFO] T. HANDLE: 0x000007B0
      [INFO] - Injecting DLL...
      [OK] - Allocate memory in the extern process.
      [INFO] - Address reserved on the other process: 0x00240000
      [INFO] - Space requested: 306
      [OK] - Creating structure for the dll load.
      [OK] - Writing structure for the dll load.
      [OK] - Creating remote thread.
      [INFO] - Thread created with TID: 0x0B28
      [INFO] - Attempt: 1
      [INFO] - Thread has entered suspension mode.
      [OK] - Injection thread ended.
      [OK] - Memory in remote thread freed.
      [OK] - DLL injected.

      [OK] - Injection ended.
      • Запустил еще один cmd.exe;
      • Ввел: nc 127.0.0.1 1234
      • Получил:
      C:\Document and Settings\ ... \Рабочий стол\bin>nc 127.0.0.1 1234
      __________________________________________________ ______________
      | Phook Prompt v1.0 |
      | Juan Carlos Montes eunimedes@hotmail.com |
      | David Reguera Garcia Dreg@fr33project.org / Dreg@7a69ezine.org |
      | -------------------------------------------------------------- |
      | http://www.fr33project.org |
      |_________________________________________________ _______________|

      ph >|
    • Подменил DLL, введя: ph > pebhook kernel32.dll ph_ker32.dll
    • Возобновил выполнение: ph > resume
      ph >
      C:\Document and Settings\ ... \Рабочий стол\bin>
    • Посмотрел на корень: C:\ (файлы создались), там же и CreateFile.log

    Что бы запустить под SP3, надо с бубном потанцевать.
    Успех – это путь от провала до провала без потери энтузиазма. (В. Черчиль)

    Не бойся идти медленно, бойся остановиться. (Китайская пословица)

    When you lose fun and start doing things only for the payback, you're dead. (c) TCLH (Phrack 65, Intro)

  7. 2 пользователя(ей) сказали cпасибо:
    ARCHANGEL (25-10-2010) ximera (24-10-2010)
  8. #6
    ARCHANGEL's Avatar

    Default Re: (Phrack 65): phook - The PEB Hooker

    Разобрался. Блин, результат превзошёл все ожидания. Отпишусь в статье, но вначале надо бы до разрабов RKU - есть разговор к ним.
    Добрым быть просто - достаточно обратить свой гнев на негодяев...

  9. #7
    Izg0y's Avatar

    Default Re: (Phrack 65): phook - The PEB Hooker

    >но вначале надо бы до разрабов RKU - есть разговор к ним.

    kernelmode.info тут сможишь связаться с ними
    ,--= Реальность - это костыль для тех, кто не имеет воображения =--,

  10. #8
    ARCHANGEL's Avatar

    Default Re: (Phrack 65): phook - The PEB Hooker

    http://www.kernelmode.info/forum/vie...php?f=11&t=407

    Ждём результатов...
    Добрым быть просто - достаточно обратить свой гнев на негодяев...

  11. #9
    ARCHANGEL's Avatar

    Default Re: (Phrack 65): phook - The PEB Hooker

    Что-то глухо. Короче, статья выйдет независимо от того, когда там проснутся.
    Добрым быть просто - достаточно обратить свой гнев на негодяев...

  12. #10
    root's Avatar

    Default Re: (Phrack 65): phook - The PEB Hooker

    Уже должны были ответить...

    PS: Никогда не нужно спешить, если что-то сделал. Статья никуда не улетит за несколько дней...
    Успех – это путь от провала до провала без потери энтузиазма. (В. Черчиль)

    Не бойся идти медленно, бойся остановиться. (Китайская пословица)

    When you lose fun and start doing things only for the payback, you're dead. (c) TCLH (Phrack 65, Intro)

  13. #11
    ARCHANGEL's Avatar

    Default Re: (Phrack 65): phook - The PEB Hooker

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

  14. Пользователь сказал cпасибо:
    root (28-10-2010)
+ Reply to Thread

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
All times are GMT. The time now is 01:38
vBulletin® Copyright ©2000 - 2018
www.reverse4you.org