drsuapi

package
v0.0.0-...-f638237 Latest Latest
Warning

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

Go to latest
Published: Jun 9, 2026 License: Apache-2.0 Imports: 15 Imported by: 0

Documentation

Index

Constants

View Source
const (
	OpDsBind              = 0
	OpDsUnbind            = 1
	OpDsReplicaSync       = 2
	OpDsGetNCChanges      = 3
	OpDsReplicaUpdateRefs = 4
	OpDsReplicaAdd        = 5
	OpDsCrackNames        = 12
	OpDsGetDCInfo         = 16
)

Operation numbers

View Source
const (
	DRS_EXT_BASE                         = 0x00000001
	DRS_EXT_ASYNCREPL                    = 0x00000002
	DRS_EXT_REMOVEAPI                    = 0x00000004
	DRS_EXT_MOVEREQ_V2                   = 0x00000008
	DRS_EXT_GETCHG_DEFLATE               = 0x00000010
	DRS_EXT_DCINFO_V1                    = 0x00000020
	DRS_EXT_RESTORE_USN_OPTIMIZATION     = 0x00000040
	DRS_EXT_ADDENTRY                     = 0x00000080
	DRS_EXT_KCC_EXECUTE                  = 0x00000100
	DRS_EXT_ADDENTRY_V2                  = 0x00000200
	DRS_EXT_LINKED_VALUE_REPLICATION     = 0x00000400
	DRS_EXT_DCINFO_V2                    = 0x00000800
	DRS_EXT_INSTANCE_TYPE_NOT_REQ_ON_MOD = 0x00001000
	DRS_EXT_CRYPTO_BIND                  = 0x00002000
	DRS_EXT_GET_REPL_INFO                = 0x00004000
	DRS_EXT_STRONG_ENCRYPTION            = 0x00008000
	DRS_EXT_DCINFO_V01                   = 0x00010000
	DRS_EXT_TRANSITIVE_MEMBERSHIP        = 0x00020000
	DRS_EXT_ADD_SID_HISTORY              = 0x00040000
	DRS_EXT_POST_BETA3                   = 0x00080000
	DRS_EXT_GETCHGREQ_V5                 = 0x00100000
	DRS_EXT_GETMEMBERSHIPS2              = 0x00200000
	DRS_EXT_GETCHGREQ_V6                 = 0x00400000
	DRS_EXT_NONDOMAIN_NCS                = 0x00800000
	DRS_EXT_GETCHGREQ_V8                 = 0x01000000
	DRS_EXT_GETCHGREPLY_V5               = 0x02000000
	DRS_EXT_GETCHGREPLY_V6               = 0x04000000
	DRS_EXT_ADDENTRYREPLY_V3             = 0x08000000
	DRS_EXT_GETCHGREPLY_V7               = 0x08000000
	DRS_EXT_VERIFY_OBJECT                = 0x08000000
	DRS_EXT_XPRESS_COMPRESS              = 0x10000000
	DRS_EXT_GETCHGREQ_V10                = 0x20000000
	DRS_EXT_RESERVED_FOR_WIN2K_OR_DOTNET = 0x80000000
)

DRS_EXT flags for client/server capabilities

View Source
const (
	DS_UNKNOWN_NAME                 = 0
	DS_FQDN_1779_NAME               = 1 // CN=John,OU=Users,DC=example,DC=com
	DS_NT4_ACCOUNT_NAME             = 2 // DOMAIN\username
	DS_DISPLAY_NAME                 = 3
	DS_UNIQUE_ID_NAME               = 6 // GUID string
	DS_CANONICAL_NAME               = 7 // example.com/Users/John
	DS_USER_PRINCIPAL_NAME          = 8 // user@domain.com
	DS_CANONICAL_NAME_EX            = 9
	DS_SERVICE_PRINCIPAL_NAME       = 10
	DS_SID_OR_SID_HISTORY_NAME      = 11
	DS_DNS_DOMAIN_NAME              = 12  // domain.com
	DS_NT4_ACCOUNT_NAME_SANS_DOMAIN = 0xb // username (no domain prefix)
)

DS_NAME_FORMAT - name format types for DsCrackNames

