Skip to content

feat: add sipexec exec method - #1363

Open
KriyosArcane wants to merge 1 commit into
Pennyw0rth:mainfrom
KriyosArcane:sipexec-nothreads
Open

feat: add sipexec exec method#1363
KriyosArcane wants to merge 1 commit into
Pennyw0rth:mainfrom
KriyosArcane:sipexec-nothreads

Conversation

@KriyosArcane

Copy link
Copy Markdown
Contributor

This PR and exec method originate from my research presented at DEFCON Red Team Village: Trust Me, Bro: Breaking Windows Authenticode Trust. I initially added this method for my own use, but I am opening a PR in case you guys see it fit for everyone.

This slightly older version might help explain the chain better:
image

Description

This adds sipexec as a new --exec-method for the SMB protocol. SIPExec performs lateral movement by hijacking the WinVerifyTrust FinalPolicy trust provider registry key, causing wmiprvse.exe to load a payload DLL when WMI triggers signature verification.

How it works:

  1. Uploads a DLL to C:\Windows\Temp via the existing SMB connection. I have a working version that is fully fileless over self-hosted SMB, but I think this is better for most. If you guys decide fully fileless (no more poly dll) is also good to add, I can PR that too.
  2. Hijacks HKLM\...\FinalPolicy\{GENERIC_VERIFY_V2}\$DLL via WMI StdRegProv
  3. Fires Win32_PnPSignedDriver WMI query, which triggers WinVerifyTrust in wmiprvse.exe, loading our DLL. It is not the only way to trigger it remotely, but it is my preferred way currently. If signatured, I could switch it out to a different process and trigger method.
  4. DLL creates a named pipe and impersonates the connecting client; commands run as the authenticated user via token impersonation. By default, it runs as network service user, which already has permissions to SeImpersonate. Again, pipe is only a preference. It could execute any DLL, meaning you can do anything you like in that DLL.
  5. Registry restored, wmiprvse killed, DLL deleted on cleanup.

It initially ran multithreaded to overlap independent steps, but based on feedback that multithreading may exhaust resources when running against many hosts, I redesigned it to be fully sequential.

One thing that may make you question it is probably the DLL patching. As static files gets signatured almost instantly in a repo this popular, the DLL being used here (initially meant to be customized) is patched at runtime by a secondary Python script to leave minimal static sections in an attempt to increase its lifetime.

image

If you have used AI in any form, please state the tool you used (e.g. Claude Code, Cursor, Amp) along with the extent that the work was AI-assisted. See the project's AI policy for more details: https://github.com/Pennyw0rth/NetExec/blob/main/AI_POLICY.md

I have used Claude Opus 4.6 for coding. I did a manual review of the code. I have done tests against multiple hosts.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Deprecation of feature or functionality
  • This change requires a documentation update
  • This requires a third party update (such as Impacket, Dploot, lsassy, etc)
  • This PR was created with the assistance of AI (list what type of assistance, tool(s)/model(s) in the description)

Screenshots

image

As of right now, it's fully undetected by Elastic EDR.

Checklist:

  • I have ran Ruff against my changes (poetry: poetry run ruff check ., use --fix to automatically fix what it can)
  • I have added or updated the tests/e2e_commands.txt file if necessary (new modules or features are required to be added to the e2e tests)
  • If reliant on changes of third party dependencies, such as Impacket, dploot, lsassy, etc, I have linked the relevant PRs in those projects
  • I have linked relevant sources that describes the added technique (blog posts, documentation, etc)
  • I have performed a self-review of my own code (not an AI review)
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation (PR here: https://github.com/Pennyw0rth/NetExec-Wiki)

WinVerifyTrust FinalPolicy hijack for lateral movement.
Zero threading, single DCOM (dual namespace via one login).
Polymorphic DLL, non-blocking FinalPolicy, admin impersonation.
~3.3s local, ruff clean, clean DLL deletion after kill.
@github-actions

Copy link
Copy Markdown

It looks like the PR template may not have been filled out. The following sections appear to be missing:

  • Setup guide for the review

Please edit your PR description to include them. The template helps reviewers understand and test your changes. Thanks!

@XiaoliChan

XiaoliChan commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Interesting, "SetStringValue" will not trigger EDR? @KriyosArcane Would U like to share the paper for this research?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants