RunAs /savecred ask for password if another user runs the same batch file
Solution 1:
The short answer: DO NOT DO THIS. You're only going to open your system to a HUGE, and I do mean HUGE system security flaw: Once you /savecred, you're saving your admin password to the users profile, UNCONDITIONALLY, for them to use any time, any way they like. That means, once saved, they can launch a console window (CMD prompt), type in "runas /savecred /user:administrator cmd.exe" and instantly launch a new command console with full admin rights to do anything they want. You probably do not want them to be able to do this!
What I think you really want is to allow any user to run a specific command without being asked for elevated (admin) permissions or needing to enter an admin password. For this, there is a secure and working solution in modern Microsoft(tm) Windows operating systems: Set the program to run as a scheduled task with the specific access rights that the program needs. You might create a user account specifically for this program, or you might just use the admin/system credentials for this, and only this, program. Here's how..
First, you need to set up a scheduled task, like any other scheduled task. You must assign it a specific command line (so if you need to pass parameters to the task, you'll have to use scripting or batch files to create an "parameter file" to pass the parameters to the program, or use some other method to do so.. This solution isn't perfect!). You can then assign it whatever security rights you need to give it. Name it something appropriate--and avoid the use of spaces in the name to keep it simple; We're going to be using this name to actually run the program when your user needs to run it. Also, do not schedule an actual time to run the task, since we'll be calling it to run on demand in a moment, rather than always running at a specific time.
Once the task is created, the next question is going to be "How do I RUN it?" Well, you either create a shortcut, or a batch/script file, which will call the scheduled task to run: "schtasks /run /tn name-you-gave-the-task-above". So, if you created a task called "AutoAddLocalPrinters" (a common admin task, for example), you'd create a batch file or shortcut to run the command "schtasks /run /tn AutoAddLocalPrinters" (if you did name it something with spaces, you'll have to put the entire name in quotes--this is why I avoid spaces in names).
Note that the only time it requires admin rights or a password is when setting up the scheduled task. Just running the task once set up does not need a password, does not ask for one, and most importantly, does not globally and blindly save the admin password to the users profile. It's saved as part of the scheduled task, which only affects that, and only that task, and won't let the user modify or change it, or start a new elevated console prompt with it, etc.
Furthermore, you can adjust the permissions on the scheduled task to allow only certain user groups to run it, and so on. You can further fine tune it by creating special user accounts or batch/script files with which you can check and validate any permissions of criteria you desire. For example, if you have children, you can create a script which checks if it's past their bedtime before allowing them to launch their chat program.. ;-) In short, you can pretty much do anything you want or need to do to validate and control how the program is run (or denied).
Finally, one more advantage (or disadvantage..) to doing it this way: It works on just about every edition of Windows where you can schedule tasks and run the "schtasks" command. For example, my understanding is that Windows Home editions ignore the /savecred option of "runas" anyhow, so you'll always have to provide the password. A scheduled task will run with the credentials you set it up with, even in Home editions.
Footnote: I mention this because I usually remove many program paths from the system PATH variable, and add "C:\sys\admin;C:\sys\bat;C:\sys\bin" to the system path. Then under the "C:\sys*" folders (you'll need to create them, obviously), I create individual batch/script/shortcut files which call the real programs or scheduled tasks. This way, I have complete control over who, what, when, where, and how various programs are allowed/disallowed to run. It also helps prevent stupid errors--One error I've actually encountered was one of my end-users trying to convert a file and running the "convert" command without knowing what they were doing. Since Windows already has a "convert" command, which converts FAT to NTFS, all they managed to do was convert their file system.. They got lucky and it still worked since their computer didn't care if the file system was FAT or NTFS. But now I always have a C:\sys\bat\convert.bat file which slaps them on the hand and tells them to talk to me before trying to run this command.. ;-) I do the same with many other potentially dangerous or power-user commands that can seriously cause problems when mis-used/mis-typed.
Good luck!
Edited 2020-09-18 to add:
- As an administrator (even in the context of a personal/home computer, not just professionally), get in the habit of ALWAYS securing your file system and files. Do not give read, write, execute, or other types of permissions to users unless they really make sense in context. I strongly advise against giving additional access rights simply because it may reduce administrative headaches--the headaches caused by mis-use, whether benign or malicious, far outweigh the extra work done to keep your system secure in the first place. I personally even set up and use two user accounts for myself, a administrative one and a "regular user" one for my daily and regular use. Despite the hassle of switching between them a lot, it has saved me from far worse issues when it comes to others' attempts to "hack" systems I manage, including (but not limited to) keyloggers, trojans, viruses, and even my nephew simply innocently trying to set up a game server to game with a 'friend'--which said 'friend' tried to exploit a game server flaw to gain access to his system.
- I have not reviewed my original post to update it for Windows (tm) versions after Windows XP/2003/7, which are no longer supported by Microsoft (tm). I have switched to a Linux based OS around 2016, and am no longer "up to date" on issues with Microsoft Windows based systems to further verify things.
Solution 2:
A script can be run as a task, but if we have to run an interactive application as another user, then creating a task does not work. You will have to necessarily tick the box "Run whether user is logged on or not" and if you do that, the task will not show the user interface of the application. Dont know whether there is a solution for this.
Solution 3:
There is not a simple way to run a program with higher privileges without /savecred option, if the program must be interactive.
With scheduled Task the interface is not shown to the actual user, so it's not possible to interact.
The only way i've found for my purpose was to create a small vb program that launch a runas command (without /savecred option) and then send the password to the Dos window through the Windows API SendMessage.
User and password are stored in the Windows Registry, and password is crypted with a Blowfish Algorithm (in my case, but everyone can choose a different way).
Then i simply launch that program when i need it (in my case during login).
I don't know how to attach the source code, anyway this is the main part:
Declaration:
Private Declare Sub Sleep Lib "kernel32.dll" (ByVal dwMilliseconds As Long)
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal
lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function GetSystemDirectory Lib "kernel32" Alias
"GetSystemDirectoryA" (ByVal lpBuffer As String, ByVal nSize As Long) As
Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA"
(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As
Any) As Long
Private Const WM_CHAR = &H102
Private WshShell
Body:
' Used in a Subroutine
If Not IsRunning("runas.exe") Then
Set WshShell = CreateObject("WScript.Shell")
Set WshEnv = WshShell.Environment("Process")
rc = WshShell.Run("runas /user:" & sUser & " notepad.exe", 2, False)
Sleep 400
End If
SendPass
The function isRunning check if there is already an active runas window:
Private Function IsRunning(ByVal proc As String) As Boolean
Dim oProcs As Object
Set oProcs = GetObject("winmgmts:").ExecQuery("SELECT * FROM Win32_Process
WHERE Name='" & proc & "'")
IsRunning = (oProcs.Count > 0)
Set oProcs = Nothing
End Function
And the function SendPass , send the password to the runas command:
Public Function SendPass()
Dim winHwnd As Long
Dim sSave As String, Ret As Long
Dim intConta As Integer
Dim bytBuffer() As Byte
sSave = Space(255)
Ret = GetSystemDirectory(sSave, 255)
sSave = Left$(sSave, Ret)
winHwnd = FindWindow(vbNullString, sSave & "\runas.exe")
If winHwnd <> 0 Then
bytBuffer = StrConv(sPass & vbNullChar, vbFromUnicode)
For intConta = 0 To UBound(bytBuffer, 1) - 2
Call SendMessage(winHwnd, WM_CHAR, bytBuffer(intConta), ByVal 0&)
Next intConta
End If
End Function