Dns enum threaded bf #852

Closed
wants to merge 11 commits into from

7 participants

@sempervictus

Allow threading DNS brute force attempts, logging found hosts, and ignoring wildcard results in brute force.

RageLtMan added some commits Oct 1, 2012
RageLtMan Add multi-threaded bruteforce mode and reporting
This commit allows splitting the DNS brute force process into
separate threads each running against a segment of the wordlist.
The wildcard method was modified to return the wildcard address if
one is found in order to exclude it from the brute force results.
Lastly, hosts found via brute force can be reported as new targets.
3ac6f66
RageLtMan clean up threaded bf and rvl 155d01d
RageLtMan Merge branch 'master' of https://github.com/rapid7/metasploit-framework
… into dns_enum_threaded_bf
a29df25
RageLtMan Only perform reverse lookups against DB hosts
This commit adds a boolean option to limit reverse lookups to
existing hosts. Reverse lookups are threaded anyway, and this
helps all the more with quick name lookups for known IPs.

Testing: populate DB with some hosts, run reverse lookup with
IPRANGE set to 0.0.0.0/0.
1160591
RageLtMan Module cleanup and additions
Allow reporting of found A records
Proper handling of brute forced domains (AAAA converted to A)
RVL call cleanup
95627d1
RageLtMan add dns enum rc script 455d38b
RageLtMan dns_enum rc fixup 6c840f9
RageLtMan chomp proper "." 36a1e8b
@brandonprry

Hey, I know this has been open a while. I will test this this weekend. Sorry for the delay.

@wvu-r7

@brandonprry: You gonna test this? :P

@todb-r7 todb-r7 referenced this pull request in sempervictus/metasploit-framework Sep 5, 2013
Merged

Retab/pr/852 #17

@jvazquez-r7 jvazquez-r7 commented on the diff Nov 19, 2013
modules/auxiliary/gather/enum_dns.rb
@@ -542,5 +636,10 @@ def run
if(datastore['ENUM_RVL'] and datastore['IPRANGE'] and not datastore['IPRANGE'].empty?)
reverselkp(datastore['IPRANGE'],datastore['NS'])
end
+ # Do not let module finish while threads exist
+ while not @dns_enum_threads.empty? do
+ vprint_status("Waiting on #{@dns_enum_threads.length} threads to finish")
+ Rex::ThreadSafe.sleep(10)

oumgh really :? isn't there any other way of synchronization?

just asking

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@jvazquez-r7 jvazquez-r7 commented on the diff Nov 19, 2013
modules/auxiliary/gather/enum_dns.rb
+ #-------------------------------------------------------------------------------
+ def dnsbrute(target, wordlist, nssrv, wldcrd = nil)
+ print_status("Bruteforcing IPv4 addresses against domain #{target}")
+ # Read words, split list for threaded bruteforce
+ words = split_wordlist(
+ ::File.read(wordlist).split("\n").uniq.map {|w| w.gsub(".#{target}", '')}
+ )
+ # chunk_size = words.length/@threadnum
+ # words = words.each_slice(chunk_size).to_a
+ print_status("Running with #{words.flatten.length} words in #{@threadnum} threads of #{words.first.length} each")
+ print_good("Ignoring #{wldcrd}") if wldcrd
+ # Give each thread a chunk of words to test
+ while !words.empty? do
+ if @dns_enum_threads.length < @threadnum
+ chunk = words.pop
+ @dns_enum_threads << Rex::ThreadFactory.spawn("DNS Brute Force #{target} #{@dns_enum_threads.length + 1}", false) do

I've the feeling these threads should be handled from the framework instance's thread manager

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@jvazquez-r7 jvazquez-r7 commented on the diff Nov 19, 2013
modules/auxiliary/gather/enum_dns.rb
end
end
+ else
+ Rex::ThreadSafe.sleep(5)

really, why :? if it is for sync purposes, can't it be done in another way?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@jvazquez-r7 jvazquez-r7 commented on the diff Nov 19, 2013
modules/auxiliary/gather/enum_dns.rb
- print_status("Hostname: #{line.chomp}.#{target} IP address: #{rr.address.to_s}")
- report_note(:host => @nsinuse.to_s,
- :proto => 'udp',
- :sname => 'dns',
- :port => 53 ,
- :type => 'dns.enum',
- :update => :unique_data,
- :data => "#{rr.address.to_s},#{line.chomp}.#{target},A")
- next unless rr.class == Net::DNS::RR::CNAME
+ def split_wordlist(words)
+ length = (words.length / @threadnum).ceil
+ words = words.each_slice(length).to_a
+ end
+
+ #-------------------------------------------------------------------------------
+ def dnsbrute(target, wordlist, nssrv, wldcrd = nil)

Honestly, if code complexity could be reduced on dnsbrute and bruteipv6 it would help review a lot! Indeed would help a lot with code readability :)

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

@jvazquez-r7:
Msf overrides some of Rex' internals when it boots, see https://github.com/rapid7/metasploit-framework/blob/master/lib/msf/core/framework.rb#L91.
https://github.com/rapid7/metasploit-framework/blob/master/lib/rex.rb#L97 covers the sleep bit as well (see below for select). Overloading those at the Kernel makes msf look a lot more threadsafe than it is, and with the GIL it works the vast majority of the time.
Will try to clean up redundant code, but from a functional standpoint i use this daily so it does work...

@todb-r7

So, since this is the oldest living PR, I'd love to save it. Looks like @jvazquez-r7 had a bunch of comments, @sempervictus do you plan to address? If not we can shuffle this off to the unstable retirement home.

@darkoperator

in fact I migrated all functionality to individual modules except the AXFR function by request of Jcran back then. This module can be retired, only thing missing is AXFR as a individual module.

@todb-r7

Retiring per request.

@todb-r7 todb-r7 closed this Apr 5, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment