Please Describe The Problem To Be Solved
First of all, this is an enhancement that I'd be open to implement myself via a Pull Request, but it is sufficiently complex that I'd like to discuss with maintainers before starting work on it, to determine the best course of implementation.
Many actions in netexec have prerequisites, such as:
- Having credentials,
- Having admin rights on the targets,
- The target having a specific service enabled (ad cs, etc.).
And there is no feature to automatically select the right set of credentials to apply a given module or action on the right set of targets.
Currently, netexec has the -id feature allowing to do something using some or all known credentials
But credentials selection remain manual (you have to export the creds table and do a lot of grepping to e.g., get a list of all users with admin rights on one machine)
Target selection remains also largely manual, you similarly have to extract tables and use grep to e.g., get a list of targets where you have at least one set of credentials with administrative rights.
And you also have to manually keep track of "what's been done with this set of credentials on which targets", there is no easy way to determine "ok I have dumped dpapi secrets on this set of machines, but I just got a new set of credentials, I'd like to know if they have admin rights on new machines, and possibly dump dpapi secrets on these new machines"
In a typical engagement, that means I usually end up with hundreds of CSV files with names like "new_admin_creds_to_try" and I do a lot of grep|cut|join to get my lists of credentials and targets to move on to the next step.
It would be nice if netexec provided a way to do away with all these CSV files and provided a smart built-in creds and target selection.
Suggested Solution
I've delved into the code base a bit to see how this could be done pragmatically, and here are my first ideas:
- Add an "auto" keyword to the "-u", "-p", "-id" options as well as the target selection
a command may thus look like: nxc smb auto -id auto --shares
- Where credentials selection happen (typically where the "all" keyword of the "-id" selection is processed), introduce logic that would:
a) Have a look at the arguments (what we are doing),
b) If autoselection is not currently implemented for one of the actions selected, raise something like NotImplementedError,
c) Infer the prerequisites from what we are currently doing ("does enumerating shares require admin rights ? No, we can try with all credentials in the db") ("does dumping sam require admin rights ? yes, filter out all creds with an admin count of 0"),
d) Automatically select from the db the set of credentials that meet the prerequisites, based on the highest prerequisites (if something requires admin rights, filter out all credentials that are not admin).
- Apply a similar logic for target selection:
a) Have a look at the arguments (what we are doing),
b) If autoselection is not currently implemented for one of the actions selected, raise something like NotImplementedError,
c) Infer the prerequisites from what we are currently doing ("does enumerating shares require admin rights ? No, we can try with all hosts in the db") ("does dumping sam require admin rights ? yes, filter out all hosts where we have no admin creds"),
d) Automatically select from the db the set of credentials that meet the prerequisites, based on the highest prerequisites (if something requires admin rights, filter out all credentials that are not admin).
It can even be smarter: if what we are doing requires local admin rights on one machine, and we have more than one set of admin credentials, it is unlikely that we need to do it more than once, so we should only keep one set of (cred, target) per target in this case (ex: there is no need to dump SAM twice). This seems harder to implement however, and may not be feasible at credentials selection time (if we have the creds A, B C, A and B being admin on target X, B being admin on target Y and C being admin on target Z, then we can neither remove A nor B).
And the cherry on top, an addition that would make this feature truly amazing:
- Create a table in the db, to keep track of what has been done on each target with each set of credentials. Did we enumerate shares on this target with these creds already ?
- If indeed something has already been done on a target, do not do it again (remove the set of credentials from the selection if the action does not require admin rights, remove the target otherwise)
- The db would be updated automatically, but I don't know yet where in the code (maybe as a module? I need to delve a bit deeper in the code to have a clearer picture).
- This feature would be opt-in or opt-out (preferably opt-in, with a new switch?), and may or may not be implemented at the same place as smart creds/target selection (in which case only this selection method would benefit) or elsewhere (in which case it may also be enabled with the usual creds input methods)
In fact, this "caching" mechanism would probably be implemented at a later time (different Pull Request) than the previously discussed selection mechanism.
- Some finesse might be required: if lsass has been dumped with lsassy, surely there is no need to do it again with another method
The problems and challenges of these ideas are that they fall apart pretty fast (or rather, the complexity explodes) if one is trying to do multiple things (like enumerating shares and dumping dpapi secrets) simultaneously, because filtering becomes a nightmare (we've already enumerated shares but not dumped the secrets, so can't filter things at target selection, and introducing logic down the line will quickly become very annoying and unmaintainable. To address this, I'd like at first to tell users that doing more than one actions is unsupported and raise an error, but there may be a better, smarter way.
Also, it has the potential of being a footgun (users locking accounts and crashing stuff) and introduce bugs, so I'd like to tackle this conservatively, by first implementing the scaffolding (adding support for these arguments in args parsing and raising appropriate NotImplementedError on target/creds selection, before writing selection logic)
also, the whole DB caching would be implemented after at least some trivial actions such as listing shares are already done
I do not expect to really start work on this right away (I'll probably start this summer), so this is supposed to be a long-standing issue, I'm posting it mostly to get feedback from maintainers ahead of time
Please Describe The Problem To Be Solved
First of all, this is an enhancement that I'd be open to implement myself via a Pull Request, but it is sufficiently complex that I'd like to discuss with maintainers before starting work on it, to determine the best course of implementation.
Many actions in netexec have prerequisites, such as:
And there is no feature to automatically select the right set of credentials to apply a given module or action on the right set of targets.
Currently, netexec has the -id feature allowing to do something using some or all known credentials
But credentials selection remain manual (you have to export the creds table and do a lot of grepping to e.g., get a list of all users with admin rights on one machine)
Target selection remains also largely manual, you similarly have to extract tables and use grep to e.g., get a list of targets where you have at least one set of credentials with administrative rights.
And you also have to manually keep track of "what's been done with this set of credentials on which targets", there is no easy way to determine "ok I have dumped dpapi secrets on this set of machines, but I just got a new set of credentials, I'd like to know if they have admin rights on new machines, and possibly dump dpapi secrets on these new machines"
In a typical engagement, that means I usually end up with hundreds of CSV files with names like "new_admin_creds_to_try" and I do a lot of grep|cut|join to get my lists of credentials and targets to move on to the next step.
It would be nice if netexec provided a way to do away with all these CSV files and provided a smart built-in creds and target selection.
Suggested Solution
I've delved into the code base a bit to see how this could be done pragmatically, and here are my first ideas:
a command may thus look like:
nxc smb auto -id auto --sharesa) Have a look at the arguments (what we are doing),
b) If autoselection is not currently implemented for one of the actions selected, raise something like NotImplementedError,
c) Infer the prerequisites from what we are currently doing ("does enumerating shares require admin rights ? No, we can try with all credentials in the db") ("does dumping sam require admin rights ? yes, filter out all creds with an admin count of 0"),
d) Automatically select from the db the set of credentials that meet the prerequisites, based on the highest prerequisites (if something requires admin rights, filter out all credentials that are not admin).
a) Have a look at the arguments (what we are doing),
b) If autoselection is not currently implemented for one of the actions selected, raise something like NotImplementedError,
c) Infer the prerequisites from what we are currently doing ("does enumerating shares require admin rights ? No, we can try with all hosts in the db") ("does dumping sam require admin rights ? yes, filter out all hosts where we have no admin creds"),
d) Automatically select from the db the set of credentials that meet the prerequisites, based on the highest prerequisites (if something requires admin rights, filter out all credentials that are not admin).
It can even be smarter: if what we are doing requires local admin rights on one machine, and we have more than one set of admin credentials, it is unlikely that we need to do it more than once, so we should only keep one set of (cred, target) per target in this case (ex: there is no need to dump SAM twice). This seems harder to implement however, and may not be feasible at credentials selection time (if we have the creds A, B C, A and B being admin on target X, B being admin on target Y and C being admin on target Z, then we can neither remove A nor B).
And the cherry on top, an addition that would make this feature truly amazing:
In fact, this "caching" mechanism would probably be implemented at a later time (different Pull Request) than the previously discussed selection mechanism.
The problems and challenges of these ideas are that they fall apart pretty fast (or rather, the complexity explodes) if one is trying to do multiple things (like enumerating shares and dumping dpapi secrets) simultaneously, because filtering becomes a nightmare (we've already enumerated shares but not dumped the secrets, so can't filter things at target selection, and introducing logic down the line will quickly become very annoying and unmaintainable. To address this, I'd like at first to tell users that doing more than one actions is unsupported and raise an error, but there may be a better, smarter way.
Also, it has the potential of being a footgun (users locking accounts and crashing stuff) and introduce bugs, so I'd like to tackle this conservatively, by first implementing the scaffolding (adding support for these arguments in args parsing and raising appropriate NotImplementedError on target/creds selection, before writing selection logic)
also, the whole DB caching would be implemented after at least some trivial actions such as listing shares are already done
I do not expect to really start work on this right away (I'll probably start this summer), so this is supposed to be a long-standing issue, I'm posting it mostly to get feedback from maintainers ahead of time