Resetting Local Administrator Passwords

Resetting the local administrator passwords has always been problematic.

I frequently used a computer startup script that reset passwords.

It was easy; it contained a single command: Net user administrator newPasswordWhateverItIs

The problem with this solution is that the script is a simple text file and it is placed in the Sysvol Folder that everybody can reach and read the new password.

So, a new technique must be found.

Microsoft has a good solution: Local Administrator Password Solution (LAPS)

LAPS modifies schema, creates new attributes, also installs a client side extension.

Then, local administrator password can be changed in bulk, to be unique to each machine.

New password is then transferred to a DC over an encrypted channel.

And the password attribute can be read by only specified admins.

LAPS is somewhat complicated at the same time: Installation of client side extensions, modifying schema, assigning permissions, etc

 

So, I created a new solution to reset the local admin passwords.

This solution has its own drawbacks.

First, the new password is not transferred to anywhere!

After resetting the password, no one knows it!

But most of the times, not knowing local admin password may have its advantages.

Domain admins can access the machines without knowing its local admin password anyway.

Only case the unknown local admin password may create problems is when the connection (trust relationship) of the machine with the domain is broken.

In such a case, you need to logon to that machine as a local admin.

But in those times, we can easily reset this password using many techniques.

Ok, if you accept these shortcomings, you can examine the solution.

Solution consists of creating a random password and assigning this password to the administrator user.

 

I took random password generation part from a Stackoverflow post:

https://stackoverflow.com/questions/37256154/powershell-password-generator-how-to-always-include-number-in-string

I wanted this code to run only once.

So, at the beginning, I check the existence of a file with a name containing the local machine name.

If there is the specified file, then it means, code was run and skip the resetting.

If there is no such file, I create a random password, assign it, then I create the computername-file and also append the name to another text file to see the affected machines.

Files will be created in a share. On the share, permissions must be Everyone, Change.

Hackers can read the content of the files, but they cannot see the new passwords.

And when you want to reset the passwords again, you just need to delete the files under that share.

Code:

if (test-path \\servername\ortak\$env:computername.txt)

{#doNothing} else

{

$punc = 46..46

$digits = 48..57

$letters = 65..90 + 97..122

$YouShallNotPass = get-random -count 15 `

-input ($punc + $digits + $letters) |

% -begin { $aa = $null } `

-process {$aa += [char]$_} `

-end {$aa}

net user administrator $YouShallNotPass

OK | out-file \\servername\ortak\$env:computername.txt

$env:computername | out-file \\servername\ortak\list.txt -append

}

Stopping a Process Using Its Certificate

Recently, Im asked to find a way to prevent "ProcessHacker" program, a popular program to manage running processes.

First, I wanted to use Software Restriction Policies in Group Policy, using the hash values of the program.

But Im told that the program is frequently updated, so its hash value changes, therefore software restriction policy using the hashname cannot be a solution.

Software restriction policies can restrict a folder so that no program can be run in that folder but ProcessHacker has no installation folder, so this option is invalid also.

The unchanged and cannot be easily changed parameter is the certificate used to sign the code of the program.

This certificate has a subject line reading as "CN=Wen Jia Liu, O=Wen Jia Liu, L=Sydney, S=New South Wales, C=AU".

If we scan all the running tasks, check their certificates to see if its subject line is so and so, then we can stop that task.

The following code just does it:

get-process | foreach {

$exename=$_.path

$sert=(Get-AuthenticodeSignature $exename).signercertificate.subject

if ($sert -eq "CN=Wen Jia Liu, O=Wen Jia Liu, L=Sydney, S=New South Wales, C=AU") {stop-process $_}

}

This code can be run locally or remotely and can also be scheduled, so it stops the process not once.

 If we assume mainly a single user uses a machine, then we can find their profile folder size using the folllowing code:

 

Reporting the User Profile Folder Size

$profilsize=Get-ChildItem $env:userprofile -recurse | Measure-Object -property length -sum
$profilsize=$profilsize/1GB

$Info=$env:computername+" "+$env:username+" "+(($profilsize).sum).tostring()
$info | out-file \\servername\ortak\list.txt -append

This code must be run as a logon script.

So, when a user logons to their machine, profile size is reported to a file in a share.

Displaying Bitcoin Value from coinmarketcap.com

The following code retrieves the value of Bitcoin in US Dollars and and displays the value as a message box:

$Google = Invoke-WebRequest -Uri https://coinmarketcap.com/currencies/bitcoin/ -UseBasicParsing

$Content = ($Google.Content).ToString()

$FindPriceLeft = $Content.IndexOf(data-usd=)

$PriceTop = $Content.Substring($FindPriceLeft+10,7)

write-host "One bitcoin=$",$pricetop

$BitcoinValue="One Bitcoin=$"+$pricetop

$wshell = New-Object -ComObject Wscript.Shell

$wshell.Popup($BitcoinValue,0,"Bitcoin",0x1)