micetools/src/micetools/miceboot/mxprestartup.c

217 lines
6.5 KiB
C
Raw Permalink Normal View History

2022-10-30 17:33:02 +00:00
/*
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;
}