UACME/Source/Yuubari/main.c

486 lines
13 KiB
C

/*******************************************************************************
*
* (C) COPYRIGHT AUTHORS, 2014 - 2019
*
* TITLE: MAIN.C
*
* VERSION: 1.40
*
* DATE: 19 Mar 2019
*
* Program entry point.
*
* 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"
#include "Shlobj.h"
BOOL g_VerboseOutput = FALSE;
ULONG g_NtBuildNumber = 0;
HANDLE g_LogFile = INVALID_HANDLE_VALUE;
/*
* AppInfoDataOutputCallback
*
* Purpose:
*
* Output callback for AppInfo scan.
*
*/
VOID AppInfoDataOutputCallback(
UAC_AI_DATA *Data
)
{
LPWSTR lpLog = NULL, Text = NULL;
SIZE_T sz = 0;
if (Data == NULL)
return;
sz = (_strlen(Data->Name) * sizeof(WCHAR)) + MAX_PATH;
lpLog = (LPWSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sz);
if (lpLog) {
switch (Data->Type) {
case AiSnapinFile:
Text = TEXT("SnapinFile: ");
break;
case AiManagementConsole:
Text = TEXT("ManagementConsole: ");
break;
case AiAutoApproveEXE:
Text = TEXT("AutoApproveEXE: ");
break;
case AiIncludedPFDirs:
Text = TEXT("IncludedPFDir: ");
break;
case AiIncludedSystemDirs:
Text = TEXT("IncludedSystemDir: ");
break;
case AiExemptedAutoApproveExes:
Text = TEXT("ExemptedAutoApproveExe: ");
break;
case AilpIncludedWindowsDirs:
Text = TEXT("IncludedWindowsDirs: ");
break;
case AiExcludedWindowsDirs:
Text = TEXT("ExcludedWindowsDir: ");
break;
default:
Text = TEXT("Unknown ");
break;
}
_strcpy(lpLog, Text);
_strcat(lpLog, Data->Name);
LoggerWrite(g_LogFile, lpLog, TRUE);
cuiPrintText(lpLog, TRUE);
HeapFree(GetProcessHeap(), 0, lpLog);
}
}
/*
* BasicDataOutputCallback
*
* Purpose:
*
* Output callback for basic UAC settings scan.
*
*/
VOID WINAPI BasicDataOutputCallback(
UAC_BASIC_DATA *Data
)
{
LPWSTR lpLog = NULL;
SIZE_T sz = 0;
if (Data == NULL)
return;
sz = (_strlen(Data->Name) * sizeof(WCHAR)) + MAX_PATH;
lpLog = (LPWSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sz);
if (lpLog) {
_strcpy(lpLog, Data->Name);
_strcat(lpLog, TEXT("="));
if (Data->IsValueBool) {
if (Data->Value == 0)
_strcat(lpLog, TEXT("Disabled"));
else
_strcat(lpLog, TEXT("Enabled"));
}
else {
ultostr(Data->Value, _strend(lpLog));
}
LoggerWrite(g_LogFile, lpLog, TRUE);
cuiPrintText(lpLog, TRUE);
HeapFree(GetProcessHeap(), 0, lpLog);
}
}
/*
* RegistryOutputCallback
*
* Purpose:
*
* Output callback for registry autoelevated objects scan.
*
*/
VOID WINAPI RegistryOutputCallback(
UAC_REGISTRY_DATA *Data
)
{
UAC_INTERFACE_DATA *InterfaceData;
LPOLESTR OutputString = NULL;
if (Data == NULL)
return;
if (Data->DataType == UacCOMDataCommonType) {
//
// Output current registry key to show that we are alive.
//
LoggerWrite(g_LogFile, Data->Name, TRUE);
cuiPrintText(Data->Key, TRUE);
LoggerWrite(g_LogFile, Data->AppId, TRUE);
LoggerWrite(g_LogFile, Data->LocalizedString, TRUE);
LoggerWrite(g_LogFile, Data->Key, TRUE);
LoggerWrite(g_LogFile, TEXT("\r\n"), TRUE);
}
if (Data->DataType == UacCOMDataInterfaceType) {
InterfaceData = (UAC_INTERFACE_DATA*)(PVOID)Data;
LoggerWrite(g_LogFile, InterfaceData->Name, TRUE);
cuiPrintText(InterfaceData->Name, TRUE);
if (StringFromCLSID(&InterfaceData->Clsid, &OutputString) == S_OK) {
LoggerWrite(g_LogFile, TEXT("CLSID"), TRUE);
LoggerWrite(g_LogFile, OutputString, TRUE);
cuiPrintText(OutputString, TRUE);
CoTaskMemFree(OutputString);
}
if (StringFromIID(&InterfaceData->IID, &OutputString) == S_OK) {
LoggerWrite(g_LogFile, TEXT("IID"), TRUE);
LoggerWrite(g_LogFile, OutputString, TRUE);
cuiPrintText(OutputString, TRUE);
CoTaskMemFree(OutputString);
}
LoggerWrite(g_LogFile, TEXT("\r\n"), TRUE);
cuiPrintText(TEXT("\r\n"), TRUE);
}
}
/*
* FusionOutputCallback
*
* Purpose:
*
* Output callback for autoelevated applications scan.
*
*/
VOID WINAPI FusionOutputCallback(
UAC_FUSION_DATA *Data
)
{
LPWSTR lpText;
LPWSTR lpLog = NULL;
SIZE_T sz = 0;
UAC_FUSION_DATA_DLL *Dll;
if (Data == NULL)
return;
if (Data->DataType == UacFusionDataCommonType) {
//
// Display only binaries with autoelevation flags if not in verbose output
//
if ((Data->AutoElevateState == AutoElevateUnspecified) && (g_VerboseOutput == FALSE))
return;
//
// Output current filename
//
LoggerWrite(g_LogFile, TEXT("\r\n"), FALSE);
LoggerWrite(g_LogFile, Data->Name, TRUE);
cuiPrintText(Data->Name, TRUE);
//
// If application has autoElevate attribute, report full info
//
if (Data->IsFusion) {
switch (Data->RunLevel.RunLevel) {
case ACTCTX_RUN_LEVEL_AS_INVOKER:
lpText = TEXT("asInvoker");
break;
case ACTCTX_RUN_LEVEL_HIGHEST_AVAILABLE:
lpText = TEXT("highestAvailable");
break;
case ACTCTX_RUN_LEVEL_REQUIRE_ADMIN:
lpText = TEXT("requireAdministrator");
break;
case ACTCTX_RUN_LEVEL_UNSPECIFIED:
default:
lpText = TEXT("unspecified");
break;
}
//RequestedExecutionLevel
LoggerWrite(g_LogFile, lpText, TRUE);
if (Data->RunLevel.UiAccess > 0) {
lpText = TEXT("uiAccess=TRUE");
}
else {
lpText = TEXT("uiAccess=FALSE");
}
//UIAccess state
LoggerWrite(g_LogFile, lpText, TRUE);
//autoElevate state
if (Data->AutoElevateState != AutoElevateUnspecified) {
switch (Data->AutoElevateState) {
case AutoElevateEnabled:
lpText = TEXT("autoElevate=TRUE");
break;
case AutoElevateDisabled:
lpText = TEXT("autoElevate=FALSE");
break;
default:
break;
}
LoggerWrite(g_LogFile, lpText, TRUE);
}
}
else {
// no embedded manifest
lpText = TEXT("Binary without embedded manifest");
LoggerWrite(g_LogFile, lpText, TRUE);
if (Data->IsOSBinary) {
if (Data->IsSignatureValidOrTrusted == FALSE) {
lpText = TEXT("Warning: signature not valid or trusted");
LoggerWrite(g_LogFile, lpText, TRUE);
}
else {
lpText = TEXT("OS binary with valid digital signature");
LoggerWrite(g_LogFile, lpText, TRUE);
}
}
}
if (Data->IsDotNet) {
lpText = TEXT("DotNet");
LoggerWrite(g_LogFile, lpText, TRUE);
}
}
if (Data->DataType == UacFusionDataRedirectedDllType) {
Dll = (UAC_FUSION_DATA_DLL*)Data;
sz = _strlen(Dll->DllName) + _strlen(Dll->FileName) + MAX_PATH;
lpLog = (LPWSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sz * sizeof(WCHAR));
if (lpLog) {
_strcpy(lpLog, TEXT("DllRedirection: "));
_strcat(lpLog, Dll->FileName);
_strcat(lpLog, TEXT(" -> "));
_strcat(lpLog, Dll->DllName);
LoggerWrite(g_LogFile, lpLog, TRUE);
HeapFree(GetProcessHeap(), 0, lpLog);
}
}
}
/*
* ListBasicSettings
*
* Purpose:
*
* Scan basic UAC settings.
*
*/
VOID ListBasicSettings(
VOID
)
{
cuiPrintText(T_BASIC_HEAD, TRUE);
LoggerWrite(g_LogFile, T_BASIC_HEAD, TRUE);
ScanBasicUacData((OUTPUTCALLBACK)BasicDataOutputCallback);
LoggerWrite(g_LogFile, T_SPLIT, TRUE);
}
/*
* ListCOMFromRegistry
*
* Purpose:
*
* Scan HKEY_CLASSES_ROOT for autoelevated COM objects.
*
*/
VOID ListCOMFromRegistry(
VOID
)
{
cuiPrintText(T_COM_HEAD, TRUE);
LoggerWrite(g_LogFile, T_COM_HEAD, TRUE);
CoListInformation((OUTPUTCALLBACK)RegistryOutputCallback);
LoggerWrite(g_LogFile, T_SPLIT, TRUE);
//
// AutoApproval COM list added since RS1.
//
if (g_NtBuildNumber >= 14393) {
cuiPrintText(T_COM_APPROVE_HEAD, TRUE);
LoggerWrite(g_LogFile, T_COM_APPROVE_HEAD, TRUE);
CoScanAutoApprovalList((OUTPUTCALLBACK)RegistryOutputCallback);
LoggerWrite(g_LogFile, T_SPLIT, TRUE);
}
}
/*
* ListFusion
*
* Purpose:
*
* Scan Windows directory for autoelevated apps.
*
*/
VOID ListFusion(
VOID
)
{
HMODULE hModule;
WCHAR szPath[MAX_PATH * 2];
RtlSecureZeroMemory(szPath, sizeof(szPath));
_strcpy(szPath, USER_SHARED_DATA->NtSystemRoot);
_strcat(szPath, TEXT("\\system32\\wintrust.dll"));
hModule = LoadLibraryEx(szPath, NULL, 0);
if (hModule != NULL) {
WTGetSignatureInfo = (ptrWTGetSignatureInfo)GetProcAddress(hModule, "WTGetSignatureInfo");
}
//scan Windows first
cuiPrintText(T_WINFILES_HEAD, TRUE);
LoggerWrite(g_LogFile, T_WINFILES_HEAD, TRUE);
#ifdef _DEBUG
FusionScanDirectory(L"C:\\sxs", (OUTPUTCALLBACK)FusionOutputCallback);
return;
#else
FusionScanDirectory(USER_SHARED_DATA->NtSystemRoot, (OUTPUTCALLBACK)FusionOutputCallback);
LoggerWrite(g_LogFile, T_SPLIT, TRUE);
//scan program files next
cuiPrintText(T_PFDIRFILES_HEAD, TRUE);
LoggerWrite(g_LogFile, T_PFDIRFILES_HEAD, TRUE);
RtlSecureZeroMemory(szPath, sizeof(szPath));
if (SUCCEEDED(SHGetFolderPath(NULL,
CSIDL_PROGRAM_FILES,
NULL,
SHGFP_TYPE_CURRENT,
(LPWSTR)&szPath)))
{
FusionScanDirectory(szPath, (OUTPUTCALLBACK)FusionOutputCallback);
}
LoggerWrite(g_LogFile, T_SPLIT, TRUE);
#endif
}
/*
* ListAppInfo
*
* Purpose:
*
* Scan memory of appinfo.dll.
*
*/
VOID ListAppInfo(
VOID
)
{
WCHAR szFileName[MAX_PATH * 2];
cuiPrintText(T_APPINFO_HEAD, TRUE);
LoggerWrite(g_LogFile, T_APPINFO_HEAD, TRUE);
#ifndef _DEBUG
_strcpy(szFileName, USER_SHARED_DATA->NtSystemRoot);
_strcat(szFileName, TEXT("\\system32\\appinfo.dll"));
#else
_strcpy(szFileName, TEXT("C:\\appinfo\\18361.dll"));
#endif
ScanAppInfo(szFileName, (OUTPUTCALLBACK)AppInfoDataOutputCallback);
LoggerWrite(g_LogFile, T_SPLIT, TRUE);
}
/*
* main
*
* Purpose:
*
* Program entry point.
*
*/
VOID main()
{
ULONG l = 0;
WCHAR szBuffer[MAX_PATH];
__security_init_cookie();
HeapSetInformation(GetProcessHeap(), HeapEnableTerminationOnCorruption, NULL, 0);
cuiInitialize(FALSE, NULL);
cuiPrintText(T_PROGRAM_TITLE, TRUE);
g_NtBuildNumber = 0;
supQueryNtBuildNumber(&g_NtBuildNumber);
if (g_NtBuildNumber < YUUBARI_MIN_SUPPORTED_NT_BUILD) {
cuiPrintText(TEXT("[UacView] Unsupported Windows version."), TRUE);
ExitProcess(0);
}
if (g_NtBuildNumber > YUUBARI_MAX_SUPPORTED_NT_BUILD) {
cuiPrintText(TEXT("\r\n[UacView] Not all features available for this build\r\n"), TRUE);
}
RtlSecureZeroMemory(szBuffer, sizeof(szBuffer));
GetCommandLineParam(GetCommandLine(), 1, (LPWSTR)&szBuffer, MAX_PATH * sizeof(WCHAR), &l);
if (_strcmpi(szBuffer, TEXT("/?")) == 0) {
MessageBox(GetDesktopWindow(), T_HELP, T_PROGRAM_NAME, MB_ICONINFORMATION);
ExitProcess(0);
}
else {
g_VerboseOutput = (_strcmpi(szBuffer, TEXT("/v")) == 0);
}
RtlSecureZeroMemory(szBuffer, sizeof(szBuffer));
_strcpy(szBuffer, TEXT("uac"));
ultostr(g_NtBuildNumber, _strend(szBuffer));
_strcat(szBuffer, TEXT(".log"));
g_LogFile = LoggerCreate(szBuffer);
if (g_LogFile != INVALID_HANDLE_VALUE) {
cuiPrintText(TEXT("Output will be logged to the file"), TRUE);
cuiPrintText(szBuffer, TRUE);
}
//#ifndef _DEBUG
ListBasicSettings();
ListCOMFromRegistry();
//#endif
ListAppInfo();
ListFusion();
if (g_LogFile != INVALID_HANDLE_VALUE)
CloseHandle(g_LogFile);
ExitProcess(0);
}