Jump to content

Recommended Posts

Posted

Hi again.

 

As you have seen in today's other thread, I'm working on getting the password resetting for Windows to work without using local admin privileges. Whilst doing so, I've stumbled upon an error in the Windows local account password reset script "Set-WindowsPassword.ps1". I'm working with build 8180.

 

After reducing the Powershell code to its bare essentials and running it on one of my test boxen, I've found that the relevant ScriptBlock contains a Write-Output that it really shouldn't, or that the test is written badly. Its current state leads to false positives.

 

 

REPRODUCTION:

Expire a local admin account's password on a Windows box. A few minutes later, the reset status lights up green as does the heartbeat. However, running another heartbeat attempt sets the HB status to red. Upon closer inspection I also find that the password has NOT been changed. No errors are reported by the reset script, which is recorded as successful in the audit log.

 

 

DEBUGGING:

I've reduced the relevant Powershell code to the bare minimum. I'm running it in Powershell ISE on the target host, with the privileged user account. Running things manually clearly shows an "access denied" message which is not getting caught by the test.

 

 

EXAMPLE CODE:

$HostName = "myhost"
$TargetUser = "administrator"
$NewPassword = "supersecrettotallynotit-1234"

function ScriptBlock ()
{
	$account = [ADSI]"WinNT://$HostName/$TargetUser,user"
	$account.psbase.invoke("SetPassword", $NewPassword)
	$account.psbase.CommitChanges()
	Write-Output "Success"		# THIS IS YOUR SMOKING GUN
}

$resultsarray = scriptblock 2>&1

if ($resultsarray -eq "Success")
{
	Write-Output "Success"
}
else
{
	Write-Output "Failboat"
} 

 

PROOF:

Run the code above ultimately leads to the output "Success", even if the psbase commands fail. In my case, I'm given an "access denied". Taking out the Write-Output from the function makes it exit with "Failboat".

 

Now, if I swap the final IF-THEN-ELSE test with the actual code from the original PS1 (which includes the Switch statement for various error messages), then we see the same pattern. Making ScriptBlock output "Success" always leads to an exit of the script with "Success". Taking out that Write-Output line however, will correctly display the "access denied" error message.

 

 

FIX:

You'll need some error handling in your codeblock, to verify if there's any failures on the remote end and to indicate at which step.

function ScriptBlock ()
{
	$account = [ADSI]"WinNT://$HostName/$TargetUser,user"
	$account.psbase.invoke("SetPassword", $NewPassword)
	if ($?) 
	{ 
		$account.psbase.CommitChanges()
		if ($?) { Write-Output "Success" }
		else { Write-Output "Failure on commit"} 
	}
	else { Write-Output "Failure on invoke" } 
}

 

 

Posted

Hello,

 

Thanks for the feedback. We do try and capture as many errors as we can in our scripts, but possibly we've missed the error you're reporting as this script is designed to work only with an administrative account.

 

For now, you can clone this script yourself, and make any changes to it you require.

Regards

Click Studio

Posted

Well, the fun part is that it even occurred when the account is member of the local admin group. So even with admin rights the command fails, but the Powershell script does not handle it correctly. So to sum it up: if someone were to accidentally strip rights of the privileged Windows account, the Powerstate script in its current incarnation would not alert you about failed password changes. That could seriously mess up someone's production environment.

 

Thus I would sincerely suggest that this bug is fixed quickly. It is detrimental that false positives can be reported for password changes.

Posted

Hi Buckit,

 

Could you share with us how to reproduce the issue, and then we'll look into making a change to the script?

 

Thanks very much.


Regards

Click Studios

Posted

Hi, thanks for your help.

 

Everything you need to know is in my first post in this thread: reproduction, code analysis and a suggested fix. One easy way of reproducing the situation is by manually removing the Windows privileged user from the administrators group on the target host. This will ensure that the password change request fails. But as I showed, the itself will still report a success and will thus not report any errors.

 

Of course... removing administrator rights form the account means you'll have to ensure that the account gets Powershell Remoting access in another way (see my other thread).

 

Funnily enough, my Windows privileged account -DOES- have full admin rights and it still gets "access denied" on the $account.psbase.invoke. That's a WIP on my side, which led to the discovery of this bug.

 

EDIT:

I have just tested my suggested fix in my sandbox environment. The password script now correctly sets "reset status" to RED, with the correct error message as reported by the failing $account.psbase.invoke.

 

Of course, that leaves all the other scripts to double-check for similar bugs ;)

Posted

Hi Buckit,

 

If your account has full admin rights, then you should not be seeing this Access Denied - possibly you've done some hardening in your environment?

 

We'll take a look at your suggestions and see what we can do.

Regards

Click Studios

Posted

Aye, I'll poke around some more in our global policies and settings. It's an interesting situation.

 

In another test, I use the same commands with a proper admin account and while the password changing went off without errors, the validation still fails (suggesting that the change wasn't made). 

 

I'll report back when I've had the chance to poke around some more.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...