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  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** → **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