Update block-api to prepare for a random IV#21085
Update block-api to prepare for a random IV#21085smcintyre-r7 merged 13 commits intorapid7:masterfrom
Conversation
|
@zeroSteiner we will need to update all the cache size that are using |
There was a problem hiding this comment.
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.asmto seed function hashing with the module hash (and adjust module name length field offsets). - Update
hash.pyto reflect the new hashing approach (currently has correctness issues). - Add a temporary git-sourced
rex-textdependency (and lock it inGemfile.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.asmlogic: you now seedfunction_hashwithmodule_hash, but still computeh = module_hash + function_hash ..., which effectively adds the module hash twice. With the new IV-based algorithm, the final hash should be derived fromfunction_hashalone (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.
smcintyre-r7
left a comment
There was a problem hiding this comment.
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.
|
Yes, I think this PR should include:
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 |
|
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. |
|
Done 🚀 |
|
@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')} |
There was a problem hiding this comment.
@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
smcintyre-r7
left a comment
There was a problem hiding this comment.
I went and tested this with a 32-bit and 64-bit Meterpreter just as a sanity check and neither worked.
| remote: https://github.com/dledda-r7/rex-text | ||
| revision: 995d34cc4720b87ad70adeb2d6d2c7696834a276 | ||
| branch: feat/block-api-iv | ||
| specs: | ||
| rex-text (0.2.59) |
There was a problem hiding this comment.
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.
Allow the block API hashing algorithm to accept an IV
|
CI (almost) passing ✅ |
smcintyre-r7
left a comment
There was a problem hiding this comment.
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.
Release NotesThis 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 |
Fix: #19309
Update block-api to use random IV