Alex Roberts
Alex Roberts

Reputation: 66

Run a Command as Administrator with Elevated Flag (with known password)

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".

Upvotes: 0

Views: 1161

Answers (0)

Related Questions