View Source
const (
	DS_NAME_NO_FLAGS              = 0x0
	DS_NAME_FLAG_SYNTACTICAL_ONLY = 0x1
	DS_NAME_FLAG_EVAL_AT_DC       = 0x2
	DS_NAME_FLAG_GCVERIFY         = 0x4
	DS_NAME_FLAG_TRUST_REFERRAL   = 0x8
)

DS_NAME_FLAGS

View Source
const (
	DS_NAME_NO_ERROR                     = 0
	DS_NAME_ERROR_RESOLVING              = 1
	DS_NAME_ERROR_NOT_FOUND              = 2
	DS_NAME_ERROR_NOT_UNIQUE             = 3
	DS_NAME_ERROR_NO_MAPPING             = 4
	DS_NAME_ERROR_DOMAIN_ONLY            = 5
	DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING = 6
	DS_NAME_ERROR_TRUST_REFERRAL         = 7
)

DS_NAME_ERROR - error codes from DsCrackNames

View Source
const (
	DRSUAPI_ATTID_objectSid               = 0x00090092 // 1.2.840.113556.1.4.146
	DRSUAPI_ATTID_sAMAccountName          = 0x000900DD // 1.2.840.113556.1.4.221 (was wrong: 0x45)
	DRSUAPI_ATTID_userPrincipalName       = 0x00090290 // 1.2.840.113556.1.4.656
	DRSUAPI_ATTID_sAMAccountType          = 0x0009004e
	DRSUAPI_ATTID_userAccountControl      = 0x00090008 // 1.2.840.113556.1.4.8
	DRSUAPI_ATTID_accountExpires          = 0x0009005f
	DRSUAPI_ATTID_pwdLastSet              = 0x00090060 // 1.2.840.113556.1.4.96
	DRSUAPI_ATTID_objectGUID              = 0x00090048
	DRSUAPI_ATTID_objectClass             = 0x00000000
	DRSUAPI_ATTID_cn                      = 0x00000003
	DRSUAPI_ATTID_description             = 0x0000000d
	DRSUAPI_ATTID_unicodePwd              = 0x0009005a // 1.2.840.113556.1.4.90
	DRSUAPI_ATTID_ntPwdHistory            = 0x0009005e // 1.2.840.113556.1.4.94
	DRSUAPI_ATTID_dBCSPwd                 = 0x00090037 // 1.2.840.113556.1.4.55
	DRSUAPI_ATTID_lmPwdHistory            = 0x000900a0 // 1.2.840.113556.1.4.160
	DRSUAPI_ATTID_supplementalCredentials = 0x0009007d // 1.2.840.113556.1.4.125
	DRSUAPI_ATTID_member                  = 0x0001f401
)

DRSUAPI_ATTID - attribute IDs (matching Impacket's NAME_TO_ATTRTYP)

View Source
const (
	DRS_INIT_SYNC                 = 0x00000020
	DRS_WRIT_REP                  = 0x00000010
	DRS_INIT_SYNC_NOW             = 0x00800000
	DRS_FULL_SYNC_NOW             = 0x00008000
	DRS_SYNC_URGENT               = 0x00080000
	DRS_GET_ANC                   = 0x00000200
	DRS_GET_NC_SIZE               = 0x00001000
	DRS_SPECIAL_SECRET_PROCESSING = 0x00002000
	DRS_CRITICAL_ONLY             = 0x00000004
)

DRS_OPTIONS flags for GetNCChanges

View Source
const (
	EXOP_NONE              = 0
	EXOP_FSMO_REQ_ROLE     = 1
	EXOP_FSMO_RID_ALLOC    = 2
	EXOP_FSMO_RID_REQ_ROLE = 3
	EXOP_FSMO_REQ_PDC      = 4
	EXOP_FSMO_ABANDON_ROLE = 5
	EXOP_REPL_OBJ          = 6
	EXOP_REPL_SECRETS      = 7
)

EXOP codes for extended operations

View Source
const (
	KERB_ETYPE_DES_CBC_CRC             = 1
	KERB_ETYPE_DES_CBC_MD5             = 3
	KERB_ETYPE_AES128_CTS_HMAC_SHA1_96 = 17
	KERB_ETYPE_AES256_CTS_HMAC_SHA1_96 = 18
	KERB_ETYPE_RC4_HMAC                = 0xffffff74
)

Kerberos key type constants

View Source
const MajorVersion = 4
View Source
const MinorVersion = 0

Variables

View Source
var NTDSAPI_CLIENT_GUID = [16]byte{
	0x1a, 0x20, 0x4d, 0xe2, 0xd6, 0x4f, 0xd1, 0x11,
	0xa3, 0xda, 0x00, 0x00, 0xf8, 0x75, 0xae, 0x0d,
}

NTDSAPI_CLIENT_GUID - standard client GUID for DRSUAPI (5.137 in MS-DRSR) e24d201a-4fd6-11d1-a3da-0000f875ae0d

View Source
var UUID = [16]byte{
	0x35, 0x42, 0x51, 0xe3, 0x06, 0x4b, 0xd1, 0x11,
	0xab, 0x04, 0x00, 0xc0, 0x4f, 0xc2, 0xdc, 0xd2,
}

DRSUAPI UUID: e3514235-4b06-11d1-ab04-00c04fc2dcd2

Functions

func DecryptLSASecret

func DecryptLSASecret(sessionKey, encryptedData []byte) ([]byte, error)

DecryptLSASecret decrypts an LSA secret using the session key This implements MS-LSAD Section 5.1.2 encryption scheme

func DecryptNTHash

func DecryptNTHash(pek, encryptedHash []byte, rid uint32) ([]byte, error)

DecryptNTHash decrypts the NT hash from the unicodePwd attribute. The hash is encrypted with a key derived from the user's RID.

func DecryptSecret

func DecryptSecret(sessionKey, encryptedData []byte) ([]byte, error)

DecryptSecret decrypts an encrypted attribute value from DRS replication. The encryption uses the session key and either RC4 or AES depending on server version.

func DomainDNSToLDAP

func DomainDNSToLDAP(domain string) string

DomainDNSToLDAP converts a DNS domain name to LDAP DN format. Example: "corp.local" -> "DC=corp,DC=local"

func ExtractRIDFromSID

func ExtractRIDFromSID(sid []byte) uint32

ExtractRIDFromSID extracts the RID (last 4 bytes) from a SID

func GetDomainDN

func GetDomainDN(client *dcerpc.Client, hBind []byte, domainDNS string) (string, error)

GetDomainDN converts a DNS domain name to a distinguished name. For example: "corp.local" -> "DC=corp,DC=local"

func GetKeyTypeName

func GetKeyTypeName(keyType uint32) string

GetKeyTypeName returns the human-readable name for a Kerberos key type

Types

type BindResult

type BindResult struct {
	Handle     []byte         // Context handle (20 bytes)
	ServerGUID [16]byte       // Server DSA GUID
	Extensions *DrsExtensions // Server capabilities
}

BindResult contains DsBind results

func DsBind

func DsBind(client *dcerpc.Client) (*BindResult, error)

DsBind performs the initial handshake and returns the context handle.

type CrackedName

type CrackedName struct {
	Status    uint32
	DNSDomain string
	Name      string
}

CrackedName represents a single result from DsCrackNames

func DsCrackNames

func DsCrackNames(client *dcerpc.Client, hBind []byte, formatOffered, formatDesired uint32, names []string) ([]CrackedName, error)

DsCrackNames translates names from one format to another. This is used to get the domain DN from the domain DNS name.

type DCInfo

type DCInfo struct {
	NtdsDsaObjectGuid  [16]byte
	ServerObjectGuid   [16]byte
	ComputerObjectGuid [16]byte
	DnsHostName        string
	NetbiosName        string
}

DCInfo contains DC information from DsDomainControllerInfo

func DsDomainControllerInfo

func DsDomainControllerInfo(client *dcerpc.Client, hBind []byte, domain string) (*DCInfo, error)

DsDomainControllerInfo retrieves DC information including the DSA GUID

type DSNAME

type DSNAME struct {
	StructLen  uint32
	SidLen     uint32
	Guid       [16]byte
	Sid        []byte
	NameLen    uint32
	StringName string
}

DSNAME represents an AD object name

type Decoder

type Decoder struct {
	// contains filtered or unexported fields
}

Decoder walks an NDR byte stream.

func NewDecoder

func NewDecoder(data []byte) *Decoder

NewDecoder creates a decoder positioned at offset 0.

func (*Decoder) Align

func (d *Decoder) Align(n int)

Align moves the cursor forward to the next multiple of n. NDR requires padding to each primitive's natural alignment before reading.

func (*Decoder) CheckBounds

func (d *Decoder) CheckBounds(count uint32, elemSize int, what string) bool

CheckBounds validates that count elements of elemSize bytes can fit in the remaining wire buffer. If not, it Fails the decoder (so subsequent reads return zero values) and returns false. Use this before any allocation or Skip whose size is driven by a wire-supplied count, so a malformed reply with a tiny payload and a huge embedded count can't trigger a multi-MB speculative make for bytes that don't actually exist on the wire. The product is computed in uint64 so it stays safe on 32-bit builds where int(count)*elemSize could otherwise overflow.

func (*Decoder) Err

func (d *Decoder) Err() error

Err returns the first error encountered, if any. Callers that want per-call error handling should check Err after a block of reads.

func (*Decoder) Fail

func (d *Decoder) Fail(format string, args ...interface{})

Fail records a sticky error on the decoder. Subsequent reads become no-ops returning zero values, so a caller that aborts a helper for structural reasons (e.g. exceeded a bounds cap) MUST call Fail before returning so downstream helpers don't read from an unadvanced cursor and drift the rest of the stream.

func (*Decoder) Pos

func (d *Decoder) Pos() int

Pos returns the current byte offset.

func (*Decoder) ReadBytes

func (d *Decoder) ReadBytes(n int) []byte

ReadBytes reads n raw bytes with no alignment. Returns a slice that aliases the underlying buffer; copy before mutating.

func (*Decoder) ReadConformance

func (d *Decoder) ReadConformance() uint32

ReadConformance reads the MaxCount prefix of a conformant array (ULONG, 4-byte aligned).

func (*Decoder) ReadConformantVaryingHeader

func (d *Decoder) ReadConformantVaryingHeader() (maxCount, offset, actualCount uint32)

ReadConformantVaryingHeader reads the MaxCount + Offset + ActualCount prefix of a conformant-varying array. Returns (maxCount, offset, actualCount). Most callers ignore offset (always 0) and use actualCount as the element count.

func (*Decoder) ReadGUID

func (d *Decoder) ReadGUID() [16]byte

ReadGUID reads a 16-byte GUID. GUIDs in NDR require 4-byte alignment (their max internal alignment, since UUID is a struct of DWORD/USHORTs).

func (*Decoder) ReadPointer

func (d *Decoder) ReadPointer() uint32

ReadPointer reads a pointer referent ID (ULONG). Zero means NULL, which means the pointed-to data is NOT serialized. Non-zero means the deferred data for this pointer will appear later.

func (*Decoder) ReadUTF16LEString

func (d *Decoder) ReadUTF16LEString(chars uint32) string

ReadUTF16LEString reads chars * 2 bytes as UTF-16LE, trimming a trailing null character if present.

func (*Decoder) ReadUint8

func (d *Decoder) ReadUint8() uint8

ReadUint8 reads a single byte (no alignment).

func (*Decoder) ReadUint16

func (d *Decoder) ReadUint16() uint16

ReadUint16 reads a USHORT with 2-byte alignment.

func (*Decoder) ReadUint32

func (d *Decoder) ReadUint32() uint32

ReadUint32 reads a ULONG/DWORD with 4-byte alignment.

func (*Decoder) ReadUint64

func (d *Decoder) ReadUint64() uint64

ReadUint64 reads a LONGLONG/UHYPER with 8-byte alignment.

func (*Decoder) Remaining

func (d *Decoder) Remaining() int

Remaining is the number of bytes left to read.

func (*Decoder) SeekTo

func (d *Decoder) SeekTo(pos int)

SeekTo moves the cursor to an absolute offset. Fails softly if out of range: the error is recorded and subsequent reads return zero values. If a prior error is already set, leaves both error and position alone so the first-failure context survives downstream Skip/Align calls.

func (*Decoder) Skip

func (d *Decoder) Skip(n int)

Skip advances the cursor by n bytes. A negative n seeks backward.

type DrsExtensions

type DrsExtensions struct {
	Cb            uint32
	Flags         uint32
	SiteObjGuid   [16]byte // GUID
	Pid           uint32
	DwReplEpoch   uint32
	DwFlagsExt    uint32
	ConfigObjGUID [16]byte
	DwExtCaps     uint32
}

DRS_EXTENSIONS_INT used in Bind (5.39 in MS-DRSR)

type EncryptedHash

type EncryptedHash struct {
	Version uint16
	Flags   uint16
	Salt    [16]byte
	Hash    []byte
}

ParseEncryptedHash parses the encrypted hash structure

func ParseEncryptedPwdBlob

func ParseEncryptedPwdBlob(data []byte) (*EncryptedHash, error)

type GetNCChangesResult

type GetNCChangesResult struct {
	Objects       []ReplicatedObject
	MoreData      bool
	HighWaterMark USNVector // USN state for continuation
}

GetNCChangesResult contains the response from DsGetNCChanges

func DsGetNCChanges

func DsGetNCChanges(client *dcerpc.Client, hBind []byte, domainDN string, userDN string, dsaGuid [16]byte, sessionKey []byte) (*GetNCChangesResult, error)

DsGetNCChanges requests replication of a single object from a naming context. For DCSync, we use EXOP_REPL_OBJ to get password hashes. dsaGuid should be the NtdsDsaObjectGuid from DsDomainControllerInfo. sessionKey is the NTLM session key used to decrypt encrypted attributes.

func DsGetNCChangesAll

func DsGetNCChangesAll(client *dcerpc.Client, hBind []byte, domainDN string, dsaGuid [16]byte, sessionKey []byte, usnFrom USNVector) (*GetNCChangesResult, error)

DsGetNCChangesAll requests replication of all objects from a naming context. This is used for full domain credential dumping. usnFrom is the USN watermark for pagination (use empty USNVector for initial request).

type KerberosKey

type KerberosKey struct {
	KeyType  uint32 // 18=AES256, 17=AES128, 3=DES-MD5, 1=DES-CRC, 0xffffff74=RC4
	KeyValue []byte
}

KerberosKey represents a Kerberos encryption key

func ParseSupplementalCredentials

func ParseSupplementalCredentials(data []byte) ([]KerberosKey, error)

ParseSupplementalCredentials parses the decrypted supplementalCredentials attribute and extracts Kerberos keys

type PrefixEntry

type PrefixEntry struct {
	Index  uint32
	Prefix []byte
}

PrefixEntry represents an entry in the schema prefix table

type ReplicatedObject

type ReplicatedObject struct {
	GUID               [16]byte
	DN                 string
	SAMAccountName     string
	ObjectSid          []byte
	RID                uint32
	NTHash             []byte        // Decrypted NT hash (16 bytes)
	LMHash             []byte        // Decrypted LM hash (16 bytes)
	NTHashHistory      [][]byte      // Historical NT hashes (each 16 bytes)
	LMHashHistory      [][]byte      // Historical LM hashes (each 16 bytes)
	SupplementalCreds  []byte        // Decrypted supplementalCredentials
	KerberosKeys       []KerberosKey // Parsed Kerberos keys from supplementalCredentials
	UserAccountControl uint32
	PwdLastSet         int64 // Windows FILETIME (100-nanosecond intervals since 1601-01-01)
}

ReplicatedObject contains the replicated attributes of an AD object

func GetUserSecrets

func GetUserSecrets(client *dcerpc.Client, hBind []byte, userDN string, domainDN string, dsaGuid [16]byte, sessionKey []byte) (*ReplicatedObject, error)

GetUserSecrets performs DCSync for a single user

type USNVector

type USNVector struct {
	HighObjUpdate  uint64
	Reserved       uint64
	HighPropUpdate uint64
}

USNVector tracks replication state for pagination

Jump to

Keyboard shortcuts

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