MySQL Veri Tabanı Güvenliği Checklist

Standart sızma testi süreçlerine bakıldığında Veri Tabanı Güvenliği maddesi ile karşılaşmak pek mümkün değildir. Özellikle Türkiye’de yapılan sızma testi hizmetlerinde bu durum daha da fazla yaşanmakta. Veri tabanını konfigürasyonu ve güvenlik testleri gerçekleştirilmemiş bir uygulamanın güvenli olması mümkün değildir.

Gene iş Türkiye’ye geldiğinde bu konu ile ilgili karşılaştığım en ciddi problem; veri tabanı sistemi güvenliğinin, güvenlik testi yapılan web uygulamasında bulunan zafiyetler üzerinden gerçekleştirildiğinin iddia edilmesidir.  Örneğin sızma testi uzmanı hedef uygulama üzerinde SQL Injection zafiyeti tespit ettiği zaman veri tabanı üzerinde güvenlik testleri gerçekleştirmeye çalışmakta. Bu durumdaysa malesef hizmet kalitesi son derece düşük olmakta. Çünkü ilgili uygulamanın veri tabanı kullanıcısı yetkileri ile farklı kullanıcıların yetkileri aynı olmaya olabilir veya veri tabanı uygulaması konfigürasyonunda güvenlik ile ilgili çalışmalar yapılmamış olabilir.

Sonuç olarak; güvenlik testi hizmetlerinin içerisinde olması gereken Veri Tabanı Güvenliği Kontrolü önemlidir. Bu yazıda MySQL yazılımı için nelerin kontrol edilmesi gerektiğinden bahsedilecektir.

1 – Uzak Bağlantı yerine SSH Tunneling Yapmak

MySQL servisi default olarak 3306 portunda çalışmaktadır. Default kurulumda bu port tüm bağlantılar için dinleme moduna alınmaktadır. Bu durumda ilgili mysql port’u dış dünyaya da açılmış olmaktadır.

Aşağıdaki komutlardan ilki /etc/my.cnf dosyasında [mysqld] alanı altına yapılacak bir tanımlamadır. Bu tanımlama ile MySQL servisi sadece yerel adres üzerinde dinleme moduna geçecektir. Nmap ile yapacağınız bir tarama ile yeni konfigürasyonun durumunu kontrol edebilirsiniz.

// Sadece yerel interface dinlenmeye zorlanmaktadır.
bind-address=127.0.0.1

Eğer mevcut yapı üzerinde dış bağlantıları kapatmak mümkün değilse, MySQL kullanıcılarının Remote Host ayarları tanımlanmalıdır. Örneğin sadece  1.2.3.4 ip adresinden bağlantı gerçekleştirecek bir kullanıcı için aşağıdaki tanımlama gerçekleştirilebilir.

// Kullanıcı yetkilerinin tanımlanması
mysql> GRANT SELECT, INSERT ON mydb.* TO 'someuser'@'somehost';

MySQL sunucusu için grafiksel arayüz ve yönetim imkanı sunan MySQL Workbench SSH Tunneling desteği vermektedir. Yukarıda tanımlanan komut ile artık MySQL portuna dış dünyadan erişim yapmak mümkün değildir. Bu durumda MySQL sunucusuna SSH üzerinden bağlantı gerçekleştirip, bu bağlantı üzerindende MySQL oturumu açılabilir. Bu yapı ile MySQL sunucunuz daha da güvenli hale gelecektir.

2 – Yerel Dosya Erişimi Engeli

MySQL yerel dosya sistemi ile iletişim kurabilme özelliğine sahiptir. Sorgular üzerinde yerel dosya sisteminde bulunan bir metnin içeriği alınabilir veya sorgu sonucu diske yazılabilir. Bu özelliği bilen ve saldırılar kullanan hacker’ların önüne geçebilmek için MySQL’in yerel dosya sistemi ile iletişim kurabilmesini engellemek gerekmektedir.

mysql> SELECT load_file("/etc/passwd");

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin

Yukarıdaki örnekte görüldüğü üzere yerel dosyalara erişim yapabilmekte mümkündür. Yerel dosya sistemine erişimin kapatılması için /etc/my.cnf dosyasında ki [mysqld] kısmı altına aşağıdaki değişken tanımlaması yapılmalıdır.

set-variable=local-infile=0

 3 – Uygulama Kullanıcıları ve Şifreler

