Octroi de droits à un compte sur un service grâce à subinacl

En recherchant un moyen d’accorder les droits de démarrage / arrêt sur un service particulier pour un compte d’utilisateur standard, je suis tombé sur cet article sur Serverfault. Le but était d’éviter d’accorder des privilèges d’administration à l’utilisateur en question.

Il existe donc un outil nommé SubInACL, qui fait partie du Windows Resource Kit (aux côtés de nombreux autres outils que je connaissais comme LockOutStatus). Cet outil qui s’exécute en ligne de commande permet de choisir précisément quels privilèges accorder sur un service pour un utilisateur, qu’il soit local ou du domaine.

J’ai testé cet outil sur un serveur de test en 2008 R2 et appliqué le fonctionnement sur un 2016 ; son exécution est très simple. Microsoft explique toute la syntaxe disponible à ce lien. Si je souhaite accorder à l’utilisateur dschrute le droit de voir l’état et de relancer le service NTP, je vais devoir envoyer cette instruction :

subinacl.exe /service w32time /GRANT=DUNDERMIFFLIN\dschrute=STO

Voici sur un Server 2016, le résultat de la commande pour le service Windows Update :

Si SubInACL n’est plus disponible sur le site de Microsoft, il est disponible en téléchargement sur le miroir du blog à ce lien.

Utilisation de Get-ACL sur une arborescence ActiveDirectory

Cet article fait plus ou moins écho à celui d’hier où j’explique comment accorder des droits spécifiques à un utilisateur ou un groupe sur une OU ActiveDirectory. Get-ACL est une instruction Powershell permettant de retourner les permissions d’un fichier, répertoire ou même clef de registre. Par défaut, Get-ACL ne permet pas de retourner les autorisations d’un objet ActiveDirectory, mais il existe une technique de sioux permettant d’utiliser cette instruction sur un AD.

Sur une station ayant les RSAT d’installés ou bien directement sur un contrôleur de domaine, il suffit d’importer le module AD pour Powershell :

Import-Module ActiveDirectory

Ensuite, se placer dans l’arborescence AD :

Set-Location AD:

Un simple dir permet de retourner des informations nous confirmant que nous sommes bien dans l’AD.

Lancer un Get-ACL à la racine de AD: n’aura aucun effet. Il est tout de même nécessaire d’indiquer un chemin à la commande ; on utilisera alors le DistingushedName. Par exemple, pour récupérer l’intégralité des permissions à la racine du domaine (attention, ce n’est pas récursif !) :

(Get-Acl (Get-ADDomain).DistinguishedName).Access

Ainsi, il est possible de se concocter un petit snippet si l’on souhaite parcourir tout l’AD à la recherche de privilèges accordés à un groupe ou à un utilisateur sur des OU, par exemple :

Import-Module ActiveDirectory
Set-Location AD:
$oulist = Get-ADOrganizationalUnit -Filter * | select DistinguishedName
foreach($ou in $oulist){
$privileges = (Get-Acl $ou.DistinguishedName).Access | Where-Object { $_.IdentityReference -eq "DUNDERMIFFLIN\gclooney" }
if($privileges -ne $null) { Write-Host "OU:"$ou.DistinguishedName ; $privileges }
}

Par exemple, ayant accordé les droits à l’utilisateur gclooney sur l’OU End-Users, il récupère par héritage ces mêmes privilèges sur les 3 OU enfant.

Cela se vérifie avec le snippet plus haut :

Ce code peut naturellement être modifié pour interroger des groupes ou des utilisateurs. Par exemple, je vais octroyer des droits au groupe US-Presidents sur le groupe Actors. La capture suivante montre bien que le droit WriteProperty a été attribué.

En jouant sur la clause Where-Object de ce snippet, on peut modifier le filtre de recherche. Par exemple, afin rechercher tous les utilisateurs ayant le droit WriteProperty sur un objet défini, il suffit de modifier le snippet :

$grplist = Get-ADgroup -Identity "Actors" | select DistinguishedName
$privileges = (Get-Acl $grp.DistinguishedName).Access | Where-Object { $_.ActiveDirectoryRights -like "*WriteProperty*" }

Au final, la seule limite de Get-Acl et du code que l’on adapte autour, ce sont les informations que l’on souhaite récupérer et les actions éventuelles à mener pour cadrer au mieux les privilèges attribués au fil du temps !

Octroi de droits à un utilisateur spécifique sur une OU

Récemment, j’ai dû implémenter une tâche planifiée exécutant des scripts Powershell – vulgairement appelés moulinettes – de manière assez régulière pour automatiser et palier à de possibles oublis humains. Cette tâche s’exécute avec un compte de service ; seulement ce compte de service doit pouvoir modifier des groupes ActiveDirectory. Par défaut, un compte fraîchement créé ne dispose pas de tels privilèges. Il a donc fallu que j’accorde les droits à ce compte de service pour qu’il puisse écrire sur les objets présents dans une OU spécifique. A noter que la procédure ci-dessous – quasi-similaire à l’octroi de droits sur un répertoire NTFS tout simple – fonctionne pour la très grande majorité des objets ActiveDirectory.

La console ActiveDirectory, pouvant s’appeler avec dsa.msc doit avoir les fonctionnalités avancées d’activées : View > Advanced Features.

Ensuite, se rendre sur l’OU en question, puis ouvrir les propriétés de celle-ci. Les fonctionnalités avancées débloquent l’onglet Security. Cet onglet affiche les entités ayant des privilèges particuliers sur l’OU. En cliquant sur Advanced, une fenêtre apparaît.

Les diverses autorisations ou interdictions sont listées ; il est possible de faire un test avec un compte d’utilisateur dans Effective Access pour vérifier que ce dernier a bien le droit – ou non – d’effectuer certaines opérations sur cette OU.

Add ouvre une nouvelle fenêtre qui demandera de saisir un compte ; je vais donc saisir mon compte de service, puis lui accorder le privilège d’écriture (encadré en bleu).

Par défaut, le compte de service a le droit de lire les propriétés de l’OU ainsi que la parcourir. En ajoutant le droit d’écriture, j’autorise le compte à modifier les objets présents dans l’OU car l’octroi concerne cette OU et ce qu’elle contient (paramètre encadré en vert).

Une simple exécution de test de la tâche planifiée a confirmé le bon fonctionnement de l’accord des privilèges.