217 lines
6.5 KiB
C
217 lines
6.5 KiB
C
/*
|
|
Currently unimplemented:
|
|
- Changing the screen resoltuion to something very small (lol)
|
|
- The UI that shows "NOW LOADING"
|
|
*/
|
|
#include <Windows.h>
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#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 <mxstartup.exe>\n", argv[0]);
|
|
printf(" %s <username> <password>\n", argv[0]);
|
|
printf(" %s <mxstartup.exe> <username> <password>\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;
|
|
}
|