diff --git a/DuckMemoryScan/main.cpp b/DuckMemoryScan/main.cpp index 6e7a0aa..2702707 100644 --- a/DuckMemoryScan/main.cpp +++ b/DuckMemoryScan/main.cpp @@ -266,7 +266,7 @@ void WalkProcessMoudle(DWORD pID,HANDLE pHandle,WCHAR* pMoudleName) { FoundNum++; } if (FoundNum > 1) { - printf("\t => [进程检测] 检测到额外的可执行区段(.rdata免杀 or 加壳程序) 进程名 %ws 进程id %d 模块名 %ws 区段名字 %s \n", pMoudleName, moduleEntry.szExePath, pID, SectionHeader[i].Name); + printf("\t => [进程检测] 检测到额外的可执行区段(.rdata免杀 or 加壳程序) 进程名 %ws 路径 %ws 进程id %d\n", pMoudleName, moduleEntry.szExePath, pID); break; } } diff --git a/README.md b/README.md new file mode 100644 index 0000000..27ab4af --- /dev/null +++ b/README.md @@ -0,0 +1,26 @@ +# DuckMemoryScan +涓涓畝鍗曞鎵炬棤鏂囦欢钀藉湴鍚庨棬鐨勫伐鍏,鐢県uoji鑺变簡1澶╃紪鍐,缂栧啓鏃堕棿2021-02-24 + +# 鍔熻兘鍒楄〃 +1. HWBP hook妫娴 妫娴嬬嚎绋嬩腑鎵鏈夌枒浼艰hwb鎸傞挬 +2. 鍐呭瓨鍏嶆潃shellcode妫娴(metasploit,Cobaltstrike瀹屽叏妫娴) +3. 鍙枒杩涚▼妫娴(涓昏閽堝鏈夐冮伩鎬ц川鐨勮繘绋媅濡傝繃鏈熺鍚嶄笌澶氬悇鍙墽琛屽尯娈礭) +4. 鏃犳枃浠惰惤鍦版湪椹娴(妫娴嬫墍鏈夊凡鐭ュ唴瀛樺姞杞芥湪椹) +5. 绠鏄搑ootkit妫娴(妫娴嬭瘉涔﹁繃鏈/鎷︽埅璇诲彇/璇佷功鏃犳晥鐨勯┍鍔) + +# 鍏嶆潃鏈ㄩ┈妫娴嬪師鐞: +鎵鏈夋墍璋撶殑鍐呭瓨鍏嶆潃鍚庨棬澶ч儴鍒嗗熀浜"VirtualAlloc"鍑芥暟鐢宠鍐呭瓨 涔嬪悗閫氳繃鍚勭鑾悕鍏跺鐨剎or鐢氳嚦鏄痑es鍔犲瘑鍘绘贩娣唖hellcode杈惧埌"鍏嶆潃"鏁堟灉. +鏈伐鍏烽氳繃绾跨▼鍫嗘爤鍥炴函鏂规硶(StackWalkEx鍑芥暟)閬嶅巻绾跨▼,瀵绘壘绯荤粺涓湪VirtualAlloc鍖哄煙鎵ц浠g爜鐨勫尯鍩,浠庤屾彧鍑"鍏嶆潃鏈ㄩ┈" +褰撶劧涔熶細瀛樺湪璇姤,澶氬父瑙佷簬鍔犲3绋嬪簭涔熶細鐢宠VirtualAlloc鍒嗛厤鍐呭瓨. + +# 鏃犳枃浠惰惤鍦版湪椹娴嬪師鐞: +鎵鏈夋棤鏂囦欢钀藉湴鏈ㄩ┈閮芥槸涓涓爣鍑哖E鏂囦欢琚槧灏勫埌鍐呭瓨涓,涓昏鐗瑰緛濡備笅: +1. 鍐呭瓨鍖烘鏈塎.Z鏍囧織 +2. 绾跨▼鎸囧悜涓涓狽OIMAGE鍐呭瓨 +鏈伐鍏峰皢浼氶氳繃绗竴绉嶇壒寰佹娴嬪嚭鎵鏈"鏃犳枃浠惰惤鍦版湪椹" + +# 浣跨敤鏂瑰紡 +缂栬瘧 杩愯 寰楀埌淇℃伅鍒楄〃 + +# 杩借釜杩欎釜椤圭洰 +https://key08.com \ No newline at end of file diff --git a/enc_temp_folder/e27b8a5668995a66c9342927ce26b149/main.cpp b/enc_temp_folder/e27b8a5668995a66c9342927ce26b149/main.cpp deleted file mode 100644 index 900d1d1..0000000 --- a/enc_temp_folder/e27b8a5668995a66c9342927ce26b149/main.cpp +++ /dev/null @@ -1,380 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#pragma comment(lib,"dbghelp.lib") -#include "tlhelp32.h" -#include "CdigitalSig.h" -BOOL Is64BitPorcess(HANDLE hProcess) -{ - BOOL bIsWow64 = false; - IsWow64Process(hProcess, &bIsWow64); - return bIsWow64 == false; -} -BOOL EnableDebugPrivilege(BOOL bEnable) -{ - //Enabling the debug privilege allows the application to see - //information about service application - BOOL fOK = FALSE; //Assume function fails - HANDLE hToken; - //Try to open this process's acess token - if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) - { - //Attempt to modify the "Debug" privilege - TOKEN_PRIVILEGES tp; - tp.PrivilegeCount = 1; - LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid); - tp.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0; - AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL); - fOK = (GetLastError() == ERROR_SUCCESS); - CloseHandle(hToken); - } - return fOK; -} - -void WCharToChar(const WCHAR* tchar, char* _char) -{ - int iLength; - iLength = WideCharToMultiByte(CP_ACP, 0, tchar, -1, NULL, 0, NULL, NULL); - WideCharToMultiByte(CP_ACP, 0, tchar, -1, _char, iLength, NULL, NULL); -} -void CharToWchar(const char* _char, WCHAR* tchar) -{ - int iLength; - iLength = MultiByteToWideChar(CP_ACP, 0, _char, strlen(_char) + 1, NULL, 0); - MultiByteToWideChar(CP_ACP, 0, _char, strlen(_char) + 1, tchar, iLength); -} -BOOL DosPathToNtPath(WCHAR* pszDosPath, LPTSTR pszNtPath) -{ - TCHAR szDriveStr[500]; - TCHAR szDrive[3]; - TCHAR szDevName[100]; - INT cchDevName; - INT i; - - //检查参数 - if (!pszDosPath || !pszNtPath) - return FALSE; - - //获取本地磁盘字符串 - if (GetLogicalDriveStrings(sizeof(szDriveStr), szDriveStr)) - { - for (i = 0; szDriveStr[i]; i += 4) - { - if (!lstrcmpi(&(szDriveStr[i]), L"A:\\") || !lstrcmpi(&(szDriveStr[i]), L"B:\\")) - continue; - - szDrive[0] = szDriveStr[i]; - szDrive[1] = szDriveStr[i + 1]; - szDrive[2] = '\0'; - if (!QueryDosDevice(szDrive, szDevName, 100))//查询 Dos 设备名 - return FALSE; - - cchDevName = lstrlen(szDevName); - if (_wcsnicmp(pszDosPath, szDevName, cchDevName) == 0)//命中 - { - lstrcpy(pszNtPath, szDrive);//复制驱动器 - lstrcat(pszNtPath, pszDosPath + cchDevName);//复制路径 - - return TRUE; - } - } - } - - lstrcpy(pszNtPath, pszDosPath); - - return FALSE; -} -DWORD64 GetProcessMoudleHandle(DWORD pid) { - MODULEENTRY32 moduleEntry; - HANDLE handle = NULL; - handle = ::CreateToolhelp32Snapshot(0x00000008, pid); - ZeroMemory(&moduleEntry, sizeof(MODULEENTRY32)); - moduleEntry.dwSize = sizeof(MODULEENTRY32); - if (!Module32First(handle, &moduleEntry)) { - CloseHandle(handle); - return NULL; - } - do { - CloseHandle(handle); - return (DWORD64)moduleEntry.hModule; - } while (Module32Next(handle, &moduleEntry)); - return 0; -} -bool CheckThreadAddressIsExcute(DWORD64 pAddress,HANDLE pHandle, HANDLE pID, HANDLE Tid) { - - DWORD64 ReadNum = 0; - MEMORY_BASIC_INFORMATION mbi = { 0 }; - - if (VirtualQueryEx(pHandle, (LPCVOID)pAddress, &mbi, sizeof(mbi))) - { - if (mbi.AllocationBase) { - if (mbi.Type != MEM_IMAGE) { - if (mbi.AllocationProtect & PAGE_EXECUTE || - mbi.AllocationProtect & PAGE_EXECUTE_READ || - mbi.AllocationProtect & PAGE_EXECUTE_READWRITE || - mbi.AllocationProtect & PAGE_EXECUTE_WRITECOPY) - { - printf("\t => [线程堆栈回溯] 检测到未知内存区域[VirtualAlloc免杀?] 地址 %p PID %d TID %d \n", pAddress, pID, Tid); - char PEStack[0x2]; - if (ReadProcessMemory(pHandle, mbi.BaseAddress, PEStack, sizeof(PEStack), &ReadNum)) { - if (PEStack[0] == 'M' && PEStack[1] == 'Z') { - printf("\t => [!!!线程堆栈回溯!!!] 检测到内存加载程序 线程地址 %p PID %d TID %d 内存加载模块地址: %p\n", pAddress, pID, Tid, mbi.BaseAddress); - } - } - return true; - } - } - } - } - return false; -} -void ThreadStackWalk() { - HANDLE hThreadSnap = INVALID_HANDLE_VALUE; - THREADENTRY32 te32; - DWORD ExitCode = 0; - hThreadSnap = CreateToolhelp32Snapshot(0x00000004, GetCurrentProcessId()); - if (hThreadSnap) - { - te32.dwSize = sizeof(THREADENTRY32); - if (!Thread32First(hThreadSnap, &te32)) - { - CloseHandle(hThreadSnap); - return; - } - do - { - if (te32.th32OwnerProcessID != GetCurrentProcessId() && te32.th32ThreadID != GetCurrentThreadId()) - { - HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, 0, te32.th32ThreadID); - if (hThread && hThread != (HANDLE)-1) - { - HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, te32.th32OwnerProcessID); - if (hProcess) { - STACKFRAME_EX StackFarmeEx; - memset(&StackFarmeEx, 0, sizeof(STACKFRAME_EX)); - if (Is64BitPorcess(hProcess)) { - CONTEXT context = { 0 }; - context.ContextFlags = CONTEXT_ALL; - if (GetThreadContext(hThread, &context)) - { - if (context.Dr0 != 0 || context.Dr1 != 0 || context.Dr2 != 0 || context.Dr3 != 0) - { - //hwbp hook - printf("\t => [线程堆栈回溯] 检测到HWBP Hook PID %d TID %d \n", te32.th32OwnerProcessID, te32.th32ThreadID); - } - CheckThreadAddressIsExcute(context.Rip, hProcess, (HANDLE)te32.th32OwnerProcessID, (HANDLE)te32.th32ThreadID); - StackFarmeEx.AddrPC.Offset = context.Rip; - StackFarmeEx.AddrPC.Mode = AddrModeFlat; - StackFarmeEx.AddrStack.Offset = context.Rsp; - StackFarmeEx.AddrStack.Mode = AddrModeFlat; - StackFarmeEx.AddrFrame.Offset = context.Rsp; - StackFarmeEx.AddrFrame.Mode = AddrModeFlat; - DWORD machineType = IMAGE_FILE_MACHINE_AMD64; - while (true) - { - if (!StackWalkEx(machineType, hProcess, hThread, &StackFarmeEx, &context, NULL, NULL, NULL, NULL, NULL)) - break; - if (StackFarmeEx.AddrFrame.Offset == 0) - break; - CheckThreadAddressIsExcute(StackFarmeEx.AddrPC.Offset, hProcess, (HANDLE)te32.th32OwnerProcessID, (HANDLE)te32.th32ThreadID); - } - } - } else { - WOW64_CONTEXT context = { 0 }; - context.ContextFlags = CONTEXT_ALL; - if (Wow64GetThreadContext(hThread, &context)) - { - if (context.Dr0 != 0 || context.Dr1 != 0 || context.Dr2 != 0 || context.Dr3 != 0) - { - //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); - StackFarmeEx.AddrPC.Offset = context.Eip; - StackFarmeEx.AddrPC.Mode = AddrModeFlat; - StackFarmeEx.AddrStack.Offset = context.Esp; - StackFarmeEx.AddrStack.Mode = AddrModeFlat; - StackFarmeEx.AddrFrame.Offset = context.Ebp; - StackFarmeEx.AddrFrame.Mode = AddrModeFlat; - DWORD machineType = IMAGE_FILE_MACHINE_I386;//IMAGE_FILE_MACHINE_I386; IMAGE_FILE_MACHINE_AMD64; - while (true) - { - if (!StackWalkEx(machineType, hProcess, hThread, &StackFarmeEx, NULL, NULL, NULL, NULL, NULL, NULL)) - break; - if (StackFarmeEx.AddrFrame.Offset == 0) - break; - CheckThreadAddressIsExcute(StackFarmeEx.AddrPC.Offset, hProcess, (HANDLE)te32.th32OwnerProcessID, (HANDLE)te32.th32ThreadID); - } - } - } - CloseHandle(hProcess); - } - CloseHandle(hThread); - } - } - - } while (Thread32Next(hThreadSnap, &te32)); - CloseHandle(hThreadSnap); - } -} -void WalkProcessMoudle(DWORD pID,HANDLE pHandle,WCHAR* pMoudleName) { - - 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); - if (AllocBuff) { - if (!Module32First(handle, &moduleEntry)) { - CloseHandle(handle); - return; - } - do { - DWORD64 ReadNum = 0; - if (ReadProcessMemory(pHandle, moduleEntry.modBaseAddr, AllocBuff, 0x200, &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; - } - */ - PIMAGE_SECTION_HEADER SectionHeader = (PIMAGE_SECTION_HEADER)((PUCHAR)CopyNthead + sizeof(CopyNthead->Signature) + sizeof(CopyNthead->FileHeader) + CopyNthead->FileHeader.SizeOfOptionalHeader); - int FoundNum = 0; - for (WORD i = 0; i < CopyNthead->FileHeader.NumberOfSections; i++) - { - if (SectionHeader[i].Characteristics & IMAGE_SCN_MEM_EXECUTE) { - FoundNum++; - } - if (FoundNum > 1) { - printf("\t => [进程检测] 检测到额外的可执行区段(.rdata免杀 or 加壳程序) 进程名 %ws 模块名 %ws 区段名字 %s \n", pMoudleName, moduleEntry.szExePath, SectionHeader[i].Name); - break; - } - } - } - } - - } while (Module32Next(handle, &moduleEntry)); - VirtualFree(AllocBuff, 0, MEM_RELEASE); - } - CloseHandle(handle); -} -void ProcessStackWalk() { - PROCESSENTRY32 pe32; - pe32.dwSize = sizeof(pe32); - HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - if (hProcessSnap == INVALID_HANDLE_VALUE) - { - printf("CreateToolhelp32Snapshot error.\n"); - return; - } - BOOL bProcess = Process32First(hProcessSnap, &pe32); - while (bProcess) - { - //打印进程名和进程ID - HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pe32.th32ProcessID); - if (hProcess) { - WalkProcessMoudle(pe32.th32ProcessID, hProcess, pe32.szExeFile); - WCHAR szImagePath[MAX_PATH]; - WCHAR pszFullPath[MAX_PATH]; - if (GetProcessImageFileName(hProcess, szImagePath, MAX_PATH)) - { - if (DosPathToNtPath(szImagePath, pszFullPath)) - { - CdigitalSig DigitalSig(pszFullPath); - DWORD dDigitalState = DigitalSig.GetDigitalState(); - if (dDigitalState == DIGITAL_SIGSTATE_REVOKED || dDigitalState == DIGITAL_SIGSTATE_EXPIRE) { - printf("\t => [进程扫描] 检测到可疑签名进程 路径 %ws static %d \n", pszFullPath, dDigitalState); - } - } - } - CloseHandle(hProcess); - } - bProcess = Process32Next(hProcessSnap, &pe32); - } - CloseHandle(hProcessSnap); - return; - -} -void ScanSystemDrivers() { - DWORD cbNeeded = 0; // drivers[] 返回的字节数 - LPVOID drivers[MAX_PATH] = { 0 }; // 驱动程序地址列表数组 - int cDrivers = 0; // 驱动个数 - Wow64EnableWow64FsRedirection(0); - if (EnumDeviceDrivers(drivers, sizeof(drivers), &cbNeeded) && cbNeeded < sizeof(drivers)) // EnumDeviceDrivers 检索每个驱动文件的加载地址 - { - char szDriver[MAX_PATH] = { 0 }; // 驱动文件名 - char szPath[MAX_PATH] = { 0 }; // 存放驱动文件全路径 - char szNtPath[MAX_PATH] = { 0 }; - char szSystemPath[MAX_PATH] = { 0 }; // 存放 system32 文件夹路径 - cDrivers = cbNeeded / sizeof(LPVOID); // 驱动个数 - - for (int i = 0; i < cDrivers; i++) - { - if (drivers[i]) { - if (GetDeviceDriverBaseNameA(drivers[i], szDriver, sizeof(szDriver) / sizeof(LPVOID))) - { - if (GetDeviceDriverFileNameA(drivers[i], szPath, sizeof(szPath))) { - bool isSystemDriver = true; - //只判断非系统驱动 - if (szPath[1] == '?') - { - isSystemDriver = false; - int len = strlen(szPath); - szPath[len + 1] = '\0'; - for (int j = 0; j < len; j++) - { - szPath[j] = szPath[j + 4]; - } - WCHAR UnicodeFilePath[MAX_PATH << 1] = { 0 }; - CharToWchar(szPath, UnicodeFilePath); - CdigitalSig DigitalSig(UnicodeFilePath); - DWORD dDigitalState = DigitalSig.GetDigitalState(); - if (dDigitalState != DIGITAL_SIGSTATE_VALID) { - printf("\t => [驱动扫描] 检测到未知驱动 路径 %ws \n", UnicodeFilePath); - } - } - } - } - } - } - } - Wow64EnableWow64FsRedirection(1); -} -int main() -{ - printf("DuckMemoryScan By huoji 2021-02-23 \n"); - if (EnableDebugPrivilege(true) == false) { - printf("权限提升失败,请以管理员身份运行 \n"); - system("pause"); - return 0; - } - printf("线程堆栈回溯检测 ... \n"); - ThreadStackWalk(); - printf("驱动检测... \n"); - ScanSystemDrivers(); - printf("进程检测... \n"); - ProcessStackWalk(); - printf("检测完毕 ... \n"); - system("pause"); - return 0; -} \ No newline at end of file