windows-sddl 0.1.0

Pure-Rust, no-FFI parser and builder for Windows self-relative SECURITY_DESCRIPTOR / DACL / ACE blobs (MS-DTYP), plus SID/GUID types and AD extended-right GUIDs.
Documentation
  • Coverage
  • 48.89%
    44 out of 90 items documented1 out of 48 items with examples
  • Size
  • Source code size: 29.26 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 1.1 MB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 10s Average build duration of successful builds.
  • all releases: 10s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • icedracon/windows-sddl
    1 0 0
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • icedracon

windows-sddl

crates.io docs.rs License: MIT

A pure-Rust, no-FFI parser and builder for the Windows self-relative SECURITY_DESCRIPTOR blob (MS-DTYP §2.4.6) — the binary form stored in nTSecurityDescriptor, returned over LDAP, and found in registry hives and backup formats.

It works cross-platform against raw bytes: no windows crate, no OS calls, so you can read and reason about Windows ACLs from Linux/macOS — for DFIR, ACL auditing, backup/migration tooling, or an AD security scanner.

Features

  • Parse self-relative SECURITY_DESCRIPTOR → owner / group / DACL with typed ACEs (AccessAllowed, AccessDenied, and their object variants).
  • Typed AccessMask bitflags (WriteDacl, WriteOwner, GenericAll, extended-right bits …).
  • Sid and Guid types with binary + string parsing/formatting (objectSid, S-1-5-…).
  • A table of Active-Directory extended-right GUIDs ([rights]) so an object ACE resolves into a concrete right: DCSync, Shadow Credentials, RBCD, cert enrollment, force-change-password, …
  • Build helper (build_rbcd_sd) for emitting a self-relative SD with an allow ACE.
  • Never panics on malformed input — hostile/truncated blobs return an error. Fuzz-tested.

Example

use windows_sddl::{parse, rights, AccessMask};

let sd = parse(&nt_security_descriptor_bytes)?;
for ace in sd.dacl.iter().flat_map(|d| &d.aces).filter(|a| a.is_allow()) {
    if ace.mask.contains(AccessMask::GENERIC_ALL) {
        println!("{} has GenericAll", ace.trustee);
    }
    if let Some(g) = &ace.object_type {
        if rights::is_dcsync_right(g) {
            println!("{} can DCSync", ace.trustee);
        }
    }
}

Or from the CLI:

cargo run --example parse_sd -- 010004801400...   # a hex nTSecurityDescriptor

Scope

Parsing + building of self-relative security descriptors, ACLs, ACEs, SIDs, and GUIDs, plus the AD extended-right GUID table. SACL/audit ACEs are preserved as AceType::Other. Conditional ACEs (SDDL string form) are out of scope for now.

License

MIT © icedracon. Extracted from ADhammer.