mardi 5 août 2014

Reseter le mot de passe du compte Administrateur sur un Server Core

Bonjour à tous,

Je vous propose aujourd'hui un petit tips pour reseter le mot de passe du compte administrateur sur un OS de type Server Core.

Je pense que tous le monde connait la technique utilisant sethc.exe ou utilman.exe.

Personnellement j'utilise souvent la méthode avec sethc.exe.

Ayant eu besoin récemment de reseter le mot de passe d'un compte administrateur sur un Server Core, j'ai voulu comme d'habitude utiliser cette méthode.

Premier constat, les binaires sethc.exe et utilman.exe ne sont pas présents dans une version Core ...
 

Ça commence mal mais on peut quand même essayer d'utiliser cette méthode.
 

Second constat la méthode avec sethc.exe n'est pas fonctionnelle...

On essaie cette fois avec utilman.exe:




La méthode avec utilman.exe est bien fonctionnelle.



J'irai pas plus loin, le reste de la procédure étant bien documenté.

Il n'y a rien de vraiment nouveau ici mais il ne me semble pas que la procédure était documentée pour les versions Core et on voit bien qu'il y a quelques particularités.

A très bientôt.

dimanche 3 août 2014

Powershell : Exporter les GPO contenant des Groupes Restreints

Bonjour à tous,

Je vous propose aujourd'hui  un script qui va vous permettre de récupérer les Stratégies de Groupes qui contiennent des Groupes Restreints.

Lors d'un audit Active Directory, il peut y avoir beaucoup de GPO à auditer et il est donc difficile de cibler certaines configurations de GPO, notamment celles avec des Groupes Restreints.

Le fonctionnement du script est assez simple, on récupère un rapport de GPO au format XML puis on analyse le XML pour détecter la présence de Groupes Restreints et on exporte la configuration. 

Le script permet soit de retourner un tableau contenant les GPO avec la configuration des Groupes Restreints  :


Soit d'exporter le rapport dans le format souhaité (XML ou HTML) :


Le résultat :



Voici le code  :



[CmdletBinding(DefaultParameterSetName="Default")]

Param(
    [Parameter(Mandatory=$true,Position=1,ParameterSetName="Report")]
    [String]$ReportFolder,

    [Parameter(Mandatory=$true,Position=2,ParameterSetName="Report")]
    [ValidateSet("XML","HTML")]
    [String]$ReportType
    )

Try { Import-Module GroupPolicy |Out-Null}
Catch { Write-Warning "Cannot load GroupPolicy module."; Break }

If($psCmdlet.ParameterSetName -eq "Report"){
    If(!(Test-Path $ReportFolder)){
        Write-Warning "The Report folder doesn't exist or isn't available."
        Break
        }

    If($ReportFolder.chars(($ReportFolder.Length -1)) -ne "\"){
       $ReportFolder = $ReportFolder + "\"
        }
}

$AllGPO = Get-GPO -All
$TabAllRestrictedGroupsPolicies = @()

$AllGPO | foreach {
   
    [XML] $XMLReport = Get-GPOReport -Guid $_.Id -ReportType XML
    $RestrictedGroups = $null
    $RestrictedGroups = $XMLReport.DocumentElement.Computer.ExtensionData.Extension.ChildNodes|Where{$_.name -match "RestrictedGroups"}
    If ($RestrictedGroups -ne $null){
        $TabRestrictedGroups = @()
        $RestrictedGroups | foreach {
            $obj = New-Object psobject
            Add-Member -InputObject $obj -type NoteProperty -Name GroupName -Value $_.GroupName.Name.InnerText
            Add-Member -InputObject $obj -type NoteProperty -Name MemberOf -Value $_.MemberOf.Name.InnerText
            Add-Member -InputObject $obj -type NoteProperty -Name Members -Value $_.Member.Name.InnerText
            $TabRestrictedGroups += $obj
            }
        $GPO = New-Object psobject
        Add-Member -InputObject $GPO -type NoteProperty -Name Name -Value $XMLReport.DocumentElement.Name
        Add-Member -InputObject $GPO -type NoteProperty -Name GUID -Value $XMLReport.DocumentElement.Identifier.Identifier.InnerText
        Add-Member -InputObject $GPO -type NoteProperty -Name RestrictedGroups -Value $TabRestrictedGroups
        $TabAllRestrictedGroupsPolicies += $GPO
        }
    }

