PowerShell Remoting Project Home

Thursday, February 02, 2006

Survival as a Non-Administrator: A Monad view

DON'T ROOT AROUND!

Remember the security rule NO.1 in unix world? It is also 100% rule NO.1 in windows world. Do you get some worms, viruses, spywares or adware in you windows box? You should blame yourself first if you logged in as an Adminstrator EVERYTIME EVERYDAY. It is you who let those malware bypass all windows security check and write themselves directly in system folder and registry. Do you really need Administrator privilege to read Emails or surf the internet? Or do you really need Administrator privilege to compile your code? If you want to write secure code, login as a limited user and find out how you code works. Don't rely on testing afterwards.

Reality check: But calm down man! Don't point to that logout button so soon! There are plenty of ways to regain your power without logout. You can control your computer as Administrator and return back to your non-Administrator environment after you are done.

Since this is a blog about MSH, I am going to talk about some solutions in MSH.

1. -Credential Parameter
It is good to see that (although still in beta stage) monad designers kept "running at least privilege" in mind. For example, they plan to implemetation -Credential parameter for file/registry provider. There are some buildin cmdlet using -Credential parameter. For example those Item cmdlet:

Name       : clear-item
Definition : clear-item [-Path] String[] [-Force] [-Filter String] [-Include St
             ring[]] [-Exclude String[]] [-Credential MshCredential] [-Verbose]
              [-Debug] [-ErrorAction ActionPreference] [-ErrorVariable String]
             [-OutVariable String] [-OutBuffer Int32] [-WhatIf] [-Confirm]

Name       : copy-item
Definition : copy-item [-Path] String[] [[-Destination] String] [-Container] [-
             Force] [-Filter String] [-Include String[]] [-Exclude String[]] [-
             Recurse] [-PassThru] [-Credential MshCredential] [-Verbose] [-Debu
             g] [-ErrorAction ActionPreference] [-ErrorVariable String] [-OutVa
             riable String] [-OutBuffer Int32] [-WhatIf] [-Confirm]

Name       : get-item
Definition : get-item [-Path] String[] [-Filter String] [-Include String[]] [-E
             xclude String[]] [-Force] [-Credential MshCredential] [-Verbose] [
             -Debug] [-ErrorAction ActionPreference] [-ErrorVariable String] [-
             OutVariable String] [-OutBuffer Int32]

Name       : invoke-item
Definition : invoke-item [-Path] String[] [-Filter String] [-Include String[]]
             [-Exclude String[]] [-Credential MshCredential] [-Verbose] [-Debug
             ] [-ErrorAction ActionPreference] [-ErrorVariable String] [-OutVar
             iable String] [-OutBuffer Int32] [-WhatIf] [-Confirm]

Name       : move-item
Definition : move-item [-Path] String[] [[-Destination] String] [-Force] [-Filt
             er String] [-Include String[]] [-Exclude String[]] [-PassThru] [-C
             redential MshCredential] [-Verbose] [-Debug] [-ErrorAction ActionP
             reference] [-ErrorVariable String] [-OutVariable String] [-OutBuff
             er Int32] [-WhatIf] [-Confirm]

Name       : new-item
Definition : new-item [-Path] String[] [-Type String] [-Value Object] [-Force]
             [-Credential MshCredential] [-Verbose] [-Debug] [-ErrorAction Acti
             onPreference] [-ErrorVariable String] [-OutVariable String] [-OutB
             uffer Int32] [-WhatIf] [-Confirm]

Name       : remove-item
Definition : remove-item [-Path] String[] [-Filter String] [-Include String[]]
             [-Exclude String[]] [-Recurse] [-Force] [-Credential MshCredential
             ] [-Verbose] [-Debug] [-ErrorAction ActionPreference] [-ErrorVaria
             ble String] [-OutVariable String] [-OutBuffer Int32] [-WhatIf] [-C
             onfirm]

Name       : rename-item
Definition : rename-item [-Path] String [-Name] String [-Force] [-PassThru] [-C
             redential MshCredential] [-Verbose] [-Debug] [-ErrorAction ActionP
             reference] [-ErrorVariable String] [-OutVariable String] [-OutBuff
             er Int32] [-WhatIf] [-Confirm]


