2025-01-04 18:30:18 ctf
参考文章: 1.12 进程注入ShellCode套接字 | LyShark®
注入shellcode调用messagebox正常,调用NtAllocateVirtualMemory目标程序崩溃,发现调大SizeOfMyShell一千倍之后程序可以正常运行,查看注入的代码发现跳转到了shellcode以外的区域
跳转到这个地址发现没看出什么有用的线索
我们查看负责注入程序的函数指令,发现call了一个TestShellCode.__security_check_cookie这个东西
上网搜索得知TestShellCode.__security_check_cookie是vistual studio为了防止栈溢出的一个编译选项
我们在项目属性 --> c/c++ --> 代码生成 --> 安全检查 中关闭gs安全检查
、
恢复SizeOfMyShell ,程序正常注入运行
附上完整代码:
test.cpp:
#include#include using namespace std; const int js_start=1; int js(int a,int b) { return a+b; } void js_end_func() { return ; } const int js_end=1; int main() { printf("js_start address: %p js_end address: %p\n",&js_start,&js_end); printf("js_address: %p\n js_end_func_address%p\n",&js,&js_end_func); printf("sizeof js : %d\n",(uintptr_t)&js_end_func-(uintptr_t)&js); printf("%p\n",&js_end-&js_start); while(true) { printf("1\n"); Sleep(1000); } return 0; }
TestShellCode.cpp
#include#include #include // Kernel32 调用约定定义 typedef HMODULE(WINAPI* LOADLIBRARY)(LPCTSTR lpFileName); typedef FARPROC(WINAPI* GETPROCADDRESS) (HMODULE hModule, LPCSTR lpProcName); // User32 中针对MessageBox的调用约定定义 typedef int(WINAPI* MESSAGEBOX)(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType); // NtDll 调用约定定义 typedef NTSTATUS(WINAPI* NTALLOCATEVIRTUALMEMORY)(IN HANDLE ProcessHandle, IN OUT PVOID* BaseAddress, IN ULONG ZeroBits, IN OUT PSIZE_T RegionSize, IN ULONG AllocationType, IN ULONG Protect); //typedef NTSTATUS(WINAPI* NTALLOCATEVIRTUALMEMORY)( // HANDLE ProcessHandle, // PVOID* BaseAddress, // ULONG_PTR ZeroBits, // PSIZE_T RegionSize, // ULONG AllocationType, // ULONG Protect //); typedef struct _ShellBase { // 针对Kernel32的操作 HANDLE Kernel32Base; char KernelString[20]; // kernel32.dll LOADLIBRARY Kernel_LoadLibrary; GETPROCADDRESS Kernel_GetProcAddress; NTALLOCATEVIRTUALMEMORY Func_NtAllocateVirtualMemory; // 针对User32的操作 HANDLE User32Base; char UserString[20]; // 存储 user32.dll 字符串 char User_MsgBox[20]; // 存储 MessageBoxA 字符串 HANDLE NtDllBase; char NtDllString[20]; // 存储 ntdll.dll 字符串 char NtAllocateVirtualMemoryString[40]; // 输出一段话 char Text[32]; }ShellParametros; void __stdcall MyShell(ShellParametros*); // 定义远程线程函数 void __stdcall MyShell(ShellParametros* ptr) { /*ptr->Kernel32Base = (HANDLE)(*ptr->Kernel_LoadLibrary)((const TCHAR*)ptr->KernelString); ptr->User32Base = (HANDLE)(*ptr->Kernel_LoadLibrary)((const TCHAR*)ptr->UserString); ptr->NtDllBase = (HANDLE)(*ptr->Kernel_LoadLibrary)((const TCHAR*)ptr->NtDllString);*/ //printf("动态获取到Kernel32基地址 = %x \n", ptr->Kernel32Base); //printf("动态获取到User32基地址 = %x \n", ptr->User32Base); // printf("动态获取到NtDll基地址 = %x \n", ptr->NtDllBase); //// 调用NtDll中的NtAllocateVirtualMemory函数 //NTALLOCATEVIRTUALMEMORY NtAllocateVirtualMemory = (NTALLOCATEVIRTUALMEMORY)GetProcAddress((HINSTANCE)ptr->NtDllBase, ptr->NtAllocateVirtualMemoryString); PVOID BaseAddress = NULL; SIZE_T RegionSize = 4096; //while (true); NTALLOCATEVIRTUALMEMORY NtAllocateVirtualMemory = ptr->Func_NtAllocateVirtualMemory; void* p = NtAllocateVirtualMemory; NTSTATUS status = NtAllocateVirtualMemory((HANDLE)-1, &BaseAddress, 0, &RegionSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); //printf("NtAllocateVirtualMemory Address %p \r\n", NtAllocateVirtualMemory); //printf("NtAllocateVirtualMemory 调用结果 = %d \n", status); // MESSAGEBOX msgbox = (MESSAGEBOX)(*ptr->KernelGetProcAddress)((HINSTANCE)ptr->UserHandle, "MessageBoxA"); //MESSAGEBOX msgbox = (MESSAGEBOX)(*ptr->Kernel_GetProcAddress)((HINSTANCE)ptr->User32Base, ptr->User_MsgBox); //MESSAGEBOX msgbox = ptr->Func_MessageBox; //printf("MessageBox 基地址 = %x \n", msgbox); //msgbox(0, ptr->Text, 0, 0); } void __stdcall MyShell_end(ShellParametros* ptr) { ; } // 通过进程名获取进程ID DWORD GetProcessId(const char* processName) { DWORD processId = 0; HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (snapshot != INVALID_HANDLE_VALUE) { PROCESSENTRY32 processEntry; processEntry.dwSize = sizeof(processEntry); if (Process32First(snapshot, &processEntry)) { do { // 将宽字符转换为多字节字符 char exeName[MAX_PATH]; WideCharToMultiByte(CP_ACP, 0, processEntry.szExeFile, -1, exeName, MAX_PATH, NULL, NULL); if (_stricmp(exeName, processName) == 0) { processId = processEntry.th32ProcessID; break; } //printf("Process Name: %s, Process ID: %d\n", exeName, processEntry.th32ProcessID); } while (Process32Next(snapshot, &processEntry)); } CloseHandle(snapshot); } return processId; } BOOL AdjustPrivilege() { HANDLE hToken = NULL; TOKEN_PRIVILEGES priv = { 0 }; //提权操作 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { return FALSE; } priv.PrivilegeCount = 1; priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &priv.Privileges[0].Luid)) AdjustTokenPrivileges(hToken, FALSE, &priv, 0, NULL, NULL); CloseHandle(hToken); return TRUE; } int main() { AdjustPrivilege(); ShellParametros Param, * remote = NULL; HANDLE hProcess; void* p = NULL; // 进程PID int ProcessID = GetProcessId("test.exe"); printf("notepad.exe PID = %d\n", ProcessID); // 得到加载基地址的工具函数 Param.Kernel32Base = LoadLibraryA("kernel32.dll"); printf("Kernel32Base: %p\r\n", Param.Kernel32Base); Param.Kernel_LoadLibrary = (LOADLIBRARY)GetProcAddress((HINSTANCE)Param.Kernel32Base, "LoadLibraryA"); printf("Kernel_LoadLibrary: %p\r\n", Param.Kernel_LoadLibrary); Param.Kernel_GetProcAddress = (GETPROCADDRESS)GetProcAddress((HINSTANCE)Param.Kernel32Base, "GetProcAddress"); // printf("获取到Kernel32.dll = %x", Param.KernelHandle); Param.User32Base = LoadLibraryA("User32.dll"); // printf("获取到User32.dll = %x", Param.UserHandle); Param.NtDllBase = LoadLibraryA("ntdll.dll"); // printf("获取到NtDll.dll = %x", Param.NtDllHandle); // 得到NtDll中的NtAllocateVirtualMemory函数 Param.Func_NtAllocateVirtualMemory = (NTALLOCATEVIRTUALMEMORY)GetProcAddress((HINSTANCE)Param.NtDllBase, "NtAllocateVirtualMemory"); SIZE_T SizeOfMyShell = (uintptr_t)MyShell_end - (uintptr_t)MyShell; SizeOfMyShell *= 1000; printf("address of MyShell: %p\n", MyShell); printf("address of MyShell_end: %p\n", MyShell_end); printf("sizeofmyshell: %d\n", SizeOfMyShell); printf("myshell address: %p\n", &MyShell); // 分别获取Kernel32与User32的对应字符串 strcpy_s(Param.KernelString, "kernel32.dll"); strcpy_s(Param.UserString, "user32.dll"); strcpy_s(Param.NtDllString, "ntdll.dll"); strcpy_s(Param.User_MsgBox, "MessageBoxA"); strcpy_s(Param.Text, "hello lyshark"); strcpy_s(Param.NtAllocateVirtualMemoryString, "NtAllocateVirtualMemory"); NTALLOCATEVIRTUALMEMORY NtAllocateVirtualMemory = (NTALLOCATEVIRTUALMEMORY)GetProcAddress((HINSTANCE)Param.NtDllBase, Param.NtAllocateVirtualMemoryString); PVOID BaseAddress = NULL; SIZE_T RegionSize = 4096; NTSTATUS status = NtAllocateVirtualMemory(GetCurrentProcess(), &BaseAddress, 0, &RegionSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); printf("NtAllocateVirtualMemory Address %p \r\n", NtAllocateVirtualMemory); printf("NtAllocateVirtualMemory 调用结果 = %d \n", status); printf("BaseAddress 地址 = %p \n", BaseAddress); // 根据PID注入代码到指定进程中 hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID); p = VirtualAllocEx(hProcess, 0, SizeOfMyShell, MEM_COMMIT, PAGE_EXECUTE_READWRITE); remote = (ShellParametros*)VirtualAllocEx(hProcess, 0, sizeof(ShellParametros), MEM_COMMIT, PAGE_READWRITE); printf("shellcode address: %p\r\n", p); WriteProcessMemory(hProcess, p, &MyShell, SizeOfMyShell, 0); WriteProcessMemory(hProcess, remote, &Param, sizeof(ShellParametros), 0); CreateRemoteThread(hProcess, 0, 0, (DWORD(__stdcall*)(void*)) p, remote, 0, 0); //MyShell(&Param); // MyShell(&Param); system("pause"); return 0; }