# ADMIN\_TO

## Summary

|                            |           |
| -------------------------- | --------- |
| **FSProtect ACL Alias**    | ADMIN\_TO |
| **Affected Object Types**  | Computers |
| **Exploitation Certainty** | Certain   |

## Description

`ADMIN_TO` permission in an Active Directory environment grants an account local administrative privileges on a specific system. A user with this permission has near‑unrestricted access to the operating system and can perform many administrative tasks. For example, they can install software, change system settings, start or stop services, or modify system files. Administrators use this permission to expedite troubleshooting and to manage critical tasks, system performance, and security.

If misconfigured, the `ADMIN_TO` permission poses significant security risks. An attacker who obtains this permission could gain full control of the system, run arbitrary code, bypass security controls, and manipulate the system for malicious purposes. Such an attacker could misuse system resources, encrypt data for ransom, or deploy malware to maintain persistent access.

## Identification

### PowerShell

#### Active Directory Module

Using the ActiveDirectory PowerShell module, you can enumerate `ADMIN_TO` entries.

**1.** Find-ADMIN\_TO Function

```powershell
function Find-ADMIN_TO {
    [CmdletBinding()]
    param(  [string[]]$Target = $null,    [string]$SearchBase = $null, [string]$OutputPath = "ADMIN_TO.csv", [int]$TimeoutSec = 6 )
    Import-Module ActiveDirectory -ErrorAction Stop
    $computers = @()
    if ($Target) {
        Write-Host "Using provided target(s): $($Target -join ', ')"
        foreach ($t in $Target) {
            # If it's an IP or FQDN, use as-is; otherwise try to resolve via AD
            if ($t -match '^\d{1,3}(\.\d{1,3}){3}$' -or $t -like "*.*") {
                $computers += $t
            } else {
                try {
                    $adComp = Get-ADComputer -Identity $t -Properties dNSHostName -ErrorAction Stop
                    if ($adComp.dNSHostName) { $computers += $adComp.dNSHostName } else { $computers += $adComp.Name }
                } catch {
                    Write-Warning "Couldn't resolve '$t' from AD: $($_.Exception.Message). Using as provided."
                    $computers += $t
                }
            }
        }
        $computers = $computers | Sort-Object -Unique
    } else {
        Write-Host "Gathering computer objects from Active Directory..."
        try {
            $computers = if ($SearchBase) {
                Write-Host "Filtering computers under '$SearchBase'"
                Get-ADComputer -Filter * -SearchBase $SearchBase -ErrorAction Stop | Select-Object -ExpandProperty Name
            } else {
                Get-ADComputer -Filter * -ErrorAction Stop | Select-Object -ExpandProperty Name
            }
        } catch {
            Write-Error "Failed to retrieve computer objects: $($_.Exception.Message)"
            return
        }
    }
    if (-not $computers) {
        Write-Warning "No computers found; exiting."
        return
    }
    $results = New-Object System.Collections.Generic.List[object]
    Write-Host "Enumerating local Administrators on $($computers.Count) computers..."
    $opt = New-CimSessionOption -Protocol Dcom
    foreach ($c in $computers) {
        try {
            $sess = New-CimSession -ComputerName $c -SessionOption $opt -OperationTimeoutSec $TimeoutSec -ErrorAction Stop
            try {
                $grp = Get-CimInstance -CimSession $sess -ClassName Win32_Group -Filter "LocalAccount=TRUE AND Name='Administrators'" -ErrorAction Stop
                if (-not $grp) {
                    Write-Warning "Administrators group not found on '$c'."
                    continue
                }
                $members = Get-CimAssociatedInstance -CimSession $sess -InputObject $grp -Association Win32_GroupUser -ErrorAction Stop
                foreach ($m in $members) {
                    $memberType = if ($m.CimClass.CimClassName -eq 'Win32_Group') { 'Group' } else { 'User' }
                    $memberName = if ($m.Domain) { "$($m.Domain)\$($m.Name)" } else { $m.Name }
                    $results.Add([PSCustomObject]@{
                        ComputerName = $c
                        MemberName   = $memberName
                        MemberType   = $memberType
                    })
                }
            }
            finally { if ($sess) { $sess | Remove-CimSession -ErrorAction SilentlyContinue } }
        } catch { Write-Warning "Unable to enumerate Administrators on '$c': $($_.Exception.Message)"}
    }
    if ($results.Count -gt 0) {
        try {$results | Select-Object ComputerName, MemberName, MemberType |Sort-Object ComputerName, MemberType, MemberName | Export-Csv -Path $OutputPath -NoTypeInformation -Encoding UTF8 -ErrorAction Stop
            Write-Host "Results exported to '$OutputPath'"
        } catch { Write-Error "Failed to export to CSV: $($_.Exception.Message)"  }
    } else { Write-Output "No local administrator members found across scanned computers." }}
```

