1. Ayyıldız Tim forumu Hariç Hiç Bir şekilde Rütbeli Oldugunu İddaa edenlere inanmayınız..⠀ Ayyıldız Tim Adına Sizden Bilgi Belge TC Kimlik Vb Evrak İsteyenlere Asla Bilgilerinizi Vermeyiniz.

Sqlmap Kaynak Kod Çalışması

'Python' forumunda note tarafından 24 Haziran 2018 tarihinde açılan konu

  1. note Atıldı

    • Guest
    Katılım:
    20 Nisan 2017
    Mesaj:
    3,716
    Alınan Beğeniler:
    6,798

    Özel Mesaj
    Merhaba. sn Semtex tarafından açılan Havij Kaynak Kod Çalışması. adlı konuya yardımcı olmak amacıyla, SQL injection açığını kullanan bir programı incelemeye çalışacağız. Malum kendisi yoğun olduğu için, biz de elimizden geldiği kadar devam edeceğiz. Programın adı sqlmap. Birçok kişinin kullandığı bir program. Açık kaynak kodludur ve Python programlama dili ile yazılmıştır. Github adresi üzerinden güncel olarak elde edebilirsiniz. GNU GPL v2 lisansına sahiptir. Özgür bir lisanstır.

    İncelemeye başlamadan önce veritabanı nedir, SQL nedir, SQL injection nedir, neden oluşur, bu açık nasıl sömürülür, korunmanın yolları nedir gibi bazı sorulara beraber cevap vermeye çalışacağız. SQL injection açığının mantığını öğrenmeye çalışacağız ki, bu mantığı programa nasıl işlediklerini görmeye çalışacağız. Kaynaklarla desteklemeye çalışacağız. Böylece bir konuyu birden fazla kaynaktan okuyarak bilgilerimizi pekiştireceğiz.

    Lütfen konu dışında soru sormamaya çalışın.Soruyu soracaksanız, iyice araştırma yaptığınızdan emin olun. "SQL Nedir?" tarzı soruların internette kesinlikle cevabı olduğuna inanıyorum. Link vererek "bu sitede SQL injection açığı arayın" veya "Bu siteyi nasıl ele geçirebilirim" tarzı yorumlar yazmayın. Zira biz hem öğreniyoruz, hem de öğretiyoruz. Katkı sağlayacaksanız, konuyu biraz detaylı anlatmaya çalışın. İki cümlelik paragraflar pek açıklayıcı olmayacaktır(istisnalar vardır tabi)

    Bu bilgileri kesinlikle başkasına zarar vermek amacıyla kullanmayınız. Bu konu sadece bilgilendirme ve öğretme amaçlıdır.Aksi durumlardan sorumlu tutulamayız. Bilgileri test edebileceğimiz ortamlarını da, yeri geldiğinde burda belirteceğiz.

    Bilginizin olduğu konuda, kaynak destekli bir şekilde yorum yapabilirsiniz. İyi forumlar.

    Alparslan5545
     
    En son bir moderatör tarafından düzenlenmiş: 23 Ekim 2019
  2. note Atıldı

    • Guest
    Katılım:
    20 Nisan 2017
    Mesaj:
    3,716
    Alınan Beğeniler:
    6,798

    Özel Mesaj
    Terimleri tanımlamakla başlayalım. İlk olarak veritabanı nedir sorusuna cevap verelim. Veritabanı, verileri düzenli bir şekilde birarada tutan yapıdır. Verileri kaydederiz ve gerektiğinde bu verilere hızlı bir şekilde ulaşırız.

    http://www.dijitalders.com/icerik/2378/veritabani_nedir.html

    SQL veritabanı üzerinde sorgulama yapmaya imkan verir. Yani bir veriyi kaydetme,veriyi getirme, silme, güncelleme gibi işlemler için SQL kullanılır. Sanılanın aksine SQL bir açık değildir, bir sorgulama dilidir. Zaten açılımına bakarsanız Structured Query Language - yapılandırılmış sorgu dili olduğunu görürsünüz. Açık olan SQL injection'dur. Yani programlamadan veya başka sebeplerden meydana gelen hatadan dolayı, programın çalıştırdığı SQL komutlarının arasına girerek kendi komutlarımızı çalıştırmaktır. Böylece veritabanını ele geçirmektir. SQL ile karıştırılmamalıdır.

    https://www.armadigital.net/web-tasarim-blog/sql-nedir

    Peki programlamadan dolayı nasıl açık oluşur? Çok basit bir örnek verelim. Şöyle bir PHP kodu olduğunu ve gelen bir değerin komutun içine olduğu gibi koyulduğunu görelim:

    Kod:
    SELECT sifre FROM tablo WHERE id = '$_GET[İD]'
    
    Burada id = '$_GET[ID]' kısmı, bizim urlden gönderdiğimiz http://example.com/index.php?id=12 , yani 12 değeridir. Biz burada 12 yerine http://example.com/index.php?id=1' OR '1'=='1 değeri gönderirsek, SQL komutuna şöyle yansıyacaktır.

    Kod:
    SELECT sifre FROM tablo WHERE id = '1' OR '1'=='1'
    
    Eğer id = 1 ise veya 1 == 1 ise. Veya koşullu ifadesi bize en az bir durumun doğru olmasını söyler. O yüzden yukarıdaki komutumuzda 1 == 1 çalışacak ve sifre çekilmiş olacaktır. Burada SQL injeciton meydana gelir. Şu konumu da okuyabilirsiniz.

    Peki korunmak için ne yapmak gerekir? Tabi ki dışarıdan gelen verileri kesinlikle kontrol etmeden kodun içine yerleştirmemek gerekir. Aşağıdaki kaynakları da okumalısınız :)

    https://forum.ayyildiz.org/konu/sql-açığı-nedir-ve-nasıl-kapatılır.101376/
    http://blog.ftsadam.com/sql-injection-acigi-nasil-kapatilir/
    https://harunbudun.com/sql-injection-acigi-kapatma.html
    https://wmaraci.com/forum/webmaster-genel/sql-acigi-nasil-kapatilir-269873.html

    SQL konusunda temel bilgiye sahip olmanızı tavsiye ederim. Yoksa, SQL injection açığıyla bilinçsiz bir şekilde uğraşarak zaman kaybetmiş olursunuz. Elbette hazır programlar var, ancak bu programlar akıllı değil, sadece işi sizin yerinize yapan botlardır. Aksi bir durumda ne yapacağını bilemez ve hata verir. Siz de hatayı anlayamazsınız ve belki de bu basit problemi çözemezsiniz.
     
    • Guest
    Katılım:
    30 Eylül 2016
    Mesaj:
    1,663
    Alınan Beğeniler:
    1,751

    Özel Mesaj
    Havij konusunda Semtex 2 tane pdf atmıştı Sql Injection ile ilgili onları buraya atayım belki okumak isteyen olur

    https://www.nds.rub.de/media/hfs/at...ackpra09_kornburst_advanced_sql_injection.pdf

    https://www.us-cert.gov/sites/default/files/publications/Practical-SQLi-Identification.pdf
     
    hasanylmz, dragov, BAYULKEN ve 3 kişi daha bunu beğendi.
  3. note Atıldı

    • Guest
    Katılım:
    20 Nisan 2017
    Mesaj:
    3,716
    Alınan Beğeniler:
    6,798

    Özel Mesaj
    SQL injection açığını tespit etme aşamaları için, aşağıdaki siteyi bâz almaya çalışacağım. Burda bir SQL injection açığını nasıl tespit edebileceğimizi anlatmış.

    https://www.owasp.org/index.php/Testing_for_SQL_Injection_(OTG-INPVAL-005)

    İlk kısımda benim yukarıda anlattığım gibi, SQL injection açığına sebep olan kısmı anlatmış. Sonra da tespit tekniklerini anlatmış. İlk adım, bir sitenin hangi durumlarda SQL veritabanı ile iletişim kurduğunu anlamak,tespit etmektir. Örneğin kullanıcının kimliğini tespit etme amacıyla veritabanına bağlantı kurmak, e-ticaret sitelerinde ürünün detaylarını veritabanından çekmek, veya arama motorlarında olduğu gibi sonuçları bir veritabanından almak. Veritabanına bağlantı kurmak için POST yöntemi de kullanılabilir, html kodunda bir yerde gizlenmiş olabilir. Bunu siz bulmalısınız. Kodu karıştırarak SQL açığı oluşturabilecek kısımları tespit etmeye çalışmalısınız.

    Tespit ettikten sonra, test etmenin ilk aşaması tek tırnak(') koymaktır. Eğer sayfada bir hata oluşuyorsa, SQL injection açığından söz edilebilir. Hata mesajı, sitede de belirtildiği gibi, şöyle olabilir

    Kod:
    Microsoft OLE DB Provider for ODBC Drivers error '80040e14'
    [Microsoft][ODBC SQL Server Driver][SQL Server]Unclosed quotation mark before the
    character string ''.
    /target/target.asp, line 113
    
    Şöyle bir komut, bize veritabanının ne olduğu hakkında bir fikir verebilir

    Kod:
    SELECT id, name FROM users WHERE id=1 UNION SELECT 1, version() limit 1,1
    
    Bu arada, sql komutlarını incelemek için şimdilik aşağıdaki siteye bakıyorum. Size de tavsiye ederim. Gayet açık bir şekilde anlatmış ve örneklerle desteklemiş.

    http://www.sqlkodlari.com/index.asp

    Şimdi yukarıda kullandığımız UNION komutu, iki ayrı SELECT sorgusunu birleştiriyor. Yani birinci sorgu ile ikinci sorgu sonucunu bize birleştirerek veriyor. Aynı anda iki komut çalıştırabiliyoruz şeklinde düşünebiliriz. Burda anlatmak istediğim, ezberci olmak değil herşeyi sorgulamak gerektiğidir.

    Diğer aşama, veritabanında bulunan sütun sayısını tespit etmektir. Aşağıdaki gibi bir komutla test edebiliyoruz

    Kod:
    http://www.example.com/product.php?id=10 ORDER BY 10--
    
    Eğer hata yoksa, o zaman sütün sayısı 10'dan fazla demektir. Hata alana kadar devam edilirse, ve sonunda hata alınırsa max deneme sayısı kadar sütun var demektir. Yani 11 de hata alınıyorsa, 10 sütun var demektir. Burda ORDER BY komutu, sıralama işlemi için kullanılıyor. Peki, ORDER BY sıralama için kullanılıyorsa burda neden bize sütun sayısını bulmada yardımcı oldu? Bu sorunun cevabını yorum olarak yazmanızı rica ediyorum.

    Bugünlük bu kadar. Elimden geleni yazmaya çalıştım. Hatalar varsa bildirin lütfen. Ben de bazı konuları araştırarak yazıyorum. Dolayısıyla hata olabilir. İyi forumlar :)
     
  4. DuhaYunus Guest

    • Guest
    Katılım:
    6 Ekim 2016
    Mesaj:
    314
    Alınan Beğeniler:
    396

    Özel Mesaj
    Su kismi:
    hep merak etmisimdir. Bu konuyu acmani niye beklemisim kendime kiziyorum suan. Sordugun soruya gelecek olursak kendimce cevaplamaya calisacagim. Yanlis biliyorsam düzeltirsiniz bende ögrenmis olurum. Genelde "Order By" kullanirken sütun adini vererek bilgileri siralariz. Hatta bunun yaninda ASC ve DESC kullanilir. Biri kücükten büyüge giderken digeri tam tersine siralar. Order By Sütun_Ismi DESC diyerek mesela bilgileri büyükten kücüge siralar. Buraya sütun adi yerine sayi yazarsak "Order By 1" bize o sütundaki bilgiyi verir. Tam anlatamadim galiba ama örneklemeye calisayim.

    Tablomuzda 5 sütun olsun: A B C D E
    Order By 1 yazdigimizda aslinda Order By A demis oluyoruz. Oyüzden acigi bulmak icin manuel tek tek hata verene kadar sayiyi yükseltebiliriz. Yani burada Order By 6 yazarsak hatayi almis oluruz.
     
    note ve Alparslan5545 bunu beğendi.
    • Guest
    Katılım:
    30 Eylül 2016
    Mesaj:
    1,663
    Alınan Beğeniler:
    1,751

    Özel Mesaj
    Emin değilim ama şurda

    http://www.example.com/product.php?id=10 ORDER BY 10--

    komut şöyle oluyor
    SELECT id, name FROM users WHERE id= 10 ORDER BY 10--

    Yani komut eklemiş oluyoruz id'ye.Sanırım 10 tane sütunu sırala diyor eğer sıralayabiliyorsa 10 tane sütun mevcuttur eğer sıralayamıyorsa zaten öyle bir sütn yoktur.
    Cevap yanlış olabilir.İnternette hep belli bir şeye göre sıralama yapılmış mesela maaş,doğum tarihi vs.
     
    dragov, note ve DuhaYunus bunu beğendi.
  5. DuhaYunus Guest

    • Guest
    Katılım:
    6 Ekim 2016
    Mesaj:
    314
    Alınan Beğeniler:
    396

    Özel Mesaj

    Hatta bunuda örneklemeye calisayim:

    SELECT id, name FROM users WHERE id= 10 ORDER BY 10--

    Eger Tablomuz söyle olsaydi:
    Kod:
    id    name    age   birthday      city       country   team  email  cellphone password
    Kod:
    1   Mehmet  19    1.1.1996   Istanbul   Turkey    red     xxx         xxx          xxx       
    Kod:
    2    Ahmet    21    5.3.1991   Istanbul   Turkey    red     xxx         xxx          xxx       
    Kod:
    .
    Kod:
    .
    Kod:
    .
    Yani toplam sütun sayisi 10 olsaydi hatayla karsilasmazdik ve "Order by 10" 10. Sütun "password" oldugu icin password'a göre siralardi. Eger tabloda bir sütung eksik olsaydi yani "password" kismi olmasaydi maximum 9 sütun olurdu ve "Order By 10" haliyle hata verirdi.

    Dogru oldugunu bilmiyorum sadece mantik yürütüyorum
     
    dragov, note ve Alparslan5545 bunu beğendi.
    • Guest
    Katılım:
    30 Eylül 2016
    Mesaj:
    1,663
    Alınan Beğeniler:
    1,751

    Özel Mesaj
    Şimdi daha iyi anladım sağolasın.:)
     
    dragov, note ve DuhaYunus bunu beğendi.
  6. DuhaYunus Guest

    • Guest
    Katılım:
    6 Ekim 2016
    Mesaj:
    314
    Alınan Beğeniler:
    396

    Özel Mesaj
    Dedigim gibi dogru oldugunu bilmiyorum. Sn, Semtex ve note bakmasi lazim aydinlatin biti :D
     
    note ve Alparslan5545 bunu beğendi.
  7. note Atıldı

    • Guest
    Katılım:
    20 Nisan 2017
    Mesaj:
    3,716
    Alınan Beğeniler:
    6,798

    Özel Mesaj
    3W1LH4CK3R, DuhaYunus ve Alparslan5545 bunu beğendi.
    • Guest
    Katılım:
    30 Eylül 2016
    Mesaj:
    1,663
    Alınan Beğeniler:
    1,751

    Özel Mesaj
    DuhaYunus ve note bunu beğendi.
  8. note Atıldı

    • Guest
    Katılım:
    20 Nisan 2017
    Mesaj:
    3,716
    Alınan Beğeniler:
    6,798

    Özel Mesaj
    Evet malesef öyle :)
     
    3W1LH4CK3R, DuhaYunus ve Alparslan5545 bunu beğendi.
  9. dragov Guest

    • Guest
    Katılım:
    10 Ocak 2017
    Mesaj:
    568
    Alınan Beğeniler:
    1,351

    Özel Mesaj
    böyle konuları daha fazla görmek dileği ile :) sorular oldukça ben de vakit buldukça yardımcı olmaya çalışırım.
     
    DuhaYunus, note ve Alparslan5545 bunu beğendi.
  10. note Atıldı

    • Guest
    Katılım:
    20 Nisan 2017
    Mesaj:
    3,716
    Alınan Beğeniler:
    6,798

    Özel Mesaj
    Teşekkür ederim. Bugün diğer konulara vakit ayırdık. Biz de vakit kalırsa burdan devam etmeye çalışırız.
     
    3W1LH4CK3R, DuhaYunus ve Alparslan5545 bunu beğendi.
  11. AYDOĞAN TÜMGENERAL

    • Forum Denetleme Gözlem Komutanı
    Katılım:
    11 Ağustos 2012
    Mesaj:
    12,284
    Alınan Beğeniler:
    58,868
    Meslek:
    Defender Ayt

    Özel Mesaj
    Konuyu sabitledim.Gundemde tutmakta fayda var egitim diye konu acanlar gorur belki.)
     
  12. note Atıldı

    • Guest
    Katılım:
    20 Nisan 2017
    Mesaj:
    3,716
    Alınan Beğeniler:
    6,798

    Özel Mesaj
    Teşekkür ederim, kaliteli konular sizin sayenizde ayakta kalıyor :)
     
  13. note Atıldı

    • Guest
    Katılım:
    20 Nisan 2017
    Mesaj:
    3,716
    Alınan Beğeniler:
    6,798

    Özel Mesaj
    Devam edelim. Yukarıda örnek verirken hep ?id=1 gibi parametrelerden bahsettik. Bu şöyle bir algı oluşturmasın "sadece id olan yerlerde sql injection vardır". Hayır, bu yanlış bir düşünce. Amaç id'yi istismar etmek değil, sql sorgusunu istismar etmek. Peki neden id çok kullanılıyor ve sürekli karşımıza çıkıyor? Bu aslında popülarite ile ilgili. Bugün Wordpress kullanan site sayısı çok fazla. Ve Wordpress sistemlerde genelde bir veriye ulaşmak için id parametresi kullanılır. Dolayısıyla açıklar genelde burda oluşur.

    Wordpress sistemler açık kaynak kodludur. Dolayısıyla kaynak kodları inceleyip, hangi sürümlerde nasıl bir kod yapısı kullanılmış görebilirsiniz. Burdan sql sorgularını da görebilirsiniz. Farklı farklı sql sorguları görebilirsiniz. Şu siteyi inceleyebilirsiniz

    https://www.flippercode.com/how-to-hack-wordpress-site-using-sql-injection/

    Mantığı öğrenmek, bakmak ve görmek arasındaki farkı anlamayı sağlar.

    sqlmap programımıza yavaş yavaş giriş yapalım. Önceden de dediğim gibi, incelemeye çalışacağız. Tek başıma binlerce kişinin yazdığı kodu kısa sürede anlamam mümkün değil. Ama yavaş yavaş yapısını çözmeye çalışıyorum. Şimdilik en önemli klasörleri ve modülleri tespit etmeye başladım. Tabi bu arada yer alan klasörleri de açıklamaya çalışacağız elimizden geldiği kadar.

    Örneğin,lib klasörü, sqlmap için en önemli klasör. Yani sqlmap'in kalbi. Sqlmap için yazılan her modülde kesinlikle lib klasöründen import edilmiş birşeyler görürsünüz. Eğer bilginiz varsa içindeki bazı modülleri ve bunların içerdiği fonksiyon,sınıfları incelemenizi tavsiye ederim. Python bilginize çok şey katacaktır.

    sqlmap.py programında main() fonksiyonundan başlanmış. Orda şöyle bir kısım var.

    Kod:
    paths.SQLMAP_ROOT_PATH = modulePath()
    setPaths()
    
    İlk olarak bulunduğumuz dizini tespit etmiş ve sonra da diğer tüm dizinleri buna bağlı olarak tespit etmiş. paths nedir biliyor musunuz? Basit bir sınıf.

    Kod:
    paths = AttribDict()
    
    Sonra buna SQLMAP_ROOT_PATH özelliği eklenmiş. Ki başka modüller de artık buna bağlı olarak hangi dosya nerde tespit edebilsin. Hemen altındaki setPaths() ne yapmış? İşte o fonksiyon

    Kod:
    Yer: lib/core/common.py
    
    def setPaths():
        """
        Sets absolute paths for project directories and files
        """
    
        # sqlmap paths
        paths.SQLMAP_EXTRAS_PATH = os.path.join(paths.SQLMAP_ROOT_PATH, "extra")
        paths.SQLMAP_PROCS_PATH = os.path.join(paths.SQLMAP_ROOT_PATH, "procs")
        paths.SQLMAP_SHELL_PATH = os.path.join(paths.SQLMAP_ROOT_PATH, "shell")
        paths.SQLMAP_TAMPER_PATH = os.path.join(paths.SQLMAP_ROOT_PATH, "tamper")
        paths.SQLMAP_WAF_PATH = os.path.join(paths.SQLMAP_ROOT_PATH, "waf")
        paths.SQLMAP_TXT_PATH = os.path.join(paths.SQLMAP_ROOT_PATH, "txt")
        paths.SQLMAP_UDF_PATH = os.path.join(paths.SQLMAP_ROOT_PATH, "udf")
        paths.SQLMAP_XML_PATH = os.path.join(paths.SQLMAP_ROOT_PATH, "xml")
        paths.SQLMAP_XML_BANNER_PATH = os.path.join(paths.SQLMAP_XML_PATH, "banner")
        paths.SQLMAP_OUTPUT_PATH = paths.get("SQLMAP_OUTPUT_PATH", os.path.join(paths.SQLMAP_ROOT_PATH, "output"))
        paths.SQLMAP_DUMP_PATH = os.path.join(paths.SQLMAP_OUTPUT_PATH, "%s", "dump")
        paths.SQLMAP_FILES_PATH = os.path.join(paths.SQLMAP_OUTPUT_PATH, "%s", "files")
    
        # sqlmap files
        paths.SQLMAP_HISTORY = os.path.join(paths.SQLMAP_ROOT_PATH, ".sqlmap_history")
        paths.SQLMAP_CONFIG = os.path.join(paths.SQLMAP_ROOT_PATH, "sqlmap-%s.conf" % randomStr())
        paths.COMMON_COLUMNS = os.path.join(paths.SQLMAP_TXT_PATH, "common-columns.txt")
        paths.COMMON_TABLES = os.path.join(paths.SQLMAP_TXT_PATH, "common-tables.txt")
        paths.COMMON_OUTPUTS = os.path.join(paths.SQLMAP_TXT_PATH, 'common-outputs.txt')
        paths.SQL_KEYWORDS = os.path.join(paths.SQLMAP_TXT_PATH, "keywords.txt")
        paths.SMALL_DICT = os.path.join(paths.SQLMAP_TXT_PATH, "smalldict.txt")
        paths.USER_AGENTS = os.path.join(paths.SQLMAP_TXT_PATH, "user-agents.txt")
        paths.WORDLIST = os.path.join(paths.SQLMAP_TXT_PATH, "wordlist.zip")
        paths.ERRORS_XML = os.path.join(paths.SQLMAP_XML_PATH, "errors.xml")
        paths.PAYLOADS_XML = os.path.join(paths.SQLMAP_XML_PATH, "payloads.xml")
        paths.INJECTIONS_XML = os.path.join(paths.SQLMAP_XML_PATH, "injections.xml")
        paths.LIVE_TESTS_XML = os.path.join(paths.SQLMAP_XML_PATH, "livetests.xml")
        paths.QUERIES_XML = os.path.join(paths.SQLMAP_XML_PATH, "queries.xml")
        paths.GENERIC_XML = os.path.join(paths.SQLMAP_XML_BANNER_PATH, "generic.xml")
        paths.MSSQL_XML = os.path.join(paths.SQLMAP_XML_BANNER_PATH, "mssql.xml")
        paths.MYSQL_XML = os.path.join(paths.SQLMAP_XML_BANNER_PATH, "mysql.xml")
        paths.ORACLE_XML = os.path.join(paths.SQLMAP_XML_BANNER_PATH, "oracle.xml")
        paths.PGSQL_XML = os.path.join(paths.SQLMAP_XML_BANNER_PATH, "postgresql.xml")
    
    Etrafta ne kadar dosya varsa bunların yerini paths içine koymuş, ki başka bir modül artık bunu kullanırken paths.YOL diyerek hangi modül nerde bulabilsin. Buraya kadar bir sıkıntı yok :)

    Hemen altında basit bir şekilde komut satırından gelen argümanları parçalama işlemi yapmış. Hani programı çalıştırırken -u google.com gibi parametreler gönderiyoruz ya, işte onlar burda parçalanıyor ve programa işleniyor

    Kod:
    cmdLineOptions.update(cmdLineParser().__dict__)
    initOptions(cmdLineOptions)
    
    Artık parametreler conf değişkenine işleniyor. Bu conf,paths nerden geliyor diyorsanız, programın genelinde kullanılmak üzere bir dosyada tanımlanmıştır bunlar. Aşağıda

    Kod:
    Yer: lib/core/data.py
    #!/usr/bin/env python
    
    """
    Copyright (c) 2006-2013 sqlmap developers (http://sqlmap.org/)
    See the file 'doc/COPYING' for copying permission
    """
    
    from lib.core.datatype import AttribDict
    from lib.core.log import LOGGER
    
    # sqlmap paths
    paths = AttribDict()
    
    # object to store original command line options
    cmdLineOptions = AttribDict()
    
    # object to store merged options (command line, configuration file and default options)
    mergedOptions = AttribDict()
    
    # object to share within function and classes command
    # line options and settings
    conf = AttribDict()            ## <-------- BURDA
    
    # object to share within function and classes results
    kb = AttribDict()
    
    # object with each database management system specific queries
    queries = {}
    
    # logger
    logger = LOGGER
    
    Peki AttribDict() nedir diye soracak olursanız, o da sqlmap programcıları tarafından oluşturulmuş bir sınıftır. lib/core/datatype.py içinde bulunur

    Kod:
    class AttribDict(dict):
        """
        This class defines the sqlmap object, inheriting from Python data
        type dictionary.
    
        >>> foo = AttribDict()
        >>> foo.bar = 1
        >>> foo.bar
        1
        """
    
        def __init__(self, indict=None, attribute=None):
            if indict is None:
                indict = {}
    
            # Set any attributes here - before initialisation
            # these remain as normal attributes
            self.attribute = attribute
            dict.__init__(self, indict)
            self.__initialised = True
    
            # After initialisation, setting attributes
            # is the same as setting an item
    
        def __getattr__(self, item):
            """
            Maps values to attributes
            Only called if there *is NOT* an attribute with this name
            """
    
            try:
                return self.__getitem__(item)
            except KeyError:
                raise SqlmapDataException("unable to access item '%s'" % item)
    
        def __setattr__(self, item, value):
            """
            Maps attributes to values
            Only if we are initialised
            """
    
            # This test allows attributes to be set in the __init__ method
            if "_AttribDict__initialised" not in self.__dict__:
                return dict.__setattr__(self, item, value)
    
            # Any normal attributes are handled normally
            elif item in self.__dict__:
                dict.__setattr__(self, item, value)
    
            else:
                self.__setitem__(item, value)
    
        def __getstate__(self):
            return self.__dict__
    
        def __setstate__(self, dict):
            self.__dict__ = dict
    
        def __deepcopy__(self, memo):
            retVal = self.__class__()
            memo[id(self)] = retVal
    
            for attr in dir(self):
                if not attr.startswith('_'):
                    value = getattr(self, attr)
                    if not isinstance(value, (types.BuiltinFunctionType, types.BuiltinFunctionType, types.FunctionType, types.MethodType)):
                        setattr(retVal, attr, copy.deepcopy(value, memo))
    
            for key, value in self.items():
                retVal.__setitem__(key, copy.deepcopy(value, memo))
    
            return retVal
    
    Kullanımı çok basittir. Şöyle bir örnek vereyim

    Kod:
    >>> from lib.core.datatype import AttribDict
    >>> sinif = AttribDict()
    >>> sinif.veri = "deger"
    >>> sinif
    {'veri': 'deger'}
    >>> sinif["veri"]
    'deger'
    
    Yani sınıfı hem normal sınıf olarak kullanabilirsiniz hemde sözlük olarak kullanabilirsiniz. Gayet kullanılışlı olmuş. Bazen sqlmap içindeki faydalı kısımları alır inceleriz :)

    Kısaca diyoruz ki, sqlmap programı başlamadan önce dizinleri ayarlamış, sonra komut satırından gelen parametreleri ayırmış ve gerekli konfigurasyon ayarlarını da conf değişkenine yerleştirmiş.

    Ve artık programın başlaması için ayarlara(conf) bakılıyor ve buna göre program artık başlatılıyor

    Kod:
            if conf.profile:
                profile()
            elif conf.smokeTest:
                smokeTest()
            elif conf.liveTest:
                liveTest()
            else:
                start()
    
    Bir sonraki postta, profile() smokeTest() liveTest() start() bunlardan birini incelemeye çalışacağız. Sanırım artık bunlardan birinde taramaya başlıyoruz..

    İyi forumlar :)
     
    Kaank52, 3W1LH4CK3R, ELK ve 4 kişi daha bunu beğendi.
  14. note Atıldı

    • Guest
    Katılım:
    20 Nisan 2017
    Mesaj:
    3,716
    Alınan Beğeniler:
    6,798

    Özel Mesaj
    Kodu inceleyen yok mu? Tek başıma bunu yapamam demiştim...

    En azından sqlmap/xml/queries.xml dosyasına bakmaya çalışalım. Burda çeşitli veritabanları için sql komutları var. Bu komutları öğrenerek manuel olarak denemeler yapabiliriz. Mesela MySql için şöyle bir kısım var

    Kod:
            <passwords>
                <inband query="SELECT user,password FROM mysql.user" condition="user"/>
                <blind query="SELECT DISTINCT(password) FROM mysql.user WHERE user='%s' LIMIT %d,1" count="SELECT COUNT(DISTINCT(password)) FROM mysql.user WHERE user='%s'"/>
            </passwords>
    
    Burda, bir mysql veritabanı için şifrelere erişim komutları verilmiş. Bunun gibi birçok komut var.
     
    Alparslan5545 bunu beğendi.
    • Guest
    Katılım:
    30 Eylül 2016
    Mesaj:
    1,663
    Alınan Beğeniler:
    1,751

    Özel Mesaj
    Biraz işim vardı hiç bakamadım.

    Bir de sqlmap/tamper içinde waf bypass için değişik yöntemlerin olduğu klasör var.içinde değişik bypass çeşitleri var..

    Mesela şuna bakalım

    sqlmapproject/sqlmap//tamper/base64encode.py
    burda şu satiırda payload bs64 ile encode ediliyor.

    PHP:
    def tamper(payload, **kwargs):
        
    """
        Base64 all characters in a given payload
        >>> tamper("
    1' AND SLEEP(5)#")
        '
    MScgQU5EIFNMRUVQKDUpIw=='
        """
    return base64.b64encode(payload.encode(UNICODE_ENCODING)) if payload else payload

    Charencode bypasss:

    PHP:
    def tamper(payload, **kwargs):
        
    """
        Url-encodes all characters in a given payload (not processing already
        encoded)
        Tested against:
            * Microsoft SQL Server 2005
            * MySQL 4, 5.0 and 5.5
            * Oracle 10g
            * PostgreSQL 8.3, 8.4, 9.0
        Notes:
            * Useful to bypass very weak web application firewalls that do not
              url-decode the request before processing it through their ruleset
            * The web server will anyway pass the url-decoded version behind,
              hence it should work against any DBMS
        >>> tamper('SELECT FIELD FROM%20TABLE')
        '%53%45%4C%45%43%54%20%46%49%45%4C%44%20%46%52%4F%4D%20%54%41%42%4C%45'
        """

        
    retVal payload

        
    if payload:
            
    retVal ""
            
    0

            
    while len(payload):
                if 
    payload[i] == '%' and (len(payload) - 2) and payload[1:2in string.hexdigits and payload[2:3in string.hexdigits:
                    
    retVal += payload[i:3]
                    
    += 3
                
    else:
                    
    retVal += '%%%.2X' ord(payload[i])
                    
    += 1

    return retVal
    Burda da sanırım url-encode ile encode edilmiş.

    Bir başka bir klasör olan sqlmap/waf klasöründe ise waf tespiti yapılıyor.Mesela

    PHP:
    def detect(get_page):
        
    retval False

        
    for vector in WAF_ATTACK_VECTORS:
            
    pageheaderscode get_page(get=vector)
            
    retval re.search(r"cloudflare-nginx"headers.get(HTTP_HEADER.SERVER""), re.Iis not None

            
    if code >= 400:
                
    retval |= re.search(r"\A__cfduid="headers.get(HTTP_HEADER.SET_COOKIE""), re.Iis not None
                retval 
    |= headers.get("cf-ray"is not None
                retval 
    |= re.search(r"CloudFlare Ray ID:|var CloudFlare="page or ""is not None

            
    if retval:
                break

    return 
    retval
    Burda CloudFlare ile karşılaşılmış mı onu tespit ediyor.Ona göre True ya da False dönüyor.Retval değişkeni 400'den büyükse değişik parametreler arıyor mesela

    CloudFlare Ray ID:|var CloudFlare= şeklinde eğer bu " is not None " yani Boş değil diyor.Eğer bu değer None değilse True dönecek.

    Buraları anlamaya çalışıyorum.Yardımcı olmaya çalışmaya çalışıyorum ama elimden bu kadar.
     
    note ve dragov bunu beğendi.
  15. note Atıldı

    • Guest
    Katılım:
    20 Nisan 2017
    Mesaj:
    3,716
    Alınan Beğeniler:
    6,798

    Özel Mesaj
    Teşekkür ederim eline sağlık. Ekleme yapayım. SQL_Map\waf klasöründe birden fazla waf için tespit edici modüller yazılmış. Yani bu demek oluyor ki, sayfa kaynağı içerisinde eğer modüllerde belirtilen ifadeler geçiyorsa, bir waf tarafından engellendik demektir. Bunları sadece tespit ediyoruz. Şimdilik bypass yok.
     
    Alparslan5545 bunu beğendi.

Bu Sayfayı Paylaş