● Notice //GitHub (@shehzade) is temporarily suspended pending an automated false-positive review. All tools are hosted on this Code Mirror and available on request (contact); GitHub links will return once reinstated.
PUBLIC MIRRORGo v1.0.0

Offline Active Directory database (ntds.dit) parser and BloodHound graph reconstructor in pure Go. Extracts directory objects, group memberships, domain trusts, and binary DACLs from dead-disk ESE database pages and registry hives.

$ git clone https://shehzade.io/repos/ntds-to-bloodhound.git Copy
Source ZIP (246.9 KB) Prebuilt Binaries
Code 21 Commits 1 Releases 5
ntds-to-bloodhound / pkg / ese / db.go
← Back to directory
66 lines · 1.2 KB
Raw
1package ese
2
3import (
4 "fmt"
5 "io"
6 "os"
7
8 "github.com/Velocidex/ordereddict"
9 "www.velocidex.com/golang/go-ese/parser"
10)
11
12type DB struct {
13 file *os.File
14 ctx *parser.ESEContext
15 catalog *parser.Catalog
16}
17
18func OpenDB(path string) (*DB, error) {
19 f, err := os.Open(path)
20 if err != nil {
21 return nil, fmt.Errorf("failed to open ESE file %s: %w", path, err)
22 }
23
24 ctx, err := parser.NewESEContext(f)
25 if err != nil {
26 f.Close()
27 return nil, fmt.Errorf("failed to initialize ESE context: %w", err)
28 }
29
30 catalog, err := parser.ReadCatalog(ctx)
31 if err != nil {
32 f.Close()
33 return nil, fmt.Errorf("failed to read ESE catalog: %w", err)
34 }
35
36 return &DB{
37 file: f,
38 ctx: ctx,
39 catalog: catalog,
40 }, nil
41}
42
43func (db *DB) Close() error {
44 if db.file != nil {
45 return db.file.Close()
46 }
47 return nil
48}
49
50func (db *DB) TableNames() []string {
51 if db.catalog == nil || db.catalog.Tables == nil {
52 return nil
53 }
54 return db.catalog.Tables.Keys()
55}
56
57func (db *DB) StreamTable(name string, cb func(row *ordereddict.Dict) error) error {
58 if db.catalog == nil {
59 return fmt.Errorf("database catalog is nil")
60 }
61 return db.catalog.DumpTable(name, cb)
62}
63
64func (db *DB) Reader() io.ReaderAt {
65 return db.file
66}