0

I have a VB.net application that needs to be run by standard users but there are certain functions that need to be run as local administrator with an elevated flag (or LSA, Trusted installer, or other system account for all I care). This is a helper program that allows users to run internal applications without entering the local admin credentials and going through a UAC prompt. UAC is designed to prevent programs from spontaneously gaining admin privileges but in my case we intend to embed these credentials in the program. We do not want to disable UAC, just bypass it which is already being done in other ways, we just need the run command (reg add or CMD for example) to be started with the run as admin flag. Simply doing a runas is not working because these are standard user accounts, we are getting access denied when trying to add an item to a run folder in the registry.

Just to clarify, the base program will never be run as administrator. The intent is to use it to call another program or cmd.exe with embedded credentials. Standard users will be using this.

I have tried the VB.Net system.diagnostics.process.start.flag = "runas" property but that did not work.

I have also tried the below code but this is not working either and returns "1". For a call with

RunProgram("Administrator", "password", Environment.MachineName, "cmd.exe", "/c reg add HKLM\Software\Microsoft\Windows\CurrentVersion\Run /f /v MyProgram /D " & System.Windows.Forms.Application.ExecutablePath())

Any ideas how to proceed?

I have also tried a simple cmd runas using VB.Net

system.diagnostics.process.start.flag = "runas", and now Lib "Advapi32" Alias "CreateProcessWithLogonW".

Below is the module code:

Public Module Impersonation

#Region "API Structures"
    <StructLayout(LayoutKind.Sequential)>
    Public Structure PROCESS_INFORMATION
        Dim hProcess As System.IntPtr
        Dim hThread As System.IntPtr
        Dim dwProcessId As Integer
        Dim dwThreadId As Integer
    End Structure

    <StructLayout(LayoutKind.Sequential)>
    Public Structure STARTUPINFO
        Dim cb As Integer
        Dim lpReserved As System.IntPtr
        Dim lpDesktop As System.IntPtr
        Dim lpTitle As System.IntPtr
        Dim dwX As Integer
        Dim dwY As Integer
        Dim dwXSize As Integer
        Dim dwYSize As Integer
        Dim dwXCountChars As Integer
        Dim dwYCountChars As Integer
        Dim dwFillAttribute As Integer
        Dim dwFlags As Integer
        Dim wShowWindow As Short
        Dim cbReserved2 As Short
        Dim lpReserved2 As System.IntPtr
        Dim hStdInput As System.IntPtr
        Dim hStdOutput As System.IntPtr
        Dim hStdError As System.IntPtr
    End Structure
#End Region
#Region "API Constants"
    Private Const LOGON_NETCREDENTIALS_ONLY As Integer = &H2
    Private Const NORMAL_PRIORITY_CLASS As Integer = &H20
    Private Const CREATE_DEFAULT_ERROR_MODE As Integer = &H4000000
    Private Const CREATE_NEW_CONSOLE As Integer = &H10
    Private Const CREATE_NEW_PROCESS_GROUP As Integer = &H200
    Private Const LOGON_WITH_PROFILE As Integer = &H1
#End Region
#Region "API Functions"
    Public Declare Unicode Function CreateProcessWithLogon Lib "Advapi32" Alias "CreateProcessWithLogonW" _
        (ByVal lpUsername As String,
         ByVal lpDomain As String,
         ByVal lpPassword As String,
         ByVal dwLogonFlags As Integer,
         ByVal lpApplicationName As String,
         ByVal lpCommandLine As String,
         ByVal dwCreationFlags As Integer,
         ByVal lpEnvironment As System.IntPtr,
         ByVal lpCurrentDirectory As System.IntPtr,
         ByRef lpStartupInfo As STARTUPINFO,
         ByRef lpProcessInfo As PROCESS_INFORMATION) As Integer

    Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As System.IntPtr) As Integer

#End Region



    Public Function RunProgramold(ByVal UserName As String, ByVal Password As String, ByVal Domain As String, ByVal Application As String, ByVal CommandLine As String)

        Dim siStartup As STARTUPINFO
        Dim piProcess As PROCESS_INFORMATION
        Dim intReturn As Integer

        If CommandLine Is Nothing OrElse CommandLine = "" Then CommandLine = String.Empty

        siStartup.cb = Marshal.SizeOf(siStartup)
        siStartup.dwFlags = 0

        intReturn = CreateProcessWithLogon(UserName, Domain, Password, LOGON_WITH_PROFILE, Application, CommandLine, NORMAL_PRIORITY_CLASS Or CREATE_DEFAULT_ERROR_MODE Or CREATE_NEW_CONSOLE Or CREATE_NEW_PROCESS_GROUP, IntPtr.Zero, IntPtr.Zero, siStartup, piProcess)

        If intReturn = 0 Then
            Dim errorMessage As New Win32Exception(Marshal.GetLastWin32Error())
            MsgBox("Cant start program:" & Application & CommandLine & errorMessage.Message)
            Throw New System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error())
        End If

        CloseHandle(piProcess.hProcess)
        CloseHandle(piProcess.hThread)

        Return intReturn
    End Function
End Module

It should be running Reg Add as administrator and write a new entry to the run folder in the registry. No message is resulting and the only error I get is "1".

user692942
  • 16,398
  • 7
  • 76
  • 175
  • You add a manifest to an EXE file. See https://pastebin.com/KYUgEKQv for a console example and https://pastebin.com/sECS6Pyw for starting a program. – Noodles Mar 26 '19 at 20:40
  • Won't manifests require the user to accept a UAC screen with requireAdministrator though? Just to clarify, the base program will never be run as administrator. The intent is to use it to call another program or cmd.exe with embedded credentials. – Alex Roberts Mar 26 '19 at 20:52
  • You use it to elevate individual commands. Everything will require the user to accept elevation. – Noodles Mar 26 '19 at 20:57
  • Using CreateProcessWithLogonW, I can run something as the administrator without UAC getting in the way (because I called it with the username and password, is it just the elevated status that seems to get in the way. Is UAC only for the elevated status and not the running as administrator's group? It's interesting that running under the local administrator account works for some things but not others though. – Alex Roberts Mar 26 '19 at 21:17
  • There are three settings in a program file. RequireAdmin (only admins can run this), HighestAvailable (Admins MUST elevate, limited users have a choice to run elevated or not), and AsInvoker which is the normal one. Admins have two user tokens limited and administrator. – Noodles Mar 26 '19 at 21:45
  • 1
    I'm not sure you can elevate a process without being hit by a UAC prompt. Even though you launch the process as a different user you don't automatically get administrator privileges (likely this is a security feature), you must explicitly tell the OS that you want them. This should shed some light on the situation: [Why Can’t I Elevate My Application to Run As Administrator While Using CreateProcessWithLogonW?](https://blogs.msdn.microsoft.com/cjacks/2010/02/01/why-cant-i-elevate-my-application-to-run-as-administrator-while-using-createprocesswithlogonw/) – Visual Vincent Mar 26 '19 at 21:56
  • 1
    By default the Local Security Policy has Administrator Approval mode enabled, this means that even if you run the application using administrator credentials you will still be prompted by UAC. – user692942 Mar 27 '19 at 05:51

0 Answers0