Support RHOSTS for exploit modules#9246
Conversation
|
I will get this tested. My first instinct is to say that there be dragons here as we have tried this before and if memory serves things went south. That said, will review and do all I can to help it land, this has been much needed for a long time (PSH wmi for one already does this sort of madness). |
|
I've had a positive reactions from a few pen testers who are already using this. I've also been looking closely at how 'check' does this and will be following this up with some refactors so they both work in a similar way. |
|
Very handy! Reading RHOSTS from a file does not work yet, right? |
|
I'm not fundamentally opposed to the idea of this, but as @sempervictus mentioned there are dragons. I've discussed this with @hdm, @busterb, @wvu, and many others over the years. The biggest difficulty is the difference in victims as regards to payload compatibility. Theoretically, different Targets can have different size constraints but in practice there are zero exploits that actually do. Exploits targeting multiple operating systems and multiple architectures are a bigger concern. In practice, it's less of an issue because when you find a group of vulnerable boxes, they're quite often all the same, but we still need to be careful about e.g. sending x64 shellcode to an x86 process. |
|
So, about them dragons - this breaks Aux scanners pretty badly. If you pry into http/version scanner and run_host(ip) you're ok, but hitting cmd_run doesnt seem to get there. Think i'mma need to revert this till i can devote some time to digging around in the subtleties of how Aux and Exp execute their runners. |
|
Yes, aux scanner modules use the same trick as this PR. To complete this, we need to move the differentiated logic from the different module types and have only one cook in the kitchen slinging the RHOSTS values one by one into the module datastores. |
| # @return [OptAddress] | ||
| def self.RHOST(default=nil, required=true, desc="The target address") | ||
| Msf::OptAddress.new(__method__.to_s, [ required, desc, default ]) | ||
| Msf::OptAddressRange.new('RHOSTS', [ required, desc, default ], aliases: [ 'RHOST' ]) |
There was a problem hiding this comment.
FYI, this line is what is killing scanners, I believe. Specifically, the RHOST alias. If you remove the alias, then aux scanners appear to work (or at least have RHOSTS values). My best guess right now is that when we added redundant code to tear out RHOST in AUX to prevent confusion, this alias causes the logic that tore out RHOST to tear out RHOSTS, too.
There was a problem hiding this comment.
Gah....... I saw this earlier and thought I checked it. Yeah; the changes in #7127 likely delete the RHOSTS from the datastore since it is aliased. Removing the setup/cleanup functions makes the smb1 scanner and 08_067 appear to work like a champ.
There was a problem hiding this comment.
I thought I had mentioned this earlier. We can't do this though, because I want to kill RHOST as a user-visible option.
What needs to happen is the code in the 'run' method in lib/msf/core/auxiliary/scanner.rb needs to mostly be merged with the code in at this PR adds, or at least modified so it's using the datastore clone trick that we're using here.
There was a problem hiding this comment.
Whatever the common parent of Msf::Exploit and Msf::Auxiliary is, I think we can make a single run method that knows how to run them all in this mode. The main difference I think would be around whether parallelism is allowed or not, with the different module types.
There was a problem hiding this comment.
# RHOST should not be used in scanner modules, only RHOSTS
deregister_options('RHOST')
this is only one place where we do it (then it proceeds to use it as a temp variable)
| rhosts = mod.datastore['RHOSTS'] | ||
| if rhosts | ||
| Rex::Socket::RangeWalker.new(rhosts).each do |rhost| | ||
| nmod = mod.replicant |
There was a problem hiding this comment.
the way this patch works and avoids clobbering the global RHOSTS value when it sets RHOSTS per-run to a single value is to call 'replicant', which makes a fully copy. This is opposed to aux scanner which assumes that RHOST and RHOSTS coexist. But to hide that sausage-making in the background, we have dozens of unregister RHOST calls in aux scanners, that we could remove after this.
|
The above push fixes scanners (to my knowledge). It turns out that we 'fixed' problems we had with RHOST earlier by simply deleting it in the setup function for aux/scanner. This worked great, but to avoid confusion and support legacy stuff, this PR aliased RHOST and RHOSTS. Unfortunately while that was an awesome idea for exploits, it meant that when you launched a scanner module, the first step in the setup process was deleting all your targets. 😢 I removed the setup/cleanup functions and some other stuff related to RHOST as an independent concept, and it seems to work (at least with SMBv1 scanner. |
|
Are there any more dragons on this PR? Should we look to merge this now? |
|
Definitely gremlins in here, for example: |
|
I am pretty sure replicant is used in other contexts where this can go wrong (maybe MSPro?). |
|
My vote is "do not merge, will eat your pets." In testing it breaks aux all over the place. |
| if (self.respond_to?('run_host')) | ||
|
|
||
| loop do | ||
| if @range_count > 0 |
Without this, we are missing methods like exploit_simple. https://coderwall.com/p/1zflyg/ruby-the-differences-between-dup-clone
foot-shooting scanner modules
|
@sempervictus did you test 0d51ba8 or was that prior? |
|
We are not concerned about preserving MSPro compatibility with this change, by the way. I haven't stumbled into a way to break an aux module yet, but will keep trying. In the mean time, I'll look into cleaning up some aux code so it's actually shared here. |
|
Prior, I had to back it out a while ago. Will re-merge on the next window. |
|
Jenkins test this please. |
|
Do we have any status if this code is up to par ? |
Up to par with what? If you're asking whether or not it works without breaking everything in sight, it seems to, on my end anyway (though merge conflicting a decent chunk of my altered command_dispatcher/exploit, which i imagine wont be a problem for everyone else given Jenkins' approval). @busterb: it looks like its working so far, aux scanners and exploits both execute, threading appears to work. Will keep using it during sniffer & dns testing. |
|
Alright; I'm going to restart testing this and land this. If there are any last concerns, voice them. |
|
Well, this is a bit of an irritant, because as it is, with most of our exploits, this stops after the first successful exploit. I wish it were a simple matter to enable something like Regardless, this is still useful, and it is increasingly falling behind master, so I'm just going to merge it and wait for the sound of shattering glass. We can address increasing usefulness of the feature later. |
|
Each one of those handler threads has a database connection (thanks, ActiveRecord!), so that might lead to some problems with resource starvation if you can't control how many spin up. May not impact if we want to land it, but we should be aware. |
|
I had not planned on adding the changes to the handlers until I can make them not explode, and I might as well do that in another PR, anyway. |
|
@bwatters-r7 isn't there a callback when a session is created. Could that be leveraged? The callback could be modified to send the uuid (if it doesn't already). I'm not sure that is enough, along with the session information, to make useful determinations in this situation, but thought I would throw it out there. Admittedly, I don't %100 grok the full situation here. On a related note, I've always dreamed of the ability to have a callback from multi/handler that could identify the exploit used to get the session. I realize that's unrealistic as you'd somehow have to relay uniquely identifiable info, but man it'd be sweet for tracking. |
|
@kernelsmith I do not entirely grok it myself, so absolutely happy to take advice! I'm not sure that leveraging the callback would work, though I've been embarrassingly wrong before on this stuff, so I' not going to say no. Honestly, in the darkest night, I even thought about making a silly, kludgey script that just ran 'background' as the autorun script. Likely, that would work, though I really like the idea of supporting a universal handler, as I can see some benefits as the payloads get smarter, but at least my attempts over the last 2 days suggested it is non-trivial (for me, at least). |
Release NotesThis PR allows the user to specify an IP range when using remote exploits. |
This adds initial support for RHOSTS with exploit modules. What this does is:
This doesn't:
There are lots of things we can do on top of this to make it even better, so looking forward to feedback and improvements..