**2.** Scan all Computers in the domain

```powershell
Find-ADMIN_TO
```

**3.** Scan a specified target

```powershell
Find-ADMIN_TO -Target VM01
```

**4.** Using `SearchBase` to limit the Scope

```powershell
Find-ADMIN_TO -SearchBase "CN=Computers,DC=forestall,DC=labs"
```

#### .NET Directory Services

By leveraging PowerShell’s built-in .NET DirectoryServices namespace, you can enumerate `ADMIN_TO` entries without relying on any external modules or dependencies.

**1.** Find-ADMIN\_TOSimple function

```powershell
function Find-ADMIN_TOSimple {
    [CmdletBinding()]
    param([string]$Target,[string]$SearchBase = $null,[string]$OutputPath = "ADMIN_TO.csv",[int]$TimeoutSec = 6)
    $computers = @()
    try {
        if ($Target) {
            try {
                $de = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$Target")
                $name = $de.Properties["dNSHostName"].Value
                if (-not $name) { $name = $de.Properties["name"].Value }
                if ($name) { $computers = @($name) } else { Write-Error "Could not resolve a hostname for '$Target'."; return }
            } catch { Write-Error "Failed to bind to '$Target': $($_.Exception.Message)"; return }
        }
        else {
            $root   = New-Object System.DirectoryServices.DirectoryEntry("LDAP://RootDSE")
            $baseDN = $root.Properties["defaultNamingContext"].Value
            if ($SearchBase) { $base = "LDAP://$SearchBase" } else { $base = "LDAP://$baseDN" }
            $searchRoot = New-Object System.DirectoryServices.DirectoryEntry($base)
            $ds = New-Object System.DirectoryServices.DirectorySearcher($searchRoot)
            $ds.Filter = "(objectCategory=computer)"
            $ds.PageSize = 1000
            [void]$ds.PropertiesToLoad.Add("dNSHostName")
            [void]$ds.PropertiesToLoad.Add("name")
            $hits = $ds.FindAll()
            if ($hits.Count -eq 0) { Write-Warning "No computers found; exiting."; return }
            $computers = foreach ($h in $hits) {
                $dns = $h.Properties["dnshostname"]
                if ($dns -and $dns[0]) { $dns[0] } else { $h.Properties["name"][0] }
            }
        }
    } catch { Write-Error "LDAP enumeration failed: $($_.Exception.Message)"; return }
    $results = New-Object System.Collections.Generic.List[object]
    Write-Host "Enumerating local Administrators on $($computers.Count) computer(s)..."
    foreach ($c in $computers) {
        try {
            $opt  = New-CimSessionOption -Protocol Dcom
            $sess = New-CimSession -ComputerName $c -SessionOption $opt -OperationTimeoutSec $TimeoutSec -ErrorAction Stop
            try {
                $grp = Get-CimInstance -CimSession $sess -ClassName Win32_Group -Filter "LocalAccount=TRUE AND Name='Administrators'" -ErrorAction Stop
                if (-not $grp) { Write-Warning "Administrators group not found on '$c'."; continue }
                $members = Get-CimAssociatedInstance -CimSession $sess -InputObject $grp -Association Win32_GroupUser -ErrorAction Stop
                foreach ($m in $members) {
                    $memberType = if ($m.CimClass.CimClassName -eq 'Win32_Group') { 'Group' } else { 'User' }
                    $memberName = if ($m.Domain) { "$($m.Domain)\$($m.Name)" } else { $m.Name }
                    $results.Add([PSCustomObject]@{
                        ComputerName = $c
                        MemberName   = $memberName
                        MemberType   = $memberType
                    })
                }
            }
            finally {
                if ($sess) { $sess | Remove-CimSession -ErrorAction SilentlyContinue }
            }
        } catch { Write-Warning "Unable to enumerate Administrators on '$c': $($_.Exception.Message)"}
    }
    if ($results.Count -gt 0) {
        try {
            $results |
                Select-Object ComputerName, MemberName, MemberType |
                Sort-Object ComputerName, MemberType, MemberName |
                Export-Csv -Path $OutputPath -NoTypeInformation -Encoding UTF8 -ErrorAction Stop
            Write-Host "Results exported to '$OutputPath'"
        } catch { Write-Error "Failed to export to CSV: $($_.Exception.Message)" }
    } else { Write-Output "No local administrator members found across scanned computers."}
}

```

**2.** Scan all computers in the domain

```powershell
Find-ADMIN_TOSimple
```

**3.** Scan a specific computer object

```powershell
Find-ADMIN_TO -Target "CN=VM01,OU=Workstations,DC=forestall,Dc=labs"
```

### Computer Management

To identify `ADMIN_TO` using `Computer Management`, follow the steps below:

**1.** Open `Computer Management`.

