二级域名爆破
=begin
ruby 域名爆破
=end
require 'ipaddr'
require 'resolv'
require 'optparse'
require "ruby-progressbar"
#爆破封装成类 外部直接调用
class SubDomain
attr_accessor :option
def initialize(option={})
@option = option
@root_domain =@option[:domain]
@subname = []
@next_subname = []
@option[:ns] = get_root_domain_ns
@init_level = 2
@max_level = @option[:level]
@domain_result = {}
@progressbar = nil
get_root_domain_ip
load_domain_dic
end
#获取主域名对应的IP
def get_root_domain_ip
@domain_result[1] = []
get_ip_by_name(@root_domain).each do |ip|
@domain_result[1] << {name:@root_domain,host:ip}
end
@domain_result[1] << {name:@root_domain,host:'unknow'} if @domain_result[1].empty?
end
#获取主域名的域名服务器
def get_root_domain_ns
ns = []
dns = Resolv::DNS.new
domain = @root_domain
dns.each_resource(domain,Resolv::DNS::Resource::IN::NS) do |nameserver|
ns += get_ip_by_name(nameserver.name)
end
ns += get_ns
end
#获取dns解析服务器
def get_ns
ns = []
File.read('dns_servers.txt').split("\n").each do |line|
line.strip!
begin
ns << IPAddr.new(line).to_s
rescue
end
end
ns
end
#加载爆破字典
def load_domain_dic
@subname = get_subname
@next_subname = get_next_subname
end
#读取二级目录字典
def get_subname
subname = []
File.read('subnames.txt').split("\n").each do |line|
line.strip!
if not line.nil? and not line == ''
subname << line
end
end
subname
end
#读取多级域名字典
def get_next_subname
next_subname = []
File.read('next_sub.txt').split("\n").each do |line|
line.strip!
if not line.nil? and not line == ''
next_subname << line
end
end
next_subname
end
def get_ip_by_name(name,ns=[])
ip = []
if ns.empty?
dns = Resolv::DNS::new
else
dns = Resolv::DNS::new(:nameserver => ns)
end
error_count = 0
begin
dns.each_address(name) do |addr|
ip << addr.to_s
end
rescue
@progressbar.progress("Error:#{$!}")
error_count += 1
sleep 1
retry if error_count >= 5
end
ip
end
def run
queue = Queue.new
mutex = Mutex.new
threads = []
@init_level.upto(@max_level).each do |level|
@current_level = level
geted_domain = []
@domain_result[level] = []
@domain_result[level-1].each do |domain|
next if geted_domain.include?(domain[:name])
geted_domain << domain[:name]
if @current_level == 2
sub = @subname
else
sub = @next_subname
end
sub.each do |name|
queue << "#{name}.#{domain[:name]}"
end
end
next if queue.empty?
queue_size = queue.size
@progressbar = ProgressBar.create(:title=>"Current-Level:#{@current_level}",:format=>'%a |%b>>%i| %p%% %t')
@progressbar.progress = 0
progress_thread = Thread.new do
while true
sleep 1
break if @progressbar.progress == 100
@progressbar.progress = (queue_size.to_f - queue.size.to_f)/queue_size * 100
end
end
@option[:threads].times do |i|
threads << Thread.new do
Thread.current.abort_on_exception = true
until queue.empty?
name = queue.pop
get_ip_by_name(name,@option[:ns]).each do |ip|
next if ip == "0.0.0.0"
mutex.lock
if @domain_result[@current_level].select {|domain| domain[:host==ip]}.size < 10
@domain_result[@current_level] << {name:name,host:ip}
@progressbar.log("#{name}:#{ip}")
end
mutex.unlock
end
end
end
end
threads.each {|t| t.join }
@progressbar.progress = 100 unless @progressbar.progress==100
progress_thread.kill
end
end
end
#命令行解析工具
options = {}
option_parser = OptionParser.new do |opts|
opts.banner = 'here is help message of the command line tool.'
opts.on('-d DOMAIN','--domain Domain','the root domain you put') do |value|
options[:domain] = value
end
options[:threads] = 2
opts.on('-t THREAD','--thread Thread','The threads number to run') do |value|
options[:threads] = value
end
options[:level] = 2
opts.on('-l LEVEL','--level Level','the deep domain you will burp') do |value|
options[:level] = value
end
end.parse!
puts options
subdomain = SubDomain.new(options).run
网友评论