If($TabAllRestrictedGroupsPolicies.count -eq 0){
    Write-Host "No Group Policy has been found with Restricted Groups configuration"
    Break
    }

Switch ($psCmdlet.ParameterSetName) {
    "Report"  {
        Write-Host "Exporting GPO Reports"
        $TabAllRestrictedGroupsPolicies|Foreach{
            Get-GPOReport -Guid $_.GUID -ReportType $ReportType -Path ($ReportFolder + $_.Name + "." + $ReportType)
            }  
        }
    "Default" {
        Return $TabAllRestrictedGroupsPolicies
        }
    }



Le script peut être une base pour récupérer d'autres paramètres de GPO (Security Options, User Rights Assignement, ...)

A très bientôt

Comment déléguer : Sécuriser l'implémentation de votre modèle de délégation

Bonjour à tous,

Je vous propose aujourd'hui un article sur la sécurisation de votre modèle de délégation.

En effet, il m'arrive souvent de voir des environnements où de la délégation d'administration a été mise en place  mais n'a pas été sécurisée.
Les cas les plus fréquents étant les comptes d'administration présents dans la même OU que les utilisateurs standards et même chose pour les groupes du modèle de délégation.

Le risque est relativement simple à comprendre. Si vous avez par exemple délégué ne serai-ce que la réinitialisation de mot de passe à une population type Service Desk sur l'OU des utilisateurs. Rien ne les empêche de réinitialiser le mot de passe d'un compte d'administration qui est présent dans la même OU puis d'utiliser ce compte.
Pareil pour les groupes, si vous déléguez la gestion du membership sur une OU contenant des groupes et que vos groupes de délégation sont dans cette OU, un utilisateur ayant cette délégation peut s'ajouter dans un groupe de délégation pour faire une élévation de privilège.

On peut aller plus loin. Le simple fait de pouvoir savoir quels sont les comptes d'administration et quels sont les groupes et leurs membres présente un risque puisque avec ces informations une attaque sera plus ciblée.

Le constat est simple, les comptes, groupes et postes à privilèges doivent être isolés.

Microsoft propose l'exemple suivant dans le guide de sécurité inclus avec Security Compliance Manager :



Nous allons voir comment automatiser la création de cette structure d'OU en suivant ce modèle (qui peut-être discutable et pas adapté à votre infrastructure).

On commence d'abord par récupérer les informations sur le domaine Active Directory qui nous seront utiles pour la suite du script :


On créé ensuite notre structure d'OU :


On peut vérifier la création :