**2.** Select `Action` from the menu, then `Connect to Another Computer` if another computer is required.

**3.** Select the desired machine to manage.

**4.** In the Computer Management window, navigate to the `Local Users and Groups` section.

**5.** In `Local Users and Groups`, double-click and open `Administrators`.

**6.** In the Members list, locate users and groups.

**7.** Click OK to close the dialogs.

![Local users And Groups](/files/DJMn2eIOuPQsJrJdsvZI)

## Exploitation

This permission is exploitable on Windows; on Linux, attackers can use tools such as Impacket for exploitation.

### Windows

Using Current Security Context

```powershell
Enter-PSSession -ComputerName VM01
```

![WinRm Session](/files/x1lkeUwNTptrvs97YvSr)

Using Custom Credentials

```powershell
$secure = ConvertTo-SecureString "<password>" -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ("<domain>\<user>", $secure)
Enter-PSSession -ComputerName FSCA01 -Credential $cred
```

Example:

```powershell
$secure = ConvertTo-SecureString "Temp123!" -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ("Forestall.labs\adam", $secure)
Enter-PSSession -ComputerName VM01 -Credential $cred
```

![WinRm Session with credentials](/files/1YKDl3xnbBKelCEIyFij)

Using any remote execution protocol:

* Windows Management Instrumentation (WMI) -> SharpWMI.exe
* Windows Remote Management (WinRM) -> CSharpWinRM.exe
* Distributed Component Object Model (DCOM) -> Invoke-DCOM.ps1

### Linux

```bash
impacket-psexec '<domain>/<user login name>:<password>@<IP Address or Host>'
```

Example:

```bash
impacket-psexec 'forestall.labs/adam:Temp123!'@VM01.forestall.labs
```

Using `wmiexec`

```bash
impacket-wmiexec '<domain>/<user login name>:<password>@<IP Address or Host>'
```

Example:

```bash
impacket-wmiexec 'forestall.labs/adam:Temp123!'@VM01.forestall.labs
```

![WMI Execution](/files/HDJBvJN5HrbZWeA7rIgW)

Using `smbexec`

```bash
impacket-smbexec '<domain>/<user login name>:<password>@<IP Address  or Host>'
```

Example:

```bash
impacket-smbexec 'forestall.labs/adam:Temp123!'@VM01.forestall.labs
```

![SMB Execution](/files/MKCJCDeJd1NWA7Z5minm)

## Mitigation

You can mitigate `ADMIN_TO` with the following steps:

**1.** Open `Computer Management`.

**2.** Select `Action` from the menu, then `Connect to Another Computer` (skip if managing the current machine).

**3.** Select the desired machine to manage.

**4.** In the Computer Management window, navigate to the `Local Users and Groups` section.

**5.** In `Local Users and Groups`, double-click and open `Administrators`.

**6.** In the Members list, select the unwanted user or group and click `Remove`.

**7.** Click OK to close the dialogs.

![Computer Management](/files/q1JDmAXsBKCCaRpDhM8j)

## Detection

Monitor Windows Security event logs for the following Event IDs, which indicate modifications to security-enabled local, global, or universal groups. Pay close attention to additions to the local "Administrators" group on workstations and servers.

| Event ID | Description                                                  | Fields/Attributes                                                                                     | References                                                                                                                                          |
| -------- | ------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| 4732     | A member was added to a security-enabled local group.        | TargetUserName, TargetGroupName, MemberName, ComputerName                                             | <https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-10/security/threat-protection/auditing/event-4732>                      |
| 4728     | A member was added to a security-enabled global group        | TargetUserName, TargetGroupName, MemberName, ComputerName                                             | <https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-10/security/threat-protection/auditing/audit-security-group-management> |
| 4756     | A member was added to a security-enabled universal group     | TargetUserName, TargetGroupName, MemberName, ComputerName                                             | <https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-10/security/threat-protection/auditing/audit-security-group-management> |
| 4624     | Successful logon to the host. Look for admin usage patterns. | LogonType 3 (network), 10 (RDP), 2 (interactive); pivot on Logon ID, IpAddress, AuthenticationPackage | <https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-10/security/threat-protection/auditing/event-4624>                      |

## References

* [LocalGroup - FSProtect Docs](https://docs.forestall.io/fsprotect/search-and-reports/localgroup)
* [LocalUser - FSProtect Docs](https://docs.forestall.io/fsprotect/search-and-reports/localuser)
* [Invoke-DCOM.ps1 - Misc PowerShell Scripts](https://github.com/rvrsh3ll/Misc-Powershell-Scripts/blob/master/Invoke-DCOM.ps1)
* [CSharpWinRM](https://github.com/mez-0/CSharpWinRM)
* [SharpWMI](https://github.com/GhostPack/SharpWMI)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.forestall.io/fsprotect/edges/ad/admin_to.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
