Notice // Official Self-Hosted Code Mirror
My GitHub profile (@shehzade) is temporarily suspended due to an automated false-positive on open-source Active Directory security tool releases and is currently under official reinstatement review by GitHub Support. This mirror provides verified source code, file trees, commit logs, and release binaries directly from local git repositories. All codebases and research are also available upon request (contact me). Direct GitHub repository links will be restored once the account is unsuspended.

ntds-to-bloodhound

Offline Active Directory database (ntds.dit) parser and BloodHound graph reconstructor in pure Go.
git clone https://shehzade.io/repos/ntds-to-bloodhound.git
Log | Files | Refs | README | LICENSE
↓ Download Source ZIP git clone https://shehzade.io/repos/ntds-to-bloodhound.git Linux x64 Linux arm64 Windows x64 (.exe) macOS x64 macOS arm64

README.md (7688B)


      1 # ntds-to-bloodhound
      2 
      3 Offline Active Directory database (`ntds.dit`) parser and BloodHound graph reconstructor. Extracts directory objects, group memberships, domain trust topology, and binary Security Descriptors (ACEs) directly from dead-disk database pages and registry hives without LDAP queries, RSAT, or a live Domain Controller.
      4 
      5 ![ntds-to-bloodhound demo](docs/images/ntds-to-bloodhound-demo.png)
      6 
      7 ## Table of Contents
      8 
      9 - [Why / The Gap This Fills](#why--the-gap-this-fills)
     10 - [Internal Pipeline](#internal-pipeline)
     11 - [Required Files](#required-files)
     12 - [Build](#build)
     13 - [Usage](#usage)
     14   - [BloodHound Community Edition (v5)](#bloodhound-community-edition-v5)
     15   - [BloodHound Legacy (v4)](#bloodhound-legacy-v4)
     16   - [Export Hashes and Graph Simultaneously](#export-hashes-and-graph-simultaneously)
     17 - [Ingestion into BloodHound](#ingestion-into-bloodhound)
     18   - [BloodHound CE (v5)](#bloodhound-ce-v5)
     19   - [BloodHound Legacy (v4)](#bloodhound-legacy-v4-1)
     20   - [Querying Decrypted Hashes in BloodHound](#querying-decrypted-hashes-in-bloodhound)
     21 - [License](#license)
     22 
     23 ## Why / The Gap This Fills
     24 
     25 Active Directory collectors (SharpHound, BloodHound.py, adalanche) rely on live network enumeration over LDAP, SAMR, and SMB. In red team engagements involving volume shadow copies, offline disk images, isolated backups, or heavily monitored environments where LDAP querying is restricted or triggers behavioral alerts, running live collectors is not an option.
     26 
     27 Existing offline workflows typically run `secretsdump.py` against `ntds.dit` to dump password hashes. While effective for credential harvesting, `secretsdump.py` discards all structural Active Directory metadata: nested group memberships, OU containment hierarchies, domain trusts, and Windows NT Security Descriptors (ACLs). Reconstructing the BloodHound attack graph previously required restoring the database into an isolated Windows Server VM or chaining disparate Python and C scripts dependent on external libraries like `libesedb`.
     28 
     29 `ntds-to-bloodhound` solves this with a standalone Go binary with zero Cgo and zero external dependencies. It parses raw Extensible Storage Engine (ESE) database pages, decrypts PEK-wrapped account secrets, reconstructs the directory tree, decodes binary DACLs into BloodHound attack relationships, and outputs ready-to-ingest BloodHound CE (v5) and legacy (v4) packages.
     30 
     31 ## Internal Pipeline
     32 
     33 The extraction engine operates entirely offline in memory through five stages:
     34 
     35 ### SysKey & PEK Recovery
     36 The parser reads the offline `SYSTEM` registry hive, extracts permutation vectors across `JD`, `Skew1`, `GBG`, and `Data` under `Control\Lsa`, and reconstructs the 16-byte BootKey (SysKey). It streams `ntds.dit` to locate the domain PEK record (`ATTk590689`) and decrypts the active encryption keys using RC4 or AES.
     37 
     38 ### Directory Assembly
     39 Using a native pure-Go ESE database reader, the engine traverses the directory `datatable` and resolves fixed, variable, and tagged columns against schema definitions. It reconstructs organizational unit containment hierarchies, resolves primary group IDs, and indexes direct and nested group memberships.
     40 
     41 ### Credential Decryption
     42 For accounts containing encrypted password attributes (`unicodePwd`), the engine decrypts the ciphertext using the matching PEK key and strips the final RID-based DES obfuscation layer. Decrypted values are attached as `nthash` node properties on User and Computer objects.
     43 
     44 ### Security Descriptor Translation
     45 Binary Windows NT Security Descriptors (`nTSecurityDescriptor`) are retrieved from `sd_table` and parsed into owner and discretionary access control entries. Trustee SIDs, access masks, and schema GUIDs are resolved into typed BloodHound relationship edges including `Owns`, `GenericAll`, `WriteDacl`, `WriteOwner`, `GenericWrite`, `AllExtendedRights`, `ForceChangePassword`, `AddMember`, `AddSelf`, `GetChanges`, and `GetChangesAll`.
     46 
     47 ### Output Serialization
     48 Validated graph models are written to disk. In Community Edition mode, the output is formatted as JSON arrays and packaged into a timestamped ingestion ZIP file. In legacy mode, individual v4 JSON files are exported.
     49 
     50 ## Required Files
     51 
     52 | File | Source Path | Description |
     53 |---|---|---|
     54 | `ntds.dit` | `C:\Windows\NTDS\ntds.dit` | Active Directory database |
     55 | `SYSTEM` | `C:\Windows\System32\config\SYSTEM` | Registry hive containing the syskey |
     56 
     57 ## Build
     58 
     59 Requires Go 1.21+.
     60 
     61 ```bash
     62 make build
     63 ```
     64 
     65 Cross-compile for Linux, Windows, and macOS:
     66 
     67 ```bash
     68 make build-all
     69 ```
     70 
     71 Compiled binaries are output to the repository root (`./ntds-to-bloodhound`).
     72 
     73 ## Usage
     74 
     75 ```text
     76 Usage: ntds-to-bloodhound [OPTIONS]
     77 
     78 Required Flags:
     79   -n, -ntds string
     80         Path to offline ntds.dit database file
     81   -s, -system string
     82         Path to offline SYSTEM registry hive file
     83 
     84 Optional Flags:
     85   -o, -out string
     86         Output directory for generated files (default: "./output")
     87   -f, -format string
     88         Output format: "v4" (Legacy), "v5" (Community Edition), or "all" (default: "all")
     89   -d, -dump-hashes string
     90         Path to write secretsdump-compatible credential file
     91       -domain string
     92         Override Active Directory domain FQDN if not auto-detected
     93       -zip
     94         Package v5 output into BloodHound ingestion ZIP archive (default: true)
     95   -v, -verbose
     96         Enable detailed debug logging
     97   -h, -help
     98         Show help information
     99 ```
    100 
    101 ### BloodHound Community Edition (v5)
    102 
    103 Generate a timestamped ZIP archive ready for BloodHound CE:
    104 
    105 ```bash
    106 ./ntds-to-bloodhound -ntds /path/to/ntds.dit -system /path/to/SYSTEM -format v5 -out ./output
    107 ```
    108 
    109 ```text
    110 [*] [1/5] Extracting BootKey from SYSTEM hive: /path/to/SYSTEM
    111 [+] SysKey / BootKey derived: 0x429b3bce************************
    112 [*] [2/5] Opening ESE database: /path/to/ntds.dit
    113 [*] [3/5] Locating and decrypting Password Encryption Keys (PEK)...
    114 [+] PEK # 0 found and decrypted: d6a3bd48************************
    115 [*] [4/5] Reconstructing Active Directory hierarchy, group memberships, and ACLs...
    116 [+] Processed 15 users, 53 groups, 4 computers, 1 OUs, 1 domains
    117 [*] [5/5] Exporting BloodHound files (format: v5) to ./output...
    118 [+] BloodHound Community Edition (v5) JSON files written to ./output
    119 [+] BloodHound CE Ingestion Archive created: ./output/BloodHound_20261111230000.zip
    120 ```
    121 
    122 ### BloodHound Legacy (v4)
    123 
    124 Generate individual JSON files formatted for legacy BloodHound:
    125 
    126 ```bash
    127 ./ntds-to-bloodhound -ntds /path/to/ntds.dit -system /path/to/SYSTEM -format v4 -out ./output/v4
    128 ```
    129 
    130 ### Export Hashes and Graph Simultaneously
    131 
    132 Dump credentials in `secretsdump.py` format (`user:RID:LM:NT:::`) while generating the graph:
    133 
    134 ```bash
    135 ./ntds-to-bloodhound \
    136   -ntds /path/to/ntds.dit \
    137   -system /path/to/SYSTEM \
    138   -dump-hashes ./output/hashes.txt \
    139   -out ./output
    140 ```
    141 
    142 ## Ingestion into BloodHound
    143 
    144 ### BloodHound CE (v5)
    145 
    146 Upload the generated `BloodHound_<timestamp>.zip` archive directly through the BloodHound Community Edition interface under **Administration** &rarr; **File Ingest**, or post the archive to the CE ingestion REST endpoint.
    147 
    148 ### BloodHound Legacy (v4)
    149 
    150 Drag and drop the generated JSON files (`users.json`, `groups.json`, `computers.json`, `ous.json`, `domains.json`) into the legacy BloodHound desktop GUI window.
    151 
    152 ### Querying Decrypted Hashes in BloodHound
    153 
    154 `ntds-to-bloodhound` injects decrypted NT password hashes directly into the BloodHound node properties under the `nthash` key. You can query them in the Cypher console:
    155 
    156 ```cypher
    157 MATCH (u:User) WHERE u.nthash IS NOT NULL RETURN u.name, u.nthash
    158 ```
    159 
    160 Or view them in the node properties panel under the **Node Info** sidebar for any User or Computer object.
    161 
    162 ## License
    163 
    164 Apache License 2.0