├── README.md ├── compile.bat └── rwxfinder.c /README.md: -------------------------------------------------------------------------------- 1 | # RWXfinder 2 | Windows-specific tool written in C which uses Windows API functions to traverse through directories and look for DLL files with an RWX section in memory. 3 | 4 | I came up with this idea after reading this blog: https://www.securityjoes.com/post/process-mockingjay-echoing-rwx-in-userland-to-achieve-code-execution 5 | 6 | ### Tool Output 7 | ![Capture](https://github.com/pwnsauc3/RWXfinder/assets/42569696/5c0c10f4-c38b-46fa-86fd-c1bea24ab87c) 8 | 9 | -------------------------------------------------------------------------------- /compile.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | cl.exe /nologo /Ox /MT /W0 /GS- /DNDEBUG /Tcrwxfinder.c /link /OUT:rwxfinder.exe /SUBSYSTEM:CONSOLE /MACHINE:x64 -------------------------------------------------------------------------------- /rwxfinder.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | void SetConsoleColor(int colorCode) 7 | { 8 | HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); 9 | SetConsoleTextAttribute(hConsole, colorCode); 10 | } 11 | 12 | void CheckDLLForRWX(const char* dllPath) 13 | { 14 | HANDLE fileHandle = CreateFile(dllPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 15 | if (fileHandle == INVALID_HANDLE_VALUE) 16 | { 17 | fprintf(stderr, "Failed to open DLL: %s\n", dllPath); 18 | return; 19 | } 20 | 21 | DWORD fileSize = GetFileSize(fileHandle, NULL); 22 | if (fileSize == INVALID_FILE_SIZE) 23 | { 24 | fprintf(stderr, "Failed to get file size: %s\n", dllPath); 25 | CloseHandle(fileHandle); 26 | return; 27 | } 28 | 29 | HANDLE fileMapping = CreateFileMapping(fileHandle, NULL, PAGE_READONLY, 0, 0, NULL); 30 | if (fileMapping == NULL) 31 | { 32 | fprintf(stderr, "Failed to create file mapping: %s\n", dllPath); 33 | CloseHandle(fileHandle); 34 | return; 35 | } 36 | 37 | LPVOID fileView = MapViewOfFile(fileMapping, FILE_MAP_READ, 0, 0, fileSize); 38 | if (fileView == NULL) 39 | { 40 | fprintf(stderr, "Failed to map view of file: %s\n", dllPath); 41 | CloseHandle(fileMapping); 42 | CloseHandle(fileHandle); 43 | return; 44 | } 45 | 46 | PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)fileView; 47 | PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)((BYTE*)fileView + dosHeader->e_lfanew); 48 | PIMAGE_OPTIONAL_HEADER optionalHeader = &(ntHeaders->OptionalHeader); 49 | PIMAGE_SECTION_HEADER sectionHeader = IMAGE_FIRST_SECTION(ntHeaders); 50 | 51 | int hasDefaultRWXSection = 0; 52 | for (int i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++, sectionHeader++) 53 | { 54 | if (sectionHeader->Characteristics & IMAGE_SCN_MEM_EXECUTE && 55 | sectionHeader->Characteristics & IMAGE_SCN_MEM_READ && 56 | sectionHeader->Characteristics & IMAGE_SCN_MEM_WRITE) 57 | { 58 | hasDefaultRWXSection = 1; 59 | break; 60 | } 61 | } 62 | 63 | if (hasDefaultRWXSection) 64 | { 65 | SetConsoleColor(10); // Set text color to green 66 | printf("[RWX] %s\n", dllPath); 67 | SetConsoleColor(7); // Set text color to default 68 | 69 | printf("Section Name: %.8s\n", sectionHeader->Name); 70 | printf("Virtual Size: 0x%X\n", sectionHeader->Misc.VirtualSize); 71 | printf("Virtual Address: 0x%X\n", sectionHeader->VirtualAddress); 72 | printf("Size of Raw Data: 0x%X\n", sectionHeader->SizeOfRawData); 73 | printf("Characteristics: 0x%X\n", sectionHeader->Characteristics); 74 | printf("---------------------------\n"); 75 | 76 | // Perform additional testing or analysis on the DLL here 77 | // ... 78 | 79 | } 80 | else 81 | { 82 | printf("%s\n", dllPath); 83 | } 84 | 85 | UnmapViewOfFile(fileView); 86 | CloseHandle(fileMapping); 87 | CloseHandle(fileHandle); 88 | } 89 | 90 | void TraverseDirectory(const char* directory) 91 | { 92 | char searchPath[MAX_PATH]; 93 | WIN32_FIND_DATA findData; 94 | HANDLE findHandle; 95 | 96 | sprintf(searchPath, "%s\\*", directory); 97 | findHandle = FindFirstFile(searchPath, &findData); 98 | 99 | if (findHandle != INVALID_HANDLE_VALUE) 100 | { 101 | do 102 | { 103 | if (strcmp(findData.cFileName, ".") != 0 && strcmp(findData.cFileName, "..") != 0) 104 | { 105 | char filePath[MAX_PATH]; 106 | sprintf(filePath, "%s\\%s", directory, findData.cFileName); 107 | 108 | if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) 109 | { 110 | // Recursive call for subdirectories 111 | TraverseDirectory(filePath); 112 | } 113 | else if (findData.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) 114 | { 115 | // Check if the file is a DLL 116 | const char* extension = strrchr(filePath, '.'); 117 | if (extension != NULL && _stricmp(extension, ".dll") == 0) 118 | { 119 | CheckDLLForRWX(filePath); 120 | } 121 | } 122 | } 123 | } while (FindNextFile(findHandle, &findData)); 124 | 125 | FindClose(findHandle); 126 | } 127 | } 128 | 129 | int main() 130 | { 131 | // Setting PATH to check 132 | SetDllDirectory("C:\\Program Files (x86)"); 133 | 134 | TraverseDirectory("C:\\"); 135 | 136 | return 0; 137 | } 138 | --------------------------------------------------------------------------------