Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,25 @@ This module is also automatically installed if you install the `dissect` package

## Tools

Some CLI tools related to specific databases exists. These tools allow you to dump or inspect database content.

| Commands | Description |
|--------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `dissect-ntds` | Windows NTDS (Active Directory database). |
| `dissect-ual` | Windows [User Access Logging](https://learn.microsoft.com/en-us/windows-server/administration/user-access-logging/get-started-with-user-access-logging) database. |
| `dissect-sru` | Windows System Resources And Usage Monitor database. |
| `dissect-certlog` | Windows [AD CS database](https://learn.microsoft.com/en-us/windows-server/identity/ad-cs/active-directory-certificate-services-overview) database. |
| `dissect-rpm` | [Red Hat Package Manager](https://rpm.org/) database. |
| `dissect-impacket` | Impacket compatibility shim for `secretsdump.py`. |

### Impacket compatibility shim for secretsdump.py

Impacket does not ([yet](https://github.com/fortra/impacket/pull/1452)) have native support for `dissect.database`,
so in the meantime a compatibility shim is provided. To use this shim, simply install `dissect.database` using the
instructions above, and execute `secretsdump.py` like so:

```bash
python -m dissect.database.ese.tools.impacket /path/to/impacket/examples/secretsdump.py -h
dissect-impacket /path/to/impacket/examples/secretsdump.py -h
```

Impacket `secretsdump.py` will now use `dissect.database` for parsing the `NTDS.dit` file, resulting in a significant performance improvement!
Expand Down
Empty file.
28 changes: 28 additions & 0 deletions dissect/database/ese/ntds/tools/ntds.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from __future__ import annotations

import argparse
import json
from pathlib import Path

from dissect.database.ese.ntds import NTDS


def main() -> None:
parser = argparse.ArgumentParser(description="dissect.database.ese.ntds NTDS parser")
parser.add_argument("input", help="NTDS database to read")
parser.add_argument("-c", "--objectClass", help="show only objects of this class", required=True)
parser.add_argument("-j", "--json", action="store_true", default=False, help="output in JSON format")
args = parser.parse_args()

with Path(args.input).open("rb") as fh:
ntds = NTDS(fh)

for record in ntds.search(objectClass=args.objectClass):
if args.json:
print(json.dumps(record.as_dict(), default=str))
else:
print(record)


if __name__ == "__main__":
main()
19 changes: 14 additions & 5 deletions dissect/database/ese/tools/sru.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import annotations

import argparse
import json
from pathlib import Path
from typing import TYPE_CHECKING, BinaryIO

Expand Down Expand Up @@ -148,24 +149,32 @@ def __repr__(self) -> str:
column_values = serialise_record_column_values(self.record)
return f"<Entry provider={self.table.name!r} {column_values}>"

def as_dict(self) -> dict:
ret = self.record.as_dict()
ret["provider"] = self.table.name
return ret


def main() -> None:
parser = argparse.ArgumentParser(description="dissect.database.ese SRU parser")
parser.add_argument("input", help="SRU database to read")
parser.add_argument("-p", "--provider", help="filter records from this provider")
parser.add_argument("-j", "--json", action="store_true", default=False, help="output in JSON format")
args = parser.parse_args()

with Path(args.input).open("rb") as fh:
parser = SRU(fh)

if args.provider in NAME_TO_GUID_MAP:
for e in parser.get_table_entries(table_name=args.provider):
print(e)
generator = parser.get_table_entries(table_name=args.provider)
elif args.provider:
for e in parser.get_table_entries(table_guid=args.provider):
print(e)
generator = parser.get_table_entries(table_guid=args.provider)
else:
for e in parser.entries():
generator = parser.entries()
for e in generator:
if args.json:
print(json.dumps(e.as_dict(), default=str))
else:
print(e)


Expand Down
7 changes: 6 additions & 1 deletion dissect/database/ese/tools/ual.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import argparse
import datetime
import ipaddress
import json
from collections.abc import Iterator
from pathlib import Path
from typing import BinaryIO
Expand Down Expand Up @@ -89,6 +90,7 @@ def convert_day_num_to_date(year: int, day_num: int) -> datetime.datetime:

def main() -> None:
parser = argparse.ArgumentParser(description="dissect.database.ese UAL parser")
parser.add_argument("-j", "--json", action="store_true", default=False, help="output in JSON format")
parser.add_argument("input", help="UAL database to read")
args = parser.parse_args()

Expand All @@ -100,7 +102,10 @@ def main() -> None:
continue

for record in parser.get_table_records(table.name):
print(record)
if args.json:
print(json.dumps(record, default=str))
else:
print(record)


if __name__ == "__main__":
Expand Down
8 changes: 8 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@ dev = [
{include-group = "debug"},
]

[project.scripts]
dissect-ntds = "dissect.database.ese.ntds.tools.ntds:main"
dissect-ual = "dissect.database.ese.tools.ual:main"
dissect-sru = "dissect.database.ese.tools.sru:main"
dissect-certlog = "dissect.database.ese.tools.certlog:main"
dissect-rpm = "dissect.database.bsd.tools.rpm:main"
dissect-impacket = "dissect.database.ese.tools.impacket:main"

[tool.ruff]
line-length = 120
required-version = ">=0.13.1"
Expand Down
Loading