salut à tous
J’ai récemment travaillé sur une solution pour changer périodiquement le compte administrateur pré-défini sur des stations de travail Windows XP Pro / Windows Seven.
Le cachier des charges précisait :
– Que le mot de passe du compte administrateur pré-défini devait changer tous les 90 jours.
– Que le mot de passe devait être stocké sur un partage non accessible en lecture aux utilisateurs.
– Que le mot de passe devait respecter certaines contraintes en terme de tailles, nombre de familles de caractères (majuscules, minuscules, chiffres, caractères spéciaux).
– Prendre en charge le fait que le compte administrateur intégré changerait de nom selon la langue de l’OS ou pouvait avoir été renommé (“administrator” pour une version Windows anglaise, “administrateur” pour une version française).
La solution proposée ci dessous est basée sur deux scripts.
– ADMINISTRATORPASSWORD.CSV
– GENERATECSV.VBS
1 LE SCRIPT ADMINISTRATORPASSWORD.vbs :
1.1 PRESENTATION GENERALE :
Ce script permet de
– Générer le mot de passe selon les contraintes (nombre de majuscules, minuscules, caractères spéciaux…)
– Déterminer si cela fait plus de 90 jours que le mot de passe a été changé.
– Modifier le mot de passe sur la station de travail.
– Ecrire un fichier texte contenant le nom de la machine, le nom du compte administrateur pré-intégré et le mot de passe.
1.2 CONTRAINTES ET PROBLEMATIQUES DE LA SOLUTION :
– Tous les stations de travail doivent pouvoir accéder aux partages de fichiers de ces deux serveurs.
– Toutes les stations de travail doivent être membres d’un domaine Active Directory.
– Chaque station de travail doit pouvoir écrire le fichier texte contenant le mot de passe sans permettre aux utilisateurs d’accéder à tous les fichiers texte stockés sur le partage.
-La solution exige deux serveurs : un serveur hébergeant le partage où sont stockés les fichiers texte contenant le mot de passe et un serveur hébergeant les fichiers de logs d’erreurs en cas de problème lors de l’exécution du script.
1.3 SECURISATION DU REPERTOIRE CONTENANT LES FICHIERS AVEC MOTS DE PASSE :
Le script ADMINISTRATORPASSWORD.CSV s’exécute via un script de démarrage (GPO de type “Configuration Ordinateur”). Il s’exécute donc dans le contexte du compte SYSTEM (droit administrateur sur la station de travail).
La première étape consiste à créer le répertoire E:\logs et le partager en tant que logs$. Définir « Control Total » pour « Tout le monde » au niveau des permissions de partage.
Au niveau des permissions NTFS, supprimer l’héritage des permissions (dans les permissions NTFS avancées). Donner les droits “Contrôl Tôtal” à Administrators, SYSTEM, GRP_PASSWORD Viewer (groupe contenant les utilisateurs qui peuvent voir les fichiers avec les mots de passe).
Il faut ensuite ajouter des permissions spéciales pour le groupe “Authenticated users”
Créer une permissions NTFS personnalisée pour le groupe “Authenticated users”. Aller dans les permissions NTFS avancées. Sélectionner “Apply to this folder and subfolders”. Sélectionner le permissions suivantes :
– Traverse folder / execute file
– List folder / Read data
– Read attributes
– Read extended attributes
– Create files / write data
– Read permissions
Créer une seconde entrée au niveau des permissions NTFS avancées. Sélectionner “Apply to Files only“. Sélectionner le permissions suivantes :
– Read attributes
– Read extented attributes
– Create files / write data
– Create folders / append data
– Write attributes
– write extended attributes
– Delete
– Read permissions
Ne surtout pas cocher la case “List Folder / read data“.
Tester l’accès avec un compte utilisateur.
Ce dernier peut copier un fichier existant, le renommer, le supprimer mais ne peut pas le lire ou le copier depuis le serveur vers sa station de travail.
On est obligé de donner le droit de supprimer dans le cas où le compte ordinateur est supprimé. C’est en effet le compte ordinateur qui est propriétaire du fichier.
1.4 CODE DU SCRIPT ADMINISTRATORPASSWORD.CSV :
‘ More informations about RND function : http://www.w3schools.com/vbscript/func_rnd.asp
‘ More informations about ACSII code : http://www.commentcamarche.net/contents/base/ascii.php3
‘ More informations about error management : http://technet.microsoft.com/en-us/library/ee176982.aspx and http://technet.microsoft.com/en-us/library/ee692852.aspx
‘ More informations about the date : http://www.commentcamarche.net/contents/vbscript/vbs-fonctions-date.php3
‘ More information about permission NTFS : http://support.microsoft.com/kb/308419/en-us
On error resume next
strComputer = “.”
Dim text,action,digits
text = “”
‘VARIABLES TO DEFINE
serverpasswordname = “nom_serveur.domaine.dns” ‘ Server which store password files. Exemple : srv1.msreport.free.fr
serverlogname = “nom_serveur.domaine.dns” ‘ Server whuch store errors log files. Exemple : srv1.msreport.free.fr
periodTime = “7776000” ‘ Time before password expiration in seconds (7776000 = 90 days)
digits = 9 ‘ Lengh of the password
‘ MAIN
‘ Verify if the password must change on the computer
action = NeedChange()
if action = 1 then
‘ Determin the name of the administrator account (administrateur in french).
accounttomodify = AdministratorName()
‘ Generate the password
password = GeneratePassword(digits)
‘ Define the new password on the computer.
Set objUser = getobject(“WinNT://” & strComputer & “/” & accounttomodify & “,User”)
If Err <> 0 Then
WriteError(“N.A.;N.A.;No administrator account.”)
Err.Clear
else
objUser.SetPassword password
objUser.SetInfo
if Err <> 0 Then
WriteError(“N.A.;N.A.;Update of administrator fail.”)
Err.Clear
else
‘ Write the password on a file on server and write the witness file on the computer
text = accounttomodify + “;” + password
Writepasswordfile(text)
if Err = 0 then
Writewitness(now)
else
WriteError(“Unable to connect to the server !”)
End if
End if
End If
else
‘ if the password has been changed since lower than 30 days, the script takes no actions.
wscript.quit
End If
Function NeedChange()
On error resume next
‘ Script change password once every periodtime (variable). The script write a log on the computer in C:\Windows\passwordchange.txt that contains the day of the last change of the password
‘ Verify if the file exist on the station
Set objFSO = CreateObject(“Scripting.FileSystemObject”)
‘ if the file exists, we need to read it and verify the date.
If objFSO.FileExists (“C:\Windows\passwordchange.txt”) then
‘ Read the date on file C:\Windows\passwordchange.txt
dim sFileContents
dim lastchangetime
Set oTextStream = objFSO.OpenTextFile(“C:\Windows\passwordchange.txt”,1)
lastchangetime = cdate(oTextStream.ReadAll)
oTextStream.Close
‘wscript.echo “PeriodTime : ” & periodtime
‘wscript.echo ” Date du fichier : ” & lastchangetime
‘wscript.echo “Date actuelle : ” & now
‘wscript.echo “Différence de temps : ” & DateDiff(“s”,lastchangetime,now)
‘ If the file is corrupted, password must be changed.
if err <> 0 then
NeedChange = 1
Err.Clear
‘if the diffrence between the two date is greater than periodTime, we need to change the password.
elseif CDbl(DateDiff(“s”,lastchangetime,now)) > CDbl(periodTime) then
NeedChange = 1
‘wscript.echo “NeedChange : ” & NeedChange
‘ Other case, do nothing.
elseif CDbl(DateDiff(“s”,lastchangetime,now)) < 0 then
NeedChange = 1
else
NeedChange = 0
‘wscript.echo “NeedChange : ” & NeedChange
End If
‘ if the file doesn’t exist, change the password
else
NeedChange = 1
End if
End Function
‘ Function to generate password
Function GeneratePassword(digits)
Dim passwordtemp
passwordtemp = “”
Dim w
Dim i
Dim digit1, digit2, digit3
‘ Code to generate password with uppercases (A…Z), lowercases (a…z) and numbers (2…9) without 0, O,o I, l
For i = 1 To Digits
‘ The function randomize permit to change the result of the RND function
‘ The first caracters is an uppercase
digit1 = “”
digit2 = “”
digit3 = “”
if i = 1 then
Randomize
digit1 = chr(65 + INT(RND * 25))
‘ The ACSII value 79 is O and the ACSII code 73 is I
if (digit1 = chr(79)) OR (digit1 = chr(73)) then
digit1 = chr(80 + INT(RND * 10))
End if
passwordtemp = passwordtemp + digit1
elseif i = 2 then
Randomize
digit2 = chr(97 + INT(RND * 25))
‘ The ACSII value 108 is l
if (digit2 = chr(108)) OR (digit2 = chr(111)) then
digit2 = chr(112 + INT(RND * 10))
End if
passwordtemp = passwordtemp + digit2
elseif i = digits then
Randomize
‘ The ACSII value 48 is 0 and isn’t in the range.
passwordtemp = passwordtemp + chr(50 + INT(RND * 7))
else
Randomize
w = 1 + INT(RND * 4)
‘wscript.echo “value w : ” & w
If W = 1 Then
Randomize
digit1 = chr(65 + INT(RND * 25))
‘ The ACSII value 79 is O and the ACSII code 73 is I
if (digit1 = chr(79)) OR (digit1 = chr(73)) then
digit1 = chr(80 + INT(RND * 10))
End if
passwordtemp = passwordtemp + digit1
ElseIf W = 2 Then
Randomize
digit2 = chr(97 + INT(RND * 25))
‘ The ACSII value 108 is l
if (digit2 = chr(108)) OR (digit2 = chr(111)) then
digit2 = chr(112 + INT(RND * 10))
End if
passwordtemp = passwordtemp + digit2
Elseif w = 3 Then
Randomize
choice = INT(RND * 5)
‘wscript.echo “Choice : ” & choice
‘ Value ACSII : # = 35 $ = 36 * = 42 + = 43 @ = 64
if choice = 0 then
digit3 = chr(35)
elseif choice = 1 then
digit3 = chr(36)
elseif choice = 2 then
digit3 = chr(42)
elseif choice = 3 then
digit3 = chr(43)
else
digit3 = chr(64)
End if
passwordtemp = passwordtemp + digit3
Else
Randomize
‘ The ACSII value 48 is 0, 49 is 1 and isn’t in the range.
passwordtemp = passwordtemp + chr(50 + INT(RND * 7))
End If
End if
‘wscript.echo “Valeur de I : ” & i
Next
GeneratePassword = passwordtemp
End Function
‘ Function to create file with password on the share
Function Writepasswordfile(text)
‘Find the name of the workstation and create file result on server
Set WshNetwork = WScript.CreateObject(“WScript.Network”)
StationName = WshNetwork.ComputerName
resufile = “\\” & serverpasswordname & “\logs$\” & StationName & “.txt”
‘wscript.echo “Fichier mot de passe : ” & resufile
Dim objFSO,objFile
Set objFSO = CreateObject(“Scripting.FileSystemObject”)
Set objFile = objFSO.CreateTextFile(resufile)
‘ Write the date in french format.
objFile.WriteLine StationName & “;” & text & “;” & Day(now) & “/” & Month(now) & “/” & Year(now)
objFile.Close
End Function
Function WriteError(text)
‘Find the name of the workstation and create file result on server
Set WshNetwork = WScript.CreateObject(“WScript.Network”)
StationName = WshNetwork.ComputerName
resufile = “\\” & serverlogname & “\logs$\Error-” & StationName & “.txt”
‘wscript.echo “Fichier mot de passe : ” & resufile
Dim objFSO,objFile
Set objFSO = CreateObject(“Scripting.FileSystemObject”)
Set objFile = objFSO.CreateTextFile(resufile)
objFile.WriteLine StationName & “;” & text
objFile.Close
End Function
Function Writewitness(dateofchangepassword)
resufile = “C:\Windows\passwordchange.txt”
Dim objFSO,objFile
Set objFSO = CreateObject(“Scripting.FileSystemObject”)
Set objFile = objFSO.CreateTextFile(resufile)
objFile.WriteLine dateofchangepassword
objFile.Close
End Function
Function AdministratorName()
‘ Permit to find the name of the BUILTIN administrator account on the computer. This account have a sid which begin by the following strings S-1-5- and which finish by the following strings “-500”.
Set objWMIService = GetObject(“winmgmts:\\” & strComputer & “\root\cimv2”)
Set colAccounts = objWMIService.ExecQuery _
(“Select * From Win32_UserAccount Where LocalAccount = TRUE”)
For Each objAccount in colAccounts
If Left (objAccount.SID, 6) = “S-1-5-” and Right(objAccount.SID, 4) = “-500” Then
AdministratorName = objAccount.Name
End If
Next
End Function
2. LE SCRIPT GENERATECSV.VBS :
2.1 PRESENTATION GENERALE :
Ce script permet de générer un fichier CSV à partir de tous les fichiers textes contenant les mots de passe.
On ne peut pas écrire directement dans le fichier CSV depuis les stations de travail du fait du risque de corruption de données si deux machines changent de mots de passe en même temps. Il faudrait une base de données.
2.2 MISE EN OEUVRE :
Configurer une tâche planifiée sur le serveur où sont stockés les fichiers avec les mots de passe pour créer le fichier CSV contenant tous mots de passe toutes les 10 minutes.
2.3 CODE DU SCRIPT GENERATECSV.VBS :
‘ More information at http://www.computerperformance.co.uk/vbscript/vbscript_file_opentextfile.htm
‘ More information at http://www.devguru.com/technologies/vbscript/quickref/textstream_readall.html
on error resume next
‘ VARIABLES TO DEFINE :
Dim passwordfileshare
Dim targetcsvfile
passwordfileshare = “\\nom_serveurs_partage_password_files\logs$\”
targetcsvfile = “\\nom_serveurs_partage_password_files\logs$\csv\”
csvfile = “\\nom_serveurs_partage_password_files\logs$\csv\resultats\userspassword.csv”
resultfolder = “\\nom_serveurs_partage_password_files\logs$\csv\resultats\“
‘ MAIN
‘ Copy all file from passwordfileshare to targetcsvfile
copypasswordfiles()
‘ Generate the CSV file
GenerateCSV()
Function copypasswordfiles()
Dim FSO
Dim FileExt
FileExt = “*.txt”
Set FSO = CreateObject(“scripting.filesystemobject”)
‘ ADD “\” if the folder name doesn’t finish by this caracters.
If Right(passwordfileshare, 1) <> “\” Then
passwordfileshare = passwordfileshare & “\”
End If
‘ Verify if the folder to result exist
If FSO.FolderExists(passwordfileshare) = False Then
wscript.quit(1)
End if
if FSO.folderExists(targetcsvfile) = False Then
FSO.CreateFolder(targetcsvfile)
FSO.CopyFile passwordfileshare & FileExt, targetcsvfile
else
FSO.CopyFile passwordfileshare & FileExt, targetcsvfile
End if
End function
Function GenerateCSV()
Dim fso, folder, files, NewsFile
Set fso = CreateObject(“Scripting.FileSystemObject”)
‘ Verify if the result folder exist and create it if not exist.
if FSO.folderExists(resultfolder) = False Then
FSO.CreateFolder(resultfolder)
End if
‘ List each file in targetcsvfile, copy the content of each file in csvfile
‘ Create the result file
Set NewFile = fso.CreateTextFile(csvfile, True)
‘ List the file
Set folder = fso.GetFolder(targetcsvfile)
Set files = folder.Files
‘ Write the first line of the result CSV file
NewFile.WriteLine (“Computer;Login;Password;TimeLastChange”)
For each folderIdx In files
‘ Read the fisrt line of each txt file
Set TextFile = fso.opentextfile(targetcsvfile & folderIdx.Name,1)
‘ Write a new line in csvfile
NewFile.WriteLine(TextFile.ReadLine)
Next
NewFile.Close
End function
a+
Guillaume MATHIEU
http://msreport.free.fr
PROSERVIA
Le bonheur c’est le partage.