Veri tabanını kullanan uygulamanın MySQL kullanıcısı ile, veri tabanı yönetimi kullanıcısının birbirinden farklı olmalı çok önemlidir. Bir diğer deyişle uygulamalar MySQL’e root kullanıcısı ile bağlanması son derece sakıncalıdır. Hatta mümkünse  UPDATE veya INSERT işlemi gerçekleştirmeyen uygulamaların kullanıcıları ayrıca tanımlanmalı ve bu izinler verilmelidir.

Bir diğer husus ise kullanıcı şifreleri. Geçtiğimiz aylarda yaptığım bir sızma testinde tüm network’ü ele geçirmemizi sağlayan hata MySQL root kullanıcısının şifresinin tyroot olmasıydı. Hemen hemen her alanda olduğu gibi MySQL kullanıcı içinde şifrelerin komplike olması gerekmektedir. Random şifre oluşturmak için http://www.random.org kullanılabilir.

4 – Anonymous Kullanıcıların Silinmesi

Default MySQL kurulumunda Anonymous kullanıcılar oluşturulmaktadır. Bu kullanıcıların silinmesi, erişiminin engellenmesi gerekmektedir.

Güvenli bir MySQL sunucu için aşağıdaki sorgunun sonuç dönmemesi gerekmektedir.

mysql> select * from mysql.user where user="";

Eğer herhangi bir sonuç varsa, aşağıdaki komut ile bu kullanıcının silinmesi gerekmektedir.

mysql> DROP USER "";

 5 – MySQL Yerel Dosya İzinleri

Örneğin 1 hafta önceki verilere dönüş yapılacağı zaman, veri tabanı sunucusuna SSH ile bağlanılır ve ilgili mysql dosyaları değiştirilir. Bu işlem sırasında genellikle linux işletim sisteminin root kullanıcı yetkileri kullanılmaktadır. Bu durumda veri dosyalarının sahipliği ve izinleri değişmektedir.

MySQL için /var/lib/mysql altındaki tüm dosyaların sahibi ve grubu mysql kullanıcısı olmalıdır.

mince@rootlab ~ $ sudo ls -al /var/lib/mysql/
drwx------ 97 mysql mysql      4096 May 20 16:02 .
drwxr-xr-x 82 root  root       4096 May  1 14:30 ..
drwx------  2 mysql mysql      4096 Şub  3 15:18 ab2015
drwx------  2 mysql mysql     36864 Nis 16 12:28 bluethrust_db
drwx------  2 mysql mysql      4096 Nis 22 12:06 bonfire
drwx------  2 mysql mysql      4096 Mar  4 12:38 bsm
drwx------  2 mysql mysql     28672 Nis 16 11:39 btc

Dosyaların sadece mysql kullanıcısı için read,write izinleri olmalı ve diğer tüm kullanıcılar için herhangi bir iznin bulunmaması gerekmektedir.

6 – MySQL SSL

10 farklı sunucunun bulunduğu DMZ bölgesinde ki sunuculardan bir tanesinin hacker’lar tarafından ele geçirildiğini düşünelim. Bu durumda saldırganların yapacağı ilk işlem, hedef DMZ bölgesinde iç tarama gerçekleştirerek sunucular hakkında bilgi toplama adımıdır. Bu bilgi toplama işleminde MySQL sunucusu tespit edilirse, hedef sunucu için MITM saldırısı yapılarak bu sunucuya bağlanan uygulamaların, kullanıcıların oturum bilgileri çalınabilir.

Bu durumun önüne geçmek için MySQL sunucusu SSL hizmeti vermelidir. MySQL sunucunuz için SSL hizmetin nasıl aktifleştirileceği http://www.networkpentest.net/2014/01/mysql-sunucu-istemci-trafiginin-sifrelenmesi.html adresinde Gökhan Alkan tarafından adım adım anlatılmış bulunmaktadır.

7 – Log ve History Dosyaları

Herhangi bir durumda analiz yapabilmek için MySQL loglarının tutuluyor olması gereklidir.

[mysqld]
log =/var/log/mylogfile

MySQL logları hangi dosyaya yazacağı yukarıda ki şekilde tanımlanabilir.

Bir diğer önemli nokta ise ~/.mysql_history dosyası.

mince@rootlab ~ $ cat ~/.mysql_history
create database dvwa;
use dvwa;
select 1 from users;
SELECT first_name, last_name FROM users WHERE user_id = 1;
SELECT first_name, last_name FROM users WHERE user_id = '1';

Linux kullanıcıları komut satırındna MySQL sunucularına bağlanıp komut çalıştırdıklarında, bu sorgular history dosyasına yazılır. Bu dosyanın temizlenmesi gerekmektedir.

echo "temizlendi" > ~/.mysql_history

Teşekkürler.