From 399e3f543bf477799be480efcec473193845b926 Mon Sep 17 00:00:00 2001 From: Huoji's <1296564236@qq.com> Date: Fri, 26 Feb 2021 15:10:12 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E4=B8=80=E4=B8=AA=E5=8D=95?= =?UTF-8?q?=E8=AF=8D=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DuckMemoryScan/CdigitalSig.h | 1 + DuckMemoryScan/main.cpp | 96 +++++++++++++++++++++++++++++++----- README.md | 7 ++- 3 files changed, 92 insertions(+), 12 deletions(-) diff --git a/DuckMemoryScan/CdigitalSig.h b/DuckMemoryScan/CdigitalSig.h index c364e79..494d3e4 100644 --- a/DuckMemoryScan/CdigitalSig.h +++ b/DuckMemoryScan/CdigitalSig.h @@ -10,6 +10,7 @@ #include #pragma comment (lib, "wintrust") #pragma comment (lib, "crypt32.lib") +#define PE_BUFF_SIZE 0x1337 typedef enum _MEMORY_INFORMATION_CLASS { MemoryBasicInformation, MemoryWorkingSetList, diff --git a/DuckMemoryScan/main.cpp b/DuckMemoryScan/main.cpp index 37eaa1c..b347c6c 100644 --- a/DuckMemoryScan/main.cpp +++ b/DuckMemoryScan/main.cpp @@ -109,8 +109,50 @@ DWORD64 GetProcessMoudleHandle(DWORD pid) { } while (Module32Next(handle, &moduleEntry)); return 0; } +bool CheckThreadIsInCodeSection(DWORD64 pAddress, HANDLE pHandle, DWORD64 pID) { + bool result = false; + MODULEENTRY32 moduleEntry; + HANDLE handle = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pID); + ZeroMemory(&moduleEntry, sizeof(MODULEENTRY32)); + moduleEntry.dwSize = sizeof(MODULEENTRY32); + char* AllocBuff = (char*)VirtualAlloc(NULL, PE_BUFF_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + if (AllocBuff) { + if (!Module32First(handle, &moduleEntry)) { + CloseHandle(handle); + return false; + } + do { + DWORD64 ReadNum = 0; + if (ReadProcessMemory(pHandle, moduleEntry.modBaseAddr, AllocBuff, PE_BUFF_SIZE, &ReadNum)) { + if (AllocBuff[0] == 'M' && AllocBuff[1] == 'Z') { + PIMAGE_DOS_HEADER CopyDosHead = (PIMAGE_DOS_HEADER)AllocBuff; + PIMAGE_NT_HEADERS CopyNthead = (PIMAGE_NT_HEADERS)((LPBYTE)AllocBuff + CopyDosHead->e_lfanew); + DWORD64 BaseOfCode = 0; + DWORD64 SizeOfCode = 0; + if (CopyNthead->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64) { + PIMAGE_NT_HEADERS64 CopyNthead64 = (PIMAGE_NT_HEADERS64)CopyNthead; + BaseOfCode = CopyNthead64->OptionalHeader.BaseOfCode; + SizeOfCode = CopyNthead64->OptionalHeader.SizeOfCode; + } + else { + PIMAGE_NT_HEADERS32 CopyNthead32 = (PIMAGE_NT_HEADERS32)CopyNthead; + BaseOfCode = CopyNthead32->OptionalHeader.BaseOfCode; + SizeOfCode = CopyNthead32->OptionalHeader.SizeOfCode; + } + if (pAddress >= (DWORD64)moduleEntry.modBaseAddr + BaseOfCode && pAddress <= (DWORD64)moduleEntry.modBaseAddr + BaseOfCode + SizeOfCode) { + result = true; + break; + } + } + } -bool CheckThreadAddressIsExcute(DWORD64 pAddress,HANDLE pHandle, HANDLE pID, HANDLE Tid, BOOL isRipBackTrack) { + } while (Module32Next(handle, &moduleEntry)); + VirtualFree(AllocBuff, 0, MEM_RELEASE); + } + CloseHandle(handle); + return result; +} +void CheckThreadAddressIsExcute(DWORD64 pAddress,HANDLE pHandle, HANDLE pID, HANDLE Tid, BOOL isRipBackTrack) { DWORD64 ReadNum = 0; MEMORY_BASIC_INFORMATION mbi = { 0 }; @@ -127,16 +169,14 @@ bool CheckThreadAddressIsExcute(DWORD64 pAddress,HANDLE pHandle, HANDLE pID, HAN printf("\t => [!!!线程堆栈回溯!!!] 检测到内存加载程序 线程地址 %p PID %d TID %d 内存加载模块地址: %p\n", pAddress, pID, Tid, mbi.BaseAddress); } } - return true; } else if (isRipBackTrack && mbi.AllocationProtect & PAGE_READONLY && mbi.AllocationProtect & PAGE_NOACCESS) { printf("\t => [线程堆栈回溯] 检测到线程曾在不可执行的代码区域执行过[请检查是否有Rootkit存在或者是否被Hook] 地址 %p PID %d TID %d \n", pAddress, pID, Tid); - return true; } } } } - return false; + return; } void ThreadStackWalk() { HANDLE hThreadSnap = INVALID_HANDLE_VALUE; @@ -173,6 +213,11 @@ void ThreadStackWalk() { printf("\t => [线程堆栈回溯] 检测到HWBP Hook PID %d TID %d \n", te32.th32OwnerProcessID, te32.th32ThreadID); } CheckThreadAddressIsExcute(context.Rip, hProcess, (HANDLE)te32.th32OwnerProcessID, (HANDLE)te32.th32ThreadID, TRUE); + /* + if (CheckThreadIsInCodeSection(context.Rip, hProcess, (DWORD64)te32.th32OwnerProcessID) == false){ + __debugbreak(); + } + */ StackFarmeEx.AddrPC.Offset = context.Rip; StackFarmeEx.AddrPC.Mode = AddrModeFlat; StackFarmeEx.AddrStack.Offset = context.Rsp; @@ -201,8 +246,13 @@ void ThreadStackWalk() { //hwbp hook printf("\t => [线程堆栈回溯] 检测到HWBP Hook PID %d TID %d \n", te32.th32OwnerProcessID, te32.th32ThreadID); } - CheckThreadAddressIsExcute(context.Eip, hProcess, (HANDLE)te32.th32OwnerProcessID, (HANDLE)te32.th32ThreadID, TRUE); + /* + if (CheckThreadIsInCodeSection(context.Eip, hProcess, (DWORD64)te32.th32OwnerProcessID) == false) { + __debugbreak(); + } + */ + StackFarmeEx.AddrPC.Offset = context.Eip; StackFarmeEx.AddrPC.Mode = AddrModeFlat; StackFarmeEx.AddrStack.Offset = context.Esp; @@ -233,13 +283,14 @@ void ThreadStackWalk() { } } void WalkProcessMoudle(DWORD pID,HANDLE pHandle,WCHAR* pMoudleName,BOOL pCheckMoudle) { - + if (pCheckMoudle == false) + return; MODULEENTRY32 moduleEntry; HANDLE handle = NULL; handle = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pID); ZeroMemory(&moduleEntry, sizeof(MODULEENTRY32)); moduleEntry.dwSize = sizeof(MODULEENTRY32); - char* AllocBuff = (char*)VirtualAlloc(NULL, 0x200, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + char* AllocBuff = (char*)VirtualAlloc(NULL, PE_BUFF_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); if (AllocBuff) { if (!Module32First(handle, &moduleEntry)) { CloseHandle(handle); @@ -253,25 +304,49 @@ void WalkProcessMoudle(DWORD pID,HANDLE pHandle,WCHAR* pMoudleName,BOOL pCheckMo printf("\t => [模块扫描] 检测到可疑模块(也许是误报) 路径 %ws 进程名字 %ws pid %d \n", moduleEntry.szExePath, pMoudleName, pID); } } + /* DWORD64 ReadNum = 0; - if (ReadProcessMemory(pHandle, moduleEntry.modBaseAddr, AllocBuff, 0x200, &ReadNum)) { + if (ReadProcessMemory(pHandle, moduleEntry.modBaseAddr, AllocBuff, PE_BUFF_SIZE, &ReadNum)) { if (AllocBuff[0] == 'M' && AllocBuff[1] == 'Z') { PIMAGE_DOS_HEADER CopyDosHead = (PIMAGE_DOS_HEADER)AllocBuff; PIMAGE_NT_HEADERS CopyNthead = (PIMAGE_NT_HEADERS)((LPBYTE)AllocBuff + CopyDosHead->e_lfanew); - PIMAGE_SECTION_HEADER SectionHeader = (PIMAGE_SECTION_HEADER)((PUCHAR)CopyNthead + sizeof(CopyNthead->Signature) + sizeof(CopyNthead->FileHeader) + CopyNthead->FileHeader.SizeOfOptionalHeader); + DWORD64 BaseOfCode = 0; + DWORD64 SizeOfCode = 0; + DWORD64 SizeSignature = 0; + DWORD64 SizeFileHeader = 0; + DWORD64 SizeFileHeaderSizeOfOptionalHeader = 0; + if (CopyNthead->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64) { + PIMAGE_NT_HEADERS64 CopyNthead64 = (PIMAGE_NT_HEADERS64)CopyNthead; + BaseOfCode = CopyNthead64->OptionalHeader.BaseOfCode; + SizeOfCode = CopyNthead64->OptionalHeader.SizeOfCode; + SizeSignature = sizeof(CopyNthead64->Signature); + SizeFileHeader = sizeof(CopyNthead64->FileHeader); + SizeFileHeaderSizeOfOptionalHeader = CopyNthead64->FileHeader.SizeOfOptionalHeader; + } + else { + PIMAGE_NT_HEADERS32 CopyNthead32 = (PIMAGE_NT_HEADERS32)CopyNthead; + BaseOfCode = CopyNthead32->OptionalHeader.BaseOfCode; + SizeOfCode = CopyNthead32->OptionalHeader.SizeOfCode; + SizeSignature = sizeof(CopyNthead32->Signature); + SizeFileHeader = sizeof(CopyNthead32->FileHeader); + SizeFileHeaderSizeOfOptionalHeader = CopyNthead32->FileHeader.SizeOfOptionalHeader; + } + PIMAGE_SECTION_HEADER SectionHeader = (PIMAGE_SECTION_HEADER)((PUCHAR)CopyNthead + SizeSignature + SizeFileHeader + SizeFileHeaderSizeOfOptionalHeader); int FoundNum = 0; for (WORD i = 0; i < CopyNthead->FileHeader.NumberOfSections; i++) { if (SectionHeader[i].Characteristics & IMAGE_SCN_MEM_EXECUTE) { FoundNum++; } - if (FoundNum > 1) { + if (FoundNum > 3) { printf("\t => [进程检测] 检测到额外的可执行区段(.rdata免杀 or 加壳程序) 进程名 %ws 路径 %ws 进程id %d\n", pMoudleName, moduleEntry.szExePath, pID); break; } + } } } + */ } while (Module32Next(handle, &moduleEntry)); VirtualFree(AllocBuff, 0, MEM_RELEASE); @@ -305,7 +380,6 @@ void ProcessStackWalk() { printf("\t => [进程扫描] 检测到可疑签名进程 路径 %ws static %d \n", pszFullPath, dDigitalState); } WalkProcessMoudle(pe32.th32ProcessID, hProcess, pe32.szExeFile, dDigitalState == DIGITAL_SIGSTATE_VALID); - } } CloseHandle(hProcess); diff --git a/README.md b/README.md index 1fa544b..1d38250 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,12 @@ # DuckMemoryScan -涓涓畝鍗曞鎵炬棤鏂囦欢钀藉湴鍚庨棬鐨勫伐鍏,鐢県uoji鑺变簡1澶╃紪鍐,缂栧啓鏃堕棿2021-02-24 +涓涓畝鍗曞鎵惧寘鎷笉闄愪簬iis鍔寔,鏃犳枃浠舵湪椹,shellcode鍏嶆潃鍚庨棬鐨勫伐鍏,鐢県uoji鑺变簡1澶╃紪鍐,缂栧啓鏃堕棿2021-02-24 !!!鏈▼搴忛渶瑕64浣嶇紪璇戞墠鑳藉洖婧痻64鐨勭▼搴忓爢鏍,璇峰嬁鎵ц32浣嶇紪璇!!! +!!!鏈伐鍏蜂笉鑳戒唬鏇挎潃姣掕蒋浠!!! # 杩愯鎴浘 ![image](https://raw.githubusercontent.com/huoji120/DuckMemoryScan/master/%E6%BC%94%E7%A4%BA%E5%9B%BE%E7%89%87.png) ![image](https://raw.githubusercontent.com/huoji120/DuckMemoryScan/master/CS%e6%b5%8b%e8%af%95%e5%9b%be%e7%89%87.png) + # 鍔熻兘鍒楄〃 1. HWBP hook妫娴 妫娴嬬嚎绋嬩腑鎵鏈夌枒浼艰hwbp闅愬舰鎸傞挬 2. 鍐呭瓨鍏嶆潃shellcode妫娴(metasploit,Cobaltstrike瀹屽叏妫娴) @@ -12,6 +14,7 @@ 4. 鏃犳枃浠惰惤鍦版湪椹娴(妫娴嬫墍鏈夊凡鐭ュ唴瀛樺姞杞芥湪椹) 5. 绠鏄搑ootkit妫娴(妫娴嬭瘉涔﹁繃鏈/鎷︽埅璇诲彇/璇佷功鏃犳晥鐨勯┍鍔) 6. 妫娴嬪紓甯告ā鍧,妫娴嬬粷澶ч儴鍒嗗"iis鍔寔"鐨勫悗闂(2021骞2鏈26鏃ユ柊澧) + # 鍏嶆潃鏈ㄩ┈妫娴嬪師鐞: 鎵鏈夋墍璋撶殑鍐呭瓨鍏嶆潃鍚庨棬澶ч儴鍒嗗熀浜"VirtualAlloc"鍑芥暟鐢宠鍐呭瓨 涔嬪悗閫氳繃鍚勭鑾悕鍏跺鐨剎or鐢氳嚦鏄痑es鍔犲瘑鍘绘贩娣唖hellcode杈惧埌"鍏嶆潃"鏁堟灉. 鏈伐鍏烽氳繃绾跨▼鍫嗘爤鍥炴函鏂规硶(StackWalkEx鍑芥暟)閬嶅巻绾跨▼,瀵绘壘绯荤粺涓湪VirtualAlloc鍖哄煙鎵ц浠g爜鐨勫尯鍩,浠庤屾彧鍑"鍏嶆潃鏈ㄩ┈" @@ -37,4 +40,6 @@ 鐩墠宸ュ叿鍙洖婧痳ip涓巈ip,浣犲彲浠ュ洖婧疪SP鎴栬匛BP 鍙渶淇敼StackFarmeEx.AddrPC.Offset鍗冲彲 # 杩借釜杩欎釜椤圭洰 +鐧藉附wiki鏄竴涓叕鐩婃ц川鐨勭煡璇嗗簱涓烘墍鏈変汉鍦ㄧ煡璇嗕粯璐规椂浠f彁渚涗竴涓畝鍗曠殑鍏嶈垂鐨勫瓨鍌ㄧ煡璇嗙殑缃戠珯.瀵规爣vxjump.net,鎴戜細鏃犲伩鐨勫皢鎴戠殑鎵瀛﹀埌鐨勭煡璇嗗垎浜湪姝iki涓,鐩墠娑夊強鍒版満鍣ㄥ涔犻鍩,铏氭嫙鍖栧畨鍏ㄩ鍩,浼犵粺瀹夊叏棰嗗煙,娓告垙瀹夊叏棰嗗煙,EFI纭欢瀹夊叏棰嗗煙.甯屾湜鍚庝汉鑳藉皯涓鐐瑰潙. +浣犲彲浠ュ湪姝ょ綉绔欎腑鍙戠幇涓涓矇娌﹀緢涔呯殑璁ㄨ缇,閫夋嫨鍔犲叆,鐒跺悗涓璧锋壇娣¤亰澶. https://key08.com \ No newline at end of file