Skip to content

Unable to parse Windows Server 2025 NTDS.dit with 32KiB ESE pages #78

@takker-hero-se

Description

@takker-hero-se

Description

Windows Server 2025 introduced optional 32KiB ESE database pages for Active Directory (NTDS.dit). When the "Database 32k pages" forest-level feature is enabled, libesedb fails to correctly parse the database.

Reference: Microsoft: Database 32k pages for Active Directory

Issue 1: Page tag count (available_page_tag) is misread

In the 32KiB page format, the available_page_tag field (uint16) uses a new layout:

  • Upper 4 bits: ctagReserved (reserved bits, should be masked out)
  • Lower 12 bits: actual number of page tags

libesedb_page_header_read_data() reads all 16 bits as the tag count. On 32KiB pages this inflates the count, causing out-of-bounds page tag reads and garbage data.

Affected file: libesedb/libesedb_page_header.c (line ~241)

Suggested fix: Mask the upper 4 bits when page_size >= 32768:

if( io_handle->page_size >= 32768 )
{
    page_header->available_page_tag &= 0x0fff;
}

Issue 2: Leaf page walk encounters non-leaf pages

In libesedb_page_tree_get_get_first_leaf_page_number() (backward walk) and libesedb_page_tree_get_number_of_leaf_values() (forward walk), the code does not check whether a page in the leaf chain is actually a leaf page. In 32KiB databases, some pages referenced in the chain may be zeroed or non-leaf pages, causing "not a leaf page" errors or incorrect record counts.

Affected file: libesedb/libesedb_page_tree.c (two locations)

Suggested fix: Check LIBESEDB_PAGE_FLAG_IS_LEAF before processing each page and break if the flag is not set.

Environment

  • Windows Server 2025 with "Database 32k pages" feature enabled
  • NTDS.dit extracted via ntdsutil IFM
  • libesedb version: 20230824

Verification

With both fixes applied, the following was confirmed:

  • 8KiB (WS2019) NTDS.dit: 14 tables, 7008 datatable records, 13904 link_table records — no regression
  • 32KiB (WS2025) NTDS.dit: 14 tables, 7029 datatable records, 485 link_table records — parsed correctly

I have a patch ready and can submit a PR if you are interested.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions