Skip to content

fix: support 32KB page sizes in ESE parser for Windows Server 2025 - #2270

Open
juliosuas wants to merge 1 commit into
fortra:masterfrom
juliosuas:fix/ese-32kb-page-support
Open

fix: support 32KB page sizes in ESE parser for Windows Server 2025#2270
juliosuas wants to merge 1 commit into
fortra:masterfrom
juliosuas:fix/ese-32kb-page-support

Conversation

@juliosuas

Copy link
Copy Markdown

Summary

Fixes #1924secretsdump.py crashes with IndexError: bytearray index out of range when parsing NTDS.dit files from Windows Server 2025.

Root Cause

Windows Server 2025 uses 32KB (32768 byte) database pages in NTDS.dit, up from the previous 8KB (8192 byte) pages. The ESE format specification (revision 0x11+) defines a different page tag format for pages larger than 8KB:

  • Tag entries use 15-bit fields for both value size and offset (instead of 13-bit + 3-bit flags)
  • Page tag flags are moved into the upper 3 bits of the first 16-bit value in the entry data itself

The existing code in getTag() correctly handles this format except when valueSize is 0 (empty entries, such as leaf/branch page headers with no common key). In that case, tmpData is an empty bytearray and tmpData[1] raises IndexError.

The Fix

Added bounds checking before accessing tmpData[1] in the large-page code path:

valueSize Behavior
≥ 2 Extract flags from tmpData[1] >> 5 (existing logic, unchanged)
== 1 Set flags to 0, return single byte as-is
== 0 Set flags to 0, return empty bytes (was crashing)

The 8KB page code path (the else branch) is completely unchanged, preserving backward compatibility.

References

  • libyal ESE format specification — documents the page tag format change for 16KB/32KB pages
  • Database header from affected NTDS.dit: Version 0x620, Revision 0x122, Page Size 32768

Testing

  • Verified the fix handles all three value size cases (0, 1, ≥2)
  • The 8KB page path is untouched (no regression risk for existing databases)
  • Confirmed Python compilation succeeds with no syntax errors

Restored after an accidental fork deletion. Same commits as #2165.

Windows Server 2025 uses 32KB (32768 byte) database pages in NTDS.dit
instead of the previous 8KB (8192 byte) pages. The ESE parser's getTag()
method crashed with 'IndexError: bytearray index out of range' when
processing these larger pages.

Root cause: For large pages (>8KB) with format revision >= 17, the page
tag flags are stored in the upper 3 bits of the first 16-bit value of
the entry data itself (not in the tag entry). The code accessed
tmpData[1] unconditionally, but when valueSize is 0 (empty entries like
leaf/branch page headers with no common key), tmpData is an empty
bytearray, causing the IndexError.

Fix: Add bounds checking before accessing tmpData[1]:
- valueSize >= 2: extract flags from tmpData[1] as before (normal path)
- valueSize == 1: set flags to 0, return single byte as-is
- valueSize == 0: set flags to 0, return empty bytes (was crashing)

This preserves backward compatibility with 8KB pages (the else branch
is unchanged) and follows the ESE format specification from libyal.

Fixes fortra#1924
@anadrianmanrique anadrianmanrique added enhancement Implemented features can be improved or revised low Low priority item labels Aug 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Implemented features can be improved or revised low Low priority item

Projects

None yet

Development

Successfully merging this pull request may close these issues.

secretsdump.py does not parse Windows Server 2025 NTDS.dit

3 participants