fix(coerce_plus): move get_dynamic_endpoint back to module-level function#1131
Conversation
|
Claude did a pretty good job here, but checked "I have linked relevant sources that describes the added technique (blog posts, documentation, etc)" for some reason. Overall not bad because I put in minimal feedback! |
6ae0df5 to
194cb3b
Compare
…tion Commit 81c6d9f (PR #866) moved get_dynamic_endpoint from a module-level function to a @staticmethod on NXCModule. This broke coerce_plus when used with any other -M module that loads after it, because the module loader uses the same sys.modules key for all modules, causing the NXCModule class reference to be overwritten by whichever module loads last. As a module-level function, get_dynamic_endpoint is not resolved through the NXCModule class name and is unaffected by the collision. Also makes the [dcerpc] endpoint resolution lazy so it only runs when that pipe is actually selected, avoiding an unnecessary network call to port 135 on every target. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
194cb3b to
41b3fc2
Compare
|
@NeffIsBack this is now just the staticmethod fix |
There was a problem hiding this comment.
Pull request overview
Fixes an order-dependent failure in coerce_plus when multiple -M modules are loaded by moving get_dynamic_endpoint back to a module-level helper, avoiding reliance on NXCModule class attributes under the current module loader behavior.
Changes:
- Move
get_dynamic_endpointfromNXCModulestaticmethod back to a module-level function. - Update callers to use
get_dynamic_endpoint(...)directly. - Make
[dcerpc]endpoint resolution lazy (only resolve when that pipe is selected).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
NeffIsBack
left a comment
There was a problem hiding this comment.
The current state LGTM, but there are a lot of unresolved conversations. @Marshall-Hallenbeck do you want to merge it like that? We should probably either resolve the conversations or work on them.
Lemme take a look, I had/have copilot auto-enabled for my PRs but sometimes it just posts garbage. |
|
@NeffIsBack good from my end |

Description
Commit 81c6d9f (PR #866) moved
get_dynamic_endpointfrom a module-level function to a@staticmethodonNXCModule. This brokecoerce_pluswhen used with any other-Mmodule, because the module loader uses the samesys.moduleskey ("NXCModule") for all module files. Whichever module loads last overwrites theNXCModuleclass in the shared namespace, socoerce_plus's helper classes (PrinterBugTrigger,PetitPotamtTrigger) resolve a different module'sNXCModuleclass — one that doesn't haveget_dynamic_endpoint.The error is order-dependent:
-M coerce_plus -M ms17-010→ broken (ms17-010 loads last, overwritesNXCModule)-M ms17-010 -M coerce_plus→ works (coerce_plus loads last, its own class persists)-M coerce_plusalone → works (nothing to overwrite it)This is why the bug hasn't been reported — it only appears when combining
coerce_pluswith other modules ANDcoerce_plusisn't last in the list.Fix: Move
get_dynamic_endpointback to a module-level function (reverting the relocation from 81c6d9f). As a module-level name, it isn't resolved through theNXCModuleclass and is unaffected by the namespace collision. Also makes the[dcerpc]endpoint resolution lazy so it only runs when that pipe is selected, avoiding an unnecessary network call to port 135 on every target.The underlying module loader collision is addressed separately in PR #1132.
AI disclosure: Claude Code (Claude Opus 4.6) was used to assist with root cause analysis and drafting the fix. The bug was discovered during a real pentest scan, root cause was traced and verified by human and AI together, and the fix was human-reviewed and tested on live targets.
Type of change
Setup guide for the review
How to trigger the bug:
Run
coerce_pluswith any other module wherecoerce_plusis NOT last:You will see
Error in PrinterBug module: type object 'NXCModule' has no attribute 'get_dynamic_endpoint'for every target.Swap the order so coerce_plus is last and it works:
Tested on:
Screenshots (if appropriate):
Screenshots to be attached.
Checklist:
poetry run ruff check ., use--fixto automatically fix what it can)tests/e2e_commands.txtfile if necessary (new modules or features are required to be added to the e2e tests)