Ensuite on créé nos groupes du modèle de délégation (dans le cas où ils n'existent pas).
Je créé ici uniquement un groupe qui me permettra d'administrer cette  arborescence d'OU et les objets qu'elle contient. Normalement je devrais créer tous les groupes de mon modèle de délégation.



Maintenant je vais supprimer les ACL existantes sur mes OU et je vais désactiver l'héritage :


On peut vérifier dans la console ADUC :


L'OU Service Admins n'est plus "visible" (Un article sur la visibilité des objets AD est prévu).
Si on vérifie les droits sur l'OU, on voit bien qu'il n'y a plus d'ACL et que l'héritage est désactivé.

  
Etant le propriétaire de l'objet, je peux toujours modifier les permissions.

Je crée ensuite les ACE correspondantes au modèle :


J'utilise les SID et non les noms des groupes dans mes ACE. Avec le SID on est sûr de positionner le bon groupe et non un groupe qui aurait pu être renommé.

On peut maintenant appliquer les ACE que l'on vient de créer :


Ce n'est pas prévu dans le modèle de Microsoft mais on peut reconfigurer la protection contre la suppression accidentelle sur les OU:


Et on peut finir par déplacer dans la structure les groupes à privilèges :


Je ne l'ai pas fait ici mais on pourrait aussi configurer les SACL sur cette structure d'OU.

Il ne reste plus qu'à déplacer les comptes d'administration et les postes d'administration dans les OU.

Voici le code que j'ai utilisé pour faire cette implémentation, il faudra bien évidemment l'adapter au contexte et aux besoins :


Import-Module ActiveDirectory

### Getting Domain Informations
$Domain = Get-ADDomain
$DomainBaseDN = ($Domain).DistinguishedName
$DomainSID = $Domain.DomainSID.Value
$RootDSE = Get-ADRootDSE

### Getting Class And Attribute GUID
$GuidMap = @{}
Get-ADObject -SearchBase ($RootDSE.SchemaNamingContext) -LDAPFilter "(schemaidguid=*)" -Properties lDAPDisplayName,schemaIDGUID |% {
    $GuidMap[$_.lDAPDisplayName]=[System.GUID]$_.schemaIDGUID
    }

### Getting Extended Rights GUID
$ExtendedRightsMap = @{}
Get-ADObject -SearchBase ($RootDSE.ConfigurationNamingContext) -LDAPFilter "(&(objectclass=controlAccessRight)(rightsguid=*))" -Properties displayName,rightsGuid | % {
    $ExtendedRightsMap[$_.displayName]=[System.GUID]$_.rightsGuid
    }

### Create OU Structure
$ServiceAdminsOU = New-ADOrganizationalUnit -Name "Service Admins" -Path $DomainBaseDN -PassThru
$UsersAndGroupsOU = New-ADOrganizationalUnit -Name "Users And Groups" -Path $ServiceAdminsOU.DistinguishedName -PassThru
$AdminWorkstationsOU = New-ADOrganizationalUnit -Name "Admin Workstations" -Path $ServiceAdminsOU.DistinguishedName -PassThru

### Create Delegation Groups
$GroupADServiceAdmins = New-ADGroup -GroupCategory Security -GroupScope DomainLocal -Name ("AD Service Admins") -Path $UsersAndGroupsOU.DistinguishedName -PassThru

### Removing Access Rule on Service Admins OU
Get-ADOrganizationalUnit -Filter * -SearchBase $ServiceAdminsOU.DistinguishedName|%{
    $ACLOU = Get-Acl ("AD:\" + $_)
    $ACLOU.Access|%{$ACLOU.RemoveAccessRule($_)|out-null}
    $ACLOU|Set-Acl -Path ("AD:\" + $_)
    }

### Removing inheritance on Service Admins OU
$ACLAdmOU = Get-Acl ("AD:\" + $ServiceAdminsOU.DistinguishedName)
$ACLAdmOU.SetAccessRuleProtection($true,$false)
$ACLAdmOU | Set-Acl -Path ("AD:\" + $ServiceAdminsOU.DistinguishedName)

### Creating Access Rule for Administrators
[System.Security.Principal.SecurityIdentifier] $SID = "S-1-5-32-544"
[System.DirectoryServices.ActiveDirectoryRights] $ADRights = "GenericAll"
[System.Security.AccessControl.AccessControlType] $AccCtrlType = "Allow"
[System.DirectoryServices.ActiveDirectorySecurityInheritance] $SecInherit = "All"
$ACE01 = New-Object -TypeName System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList $SID,$ADRights,$AccCtrlType,$SecInherit

### Creating Access Rule for Domain Admins
[System.Security.Principal.SecurityIdentifier] $SID = ($DomainSID + "-512")
[System.DirectoryServices.ActiveDirectoryRights] $ADRights = "GenericAll"
[System.Security.AccessControl.AccessControlType] $AccCtrlType = "Allow"
[System.DirectoryServices.ActiveDirectorySecurityInheritance] $SecInherit = "All"
$ACE02 = New-Object -TypeName System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList $SID,$ADRights,$AccCtrlType,$SecInherit

### Creating Access Rule for Enterprise Admins
[System.Security.Principal.SecurityIdentifier] $SID =  ($DomainSID + "-519")
[System.DirectoryServices.ActiveDirectoryRights] $ADRights = "GenericAll"
[System.Security.AccessControl.AccessControlType] $AccCtrlType = "Allow"
[System.DirectoryServices.ActiveDirectorySecurityInheritance] $SecInherit = "All"
$ACE03 = New-Object -TypeName System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList $SID,$ADRights,$AccCtrlType,$SecInherit

### Creating Access Rule for Pre-Windows 2000 Compatible Access
[System.Security.Principal.SecurityIdentifier] $SID = ("S-1-5-32-554")
[System.DirectoryServices.ActiveDirectoryRights] $ADRights = "GenericRead,ListObject"
[System.Security.AccessControl.AccessControlType] $AccCtrlType = "Allow"
[System.DirectoryServices.ActiveDirectorySecurityInheritance] $SecInherit = "Descendents"
[system.guid]$GUID = $GuidMap["User"]
$ACE04 = New-Object -TypeName System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList $SID,$ADRights,$AccCtrlType,$SecInherit,$GUID

### Creating Access Rule for AD Service Admins
[System.Security.Principal.SecurityIdentifier] $SID = $GroupADServiceAdmins.SID
[System.DirectoryServices.ActiveDirectoryRights] $ADRights = "GenericAll"
[System.Security.AccessControl.AccessControlType] $AccCtrlType = "Allow"
[System.DirectoryServices.ActiveDirectorySecurityInheritance] $SecInherit = "All"
$ACE05 = New-Object -TypeName System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList $SID,$ADRights,$AccCtrlType,$SecInherit

### Setting Access Rules
$ObjectDN = $ServiceAdminsOU.DistinguishedName

### Applying new Access Rules
$ACL = Get-Acl ("AD:\" + $ObjectDN)
$ACL.AddAccessRule($ACE01)
$ACL.AddAccessRule($ACE02)
$ACL.AddAccessRule($ACE03)
$ACL.AddAccessRule($ACE04)
$ACL.AddAccessRule($ACE05)
$ACL|Set-ACL -Path ("AD:\" + $ObjectDN)


### Protect OU from Accidental Deletion
Set-ADOrganizationalUnit $ServiceAdminsOU.DistinguishedName -ProtectedFromAccidentalDeletion $true
Set-ADOrganizationalUnit $UsersAndGroupsOU.DistinguishedName -ProtectedFromAccidentalDeletion $true
Set-ADOrganizationalUnit $AdminWorkstationsOU.DistinguishedName -ProtectedFromAccidentalDeletion $true

### Move Highly Privileged Groups
### Move Enterprise Admins
Move-ADObject -Identity ((Get-ADGroup -Identity ($DomainSID + "-519")).DistinguishedName) -TargetPath $UsersAndGroupsOU.DistinguishedName

### Move Domain Admins
Move-ADObject -Identity ((Get-ADGroup -Identity ($DomainSID + "-512")).DistinguishedName) -TargetPath $UsersAndGroupsOU.DistinguishedName

### Move Schema Admins
Move-ADObject -Identity ((Get-ADGroup -Identity ($DomainSID + "-518")).DistinguishedName) -TargetPath $UsersAndGroupsOU.DistinguishedName

### Move Administrator Account (RID 500)
Move-ADObject -Identity ((Get-ADUser -Identity ($DomainSID + "-500")).DistinguishedName) -TargetPath $UsersAndGroupsOU.DistinguishedName



A très bientôt.