Name       : set-item
Definition : set-item [-Path] String[] [[-Value] Object] [-Force] [-PassThru] [
             -Filter String] [-Include String[]] [-Exclude String[]] [-Credenti
             al MshCredential] [-Verbose] [-Debug] [-ErrorAction ActionPreferen
             ce] [-ErrorVariable String] [-OutVariable String] [-OutBuffer Int3
             2] [-WhatIf] [-Confirm]


Unfortunately, if you try to use them now, you will get an error.

invoke-item : Dynamic parameters for the Cmdlet cannot be retrieved. Invocation of MakePath on the 'FileSystem' provider failed for path ''. Cannot call method. The provider does not support the use of credentials.

According to Abhishek Agrawal [MSFT] : "FileSystem and Registry provider do not supprt Credential parameter for V1. We plan to address this in V2. For now you will need to start an elevated MSH window using runas.exe (or Process.Start api) and carry out the required operations there. "

So you have to wait new version of monad which can utilize the -credential parameter for FileSystem and Registry provider.

2. System.Diagnostics.Process.Start() method
.NET framework 2.0 provide three new overloads of System.Diagnostics.Process.Start() method which (might use CreateProcessAsUser Win32 API to) start a process as different user:

public static Process Start ( ProcessStartInfo startInfo)
public static Process Start ( string fileName, string userName, SecureString password, string domain)
public static Process Start (string fileName, string arguments, string userName, SecureString password, string domain)

They take string type username and SecureString type password. (ProcessStartInfo.Password is a SecureString) SecureString is a new creature in .NET 2.0. How we can get an instance of SecureString? Using get-credential cmdlet we can easily and securely package username and password and then pass them to System.Diagnostics.Process.Start() method. See my previous blog entry for details.

Armed with this tool, we can do almost anything in MSH command line. For example, set file system access control rule, kill a process, modify registry or start a service.

Remember you need to type:
exit
to stop this msh.exe process. You don't want to leave a shell with Administrator privilege to someone else, do you?

3. Have to use GUI?
Well, I have to admit that sometimes command line is just not good enough. For example, you want to disable wireless network connection. There is no way to use runas.exe or do shift-click tricks. Even if you started msh.exe as an Administrator, invoking ncpa.cpl will not give you "Network Connections" in control panel. The only choice is to use other command line tools like: devcon.exe (from microsoft) or network.exe (from Wingnut Software) If you know how to do this in MSH script, please tell me, please!

ps: I found this funny story. The author had same problem as mine.

But there is always a work around: With help of monad, we can easily get a GUI shell(explorer.exe) as Administrator.

1) using su.msh to get a msh prompt as Adminstrator
2) run following commands
stop-process -ProcessName explorer
explorer.exe
Welcome to Administrator's Explorer! Go to control panel and disable wireless network connection as you wish. But remember:

a) Explorer.exe will reload itself quickly after been killed, so you better write those command in msh script.

b) After you finish your work, you need to return to your original explorer environment. You can't kill the explorer.exe process within task manager because you are a limited user (remember?). Instead, you can
stop-process -ProcessName explorer
in the msh as Adminstrator
What? you have already closed that window? Run su.msh again!
then you either wait explorer.exe to reload itself or start explorer (Do this as a non-Administrator!) by
explorer.exe

Added on 26th, Feb 2006
You can change registry to start exporler.exe in seperate process (so there is no need to kill your original explorer.exe process):
First, run su.msh
Then modify registry:
set-property HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -property SeparateProcess -value 1 -force

Without reboot, we can now start new explorer.exe windows as Administrator:
explorer.exe

You can even use System.Diagnostics.Process.Start() method to start a explorer.exe process from your msh runing as limited user.
Added on 26th, Feb 2006

Have Fun!

[Edit: Monad has now been renamed to Windows PowerShell. This script or discussion may require slight adjustments before it applies directly to newer builds.]

Tags:       


Comments:

Post a Comment





<< Home