/* Currently unimplemented: - Changing the screen resoltuion to something very small (lol) - The UI that shows "NOW LOADING" */ #include #include #include #include #include #define SYSTEM_USER "SystemUser" #define MXSTARTUP "C:\\System\\Execute\\mxstartup.exe" #define RETRIES 100 #define STR_INDIR(x) #x #define STR(x) STR_INDIR(x) /* No debugger: 153815264b5839090b0d1c1a423c02241633130673071a1e38443912410b47380f213c1d + 2e0247311e162b666c6640393737724157001f56045b4b4f24333457335a26381f4c3349 = 'C:\Windows\System32\wbem\wmitemp.mof' 270a2a053b29042b261d1b22070d140c (wmitemp.mof) + 152c05381a141f494a48060223260d29 (key) = '<6/=U=#tpe!$*3!5' Has debugger: d0b1c034a32243340505a343659517c121f0319583d205c593a690719604846000e062a6 + 63f10541f0c201c0703022f332a13094b542f130c25491a1c280a65440831296e2563590 % 255 (not 256!) = 34a3c57594e444f47535c53797374756d63323c546279667562737c5d68796f6e2379737 flip nibbles of each byte = 'C:\\WINDOWS\\system32\\drivers\\mxio.sys' 9160e5c22392918371e43573f2b095b1 (mxio.sys) + 43368004f2a34211f4f12120b1b57151 % 255 = d49666c61636d39466d65693a4660703 flip nibbles of each byte = 'Miflac=Ifme9Jfp0' */ #define PERFECT_RECREATION #ifdef PERFECT_RECREATION // C:\Windows\System32\wbem\wmitemp.mof (contains 270a2a053b29042b261d1b22070d140c) // NOTE: On 64 bit windows this is going to be redirected to syswow64 #define PATH_NODEBUG_1 "153815264b5839090b0d1c1a423c02241633130673071a1e38443912410b47380f213c1d" #define PATH_NODEBUG_2 "2e0247311e162b666c6640393737724157001f56045b4b4f24333457335a26381f4c3349" // C:\WINDOWS\system32\drivers\mxio.sys (contains 9160e5c22392918371e43573f2b095b1) // NOTE: On 64 bit windows this is going to be redirected to syswow64 #define PATH_DEBUG_1 "d0b1c034a32243340505a343659517c121f0319583d205c593a690719604846000e062a6" #define PATH_DEBUG_2 "63f10541f0c201c0703022f332a13094b542f130c25491a1c280a65440831296e2563590" #define NODEBUG_PSK "152c05381a141f494a48060223260d29" #define DEBUG_PSK "43368004f2a34211f4f12120b1b57151" #else #define PASS_NODEBUG "Miflac=Ifme9Jfp0" #define PASS_DEBUG "<6/=U=#tpe!$*3!5" #endif void reboot() { puts("Starting the next hop failed."); puts("We're not going to reboot, but mxprestartup normally would at this point."); exit(1); } char* load_password(const char* path1, const char* path2, const char* psk, bool flip) { char path[37]; path[36] = '\0'; char temp1[3] = { 0 }; char temp2[3] = { 0 }; char* pEnd; for (int i = 0; i < 72; i += 2) { temp1[0] = path1[i]; temp1[1] = path1[i + 1]; temp2[0] = path2[i]; temp2[1] = path2[i + 1]; uint8_t value = (strtol(temp1, &pEnd, 16) + strtol(temp2, &pEnd, 16)) % 0xff; if (flip) path[i >> 1] = ((value & 0xf0) >> 4) | ((value & 0x0f) << 4); else path[i >> 1] = value; } printf("Attempting to read key from %s\n", path); FILE* key_file; fopen_s(&key_file, path, "r"); if (!key_file) { printf("! Failed to read file: %d\n", GetLastError()); return NULL; } char key2[32]; fread(key2, 1, 32, key_file); fclose(key_file); char* password = malloc(17); password[16] = '\0'; for (int i = 0; i < 32; i += 2) { temp1[0] = psk[i]; temp1[1] = psk[i + 1]; temp2[0] = key2[i]; temp2[1] = key2[i + 1]; uint8_t value = (strtol(temp1, &pEnd, 16) + strtol(temp2, &pEnd, 16)) % 0xff; if (flip) password[i >> 1] = ((value & 0xf0) >> 4) | ((value & 0x0f) << 4); else password[i >> 1] = value; } return password; } char* get_password() { if (IsDebuggerPresent()) { #ifdef PERFECT_RECREATION return load_password(PATH_DEBUG_1, PATH_DEBUG_2, DEBUG_PSK, true); #else return PASS_DEBUG; #endif } #ifdef PERFECT_RECREATION return load_password(PATH_NODEBUG_1, PATH_NODEBUG_2, NODEBUG_PSK, false); #else return PASS_NODEBUG; #endif } int main(int argc, char** argv) { if (argc > 4) { puts("Usage:"); printf(" %s\n", argv[0]); printf(" %s \n", argv[0]); printf(" %s \n", argv[0]); printf(" %s \n", argv[0]); exit(0); } PVOID old = NULL; Wow64DisableWow64FsRedirection(&old); BOOL spawned = FALSE; STARTUPINFOW startup_info = { .cb = 68, .wShowWindow = SW_SHOW, .dwFlags = STARTF_USESHOWWINDOW, }; PROCESS_INFORMATION process = { 0 }; for (int i = 0; i < RETRIES; i++) { char* password = argc == 3 ? argv[2] : argc == 4 ? argv[3] : get_password(); if (password) { char* username = argc == 3 ? argv[1] : argc == 4 ? argv[2] : SYSTEM_USER; char* binary = (argc == 2 || argc == 4) ? argv[1] : MXSTARTUP; printf("Username: %s\n", username); printf("Password: %s\n", password); printf("Next hop: %s\n", binary); size_t _; wchar_t* wPassword = malloc((strlen(password) + 1) * (sizeof(wchar_t))); wchar_t* wUser = malloc((strlen(username) + 1) * (sizeof(wchar_t))); wchar_t* wBinary = malloc((strlen(binary) + 1) * (sizeof(wchar_t))); mbstowcs_s(&_, wPassword, strlen(password) + 1, password, _TRUNCATE); mbstowcs_s(&_, wUser, strlen(username) + 1, username, _TRUNCATE); mbstowcs_s(&_, wBinary, strlen(binary) + 1, binary, _TRUNCATE); spawned = CreateProcessWithLogonW(wUser, NULL, wPassword, 0, NULL, wBinary, HIGH_PRIORITY_CLASS, NULL, NULL, &startup_info, &process); free(wPassword); if (spawned) break; else puts("Failed to start next hop"); if (process.hProcess != NULL) { CloseHandle(process.hProcess); process.hProcess = NULL; } } else { puts("Failed to get password"); } Sleep(1000); puts("------------------------"); printf("Retry %d\n", i + 1); puts("------------------------"); } if (process.hProcess != NULL) { CloseHandle(process.hProcess); process.hProcess = NULL; } if (!spawned) { reboot(); } return 0; }