gpp

package
v0.783.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 29, 2026 License: AGPL-3.0 Imports: 11 Imported by: 0

Documentation

Overview

Package gpp decrypts Group Policy Preferences (GPP) cpassword values.

Group Policy Preferences let a domain admin push local accounts, scheduled tasks, services, mapped drives, and data sources to every machine in an Active Directory domain. The password for those items is stored in an XML file under the domain SYSVOL share (Groups.xml, Services.xml, ScheduledTasks.xml, DataSources.xml, Drives.xml, Printers.xml) as a "cpassword" attribute — AES-256-CBC encrypted. The catch: Microsoft *published* the 32-byte AES key in the MS-GPPREF protocol spec (§2.2.1.1), so any domain user who can read SYSVOL can decrypt every cpassword offline. This is one of the highest-impact Active Directory findings (MS14-025 removed the ability to *create* new ones, but legacy SYSVOL files persist for years).

This takes either a raw cpassword string or a pasted GPP XML snippet, extracts every cpassword (with the co-located account name when present), and decrypts it to the cleartext password. The AES key, the all-zero IV, the CBC mode, and the UTF-16LE plaintext encoding are all fixed by the spec — there is nothing to guess.

No confidently-wrong output: the key / IV / algorithm are fixed; an empty cpassword (a cleared field) is reported as "no password set", and a wrong-length or bad-padding ciphertext is reported as an error on that entry, never a garbled guess. No network, no key material beyond the public one.

Wrap-vs-native: native — Go stdlib crypto/aes + crypto/cipher + encoding/xml, no new go.mod dependency. Anchored to the well-known public cpassword vectors (see the test), cross-checked against openssl.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Entry

type Entry struct {
	Username  string `json:"username,omitempty"`
	Element   string `json:"element,omitempty"`
	Cpassword string `json:"cpassword"`
	Password  string `json:"password,omitempty"`
	Empty     bool   `json:"empty,omitempty"`
	Error     string `json:"error,omitempty"`
}

Entry is one decrypted cpassword.

type Result

type Result struct {
	Format  string  `json:"format"`
	Count   int     `json:"count"`
	Entries []Entry `json:"entries"`
	Note    string  `json:"note"`
}

Result is the set of decrypted cpasswords.

func Decode

func Decode(data []byte) (*Result, error)

Decode decrypts every cpassword in the input: a GPP XML snippet (any of the SYSVOL preference files) or a single raw cpassword string.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL