14 Şubat 2016

MySQL Nasıl Hacklenir

Bir client MySQL bağlantısını TCP 3306 portu ile gerçekleştirir.MySQL tarafından kullanılan network protocolü Oracle'a kıyasla daha basit yapıdadır. SSL-enabled versiyonları da (4.0 ve üzeri) aynı port üzerinden bağlantı sağlar. MySQL bağlantı kurarken banner mesajında versiyon bilgisi yazılmaktadır bu durum versiyon bilgisinin kolaylıkla öğrenilmesini sağlar, hatta bazı durumlarda işletim sistemi hakkında ipucu taşır. Dolayısıyla banner inceleyen TCP port tarayıcıları yüksek ihtimalle versiyonu doğru bir şekilde bulmaktadır.

nc -w 1 3306 komutu ile versiyon bilgisi çekilebilir. Gelen cevap: 5.5.46-0+deb8u1U6Ng (versiyon ve işletim sistemi bilgisi geri döndü)

MySQL Veritabanı Saldırı Yüzeyleri

Default Credentials

İlk kurulum yapıldığında mysql.user tablosu default kullanıcı hesapları ve izinlerini saklamaktadır.Bu girdiler değiştirilmezse başkaları tarafından sisteme erişmek için kullanılabilir.

Root : Bütün izinlere sahip superuser'dır ve default olarak şifresi boştur.Kurulumdan sonra bir şifre atanmazsa herhangi biri şifreye ihtiyaç duymadan root olarak erişim sağlayabilir. Windows makinelerde kullanıcı kurulum sırasında “Enable root access from remote machines” seçeneğini aktif etmediği sürece sadece yerel bağlantı için kullanılabilir.

shell> mysql -u root
mysql> UPDATE mysql.user SET Password = PASSWORD('new_password')
WHERE User = 'root';
mysql> FLUSH PRIVILEGES;


Anonymous user : Anonymous kullanıcılar oluşturulmuş ise , bu kullanıcıla için kullanıcı adı ve parola boştur , yani isteyen herkes giriş yapabilir. Windows için default olarak sadece lokal erişime izin verilmiştir. Uzaktan herhangi birinin erişmediği, yönetici izinlerine sahip olmadığı kontrol edilmeli ve şifre verilmelidir.

shell> mysql -u root -p
Enter password: (enter root password here)
mysql> UPDATE mysql.user SET Password = PASSWORD('new_password')
WHERE User = '';
mysql> FLUSH PRIVILEGES;


Ya da anonymous kullanıcılar silinebilir.

mysql> DROP USER ''@'host_name';

Test database : İlk kurulumda kalan test veya test_ ismiyle başlayan veritabanları şifre gerektirmeden erişilebilen yerlerdir. Bu yüzden silinmesi ve erişime kapatılması gereklidir.Mysql.db tablosundan test isimli veritabanlarına yapılacak erişimler engellenebilir.

mysql> DELETE FROM mysql.db WHERE Db LIKE 'test%';
mysql> FLUSH PRIVILEGES;


Ya da test isimli veri tabanı silinebilir.

mysql> DROP DATABASE test;

Hedef sisteme sızmak için yapılan uygulama testlerinde hedef sistem için bu tarz önlemler alınmamış ise MySQL servisini ele geçirmek çok kolaylaşır. Hedef sistem üzerinde port taraması yapıldıktan sonra 3306 portu üzerinde MySQL servisi çalıştığı tespit edildiğinde ; mevcut default password veya anonymous user olup olmadığı araştırılabilir. Bu test nmap aracı ile yapılabilir.

Nmap aracı port taraması yapmasının yanında güçlü özelliklerinden birisi de sağladığı geniş script imkanlarıdır . MySQL için kullanılabilecek scriptler ; mysql-databases , mysql-dump-hashes , mysql-info , mysql-query , mysql-enum , mysql-brute.

mysql-enum veya mysql-empty-password scriptleri ile default password ve anonymous user bilgileri test edilebilir. Örnekte root şifresinin boş olduğu ve anonymous kullanıcı bilgilerinin mevcut olduğu görülmektedir.Bu bilgiler ile hedef mysql servisine sızılabilir.









Default şifreler değiştirmiş ise mevcut şifreyi bulmak için brute force saldırısı yapılarak şifre veya hash öğrenilmeye çalışılabilir. Bu saldırı için birçok araç vardır , örneğin medusa aracı ile gerçekleştirdiğimiz saldırı ;

# medusa -h 127.0.0.1 -u root -P wordlist.txt -M mysql



Görüldüğü gibi 25866 kelimelik bir wordlist ile denenmiş ve root kullanıcısı için şifre admin olarak bulunmuştur.

SSL / TLS


Client ve Server arasında gerçekleşen MySQL trafiği şifrelenmeden açık metin olarak gerçekleştirilmesi trafiği dinleyen kişiler tarafından tehdit oluşturur ,bu yüzden trafik her zaman SSL/TLS protokolleri ile şifreli olarak gönderilmelidir.

mysql> SHOW SESSION STATUS LIKE 'Ssl_version';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Ssl_version | |
+---------------+-------+

Görüldüğü gibi ssl versiyon değeri boş gözükmektedir , aktif edilmemiş ve trafik şifresiz biçimde akıyor demektir. Client ve Server arasındaki trafik kötü amaçlı bir kullanıcı tarafından dinlenirse, tüm kullanıcı bilgileri ve sorgular açık metin halinde görülür. Örnek saldırı senaryosunda ilk olarak 192.168.56.101 IP adresli mysql server'ında uzaktan bağlantıya izin verildi ; root kullanıcısı olarak uzaktan erişim için btrisk şifresi atandı.


Ssl versiyonu boş döndüğü yukarıda gösterilmişti, kullanılan bir şifreleme olmadığı için araya girip trafiği dinleyen birisi login bilgileri,sql sorguları gibi tüm içeriğe erişip okuyabilir. 192.168.56.1 IP adresli Client cihazı , MySQL server'a uzaktan erişmeye çalışıp sorgu girsin. Saldırgan olarak araya girip Wireshark aracı ile dinleme yapılırsa trafiğin okunabildiği görülecektir.


Görüldüğü gibi paketler yakalanıp içeriği açık metin olarak okunmuştur , kullanıcı 'root' kullanıcı adı ve 'btrisk' şifresi(hash olarak) ile server'e erişim yapmış olduğu görüntülenebilmektedir.

SQL Injection

Kullanıcı tarafından girilen verilerin yetersiz kontor edilmesi saldırgan için veritabanı üzerinde sorgu çalıştırabilme, veri okuyup yazabilme ve daha ileri düzey ataklar için imkan doğurur. SQL Injection veritabanına erişim için yapılabilecek bir diğer saldırı türüdür. Detaylı bilgi için makaleyi inceleyebilirsiniz ;

http://blog.btrisk.com/2015/01/Web-Uygulama-Guvenlik-Testleri-SQL-Enjeksiyon-Saldirisi.html

Bilinen Açıklıklar


Bir saldırının ilk adımı hedef sistem üzerinde aktif ve pasif bilgi toplama işlemidir. MySQL servisi çalıştığı tespit edilen sistemler için versiyon bilgisi ve işletim sistemi öğrenilebilirse o versiyon için mevcut bilinen açıklıklar taranarak sistem zafiyetleri tespit edilebilir. MySQL çoğu zaman response header kısmında versiyon bilgisi içerdiğinden yukarıda bahsedilmişti. Versiyon bilgisi öğrenildikten sonra o versiyon için bilinen açıklıklar taranabilir.


Tespit edilen açıklıklar exploit geliştirilerek veya mevcut exploit'ler kullanılarak sisteme sızmak için kullanılabilir. Örneğin exploit-db.com sayfasından geçerli versiyon için bulunan CVE:2012-2122 açıklığı ile ilgili bir exploit ;


Trojanning MySQL Database


Veritabanına yapılan başarılı bir saldırı sonrasında erişim sağlayabilen saldırgan için bir sonraki adım erişimini kalıcı hale getirmektir. Bu işlem birkaç yolla sağlanabilir ;

Yeni kullanıcı eklenmesi : Erişimi kalıcı hale getirmek için en kolay ve kestirme yol yönetici izinlerine sahip yeni bir kullanıcı eklemektir. Ancak bu yöntemin en büyük dezavantajı, veritabanı yöneticisinin bu işlemi farketmesi çok kolay olacaktır.Düzgün yapılandırılmış bir mysql.users tablosunda , tüm yetkilere sahip sadece bir kişi olması gerekmektedir , dolayısıyla ikinci bir yöneticinin var olması kolay farkedilir. Bunu önlemek için saldırganlar tarafından denenen bir sonraki yöntem ise ; username ve password olarak boş girdi seçmek ya da, 'Y' veya 'N' karakterlerini seçmektir. Çünkü çoğu yönetici erişim için terminali kullandığından sorgu sonuçları biraz karışık gözükür. Saldırganlar bu durumdan faydalanmak için yeni eklenen kullanıcıyı sezdirmemeye çalışır.


Erişim sağlanabilen bir kullanıcının yetkilerinin yükseltilmesi: Yeni bir kullancı oluşturulduğunda veya mevcut yetkisiz bir kullanıcı için mysql.user tablosunda görülebileceği gibi tüm izinler kapalıdır (N) . GRANT komutu kullanılarak izin yükseltmesi yapılabilir, ve yönetici izinlerine sahip olunur. Komutun kullanımı ;

GRANT [type of permission] ON [database name].[table name] TO ‘[username]’@'localhost’;



# Yetkilerde yapılan değişikliklerden sonra FLUSH PRIVILEGES; komutu ile reload yapılması gerektiği unutulmamalıdır.

Diğer Yöneticilerin Parolalarının Kırılması: Sistem üzerinde birden çok admin yetkilerine sahip birden fazla kullanıcı varsa onlar hedef olarak kullanılabilir ve parola hash'leri kırılarak sonradan kullanım için saklanabilir. Sistemdeki kullanıcı ve yetkilerini gösteren tablo için kullanılan komut ; SELECT * FROM mysql.user
Mysql içerisinde parolalar SHA1 Hashleri olarak tutuldukları için bu hashler kırılarak ilgili kullanıcıların parolalarına ulaşılabilir.


Mevcut User Defined Function (UDF) 'ler üzerinde değişiklik yapmak: Saldırganlar tarafından MyLUA veya MyPHP gibi user defined function(udf)'ler çalıştırılabilirse istenilen her komut MySQL server üzerinde çalışır. Örneğin MyPHP fonksiyonu kendisine verilen argümanları PHP olarak yorumlar ve çalıştırır.Bu dikkat edilmesi gereken önemli ve çok güçlü bir özelliktir.

İşletim Sistemi Kontrolü ve İleri Saldırılar


MySQL Server ele geçirildiğinde bir sonraki adım olarak düşünülmesi gerekenler; database server'ın üzerinde çalıştığı işletim sistemi, dosya sistemi ve network erişimi/ kontrolü olur.

INTO OUTFILE, LOAD FILE komutları kullanılarak dosya yazma ve okuma işlemleri gerçekleştirilebilir. Komutların kullanımı ;

[ select load_file('/etc/passwd'); ] : komutu kullanılarak dosya okuma yapılabilir.Sistem kullanıcı adı ve şifresi kırılarak sisteme erişim denenebilir.


[ select "" INTO OUTFILE '/var/www/dvwa/hackable/uploads/shell.php.'; ] komutu ile sistem üzerinde dosya oluşturulup yazılabilir. Bunun için dosya yazılacak klasörde yazma izni olmalıdır. Ayrıca mysql bağlantısı kuran hesap File_priv iznine sahip (Y) olmalıdır.

Sistem tarafından verilen hatalar klasör yapısı hakkında bilgi toplamak için çok önemlidir. Web Application Script dilleri (PHP,ASP vs.) hataya zorlanarak klasör dizin yapısı hakkında verilere ulaşılabilir. Linux sistemlerde web yayını genellikle /var/www/ , /var/www/html/ , /var/www/[siteadı]/ gibi dizinler üzerinden yapılır. Load_file( ) fonksiyonu kullanılarak deneme yanılma yöntemizle dizin haritalanması yapılabilir. Ayrıca sistem üzerinde dosya yükleme izni olan yerler bulunmalıdır , örneğin resim upload yapmaya izin veriliyorsa resmin yüklendiği klasör takip edilmelidir. Gerçekleştirdiğimiz örnek saldırıda /dvwa/hackable/uploads/ dizinine sistem üzerinde uzaktan komut çalıştırma imkanı verecek olan basit bir php komutunu yükledik (yukarıda gösterilen INTO OUTFILE komutu ile).


