Performance en PowerShell
Tout savoir sur l'optimisation des performances sur vos scripts PowerShell
La durée de vie des mots de passe et leur expiration en 2024, c’est un sujet compliqué.
D’un côté, nous avons les recommandations du NIST ou de l’ANSSI qui ne préconisent plus une expiration fréquente de mot de passe pour les comptes sans privilèges. De l’autre, les assurances qui demandent encore aux entreprises de définir une durée de vie maximum des mots de passe à 90 ou 180 jours. Au milieu de tout ça, il y a les utilisateurs, qui utilisent de nombreux stratagèmes pour contourner cette expiration et se faciliter la vie.
Dans Active Directory, les politiques de mot de passe (qu’elles soient des fine-grained password policy ou la politique par défaut) se basent sur les critères suivants pour définir leurs exigences :
Pour la suite de cet article, nous allons nous baser sur la politique de mot de passe suivante :
Paramètre | Valeur |
---|---|
Historique de mot de passe | 10 mots de passe |
Durée de vie maximale du mot de passe | 90 jours |
Durée de vie minimale du mot de passe | 0 jour |
Respect des exigences de complexité | Oui |
Longueur minimale du mot de passe | 10 caractères |
Sur cette méthode, l’utilisateur respecte toutes les règles définies, mais les exploite à son avantage. Comme la configuration actuelle ne définie pas d’âge minimum avant changement, l’utilisateur va changer dix fois son mot de passe (pour respecter les règles d’historique) dans la même journée pour pouvoir redéfinir le même mot de passe que précedemment.
Pour le mot de passe initial MotDePasse!
:
Changement | Heure | Mot de passe |
---|---|---|
N°1 | 8h30 | Temporaire1 |
N°2 | 8h31 | Temporaire2 |
N°3 | 8h33 | Temporaire3 |
N°4 | 8h34 | Temporaire4 |
N°5 | 8h36 | Temporaire5 |
N°6 | 8h38 | Temporaire6 |
N°7 | 8h40 | Temporaire7 |
N°8 | 8h41 | Temporaire8 |
N°9 | 8h43 | Temporaire9 |
N°10 | 8h44 | Temporaire10 |
Après avoir défini dix mots de passe temporaires en moins de 15 minutes, l’utilisateur peut maintenant redéfinir son mot de passe à sa valeur intiale MotDePasse!
et pourra le conserver pendant 90 jours.
Pour résoudre ce problème, vous pouvez augmenter l’historique de mot de passe et/ou définir une durée de vie minimum du mot de passe :
En supposant que vous ayez bien configuré l’intégralité des Audit Policy Recommendations | Microsoft Learn dans votre domaine Active Directory, vous devriez pouvoir accéder aux évenements de changement de mot de passe.
Le script suivant permet de mettre en lumière les utilisateurs qui ont changé leur mot de passe récemment :
$dc = (Get-ADDomainController).Hostname
$events = Get-WinEvent -ComputerName $dc -ProviderName 'Microsoft-Windows-Security-Auditing' | Where-Object {$_.Id -eq 4723}
$report = $events | ForEach-Object {
$message = $_.Message -split [System.Environment]::NewLine
$accounts = $message | Where-Object {$_ -like '*Account Name:*'} | ForEach-Object { ($_ -split ':' | Select-Object -Last 1).Trim() }
[PSCustomObject]@{
TimeCreated = $_.TimeCreated
PerformedBy = $accounts[0]
TargetAccount = $accounts[1]
}
}
$report | Format-Table
$report | Group-Object PerformedBy | Sort-Object Count -Descending
Voici un exemple de résultat :
TimeCreated PerformedBy TargetAccount
----------- ----------- -------------
21/09/2024 07:00:35 leob leob
21/09/2024 07:00:27 leob leob
21/09/2024 06:58:57 leob leob
21/09/2024 06:58:43 leob leob
21/09/2024 06:58:19 leob leob
21/09/2024 06:58:03 leob leob
21/09/2024 06:57:46 leob leob
Lorsqu’un administrateur réinitialise le mot de passe d’un compte, la mécanique de vérification d’historique des hashs est ignorée (et c’est un comportement normal de Active Directory).
Sauf que certains peuvent abuser de cette exception pour conserver le même mot de passe indéfiniment, en contournant l’expiration. Cela peut provenir d’un administrateur qui a des droits sur son compte, ou d’un utilisateur qui abuse de la gentillesse du support.
Évidemment cette méthode laisse des traces derrière elle. Comme Active Directory conserve les hashs de vos anciens mots de passe (pour justement qu’on évite d’utiliser plusieurs fois le même), un simple audit de la base NTDS dévoile alors la supercherie : on retrouve plusieurs fois le même hash à la suite dans l’historique !
Pour Christie Cline, on retrouve plusieurs fois de suite le hash d96b085ea5c0d101101bb0a4d846d0df
, ce qui indique un potentiel abus de cette mécanique :
DisplayName : Christie Cline
SamAccountName : christiec
NTHash : d96b085ea5c0d101101bb0a4d846d0df
NTHashHistory : {d96b085ea5c0d101101bb0a4d846d0df, d96b085ea5c0d101101bb0a4d846d0df, 5a17c70656c8056acfc3ce0591774529...}
Prefix : d96b0
IsAdministrator : False
DistinguishedName : CN=Christie Cline,OU=Users,OU=CONTOSO,DC=contoso,DC=com
Attention
Attention cependant, retrouver plusieurs fois le même hash à la suite dans l’historique n’indique pas forcément une action malicieuse. Il est possible que le mot de passe ai été réinitalisé coup-sur-coup durant la même journée (et donc sans vouloir prolonger la vie du mot de passe).
Vous pouvez faire ce genre d’audit avec le module PowerShell DSInternals de Michael Grafnetter par exemple.
L’attribut PwdLastSet
contient la date de définition du mot de passe de l’utilisateur et permet à Active Directory de savoir si un mot de passe est expiré ou non. L’idée de cet abus n’est donc pas modifier le mot de passe, mais plutôt d’agir sur la date de définition de celui-ci. Pour cela, il y a deux méthodes qui se repose sur la même mécanique.
L’attribut PwdLastSet
ne peut prendre que deux valeurs en écriture :
L’idée est donc de modifier la valeur de l’attribut pour la passer à -1, et ainsi prolonger la vie du mot de passe en un clin d’oeil.
Cette méthode est facile à réaliser car elle peut être faite depuis la console Active Directory Users and Computers (ou dsa
pour les intimes).
Il suffit de cliquer sur le profil de l’utilisateur, naviguer dans l’onglet “Account” puis de :
PwdLastSet = 0
) pour forcer l’utilisateur a le changer lors de la prochaine connexionPwdLastSet
à -1 (donc la date actuelle).…et voilà ! La durée de vie de votre mot de passe actuel a été prolongé de 90 jours.
Ici on fait appel à la commande Set-ADUser
pour modifier directement l’attribut PwdLastSet
sans passer par quatre chemins :
Set-ADUser christiec -Replace @{PwdLastSet = -1}
Ces deux méthodes ne sont pas indétectables. Ce genre d’opération génère une différence sur les données de réplication entre les contrôleurs de domaine. Comme le mot de passe (attribut unicodePwd
) ne change pas, pas besoin de le répliquer. En revanche, la nouvelle valeur de l’attribut PwdLastSet
est partagée sur tous les contrôleurs de domaine.
Il suffit alors de trouver les comptes avec une différence de date de réplication entre les attributs unicodePwd
et PwdLastSet
.
Information
Vous pouvez consulter les données de réplication d’un utilisateur avec l’attribut
msds-replattributemetadata
.
Pour trouver les fraudeurs, vous pouvez lancer Purple Knight de Semperis qui a un indicateur pour cela, ou alors utiliser mon script PowerShell : Get-ADAbnormalPasswordRefresh.ps1 | GitHub Gist.
Exemple de résultat :
Name : Christie Cline
Enabled : True
SamAccountName : christiec
PasswordLastSet : 28/08/2024 00:00:00
RealPasswordLastSet : 22/06/2024 00:00:00
TimeSpanBetweenPassword : 67
CanonicalName : contoso.com/CONTOSO/Users/Christie Cline
Méthode | Détection | Blocage |
---|---|---|
Bête et méchant | Event 4723 | Modifier la politique de mot de passe par défaut |
PasswordReset | Audit de la base NTDS | Impossible |
PasswordLastSet | Attribut msds-replattributemetadata |
Impossible |
Tout savoir sur l'optimisation des performances sur vos scripts PowerShell
Commentaires