Ağda aldığımız IPyi çektik kullanarak bağlı olduğumuz ağın IP türünü öğrendik
IP adresinin son hanesinde biraz oynama yapıp bulunduğumuz ağda
istediğimiz aralıktaki adresleri tarayabiliriz
Bu ağ C sınıfı olduğu için 8 bitlik ilk 3 kısım (192.168.1) ağ adresini ifade ediyor.
Son kısım ağa bağlanan cihazlara ayrılıyor.
Nmapin bunu anlaması için IP adresini 192.168.1.0/24 olarak değiştireceğiz
Bu IP adresindeki ilk 24 bitin kullanılmayacağını belirtiyor.
Böylece nmap 2 ile 254 arasındaki değerleri tarayacak.
Tarama sonuçlarını daha kolay kullanabilmek için csv türüne çevirdik.
Bu verileri pandasta kullanabilmek için ya dosya ya da buffer olarak okutmamız gerekiyor.
Taramadan gelen değer string olduğu için io modülündeki StringIO nesnesini kullandık.
Veriyi from_csv() metoduna uygun ayraç ile birlikte verip DataFrame oluşturduk.
Boş verileri "not found" olarak değiştirdik.
DataFrame'deki herhangi bir sütunun plot() metodu ile istediğimiz türden grafiğini çizdirebiliriz.
Bu örnekte ağda tesbit edilen açık portların ve her IPdeki port sayısının yüzde grafiğini çizdireceğiz.
<matplotlib.axes._subplots.AxesSubplot at 0x7fe003791358>
Veritabanı
Sqlite3 pythonla birlikte gelen kullanıcı bilgisi gerektirmeyen bir veritabanı.
Veritabanımızı connect() metoduna veritabanının ismini girerek oluşturduk.
Veritabanı işlemlerini gerçekleştirmek için cursor() metodunu kullanarak bağlantı nesnesi oluşturduk.
db=sqlite3.connect("nmapsql.db")
conn=db.cursor()
Veri tabanını oluşturma
Veritabanında sorguları çalıştırmak için conn nesnesinin execute() metodunu kullanıyoruz.
DataFrame'deki sütun isimleri ile veritabanında scan adında bir tablo oluşturduk
Değişiklikleri kaydetmek için commit() metodunu kullandık.
CREATE TABLE scan(num text, hostname text, hostname_type text, protocol text, port text, name text, state text, product text, extrainfo text, reason text, version text, conf text, cpe text)
Veritabanına yazma
DataFrame'deki verileri csv formatına çevirdik.
Sütun isimlerinin yazdığı ilk satır ve boş olan son satır haricindekileri "," ile ayırdık.
Bu sayede veriler veritabanına yazmaya uygun hale geldi.
DataFrame'deki sütun sayısı adetince "?" ile veritabanına veri giriş sorgusu oluşturduk.
Verileri toplu halde girmek için executemany() metoduna sql sorgusu ve veri listesini verdik.
data=list(map(lambdax: x.split(","), df.to_csv().split("\n")[1:-1]))
i_sql="insert into scan VALUES("+",".join("?"for_inrange(len(df.columns)))+",?)"conn.executemany(i_sql, data)
db.commit()
Veritabanından okuma
conn.execute("select * from scan")
conn.fetchall()[:2]
defget_by_port(p_num):
f_sql="select * from scan as s where s.port == {}".format(p_num)
print(f_sql+"\n")
conn.execute(f_sql)
returnlist(conn.fetchall())
data_list=get_by_port(22)
print(*data_list, sep="\n\n")
print("Gelen veri sayısı: {}".format(len(data_list)))
select * from scan as s where s.port == 22
('0', '192.168.1.1', 'not found', 'tcp', '22', 'ssh', 'open', 'Dropbear sshd', 'protocol 2.0', 'syn-ack', '0.50', '10', 'cpe:/o:linux:linux_kernel')
('3', '192.168.1.3', 'not found', 'tcp', '22', 'ssh', 'open', 'OpenSSH', 'Ubuntu Linux; protocol 2.0', 'syn-ack', '7.2p2 Ubuntu 4ubuntu2.1', '10', 'cpe:/o:linux:linux_kernel')
Gelen veri sayısı: 2
SQL Injection
Yukarıda yaptığımız şekilde veritabanını sorgulamak pratik gözükse de
aslında çok büyük açıklıklar barındırıyor.
Kullanıcıya SQL sorgusunda rol verildiği için sorgu istenmeyen karakterlere açık hale geldi.
' " ; tarzı karakterlerle sql sorgusu parçalanıp şekillendirilebilir.
Aşağıda sql sorgusunda ufak bir değişiklikle veritabanındaki tüm bilgilere erişildi.
Açık bir kez bulunduktan sonra açığı bulan veritabanını tamamen silmeye kadar gidebilir.
bad_string="'heklendin' or '6=6'"print("Gelen veri sayısı: {}".format(len(get_by_port(bad_string))))
select * from scan as s where s.port == 'heklendin' or '6=6'
Gelen veri sayısı: 5
Bu açığın önüne geçmek için SQL sorgusu ile ilgili işlemleri kullanıcıya değil,
veritabanı sistemine bırakmalıyız.
defget_by_port_safe(p_num):
conn.execute("select * from scan as s where s.port=?", (p_num,))
returnlist(conn.fetchall())
Veritabanı sistemin kötü sorguyu çalıştırmamasını umuyoruz.
print(get_by_port_safe(bad_string))
[]
NoSQL Veritabanı
Verileri anahtar-değer şeklinde iç içe tutar.
Birbiriyle alakalı tüm veriler tek bir satır(document) olarak tutulur.
SQL veri tabanları dikey, NoSQL veri tabanları yatay büyür.
frompymongoimportMongoClient
Veritabanı bağlantısı
Veritabanı ile bağlantı kurmak için MongoClient nesnesi oluşturduk.
Bu nesneye hangi host ve portta çalışacağı bilgisini verebiliriz.
Öntanımlı olarak MongoClient('localhost', 27017)
client.veritabanı-adı şeklinde MongoDBde veritabanı oluşturduk.
Ardından oluşturulan veritabanı içinde bir koleksiyon (tablo) oluşturduk.
Daha önce o isimde bir veritabanı veya koleksiyon oluşturulmamış ise mongodb bizim için oluşturuyor.
Koleksiyonda tutacağımız her bir girdiye döküman deniyor.
NoSQL bir veritabanına veri eklemek için sözlük veya BSON(JSON) veri yapılarını kullanmamız gerekiyor.
Koleksiyonun insert(), insert_one(), insert_many() metodları ekleme işlemini gerçekleştiriyor.
Verileri sorun olmadan girebilmek için anahtarları ve değerleri string tipine çeviren basit bir fonksiyon yazdık.
defrefactor(data):
""" Sözlükte recursive olarak dolaşarak anahtar ve değerleri stringe çevirir. Bu fonksiyon liste vb. veri yapıları için düzenlenmeli! """new_dict= {}
forkey, valueindata.items():
iftype(value) isdict:
new_dict[str(key)] =refactor(value)
else:
new_dict[str(key)] =str(value)
returnnew_dict
Google, Facebook, Twitter gibi çok büyük verilerle uğraşan kurumlar için MapReduce teknolojisi vazgeçilmezdir.
Basitçe açıklamak gerekirse:
Map verilerin sadece bizim için önemli parçasının alınmasını,
Reduce bu parçaların herhangi bir ifadeye göre filtrelenmesine denir. Örneğin toplama, mantıksal sorgulama.
'mapper' fonksiyonu içindeki this ifadesi veritabanında eriştiğimiz herbir veriyi ifade ediyor.
Verinin cpe kısmındaki değerler içinde 'apache:http_server'leri bulduk ve bu servislerden
sürümleri 2.4.18den düşük olanları hacklenebilir diğerlerini hacklenemez olarak etiketledik.
emit() fonksiyonu ile verinin idsini ve etiketini gönderdik.
'reducer' fonksiyonu ile gelen gelen veri listesinin sadece ilk elemanını döndürdük.
Ardıdan MapReduce işlemi için tanımladığımız bu fonksiyonları tablonun map_reduce() metoduna verdik.
Metod tabloyu map,reduce fonksiyonlarında belirttiğimiz şeklinde küçülttü ve değer olarak döndürdü.
Bu sayede çok daha az sayıda veri ile işlem yapacağız.