From bf679271b842ab060a26ed34a4e150d19aee9abe Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Thu, 26 May 2016 21:47:01 +0100 Subject: [PATCH] [misc] prevent application launch if running non elevated * Since, despite what Microsoft states, having 'requireAdministrator' in a manifest STILL isn't enough to prevent an app from launching as non elevated for some weird account configurations... * Closes #757 --- res/localization/rufus.loc | 2 ++ src/db.h | 2 +- src/rufus.c | 51 ++++++++++++++++++++++++++++++++++++++ src/rufus.rc | 10 ++++---- 4 files changed, 59 insertions(+), 6 deletions(-) diff --git a/res/localization/rufus.loc b/res/localization/rufus.loc index cf14e151..f31968ae 100644 --- a/res/localization/rufus.loc +++ b/res/localization/rufus.loc @@ -549,6 +549,8 @@ t MSG_285 "The downloaded executable is signed by '%s'.\nThis is not a signature "indicate some form of malicious activity...\nAre you sure you want to run this file?" t MSG_286 "Zeroing drive: %0.1f%% completed" t MSG_287 "Detection of non-USB removable drives" +t MSG_288 "Missing elevated privileges" +t MSG_289 "This application can only run with elevated privileges" ################################################################################ ############################# TRANSLATOR END COPY ############################## diff --git a/src/db.h b/src/db.h index c6c9af39..4d1dbaf8 100644 --- a/src/db.h +++ b/src/db.h @@ -21,7 +21,7 @@ #pragma once /* - * NB: Table data was generated from the files/ directory the server with: + * NB: Table data was generated from the files/ directory on the server with: * find . -not -name "*.txt" -not -name "*.sh" -not -name "*pre*" -type f -print0 | xargs -0 sha256sum | awk '{print $1}' | sort | uniq | xxd -r -p | hexdump -v -e '31/1 "0x%02x, " 1/1 " 0x%02x,\n"' */ diff --git a/src/rufus.c b/src/rufus.c index e4e12f44..5920efd1 100644 --- a/src/rufus.c +++ b/src/rufus.c @@ -2762,6 +2762,46 @@ static HANDLE SetHogger(BOOL attached_console, BOOL disable_hogger) return hogmutex; } +/* + * Returns true if: + * 1. The OS supports UAC, UAC is on, and the current process runs elevated, or + * 2. The OS doesn't support UAC or UAC is off, and the process is being run by a member of the admin group + */ +static BOOL IsCurrentProcessElevated(void) +{ + BOOL r = FALSE; + DWORD size; + HANDLE token = INVALID_HANDLE_VALUE; + TOKEN_ELEVATION te; + SID_IDENTIFIER_AUTHORITY auth = SECURITY_NT_AUTHORITY; + PSID psid; + + if (ReadRegistryKey32(REGKEY_HKLM, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System\\EnableLUA") == 1) { + uprintf("NOTE: UAC is on"); + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) { + uprintf("Could not get current process token: %s", WindowsErrorString()); + goto out; + } + if (!GetTokenInformation(token, TokenElevation, &te, sizeof(te), &size)) { + uprintf("Could not get token information: %s", WindowsErrorString()); + goto out; + } + r = (te.TokenIsElevated != 0); + } else { + uprintf("NOTE: UAC is either disabled or not available"); + if (!AllocateAndInitializeSid(&auth, 2, SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &psid)) + goto out; + if (!CheckTokenMembership(NULL, psid, &r)) + r = FALSE; + FreeSid(psid); + } + +out: + safe_closehandle(token); + return r; +} + /* * Application Entrypoint @@ -2976,6 +3016,17 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine } selected_langid = get_language_id(selected_locale); + // This is needed as there appears to be a *FLAW* in Windows allowing the app to run unelevated with some + // weirdly configured user accounts, even as we explicitly set 'requireAdministrator' in the manifest... + if (!IsCurrentProcessElevated()) { + uprintf("FATAL: No administrative privileges!"); + // Load the translation before we print the error + get_loc_data_file(loc_file, selected_locale); + right_to_left_mode = ((selected_locale->ctrl_id) & LOC_RIGHT_TO_LEFT); + MessageBoxExU(NULL, lmprintf(MSG_289), lmprintf(MSG_288), MB_ICONSTOP | MB_IS_RTL | MB_SYSTEMMODAL, selected_langid); + goto out; + } + // Prevent 2 applications from running at the same time, unless "/W" is passed as an option // in which case we wait for the mutex to be relinquished if ((safe_strlen(lpCmdLine)==2) && (lpCmdLine[0] == '/') && (lpCmdLine[1] == 'W')) diff --git a/src/rufus.rc b/src/rufus.rc index bd18006f..b5adcc50 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL IDD_DIALOG DIALOGEX 12, 12, 242, 376 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_ACCEPTFILES -CAPTION "Rufus 2.10.940" +CAPTION "Rufus 2.10.941" FONT 8, "Segoe UI Symbol", 400, 0, 0x0 BEGIN LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8 @@ -320,8 +320,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,10,940,0 - PRODUCTVERSION 2,10,940,0 + FILEVERSION 2,10,941,0 + PRODUCTVERSION 2,10,941,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -338,13 +338,13 @@ BEGIN BEGIN VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "2.10.940" + VALUE "FileVersion", "2.10.941" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", "© 2011-2016 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" VALUE "OriginalFilename", "rufus.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "2.10.940" + VALUE "ProductVersion", "2.10.941" END END BLOCK "VarFileInfo"