Search

Recently, I got an excellent chance to put my money where my mouth is.

In the past, I’ve warned Windows shops to use unique local Administrator passwords wherever possible.  I’ve even proven the dangers of using the same local Administrator password during a penetration test in 2007.   Combine this with the fact that  I rarely have anything polite to say about VBscript (it’s not a pretty language to work with), and we have the perfect karmic storm.

Yours truly, coding in VBscript, tasked with setting a unique, strong passwords on each one of a few hundred machines.   Here’s what I came up with:

' ChangeLocalAdminOnServers.vbs
' Created by Irving Popovetsky (irving@prostructure)
' 12/15/2008, ProStructure Consulting
'
' Warning:  This script will begin changing passwords as soon
' as it collects a complete list of machine names.
'
' Read and understand this code carefully before executing,
' and always remember to fill in your own variables where appropriate.
' We assume no liability for damages that may be caused by running
' this code in your production environment!!

On Error Resume Next

Dim fso, MyFile
Set fso = CreateObject("Scripting.FileSystemObject")

' ***CHANGEME*** Change the output file to a location you trust, like an
' Encrypted folder or USB stick that can be stored away
' In the future, this could be improved to output directly to PGP or equivalent.
Set MyFile = fso.CreateTextFile("c:\Temp\Changedservers.txt", True)

Const ADS_SCOPE_SUBTREE = 2

Set objConnection = CreateObject("ADODB.Connection")
Set objCommand =   CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand.ActiveConnection = objConnection

objCommand.Properties("Page Size") = 1000
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE 

' ***CHANGEME*** Fill in your own Domain name here
objCommand.CommandText = _
    "SELECT Name FROM 'LDAP://dc=DOMAIN,dc=INTERNAL' WHERE objectCategory='computer'"
Set objRecordSet = objCommand.Execute

objRecordSet.MoveFirst

Do Until objRecordSet.EOF
    strComputer = objRecordSet.Fields("Name").Value

	' ***CHANGEME*** Skip the Domain Controllers  - fill in your own values here
	if Instr(1,strComputer, "DOMAINCONTROLLER1") Then objRecordSet.MoveNext
	if Instr(1,strComputer, "DOMAINCONTROLLER2") Then objRecordSet.MoveNext
	if Instr(1,strComputer, "DOMAINCONTROLLER3") Then objRecordSet.MoveNext

	' Irving - Random password
	Dim intUpperLimit, intLowerLimit, strPassword
	strPassword = ""
	intUpperLimit = 126
	intLowerLimit = 33

	For i = 1 to 12
	    Randomize
	    intASCIIValue = Int(((intUpperLimit - intLowerLimit + 1) * Rnd) _
	        + intLowerLimit)
	    strPassword = strPassword & Chr(intASCIIValue)
	Next

	'  Perform the Action.  Write out the computername/password then execute
	MyFile.WriteLine(strComputer & "   " & strPassword)
	Set objUser = GetObject("WinNT://" & strComputer & "/Administrator")
	objUser.SetPassword strPassword

    objRecordSet.MoveNext
Loop

MyFile.Close

Credits to The Scripting Guy’s article on scripting the change of the local administrator password. Very funny article,  I’m a big fan of the Scripting Guy.

Now, there are certainly some improvements that can be made, and WILL be made if I ever have to use this thing again.   First off, the ability to define the output location and LDAP search path.   Second, automatically determining if a server is a domain controller and skipping it.  You DEFINITELY DO NOT want this script hitting a Domain Controller, because it will change the Domain’s Administrator account, and that can be a bad thing.  Trust me, I already learned that lesson, at least I had the password in my output file.

Something to say?