Skip to content

[netexec] feat: add NetExec injector with contracts, helpers and tests (#170)#188

Merged
ncarenton merged 16 commits intorelease/currentfrom
issue/170-add-netexec-injector
Apr 8, 2026
Merged

[netexec] feat: add NetExec injector with contracts, helpers and tests (#170)#188
ncarenton merged 16 commits intorelease/currentfrom
issue/170-add-netexec-injector

Conversation

@Seb-MIGUEL
Copy link
Copy Markdown
Contributor

Summary

  • Add full NetExec injector supporting SMB, LDAP, WinRM, SSH, FTP, MSSQL, RDP, VNC, WMI protocols
  • Support for base commands, options (e.g. --asreproast, --kerberoasting, --shares) and modules (e.g. spider_plus, mssql_priv)
  • Structured output parsing with domain-specific finding types (credentials, usernames, shares, groups, vulnerabilities, etc.)
  • Catalog compatibility via manifest metadata
  • Unit tests for contracts, command builder, output parser and credential extractors

Test plan

  • Unit tests pass (contracts, helpers, credential extractors, output parser)
  • Manual testing against live GOAD lab (SMB, LDAP with various options)
  • Docker image builds and runs successfully
  • Injector registers correctly with OpenAEV platform
  • Structured findings are properly extracted and displayed

Closes #170

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.
@Seb-MIGUEL Seb-MIGUEL linked an issue Mar 5, 2026 that may be closed by this pull request
@Seb-MIGUEL Seb-MIGUEL changed the title [netexec] feat: add NetExec injector with contracts, helpers and tests [netexec] feat: add NetExec injector with contracts, helpers and tests (#170) Mar 5, 2026
if input_data is not None:
kwargs["input"] = input_data

result = subprocess.run(cmd, **kwargs)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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?

Copy link
Copy Markdown
Contributor Author

@Seb-MIGUEL Seb-MIGUEL Mar 9, 2026

Choose a reason for hiding this comment

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

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 ?

Comment thread netexec/netexec/openaev_netexec.py Outdated
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))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Two places might leak credentials:

  • line 90 logs the raw content dict which includes credentials
  • lines 100–113 pass command_args=cmd to build_execution_message,
    and cmd contains ["-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?

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.

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

@ncarenton ncarenton requested a review from mariot March 8, 2026 20:03
@Kakudou Kakudou self-requested a review March 11, 2026 07:32
@ncarenton ncarenton added the do not merge Do not merge this PR until this tag will be removed label Mar 16, 2026
@ncarenton ncarenton changed the base branch from main to release/current March 17, 2026 08:17
@Kakudou
Copy link
Copy Markdown
Member

Kakudou commented Mar 18, 2026

The injector is well loaded:
Before start:
Screenshot from 2026-03-18 21-36-12

After Start:
Screenshot from 2026-03-18 21-39-07

The tests still green:
Screenshot from 2026-03-18 21-13-59

All the contracts:
Screenshot from 2026-03-18 21-39-39

Before we had a credentials leak, in both logs and output:
Screenshot from 2026-03-18 22-13-31
Screenshot from 2026-03-18 22-13-43

Now, we have redacted value (except for the final ouput of the command, i think we must keep this one):
Screenshot from 2026-03-18 21-59-16
Screenshot from 2026-03-18 21-59-31

But, still a point i'm not sure about, once an execution ended in success, as seen in this trace:
Screenshot from 2026-03-18 22-09-29
The UI still show, "Unknown Result" no "Execution" and no "terminal view".
Screenshot from 2026-03-18 22-10-02

The only output visible is the callback of the command in "Inject Execution Details"

Also, i haven't tested all the contracts, since i don't have a lab for.

Copy link
Copy Markdown
Member

@Kakudou Kakudou left a comment

Choose a reason for hiding this comment

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

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.

@Seb-MIGUEL , @ncarenton

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`

@Kakudou Kakudou force-pushed the issue/170-add-netexec-injector branch from 2b8d454 to 839b465 Compare March 18, 2026 21:31
@Kakudou Kakudou self-assigned this Mar 18, 2026
@Seb-MIGUEL
Copy link
Copy Markdown
Contributor Author

Seb-MIGUEL commented Mar 20, 2026

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.

@Seb-MIGUEL , @ncarenton

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`

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

@Kakudou
Copy link
Copy Markdown
Member

Kakudou commented Mar 23, 2026

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 !

@Kakudou Kakudou added the filigran team use to identify PR from the Filigran team label Mar 23, 2026
@ncarenton ncarenton merged commit 6fdfc36 into release/current Apr 8, 2026
15 checks passed
@ncarenton ncarenton deleted the issue/170-add-netexec-injector branch April 8, 2026 07:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

do not merge Do not merge this PR until this tag will be removed filigran team use to identify PR from the Filigran team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Netexec Injector

3 participants