How can a .NET Framework desktop-application gain temporary elevated privileges?
-
Hello folks, my first post after years of lurking. The burden of the out-of-date articles on the Internet around .NET technologies is getting really heavy, and I can't quite locate reliable info, and I'm blocked on this. I have asked the question on Stack Overflow, but the quality of the related answers is not encouraging me I'll get a bite. I guess all the real veterans hang out here! I basically would like to force the UAC prompt to do some stuff as admin. I understand I will need a new process and must arrange IPC between the unprivileged-parent and the privileged-child (sounds familiar :-) ). But I don't know if using
System.Diagnostics.ProcessStartInfo.verb = "runas"
is the go, or if there is a Better Way Today. There are articles here and there about using the app.manifest which I can't seem to apply in VS 2019 - they feel defunct. (.NET Framework itself is starting to feel defunct, actually). TIA
-
Hello folks, my first post after years of lurking. The burden of the out-of-date articles on the Internet around .NET technologies is getting really heavy, and I can't quite locate reliable info, and I'm blocked on this. I have asked the question on Stack Overflow, but the quality of the related answers is not encouraging me I'll get a bite. I guess all the real veterans hang out here! I basically would like to force the UAC prompt to do some stuff as admin. I understand I will need a new process and must arrange IPC between the unprivileged-parent and the privileged-child (sounds familiar :-) ). But I don't know if using
System.Diagnostics.ProcessStartInfo.verb = "runas"
is the go, or if there is a Better Way Today. There are articles here and there about using the app.manifest which I can't seem to apply in VS 2019 - they feel defunct. (.NET Framework itself is starting to feel defunct, actually). TIA
Either the
runas
verb or an application manifest should work. I'm not sure whether you'll be able to use IPC from the unelevated app to the elevated app. And if you can, you need to be extremely careful to secure it, so that it can't be used by malicious code as an elevation of privilege attack vector.
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
-
Either the
runas
verb or an application manifest should work. I'm not sure whether you'll be able to use IPC from the unelevated app to the elevated app. And if you can, you need to be extremely careful to secure it, so that it can't be used by malicious code as an elevation of privilege attack vector.
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
Richard Deeming wrote:
I'm not sure whether you'll be able to use IPC from the unelevated app to the elevated app.
Thanks Richard. For IPC, I hope I can use anonymous named pipes between the processes, per Microsoft's own How to Use Anonymous Pipes for Local Interprocess Communication. I imagine the privileged-child will be able to connect to the pipe created by the unprivileged-parent without issue if it has the token. To pass the result of
(new AnonymousPipeServerStream(/*etc*/)).GetClientHandleAsString()
to the privileged-child, I will pass it as a command-line argument. I suppose a malicious application could create its own named-pipe, invoke MY privileged-child app to fool the user into approving the UAC prompt (abusing my good name) and then control the privileged-child process from their malicious app. Fortunately I only really need the pipe for signalling the privileged-child to stop ... not to direct the action of the privileged-child. Since I'll be working withProcessStartInfo
anyhow, adding a 'runas' verb is 'within easy reach'. It then becomes a question of whether anything is gained by going declarative. Yes, if I needed the 'verb' for a different purpose, I guess. Or if I wanted the privileged-child code to be useful to an audience wider than my app. No, if I am happy for my privileged-child to fail unless properly invoked by MY code (heck, I could even take steps to make it a lot harder for said malicious actor!), or if I don't wish to draw the attention of malicious parties by marking it 'hey, I run as admin!'. -
Richard Deeming wrote:
I'm not sure whether you'll be able to use IPC from the unelevated app to the elevated app.
Thanks Richard. For IPC, I hope I can use anonymous named pipes between the processes, per Microsoft's own How to Use Anonymous Pipes for Local Interprocess Communication. I imagine the privileged-child will be able to connect to the pipe created by the unprivileged-parent without issue if it has the token. To pass the result of
(new AnonymousPipeServerStream(/*etc*/)).GetClientHandleAsString()
to the privileged-child, I will pass it as a command-line argument. I suppose a malicious application could create its own named-pipe, invoke MY privileged-child app to fool the user into approving the UAC prompt (abusing my good name) and then control the privileged-child process from their malicious app. Fortunately I only really need the pipe for signalling the privileged-child to stop ... not to direct the action of the privileged-child. Since I'll be working withProcessStartInfo
anyhow, adding a 'runas' verb is 'within easy reach'. It then becomes a question of whether anything is gained by going declarative. Yes, if I needed the 'verb' for a different purpose, I guess. Or if I wanted the privileged-child code to be useful to an audience wider than my app. No, if I am happy for my privileged-child to fail unless properly invoked by MY code (heck, I could even take steps to make it a lot harder for said malicious actor!), or if I don't wish to draw the attention of malicious parties by marking it 'hey, I run as admin!'.I'll go ahead and try these things right away. I solved my
app.manifest
issues by ticking the 'NET Desktop Development' profile in the VS 2019 installer! :doh: