[netexec] feat: add NetExec injector with contracts, helpers and tests (#170)#188
Conversation
Add the netexec injector module including: - Protocol-based contracts (SMB, SSH, FTP, etc.) with module support - Command builder, output parser and process helpers - Credential extractors and modules registry - Docker and configuration setup - Updated root .gitignore to exclude local dev files
89 tests covering: - Contract ID parsing (base, option, module families) - Command builder (credentials, options, modules, security) - Output parser (filtering, dispatching, asset mapping) - Credential extractors (SAM, LSA, NTDS, shares, groups, vulns)
Add manifest-metadata.json and [tool.cmw] section required by the OpenAEV catalog to discover and deploy the injector via the UI. Also align pyproject.toml to PEP 621 format, standardize docker-compose.yml with variable substitution, and add .env.sample.
| if input_data is not None: | ||
| kwargs["input"] = input_data | ||
|
|
||
| result = subprocess.run(cmd, **kwargs) |
There was a problem hiding this comment.
subprocess.run(cmd, **kwargs) has no timeout. If netexec hangs on a slow/unreachable target, the thread running this inject will never terminate. Should we add a configurable timeout here (e.g. timeout read from config, defaulting to 3600s) and handle subprocess.TimeoutExpired with a clean error, similar to what the AWS injector does in pacu_executor.py?
There was a problem hiding this comment.
Hey @ncarenton good point, I didn't see neither on nuclei/Nmap nor Shodan don't you think we should define this kind of global injector good practices and applied them to the whole injectors and add it through something like "good_practices.md" to avoid that in the next injectors and the previous ones ?
| options = parsed_data.get("options") if parsed_data else None | ||
| extra_args = parsed_data.get("extra_args") if parsed_data else None | ||
|
|
||
| self.helper.injector_logger.info("Data: " + str(content)) |
There was a problem hiding this comment.
Two places might leak credentials:
- line 90 logs the raw content dict which includes credentials
- lines 100–113 pass
command_args=cmdtobuild_execution_message,
andcmdcontains["-p", "P@ssw0rd!", "-H", "aad3b435..."], so credentials are sent to the OpenAEV API.
Should we scrub credential fields before logging, and strip args following -p, -H, --password etc. from cmd before passing it to build_execution_message?
There was a problem hiding this comment.
Hey @ncarenton good point again, same feedback as the previous, that's a global "concern" to the whole injectors we could provide the "good practice" here and then apply on the others. About credentials we have planned on the roadmap "vertical 2" to add new kind of credentials assets which will involve integration team to define the best way to handle it
There was a problem hiding this comment.
I block my own contribution.
I'm not sure if its a desired behavior to only have output in "Inject Execution Details" or if i need to fix that point too.
Edit: Also, a really important information:
This PR OpenAEV-Platform/client-python#192 is mandatory befor the actual one !
Since netexec use the new ContractOutputType like Credentials in contract_output,py`
2b8d454 to
839b465
Compare
Hey so sorry I didn't seen the tagged ! It's normal for injector the traces are only available in Inject Execution Details and never on endpoints tab. And other thing a PR on back/frontend side is mandatory too to add the contractoutputtype to pass through client-python to injector + a frontend item unlock: OpenAEV-Platform/openaev#5092 That's why I wanted to add a dedicated major release as it's a huge a lot of new content added through that injector with the whole workflow |
Thanks, will let it as "Request Changes" and 'Do Not Merge' until the required PR(s) are merged ! |










Summary
--asreproast,--kerberoasting,--shares) and modules (e.g.spider_plus,mssql_priv)Test plan
Closes #170