Skip to content

Update block-api to prepare for a random IV#21085

Merged
smcintyre-r7 merged 13 commits intorapid7:masterfrom
dledda-r7:issue-19309
Apr 14, 2026
Merged

Update block-api to prepare for a random IV#21085
smcintyre-r7 merged 13 commits intorapid7:masterfrom
dledda-r7:issue-19309

Conversation

@dledda-r7
Copy link
Copy Markdown
Contributor

@dledda-r7 dledda-r7 commented Mar 9, 2026

Fix: #19309
Update block-api to use random IV

Comment thread Gemfile Outdated
Comment thread Gemfile.lock Outdated
@jbx81-1337
Copy link
Copy Markdown
Contributor

@zeroSteiner we will need to update all the cache size that are using block-api right? 🫠

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the Windows block_api shellcode hash algorithm (x86/x64) to use the module hash as the initialization value for function hashing, and temporarily pulls in a rex-text feature branch needed for the change.

Changes:

  • Switch x86/x64 block_api.asm to seed function hashing with the module hash (and adjust module name length field offsets).
  • Update hash.py to reflect the new hashing approach (currently has correctness issues).
  • Add a temporary git-sourced rex-text dependency (and lock it in Gemfile.lock).

Reviewed changes

Copilot reviewed 6 out of 7 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
Gemfile Temporarily sources rex-text from a git branch.
Gemfile.lock Locks the git-sourced rex-text dependency (remote/revision) and adds it to dependencies.
external/source/shellcode/windows/x86/src/hash.py Attempts to update hash generation to match new shellcode hashing.
external/source/shellcode/windows/x86/src/block/block_api.asm Updates x86 shellcode hashing semantics to use module-hash IV and corrects the UNICODE_STRING length offset.
external/source/shellcode/windows/x64/src/block/block_api.asm Updates x64 shellcode hashing semantics to use module-hash IV and corrects the UNICODE_STRING length offset.
data/shellcode/block_api.x86.graphml Regenerated graph representation reflecting the updated x86 shellcode.
data/shellcode/block_api.x64.graphml Regenerated graph representation reflecting the updated x64 shellcode.
Comments suppressed due to low confidence (1)

external/source/shellcode/windows/x86/src/hash.py:88

  • The hash algorithm in this script no longer matches the updated block_api.asm logic: you now seed function_hash with module_hash, but still compute h = module_hash + function_hash ..., which effectively adds the module hash twice. With the new IV-based algorithm, the final hash should be derived from function_hash alone (masked to 32-bit as needed) so that constants generated by this script match the shellcode lookup.
        module_hash += ord(c)
    function_hash = module_hash
    for c in str(function + '\x00'):
        function_hash = ror(function_hash, bits)
        function_hash += ord(c)
    h = module_hash + function_hash & 0xFFFFFFFF
    if print_hash:
        print('[+] 0x%08X = %s!%s' % (h, module.lower(), function))

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment thread external/source/shellcode/windows/x86/src/hash.py
Comment thread Gemfile Outdated
Comment thread external/source/shellcode/windows/x86/src/block/block_api.asm
Comment thread external/source/shellcode/windows/x64/src/block/block_api.asm
Copy link
Copy Markdown
Contributor

@smcintyre-r7 smcintyre-r7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pulls in the new hashing algorithm but it doesn't randomize the IV. @dledda-r7 are you intending to add that in a separate PR? The title makes it sound like this one should be using a random value now.

@jbx81-1337
Copy link
Copy Markdown
Contributor

Yes, I think this PR should include:

  • block api changes
  • update cache size

After is landed I can start porting the payloads consuming the block-api to use the randomized IV. This was done to avoid having too many changes in one PR.

Let me know if you prefer have everything here

@smcintyre-r7
Copy link
Copy Markdown
Contributor

That sounds like a good path forward, I'm just going to update the PR title then to reflect that we're not using random IVs yet.

Since #21124 was landed, you should be able to rebase this and use the payload cached size update script to fix the tests.

@jbx81-1337
Copy link
Copy Markdown
Contributor

jbx81-1337 commented Mar 18, 2026

Done 🚀

@bwatters-r7 bwatters-r7 self-assigned this Mar 19, 2026
@smcintyre-r7 smcintyre-r7 moved this from Todo to In Progress in Metasploit Framework 2026 Roadmap Mar 19, 2026
@smcintyre-r7 smcintyre-r7 changed the title Update block-api to use random IV Update block-api to prepare for a random IV Mar 20, 2026
@smcintyre-r7 smcintyre-r7 linked an issue Mar 20, 2026 that may be closed by this pull request
@dledda-r7
Copy link
Copy Markdown
Contributor Author

@zeroSteiner @smcintyre-r7, I think we should sqeeze inside this PR the new graphml for blockapi after crimson-forge updates. just in case.

asm << %Q^
failure:
push #{Rex::Text.block_api_hash('kernel32.dll', 'ExitProcess')}
mov r10d, #{Rex::Text.block_api_hash('kernel32.dll', 'ExitProcess')}
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@smcintyre-r7 I think that the new block-api caused a 32-bit value that couldn't be encoded in the push intruction, revealing this bug

Copy link
Copy Markdown
Contributor

@smcintyre-r7 smcintyre-r7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went and tested this with a 32-bit and 64-bit Meterpreter just as a sanity check and neither worked.

Comment thread Gemfile.lock Outdated
Comment on lines +2 to +6
remote: https://github.com/dledda-r7/rex-text
revision: 995d34cc4720b87ad70adeb2d6d2c7696834a276
branch: feat/block-api-iv
specs:
rex-text (0.2.59)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed this isn't an exact match with where the rex-text PR is https://github.com/rapid7/rex-text/pull/74/commits

That means we may not be testing the exact same code.

@dledda-r7
Copy link
Copy Markdown
Contributor Author

CI (almost) passing ✅

Copy link
Copy Markdown
Contributor

@smcintyre-r7 smcintyre-r7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to mark this as approved. I ran a bunch of spot checks with 32-bit and 64-bit payloads against a Windows Server 2019 target and found no issues. The current failure in CI seems to be a timeout that can also be seen on other PRs.

@github-project-automation github-project-automation bot moved this from Todo to In Progress in Metasploit Kanban Apr 14, 2026
@smcintyre-r7 smcintyre-r7 merged commit b3d367f into rapid7:master Apr 14, 2026
85 of 87 checks passed
@github-project-automation github-project-automation bot moved this from In Progress to Done in Metasploit Kanban Apr 14, 2026
@github-project-automation github-project-automation bot moved this from In Progress to Done in Metasploit Framework 2026 Roadmap Apr 14, 2026
@smcintyre-r7
Copy link
Copy Markdown
Contributor

Release Notes

This refactors the Block API code used by Windows payloads to leverage a new version of the hashing algorithm. This also fixes a bug whereby the MaximumLength field was used when calculating UNICODE_STRING names when it should have been the Length field.

@jheysel-r7 jheysel-r7 added the rn-enhancement release notes enhancement label Apr 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

rn-enhancement release notes enhancement

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

Vitamin-K Hash Collision Always Causes Windows API Resolution To Fail Update the Block API to use the Length Field

8 participants