Görüldüğü gibi işletim sisteminin kontrolünü ele geçirdik ve artık sistem üzerinde istediğimiz komutu çalıştırabiliriz.

UDF Injection


SQL injection veya diğer yöntemler ile server üzerinde komut çalıştırabilir olduğumuzda server tarafına hazır kütüphaneler (shared library) upload edilebilirse işletim sisteminde kod çalıştırmak mümkün olur. Yüklenecek kütüphanede çalıştırılabilecek fonksiyonlar ;

sys_eval(cmd); komutu çalıştırır ve standart output dönderir.
sys_exec(cmd); komutu çalıştırır ve exit kodu dönderir output'u göstermez.

Kullanılabilecek kütüphanelerden bir tanesi Marco Ivaldi tarafından geliştirilen raptor_udf2 dir.
Ancak mysql güncellemelerini takip edemediği için yeni UDF kurallarına pek uymaz ve kullanışsızdır. Bir diğer kütüphane ise; lib_mysqludf_sys , daha günceldir ve ayrıca sys_eval fonksiyonu eklenmiştir. https://github.com/sqlmapproject/sqlmap/tree/master/udf sayfasından indirilebilir. Güncel linux ve MySQL için 'Shared Libraries' /usr/lib/mysql/plugins dizininde tutulmaktadır. Kütüphanemiz hedef sistemde bu dizine upload edilmelidir. İşletim sistemine erişim sağlamak için sırasıyla yapılması gerekenler:

  • Session sahibi FILE ve INSERT yetkilerine sahip olmalıdır.
  • Mysql versiyonu ve geçerli shared values dizini (Mysql kütüphanelerinin bulunduğu dizin) bulunmalıdır. Bunun için kullanılabiliecek bir yöntem SHOW VARIABLES; komutu çalıştırılarak plugin_dir değerine bakılabilir.
  • sys_exec ve sys_eval fonksiyonların mevcut olup olmadığı kontrol edilir.Eğer varsa zaten upload etmeye gerek kalmadan bu fonksiyonlar kullanılabilir.
  • Bu fonksiyonları mevcut değilse, lib_mysqludf_sys kütüphanesi hedef sisteme yüklenerek bu fonksiyonları oluşturulmalıdır. Bu yükleme işlemi için lib_mysqludf_sys.so dosyasının içeriği binary olarak alınıp hedef sistemde oluşturulan bir tabloya yazılır. Daha sonra bu tablonun içeriği DUMPFILE komutu ile hedef sisteme dosya olarak yazılacaktır. Yazılacağı yer ise mysql kütüphanelerinin olduğu dizindir. Tüm bu işlemleri yapan bir python scripti hazırlayabiliriz.

Hedef Sistem kütüphane dizini incelenerise henüz lib_mysqludf_sys.so dosyasının olmadığı görülür.

Geliştirmiş olduğumuz script kodumuz :


Bu script çalıştırıldığında sys_eval ve sys_exec fonksiyonları kullanılabilir halde olacaktır. Bu fonksiyonlar yukarıda belirtildiği üzere işletim sisteminde doğrudan komut çalıştırmaya yaramaktadır. Scripti çalıştırılması (çalıştırmadan önce hedef sistem kütüphane dizinine göz atabilirsiniz);


Script çalıştırıldıktan sonra hedef sisteme kütüphanenin düzgün bir şekilde yüklendiği görülmekte.


Hedef sisteme mysql shell üzerinden bağlantı kurup kullanıcı tanımlı fonksiyonları(udf) incelenirse oluşturduğumuz sys_exec ve sys_eval fonksiyonları görülmektedir.


Bu fonksiyonlar kullanılarak artık işletim sistemi üzerinde istenen komutlar çalıştırılabilir. Örneğin hedef sistemimiz linux olduğu için 'whoami' ve 'id' komutları çalıştırılmış ve sonuç alınmıştır ;


Bu makale İstanbul Teknik Üniversitesi Bilgisayar Mühendisliği Bölümü öğrencisi stajyerimiz Cemal Türkoğlu tarafından geliştirilmiştir.