Wednesday 15 February 2012

You can add the logging in user as a local admin? Thats impossabarble!

The debate had gone on for a long time as to whether we should allow users to have local admin rights on there computer. Where I currently work it is a requirement to allow users to have local admin rights over there computer but then that raised the interesting question of how do you secure the network and/or devices where you do give them local admin rights?

Alot of people simply  add Domain Users to the Administrators group on the local computer to give there domain users local admin rights. This also unfortunately give the user local admin rights on every other computer in the school also so what can be done about this?

Besides the obligatory GPO settings to limit the amount of access a user has at a local admin level over another computer across the network, we also came up with the solution of only giving local admin rights to a user which has logged into a computer. ie as they login to a computer at a user level they will be granted local admin rights with a login script. I already here you thinking to yourself "but they are at a user level. They can't give themselves local admin rights!" and you are right, you cant give yourself local admin rights if you are logged in as a normal user, thus the fun-ness of this script :)

I wrote the script to check to see if it has admin rights, if it doesn't, to re-run the script under different user permissions to allow the local user to be added to the Administrators.

as always before we start :P
[Rant]Now before we get started on the scripting lets get one thing straight,


I AM NOT A PROGRAMMER!!  
Yes there will be a better way of doing it, could I make it work? no so if you can make it work feel free to make a post and I will change the script :) [/Rant]

 $pathTemp = "C:\Temp\Login.tmp"
$password = "lotsofnumbersandlettersinheretotisthepasswordinitsecryptedformandiwllpostthescriptandtalkaboutitlaterintheblogandyesitreallyisthislongimademine256ithinkohhandthekeyisover9000"
$key = "111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111"

$domain = "domain"
$strComputer = "$env:computername"

#downloaded from http://gallery.technet.microsoft.com/scriptcenter/63fd1c0d-da57-4fb4-9645-ea52fc4f1dfb/

function Test-Admin {
   $currentPrincipal = New-Object Security.Principal.WindowsPrincipal( [Security.Principal.WindowsIdentity]::GetCurrent() )
   if ($currentPrincipal.IsInRole( [Security.Principal.WindowsBuiltInRole]::Administrator )) {
      return $true
   }
   else {
      return $false
   }
}
#downloaded from http://myitforum.com/cs2/blogs/yli628/archive/2007/08/30/powershell-script-to-add-remove-a-domain-user-to-the-local-administrators-group-on-a-remote-machine.aspx
function AddLocal {
    if(Test-Path $pathTemp){
       $username = Get-Content $pathTemp
    }
    $computer = [ADSI]("WinNT://" + $strComputer + ",computer")
    $Group = $computer.psbase.children.find("administrators")
    $Group.Add("WinNT://" + $domain + "/" + $username)
    Remove-Item $pathTemp -Force
    break
}
   
start-sleep -s 3
  
$Invocation=(Get-Variable MyInvocation).Value
if ($Invocation.MyCommand.Path -ne $null) {
   $arg="-file "+$Invocation.MyCommand.Path
   if (!(Test-Admin)) {
           Out-File -FilePath $pathTemp -InputObject $env:username -Force
        $passwordSecure = ConvertTo-SecureString -String $password -Key ([Byte[]]$key.Split(" "))
        $credential = New-Object system.Management.Automation.PSCredential("domain\usertorunas", $passwordSecure)
          Start-Process "$psHome\powershell.exe" -Credential $credential -ArgumentList $arg
          break
   }
   else {     
    if(Test-Path $pathTemp){
       $username = Get-Content $pathTemp
       AddLocal
    }
    #downloaded from http://www.powershellcommunity.org/Forums/tabid/54/aft/1528/Default.aspx
    $group =[ADSI]"WinNT://./Administrators"
    $members = @($group.psbase.Invoke("Members"))
    $UsersInGroup= $members | foreach {$_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)}
    foreach($DomainUsers in $UsersInGroup) {
        if ($DomainUsers -eq "Domain Users") {
            $Group.Remove("WinNT://" + $domain + "/Domain Users")
            $username = $env:username
            AddLocal
        }
    }
    }
}

simply add the powershell script to start and login, and viola! you will now have users granted local admin rights at login. For the astute people that noticed(so I bet no one) you will notice the script actually checks to see if there is a Domain Users group under local admin and if so removes it then adds the user and your probably thinking whats the point in that?
The one problem with this script is that if you are logging in as a user you will not have local admin rights unless you logoff the computer then back on as you have started that login session as a normal user and the effect of being in the local admin group will not be picked up until the next login. Since the majority of our school is 1 Device to 1 User we add Domain Users to the local admin group in our SOE which means the first user login will be granter admin rights on the computer without having to logoff and in again and the Domain Users group will be removed from the local admin group.

The Username and Password used to run the script at elevated privileges should be added to the local admin group of all computers and should have absolutely no network access to anything except to add the local user to the local administrator group. This means even if they get the username and password of the user, they are still limited in what they can actually do with it.

To encrypt the password for the user in the script you can use the following
 # Path to the script to be created:
$path = 'c:\temp\template.ps1'

# Create empty template script:
New-Item -ItemType File $path -Force -ErrorAction SilentlyContinue

$pwd = Read-Host 'Enter Password' -AsSecureString
$user = Read-Host 'Enter Username'
$key = 1..32 | ForEach-Object { Get-Random -Maximum 256 }
$pwdencrypted = $pwd | ConvertFrom-SecureString -Key $key
 
$private:ofs = ' '
('$password = "{0}"' -f $pwdencrypted) | Out-File $path
('$key = "{0}"' -f "$key") | Out-File $path -Append

'$passwordSecure = ConvertTo-SecureString -String $password -Key ([Byte[]]$key.Split(" "))' | 
Out-File $path -Append
('$cred = New-Object system.Management.Automation.PSCredential("{0}", $passwordSecure)' -f $user) |
Out-File $path -Append
'$cred' | Out-File $path -Append

ise $path

# http://powershell.com/cs/media/p/7968.aspx


These scripts do the job fine. The debate of whether we should be giving the local admin rights to users I am sure will continue on for many years to come. I think that as the software changes and the lines between local admins and users blurs even more as it has in Windows 7, this problem will disappear.

No comments:

Post a Comment