Skip to content

Conversation

@overgrowncarrot1
Copy link

@overgrowncarrot1 overgrowncarrot1 commented Sep 13, 2025

Description

SSH module that allows for commands to be ran in Linux memory.

Type of change

Insert an "x" inside the brackets for relevant items (do not delete options)

  • 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)

Setup guide for the review

Ubuntu machine with ssh enabled

Screenshots (if appropriate):

image image

I know the turtle is ugly, the rest of it looks fine just wanted to show it can run LinPeas also (or other scripts) in memory.

image

Checklist:

Insert an "x" inside the brackets for completed and relevant items (do not delete options)

  • I have ran Ruff against my changes (via poetry: poetry run python -m ruff check . --preview, 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)
  • New and existing e2e tests pass locally with my changes
  • 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 performed a self-review of my own code
  • 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)

@Marshall-Hallenbeck
Copy link
Collaborator

Very cool, thanks for the PR. It looks like the tests run the module without the options, can you add in running it with a command (just like whoami) and then a script that just has one command in it? You can add the test script in the tests data dir.

@overgrowncarrot1
Copy link
Author

Very cool, thanks for the PR. It looks like the tests run the module without the options, can you add in running it with a command (just like whoami) and then a script that just has one command in it? You can add the test script in the tests data dir.

Added, I put a script in there with 3 simple commands and updated the e2e_commands.txt file to show options with said script

@NeffIsBack
Copy link
Member

Nice one!
But why do you need to spawn another thread?

@overgrowncarrot1
Copy link
Author

Nice one! But why do you need to spawn another thread?

This is to ensure reliability, I noticed that without another thread we could not get data back reliably in real time. The other thread is to ensure that output comes back to the user in a reliable fashion without affecting netexec execution. I was also looking at integrating a kill-switch with it. For instance, utilizing the public key of a user it is sent across and those goes against the users private key, as long as both are good information continues to be sent. This is to ensure that during script, a MITM cannot happen, again that is something I was looking at with a true or false KILLSWITCH=TRUE in options and mostly just for red team operations, the other thread would be needed for that.

@NeffIsBack
Copy link
Member

Nice one! But why do you need to spawn another thread?

This is to ensure reliability, I noticed that without another thread we could not get data back reliably in real time. The other thread is to ensure that output comes back to the user in a reliable fashion without affecting netexec execution. I was also looking at integrating a kill-switch with it. For instance, utilizing the public key of a user it is sent across and those goes against the users private key, as long as both are good information continues to be sent. This is to ensure that during script, a MITM cannot happen, again that is something I was looking at with a true or false KILLSWITCH=TRUE in options and mostly just for red team operations, the other thread would be needed for that.

I can see why you would like to have a life feed of the output of the execution, but i am not sure if that is the way to go. NetExec is designed to have synchronous execution per host. Adding threads inside the protocol thread can have a bunch of unwanted side effects such as race conditions in NetExec, hanging threads that result in NetExec not finishing etc. Usually you would execute a command, wait until the command has finished, retrieve the output of that command and than format/print the result via the nxc_logger. Imo we shouldn't introduce yet another thread just for asynchronous output, which could heavily mess influence other parts of NetExec as a side effect.

A few other notes:

  • If you have errors in the command you want to display please use the .fail() logging function
  • You don't need to prepend logging output with [ephemeral] because this is already done by the nxc_logger itself at the start of the line
  • You have pushed the same file in /modules/ephemeral.py and /nxc/modules/ephemeral.py. The first one is probably an unwanted duplicate

@overgrowncarrot1
Copy link
Author

Nice one! But why do you need to spawn another thread?

This is to ensure reliability, I noticed that without another thread we could not get data back reliably in real time. The other thread is to ensure that output comes back to the user in a reliable fashion without affecting netexec execution. I was also looking at integrating a kill-switch with it. For instance, utilizing the public key of a user it is sent across and those goes against the users private key, as long as both are good information continues to be sent. This is to ensure that during script, a MITM cannot happen, again that is something I was looking at with a true or false KILLSWITCH=TRUE in options and mostly just for red team operations, the other thread would be needed for that.

I can see why you would like to have a life feed of the output of the execution, but i am not sure if that is the way to go. NetExec is designed to have synchronous execution per host. Adding threads inside the protocol thread can have a bunch of unwanted side effects such as race conditions in NetExec, hanging threads that result in NetExec not finishing etc. Usually you would execute a command, wait until the command has finished, retrieve the output of that command and than format/print the result via the nxc_logger. Imo we shouldn't introduce yet another thread just for asynchronous output, which could heavily mess influence other parts of NetExec as a side effect.

A few other notes:

  • If you have errors in the command you want to display please use the .fail() logging function
  • You don't need to prepend logging output with [ephemeral] because this is already done by the nxc_logger itself at the start of the line
  • You have pushed the same file in /modules/ephemeral.py and /nxc/modules/ephemeral.py. The first one is probably an unwanted duplicate

@overgrowncarrot1
Copy link
Author

Sorry it took so long, work, however, I have updated the ephermal.py to not use threads.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants