From ea047805a7dde166ea726f63de0dd77ce1301b0e Mon Sep 17 00:00:00 2001 From: Matt Miller Date: Tue, 12 Jul 2005 22:32:46 +0000 Subject: [PATCH] brute force mixin for exploits, untested git-svn-id: file:///home/svn/incoming/trunk@2739 4d416f70-5f16-0410-b530-b9f4589650da --- lib/msf/core/exploit/brute.rb | 167 ++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 lib/msf/core/exploit/brute.rb diff --git a/lib/msf/core/exploit/brute.rb b/lib/msf/core/exploit/brute.rb new file mode 100644 index 0000000000..3763248879 --- /dev/null +++ b/lib/msf/core/exploit/brute.rb @@ -0,0 +1,167 @@ +module Msf + +### +# +# Brute +# ----- +# +# This modules provides a target-aware brute-forcing wrapper. It implements +# the exploit method and calls exploit_brute with target supplied information. +# If the selected target is not a bruteforce target, then exploit_single is +# called. +# +### +module Exploit::Brute + + def initialize(info = {}) + super + + # + # Register BruteWait and BruteStep as two advanced options for this + # exploit even though not all targets may be brute force targets + # + register_advanced_options( + [ + OptData.new('BruteWait', [ false, "Delay between brute force attempts" ]), + OptData.new('BruteStep', [ false, "Step size between brute force attempts" ]) + ], Msf::Exploit::Brute) + end + + # + # Entry point for initiating an exploit. This module wrappers the exploit + # method and determines whether or not the selected target supports brute + # force. If it does, it does some special things and wraps the brute + # forcing logic. + # + def exploit + # Is the selected target a brute force target? + if (target.bruteforce?) + # The step direction is automatically calculated + direction = {} + + bf = target.bruteforce + + # Get the start and stop address hashes + start = (bf.start_addresses && bf.start_address.dup) || {} + stop = (bf.stop_addresses && bf.stop_address.dup) || {} + step = bf.step_size + delay = bf.delay + + # Enumerate each start address and try to figure out the direction + start.each_pair { |name, addr| + # If there's a stop address, figure out if it's above or below + # the start address + if (stop[name]) + if (stop[name] < addr) + direction[name] = -1 + else + direction[name] = 1 + end + # If there's no stop address, infer the direction based on + # the default + else + direction = bf.default_direction + end + } + + # Import start/stop address overrides from the datastore + import_from_datastore(start, 'Start') + import_from_datastore(stop, 'Stop') + + # User-defined brute wait? + if (self.datastore['BruteWait']) + delay = self.datastore['BruteWait'].to_i + end + + # User-defined brute step? + if (self.datastore['BruteStep']) + step = self.datastore['BruteStep'].to_i + end + + # Okay, we've got all this crap out of the way, let's actually brute + # force + stopped = [] + curr = start.dup + + # Keep going until we run out of options + while (curr.length != stopped.length) + + # Fire off an exploit attempt with the supplied addresses + brute_exploit(curr) + + # Give it time before we try again + brute_wait(delay) + + # Scan each current key, increasing it or decreasing it by the + # step size according to its direction + curr.each_key { |k| + + # Has movement been stopped on this address? If so, skip it. + next if (stopped.include?(k)) + + # Calculate the next address before we move it to see if + # we're going to go over + next_addr = step_size * direction[k] + + # If this item has hit a stop address, add it to the stopped + # hash and move it no further + if (stop[k]) + if ((direction[k] == 1 and next_addr >= stop[k]) or + (direction[k] == -1 and next_addr < stop[k])) + stopped << k + next + end + end + + # If it's not time to stop, move it + curr[k] += next_addr + } + end + else + single_exploit + end + end + + # + # This routine is called once per brute force iteration. The addresses + # parameter is a hash of addresses that are incremented each iteration and + # are derived from the target's bruteforce information or the module's + # datastore in case they are being overriden. + # + def brute_exploit(addrs) + end + + # + # Call if the target is not a brute force target. + # + def single_exploit + end + + # + # Waits for the provide delay + # + def brute_wait(delay) + sleep(delay) + end + +protected + + # + # Imports information into the supplied hash from the datastore. + # This is a way of allowing the user to override values for a + # specific brute force target by name without them actually + # being conveyed in the options list. This is a bit of a change + # from 2.x, but 2.x didn't have per-target brute force + # addresses, which I think is more valuable. + # + def import_from_datastore(hash, prefix = '') + hash.each_key { |k| + if (self.datastore[prefix + k]) + hash[k] = self.datastore[prefix + k] + end + } + end + +end + +end