- Intérprete Ruby en su versión 1.8.6 mínimo.
- Rubygems
- Mechanize
- Net-DNS en su versión 0.5.3 (La versión 0.6.0 tiene un bug y de momento está inoperativa hasta la versión 0.7.0
Podéis instalar el interprete Ruby y Rubygems desde los repositorios ó bien compilandolo desde el código fuente desde aquí:
http://www.ruby-lang.org/en/downloads/
http://docs.rubygems.org/read/chapter/3
Mechanize y net-dns se instalan desde rubygems de la siguiente manera:
gem install mechanize
gem install net-dns -v 0.5.3
La versión 2.0. Incluye dos modalidades más de ataque.
1.- Ataque "--all": Realiza un barrido de querys a los servidores DNS.
2.- Ataque "--mantis": Realiza un barrido inverso con puntero inverso PTR y a las direcciones IP no resueltas, aplica un Reverse DNS para ver posibles Vhosts con ese nombre de dominio.
Cómo no, Open Source =)
Código
#!/usr/bin/ruby # Programmed by Sh4V. N-D Security Team. # Visit http://n3t-datagrams.net && http://foro.undersecurity.net require 'socket' require 'ftools' require 'rubygems' require 'mechanize' require 'net/dns/rr' require 'net/dns/packet' require 'net/dns/resolver' mantis=" ::: ::: ::: :::: ::: ::::::::::: ::::::::::: :::::::: :+:+: :+:+: :+: :+: :+:+: :+: :+: :+: :+: :+: +:+ +:+:+ +:+ +:+ +:+ :+:+:+ +:+ +:+ +:+ +:+ +#+ +:+ +#+ +#++:++#++: +#+ +:+ +#+ +#+ +#+ +#++:++#++ +#+ +#+ +#+ +#+ +#+ +#+#+# +#+ +#+ +#+ #+# #+# #+# #+# #+# #+#+# #+# #+# #+# #+# ### ### ### ### ### #### ### ########### ######## :::::::: ::::::: :+: :+: :+: :+: +:+ +:+ +:+ +#+ +#+ +:+ +#+ +#+ +#+ #+# #+# #+# #+# ########## ### ####### ========================================================================== " version= "v2.0" puts "Mantis #{version} by Sh4V http://n3t-datagrams.net" sub=["foro","access", "accounting", "accounts", "active", "ad", "admin", "administracion", "administrador", "administrator", "administration", "advertising", "agent", "ap", "apple", "archives", "area", "as", "b2b", "b2c", "backup", "backups", "bart", "beta", "bigip", "billing", "blackboard", "blog", "blogs", "book", "books", "c2b", "c2c", "ca", "carro", "cart", "catalog", "catalogue", "channel", "channels", "chat", "chimera", "cisco", "citrix", "classroom", "conect", "connect", "controller", "conferece", "core", "corporate", "cpanel", "csg", "customers", "database", "db", "dbs", "demo", "demostration", "design", "desk", "desktop", "dev", "devel", "developers", "development", "directory", "dmz", "dns", "dns1", "dns2", "dns3", "domain", "domain1", "domain2", "domain3", "domaincontroller", "download", "downloads", "ds", "eaccess", "e", "eng", "es", "events", "example", "examples", "exchange", "exec", "extranet", "feed", "feeds", "file", "files", "fileserver", "finance", "firewall", "forum", "foro","forums", "fs", "ftp", "ftpd", "fw", "gallery", "game", "games", "gateway", "groups", "guide", "gw", "help", "helpdesk", "home", "hotspot", "hp-ux", "hpux", "ids", "im", "images", "imail", "imap", "imap1", "imap2", "imap3", "imgs", "internal", "intranet", "ipsec", "irc", "irc1", "irc2", "irc3", "irix", "itil", "lab", "laboratories", "labs", "lan", "ldap", "library", "linux", "localhost", "login", "logs", "lotus", "mail", "mail1", "mail2", "mail3", "mailgate", "main", "man", "manager", "maps", "marketing", "member", "members", "mercury", "messenger", "meeting", "mmc", "mngt", "mobil", "mobile", "mom", "money", "monitor", "monitoring", "moodle","mrtg", "mssql", "mx", "mx1", "mx2", "mx3", "mysql", "mysql1", "mysql2", "mysql3", "nameserver", "neon", "netmail", "netmeeting", "netscaler", "netscreen", "netstats", "network", "news", "news", "newsfeed", "newsfeeds", "newsgroups", "newton", "noc", "notes", "novell", "ns", "null", "online", "open", "openbsd", "openview", "operations", "oracle", "outlook", "owa", "pan", "partner", "partners", "pc", "pcanywhere", "pegasus", "peoplesoft", "personal", "photo", "photos", "podcast", "podcasts", "pop", "portal", "postgres", "ppp", "printer", "priv", "priv8", "private", "proxy", "prtg", "public", "radius", "ras", "relay", "remote", "reports", "research", "restricted", "router", "rss", "sales", "sample", "samples", "sandbox", "search", "secure", "security", "sendmail", "server", "server1", "server2", "server3", "services", "share", "sharepoint", "shop", "shopping", "sms", "smtp", "smtp1", "smtp2", "smtp3", "solaris", "sql", "squirrel", "squirrelmail", "ssh", "staff", "stage", "staging", "stats", "storage", "sun", "support", "sus", "test", "tftp", "tmp", "transfer", "ts", "uddi", "unix", "upload", "uploads", "vid", "video", "videos", "virtual", "vista", "vnc", "vpn", "wan", "wap", "web", "webadmin", "webct", "webcast", "webcasts", "webmail", "webmaster", "wiki","windows", "wingate", "wlan", "wsus", "ww", "www", "www1", "www2", "www3", "xml"] def resolv(domain, query,all) res=Net::DNS::Resolver.new res.tcp_timeout=10 begin que=res.query(domain, query) rescue Net::DNS::RR::ArgumentError puts "The argument #{query} is wrong." rescue puts "An error ocurred while the #{query} query was sent." else if all==0 puts "Answer section:" puts que.answer print "\n" puts"Additional section:" puts que.additional elsif all==1 puts "Answer section:" puts que.answer print "\n" else puts "aaa" end end end def axfr(domain) puts "Collecting information from DNS servers in domain: #{domain} " ns=Net::DNS::Resolver.new begin que=ns.query(domain, Net::DNS::NS) rescue puts "An error ocurred while the NS query was sent." else ip=que.answer.to_a iparr=[] nsarr=[] ip.each do |ipx| ipx=ipx.to_s ipx << "*" ipx=ipx.split('NS ') ipx.shift ipx.each do |x| x=x.gsub('*', '') nsarr<<x end end nsarr.each do |x| iparr << Socket.getaddrinfo(x, 80)[0][3] end puts "DNS server(s) IP's:" iparr.each do |x| puts "[-] #{x}" end print "\n" iparr.each do |ip| puts "[+]Trying AXFR attack with DNS server: #{ip}" ns.nameservers=ip ns.tcp_timeout=10 begin axfr=ns.send(domain, Net::DNS::AXFR) rescue puts "An error ocurred while the AXFR attack was sent." else if axfr.answer.length != 0 print "\n" puts axfr.answer print "\n" else puts "Zone transfer failed." print "\n" end end end end end def ixfr(domain) puts "Collecting information from DNS servers in domain: #{domain} " res=Net::DNS::Resolver.new begin soa=res.query(domain, Net::DNS::SOA) rescue puts "An error ocurred while the SOA query was sent." else dat=soa.answer.to_s.split('. ') fields=dat[3].split(' ') fields[0,0]=dat[1].split('SOA ')[1] fields[1,0]=dat[2] begin ns=res.query(domain, Net::DNS::NS) rescue puts "An error ocurred while the NS query was sent." else ip=ns.answer.to_a nsarr=[] iparr=[] ip.each do |ipx| ipx=ipx.to_s ipx << "*" ipx=ipx.split('NS ') ipx.shift ipx.each do |x| x=x.gsub('*', '') nsarr<<x end end nsarr.each do |x| iparr << Socket.getaddrinfo(x, 80)[0][3] end puts "DNS server(s) IP's:" iparr.each do |x| puts "[-] #{x}" end print "\n" rrauth = Net::DNS::RR.new( :name => domain, :ttl =>86400, :mname => fields[0], :rname => fields[1], :serial => fields[2].to_i, :refresh => fields[3].to_i, :retry =>fields[4].to_i, :expire => fields[5].to_i, :minimum =>fields[6].to_i, :cls => "IN", :type => "SOA" ) rrques = Net::DNS::Question.new(domain, Net::DNS::IXFR) packet=Net::DNS::Packet.new(domain) packet.authority= rrauth packet.question=rrques resixfr=Net::DNS::Resolver.new iparr.each do |ip| puts "[+]Trying IXFR attack with DNS server: #{ip}" resixfr.nameservers=ip resixfr.tcp_timeout=10 begin ixfr=resixfr.send(packet) rescue puts "An error ocurred while the IXFR attack was sent." else header=ixfr.authority if ixfr.answer.length != 0 print "\n" puts ixfr.answer print "\n" else puts "Incremental zone transfer failed." print "\n" end end end end end end def ptr(ipi, ipf) control='' ipi.each do |x| if x.to_i>=255 control << "+" end end ipf.each do |x| if x.to_i>=255 control << "+" end end if ipi[0]==ipf[0] && ipi[1]==ipf[1] && ipi[2]==ipf[2] && ipi[3]<=ipf[3]&& control.length == 0 res=Net::DNS::Resolver.new ipi[3]=ipi[3].to_i ipf[3]=ipf[3].to_i if ipi[3]==0 && ipf[3]==0 ipi[3]=1 ipf[3]=254 elsif ipi[3]==0 ipi[3]=1 end ipfalse=[] while ipi[3]<ipf[3]+1 ip="#{ipi[0]}.#{ipi[1]}.#{ipi[2]}.#{ipi[3]}" arpaip="#{ipi[3]}.#{ipi[2]}.#{ipi[1]}.#{ipi[0]}.in-addr.arpa" begin que=res.query(arpaip, Net::DNS::PTR) rescue puts "An error ocurred while the PTR query was sent." else if name=que.answer.to_s.split('PTR ')[1] else name=que.answer.to_s.split('CNAME ')[1] end if que.answer.to_s!='' puts "#{ip} => #{name}" else puts "#{ip} => Not resolved." ipfalse << ip end ipi[3]+=1 end end else puts "Invalid IP address structure or interval. Example:" puts "#{$0} -4 192.168.1.1 192.168.1.254" end return ipfalse end def reverse(ip) if ip.split('.')[0].to_i == 0 || ip.split('.')[1].to_i == 0 || ip.split('.')[2].to_i == 0 || ip.split('.')[3].to_i == 0 || ip.split('.').length != 4 begin ip= Socket.getaddrinfo(ip, 800)[0][3] rescue puts "Incorrect IP Address or Domain Name." end end puts ip id=0 control=Array.new dom=Array.new domains=Array.new until id==10000 agent=WWW::Mechanize.new url=agent.get("http://api.search.live.net/json.aspx?AppId=7066FAEB6435DB963AE3CD4AC79CBED8B962779C&Query=IP:#{ip}&Sources=web&Web.Offset=#{id}") res=url.body.split('"DisplayUrl":"') control=dom dom=Array.new res.each do |x| dom<<x.split('",')[0].gsub("\\", '').split('/')[0].gsub("www.", '') end dom.shift domains << dom if control[0]==dom[0] id=9990 end id+=10 end domains=domains.flatten.uniq puts domains end def trysubsock(domain) sub='as234kj43fh2a34ieasf2234sadf3'.split('').sort_by{rand}.join begin sock=TCPSocket.new("#{sub}.#{domain}", 80) rescue puts "Incorrect IP Address or Domain Name." else sock.print("GET / HTTP/1.1\r\nHost:#{domain}\r\n\r\n") rec=sock.recv(20) sock.close if rec.include?('200') return false else return true end end end def trysubdns(domain) sub='as234kj43fh2a34ieasf2234sadf3'.split('').sort_by{rand}.join res=Net::DNS::Resolver.new begin rcode=res.query("#{sub}.#{domain}", Net::DNS::CNAME).header.rCode_str[0] if rcode== "NXDomain" return true else return false end rescue puts "Incorrect IP Address or Domain Name." end end def sockcrawl(sub, domain) begin sock=TCPSocket.new("#{sub}.#{domain}", 80) rescue puts "Incorrect IP Address or Domain Name." else sock.print("GET / HTTP/1.1\r\nHost:#{domain}\r\n\r\n") rec=sock.recv(20) sock.close if rec.include?('200') puts "[-] #{sub}.#{domain}" return '+' else return '-' end end end def dnscrawl(sub, domain) res=Net::DNS::Resolver.new begin rcode=res.query("#{sub}.#{domain}", Net::DNS::CNAME).header.rCode_str[0] rescue puts "Incorrect IP Address or Domain Name." else if rcode!= "NXDomain" puts "[-] #{sub}.#{domain}" return '+' else return '-' end end end def crawl(domain, sub) if ARGV[2] && File.exist?(ARGV[2]) == true && ARGV[2] != "-o" dic=File.open(ARGV[2], 'r') sub=dic.read.split("\n") elsif ARGV[2] && ARGV[2]!= "-o" puts "No such file or directory." end #arr=Array.new #while i < sub.length # x = ["#{sub[i]}","#{sub[i]}0","#{sub[i]}1","#{sub[i]}2","#{sub[i]}3"] # arr[i,1] = x # i+=1 #end #sub=arr control=0 succ='' print "Crawling subdomains names. This will take some minutes. Be patient.\n\n" if trysubdns(domain) == true control=1 sub.each do |sub| succ << dnscrawl(sub, domain) end puts end if trysubsock(domain) == true and control==0 sub.each do |sub| succ << sockcrawl(sub, domain) end end if trysubdns(domain) || trysubsock(domain) succ=succ.gsub('-', '').length print "\n-----------------------------------------------------------\n" puts "SUBDOMAINS SUCCESSES IN #{domain}: #{succ}" puts "-----------------------------------------------------------" else puts "The #{domain} server is protected against subdomains crawling." end end # The magic of Ruby has begun ^^ case ARGV[0] when "-0" query = ARGV[1].upcase domain= ARGV[2] resolv(domain, query, 0) when "-1" domain = ARGV[1] axfr(domain) when "-2" domain = ARGV[1] ixfr(domain) when "-3" domain=ARGV[1] crawl(domain, sub) when "-4" ipi=ARGV[1].split('.') if !ARGV[2] ipf=ARGV[1].split('.') else ipf=ARGV[2].split('.') end ptr(ipi, ipf) when "-5" ip=ARGV[1] reverse(ip) when "--all" domain=ARGV[1] que0={ "NS" => 2, "MX" => 15 } que1={ "SIGZERO" => 0, "A" => 1, "CNAME" => 5, "SOA" => 6, "WKS" => 10, "HINFO" => 13, "MINFO" => 14, "TXT" => 16, "GPOS" => 27 , "LOC" => 29, "SRV" => 33 } puts mantis que0.each_pair do |key, value| puts "Resolving #{key} query:" resolv(domain, value,0) puts "-----------------------------------------------------------------------" end que1.each_pair do |key, value| puts "Resolving #{key} query:" resolv(domain, value,1) puts "-----------------------------------------------------------------------" end axfr(domain) ixfr(domain) crawl(domain, sub) when "--mantis" puts mantis domain = ARGV[1] ipi=ARGV[1].split('.') if !ARGV[2] ipf=ARGV[1].split('.') else ipf=ARGV[2].split('.') end ips=ptr(ipi, ipf) print "\n" puts "Glup! Reversing has start with:" ips.each do |ip| print "[+] " reverse(ip) end when "-h" puts "Mantis is a tool to collect information about DNS servers of a domain name. [-0] Makes a DNS query simple query. #{$0} -0 mx domain.net [-1] Starts a zone transfer(s) (axfr) to all DNS servers associated with the domain name. #{$0} -1 domain.net [-2] Starts an incremental zone transfer(s) (ixfr) to all DNS servers associated with the domain name. #{$0} -2 domain.net [-3] Makes a crawl of subdomains in the domain name given. It includes a dictionary but you can also use your own. #{$0} -3 domain.net #{$0} -3 domain.net dic.txt [-4] Makes a reverse domain scan with an IP address interval given. #{$0} -4 192.168.1.0 #{$0} -4 192.168.1.231 #{$0} -4 192.168.1.1 192.168.1.164 [-5] Resolves domains name in the same server (Vhosts). #{$0} -5 domain.net #{$0} -5 192.168.114 [--all] Make a torbelline of querys. #{$o} --all domain.net [--mantis] Make a Mantis Attack. #{$0} --mantis 192.168.1.0 #{$0} --mantis 192.168.1.231 #{$0} --mantis 192.168.1.1 192.168.1.164 Enjoy =)" else puts "Type #{$0} for help" end
http://n3t-datagrams.net/lab/mantis2.rb.txt
Espero gente que la pruebe con sus correspondientes críticas positivas.
gracias ^^