Php Ile Güvenlik

  • Uploaded by: Tanju YILDIZ
  • 0
  • 0
  • May 2020
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Php Ile Güvenlik as PDF for free.

More details

  • Words: 1,865
  • Pages: 6
PHP ile Güvenlik Öncelikle bu makaleyi, yeni başlayan veya orta düzey PHP programlayıcısına hitap olması için gereken gayret gösterilmiştir. Orta düzey diyorum çünkü birçok kere şahit olduğum üzere, PHP ile portal kodlayan ancak güvenlikten anlamayan çok kişiye şahit oldum. Bu makalede; Iframe virüsü, SQL Injection, RFI - LFI (Remote File Include Local File Include), XSS, CSRF ve SESSION ile scriptiniz nasıl güvenlikten mahrum olur ve bunlardan nasıl kurtuluruz onu göreceğiz. PHP ile kodladığınız scripte dışarıdan nasıl sızılır onu bir öğrenelim. SQL INJECTION - Kurtulmak için gerekenler... Mesela SQL Injection dediğimiz ve günümüzde en çok kullanılan metodu ele alalım. Şimdi veritabanına bir query gönderiyoruz mesela ve diyelim ki basit bir login işlemimiz ve bir query’miz olsun. $name = $_POST['username']; $pass = $_POST['pass']; $sorgu = mysql_query("SELECT Count(id) FROM users WHERE name='$name' AN D pass='$pass';");

Gördüğünüz gibi formdan gelen bilgileri direk olarak mySQL sorgusuna ekledik ve isim ve şifreyi sorguladık. Ancak formdan gelen bilgiler süzülmediği için, bazı ne idiğü belirsiz, hayat felsefesi insanlara zarar vermekten başka bir şey olmayan hacker denilen art niyetli zararlı şahıslar; Öncelikle forma şu bilgileri girerler; username alanına ' or 1=1 – girerler, pass alanına ise asdasdasqweqweqwe gibi karakterler girerler. qweqweqwe gibi karakterler girmelerinin sebebi, sizin formu gönderildikten sonra pass alanının boş olduğunda hata verdirmenizden ötürüdür. Şimdi bu şekilde girilen bilgiler olunca SQL sorgumuz ne hale geliyor bir ona bakalım. mysql_query("SELECT Count(id) FROM users WHERE name='' or 1=1 --' AND p ass='asdasdasqweqweqwe'");

SQL’de -- karakterlerinden sonra gelen kısım, olduğu gibi açıklama olarak kaldı. Yani 'AND pass='asdasdasqweqweqwe' kısmı, burada bildiğiniz açıklama metni haline geldi ve bir işe yararlığı kalmadı. Bu şekilde bir login durumu ile 1=1 ile direk olarak admin olarak login olmuş oldu. Genelde 1. id numaralı satırda admin kayıtlıdır. O yüzden direk olarak admin olarak login olmuş oldu. Bunun sebebi ise ' veya " karakteridir. Bu karakterler eğer string olarak tanıtılmazsa, formdan gelen bilgiler otomatik olarak SQL sorgusuna dönüşmüş oluyor. Bundan kurtulmak için ise yapmamız gereken şey çok basit. Formdan gelen bilgileri escape ederek kurtulabiliriz ancak. Bu zararlıdan kurtulmak için PHP dili bize bir avantaj olarak mysql_real_escape_string ve ya mysql_escape_string fonksiyonlarını oluşturmuştur. Bu fonksiyonları kullanmak için öncelikle veritabanı bağlantısı yapmanız lazım. Sonrasında ise, fonksiyonları kullanabilirsiniz. Örnek kullanım şekli şu haldedir. $name = mysql_real_escape_string($_POST['username']); $pass = mysql_real_escape_string($_POST['pass']);

$sorgu = mysql_query("SELECT Count(id) FROM users WHERE name='$name' AN D pass='$pass';");

Şimdi bu fonksiyon ile süzülen veri, SQL sorgusuna nasıl yansır ona bakalım; mysql_query("SELECT Count(id) FROM users WHERE name='\' or 1=1 --' AND pass='asdasdasqweqweqwe'");

Gördüğünüz gibi ' ve " karakterleri hemen escape ediliyor. Yani \' \" şeklinde kaydolduğu için, SQL sorgusu olmaktan çıkıp string olduğunu mySQL’e bildirmiş oluyoruz. SQL Injection’dan kurtulduk mu peki bu kadarıyla? Tabii ki hayır. Siz de bilirsiniz ki, SQL sorgularını sadece login’de kullanmıyoruz. O yüzden önemli bir örneği vermeden geçemeyeceğim. Şimdi escape fonksiyonumuzun ismine bir göz atalım. mysql_real_escape_string(); Yani bu fonksiyon, sadece string türünü destekler. Eee, bizler http://site.com/index.php?topic_no=12312312 olarak gelen integer türündeki verileri nasıl süzeceğiz öyle ise? Bu da çok basittir. Ancak bu bilgiyi atlarsanız, bütün DB bilgilerinizi çalarlar ama haberiniz olmaz. $topic_no = $_GET['topic_no'];

Dersek, SQL sorgumuzda yine ' " gibi karakterlerle saldırıya uğrarız. O yüzden doğrusu bu şekilde olmalıdır. $topic_no = intval($_GET['topic_no']); $topic_no = str_replace("-","",$topic_no);

Integer alanını sorgulayacağımız için intval ile integer validasyon etmiş oluyoruz. Yani GET ile gelen verimiz "1231231231hebelehubele" ise, intval sayesinde "1231231231" oluyor. Yani fonksiyonumuz ilk karakterden itibaren tek tek her karakteri sona kadar inceliyor gelen veriyi ve eğer ilk karakter herhangi bir rakam ise, yani 12313 gibi başlıyorsa, döngüye devam ediyor, ama asd gibi string türe denk geliyorsa orada döngü break; olup sonlanıyor. Ve bize soldan itibaren aldığı rakamları veriyor. Eğer ilk karakter string olsaydı, o zaman da döngüden geri gelen değer 0 oluyor. Veya başlarına - gibi karakterler koyarak, mySQL’de - integer türü id incelemeye kalkıyor ve hata verdiriyor. O yüzden - karakterlerini de replace etmekte fayda var, bu düşüncem yanlış ise düzeltin lütfen. Sorgulama yapacaksanız eğer, muhakkak, COOKIE, SESSION, GET, POST ile gelen verileri muhakkak escape etmelisiniz! COOKIE ve SESSION’da değiştirilebildiği için onlardan gelen verileri de süzün yoksa hacklenmemenizi garanti edemem. Peki, sadece SQL Injection'dan kurtularak sitenin hacklenmesini engellemiş olduk mu? Tabii ki hayır. RFI - LFI(Remote File Include - Local File Include) Açığından Kurtulmak RFI dediğimiz olayın açılımı, Remote File Include, tercümesi de Uzaktan Dosya Eklemek olabilir. Bu olay, ilk olarak sunucunuzun SAFE MODE’un OFF olmasından kaynaklanır. ON olsa bile OFF yapma oyunları mevcuttur tabi. Bu olayda biz script kısmını ne kadar güvende tutsak bile, sunucunuzun güvenliği yine de ön plana çıkıyor maalesef ve o yüzden yüksek güvenlikli bir sunucuya geçmenizi tavsiye ederim her zaman.

Neden diye soracak olursak mesela bizim scriptimizde herhangi bir sorun yok diyelim. Her yerini güvenli yaptık. Ama hacker denilen zat gelir, sisteme shell sokuşturur. Shell dediğimiz zararlı kod ile sizin bütün dosyalarınızı ele geçirir, bu da demektir ki, scriptiniz kendinize ait paralı bir script ise, bu scriptin çalınmasına neden olur. Ayrıca Sql injection yapabilir. Dosya yükleyebilir. SQL yedeğinizi olduğu gibi alabilir. Yani bir nevi Cpanel şeklinde bir kodlama diyebiliriz buna. Siz Cpanel’de ne yapabiliyorsanız, aynısını hemen hemen shell’de görebilirsiniz. Tabi, suncuyu hacklemek için kodlandığı için, sadece gerekli yerleri düzenlemek görmek amaçlı yazılmıştır. Adam gelir, config dosyanızı açar, içinde DB bilgilerinizi alır. DB bilgilerinizi girerek mySQL alanınıza bağlanır. Sonra istediği tabloyu istediği gibi değiştirerek yönlendirme kodu koyar. Alın size hacked. O yüzden, config dosyalarınızı da saklamalısınız. Lamerlerden korunmak için config dosyanızın ismi config olmasın ve içeriğini şifreleyin ve eval ile çalıştırın. Mesela config dosyanızın içeriği şöyle olsun; $ayar['db']['host'] $ayar['db']['name'] $ayar['db']['user'] $ayar['db']['pass']

= = = =

'localhost'; 'veritabani_adi'; 'username'; 'pass';

Adam böyle bir dosyayı açtığı gibi bilgiler eline hemen geçer. O yüzden şifreleme metoduyla şifreleyin. Daha sonra da şifrelenmiş metni çözerek eval($cozulmus_config_dosyası) deyince, yine aynı dosyanın içindekileri almış olur ve PHP’ye o değişkenleri tanıtmış olursunuz. Bu kısımları geçtikten sonra RFI nasıl yersiniz dersek, şöyle olabilir. Mesela index sayfamızdan bütün sayfaları çağırıyoruz diyelim. http://site.com/index.php?sayfa=Anasayfa http://site.com/index.php?sayfa=Iletisim http://site.com/index.php?sayfa=Forum http://site.com/index.php?sayfa=Sikayet şeklinde sayfalarımızı çağırarak hangi sayfayı include edeceğimizi bildiriyoruz. PHP sayfamız da şöyle olsun. $sayfa = $_GET['sayfa']; include($sayfa . ".php");

Böyle bir kod ile biz GET ile gelen veriye ne yazarsak yazalım. Onu include edecektir. Adam da gelir shell adresini oraya yazar ve shell yükler sunucunuza. Tabi SAFE MODE kapalı ise hackler sitenizi. Doğrusu şöyle olmalı; $sayfalar = array("Anasayfa" => "Anasayfa.php", "Iletisim" => "Iletisim.php", "Forum" => "Forum.php", "Sikayet" => "Sikayet.php"); $sayfa = $_GET['sayfa']; if(array_key_exists($sayfa,$sayfalar)){ include ($sayfalar[$sayfa]); } else{ echo "Sayfa ismi hatalı, lütfen doğrusunu girin"; }

Veya switch, if gibi deyimler ile de kontrol edilebilir. Bu şekilde ne yaparlarsa yapsınlar siz önceden belirttiğiniz ve programa kontrol koyduğunuz için RFI yapamazlar. Bunu da basitiyle anlatmış olduk. Daha da uzar gider aslında da sınırlı olarak bırakıyorum. XSS Enjekteden Kurtulmak XSS (Cross Site Scripting - Çapraz Kod Çalıştırma) ise, HTML ve Javascript yardımı ile siteyi yönlendirmek, sitede link vererek admin’in COOKIE bilgilerini çalmak. Mesela GET ile bir ID alıyoruz şu şekilde; http://site.com/index.php?cat_name=Belgesel Ancak biz bu kategori ismini süzmeden alırsak şöyle olur. http://site.com/index.php?cat_name=<script>alert(document.cookie) Böyle bir linke çeviririz. Siz de direk olarak süzmeden sayfaya bunu yazdırırsanız, otomatik olarak sayfada bu Javascript kodu çalışacaktır. Veya diyelim ki, bir yorum yazdıracaksınız. HTML verilerini muhakkak süzmeniz gerekmektedir. Yoksa adam yorum yazarken; <script>location='http://www.hebelehubele.com/index.php'; Şu zararlı kodu da eklerse, o zaman yorumun yazıldığı sayfa her açılışında muhakkak o adrese yönlenir. Bunlardan nasıl kurtuluruz dersek; $veri $veri $veri $veri

= = = =

$_POST['comment'];//Yorumu posttan aldık. strip_tags($veri); htmlentities($veri); htmlspecialchars($veri);

Bu fonksiyonlardan birini kullanabilirsiniz. Eğer strip_tags fonksiyonunu kullanırsanız, POST’tan gelen verinin içinde, ne kadar HTML ve Javascript karakterleri varsa siler. Sadece geriye kalan string türündeki veriyi alır. Bir ziyaretçi defteri için en uygunu budur. Ancak forum portalı veya blog tarzı ise, kişi HTML ve Javascript kodlarını paylaşabileceği için, bu tagları silemezsiniz ama zararını da engellersiniz. Bunun için htmlentities ve htmlspecialchars imdadınıza yetişir. Bu fonksiyonlar neredeyse aynı işe yarar ama htmlspecialchars fonksiyonunda ek parametreler bildirebildiğiniz için htmlspecialchars kullanmanız önerilir. Veriniz nereden gelirse gelsin, muhakkak süzmeden almayın kaydetmeyin. Sonra başınız ağrımasın. Başka bir yer daha var. BBCODE uygulamalarınızda da bu süzmeyi yapmazsanız XSS yersiniz. [url="javascript:alert(document.cookie);"]URL METNİ [/ url] [img]javascript:location='http://google.com.tr';[/img]

Bu şekilde rahatça Javascript kodu çalıştırabilirsiniz. O yüzden bu verileri de süzmek için str_replace kullanmanız gerekir. Ayrıca bir fonksiyonu görmedim ancak sizin bir fonksiyon yazıp bu verileri süzmeniz lazım. Yoksa BBCODE ile çok rahat,

Javascript - HTML kodu çalıştırabilirler. Gördüğünüz gibi, hiç ummadığınız yerlerden açık çıkabiliyormuş. Mesela bir arama yapıyorsunuz. Aramanızda GET veya POST ile gelen metni olduğu gibi ekrana bastırırsanız, XSS yemeniz, kaçınılmazdır. SESSION Hack'den korunma Diyelim ki, bir login sayfamız var ve biz bu sayfadan login olan kişilere SESSION’da bir değer atadık diyelim. $_SESSION['login'] = "1"; $_SESSION['tip'] = "admin";

Adam hangi sayfaya girerse girsin hiçbir sorgulama yapmaksızın direk olarak adminliği ilan etmiş oluyor. SESSION değiştirilemez sanan arkadaşlar, SESSION’u ben de değiştirilemeyeceğini sanıyordum ancak değiştirilebildiğini öğrendiğimden beri, gözümde COOKIE kadar değeri kaldı. Bunu nasıl değiştirildiğine dair ufak bilgilendirme yapacağım. Muhakkak süzmekte fayda var SESSION bilgilerini de. SESSION değişmesi için öncelikle aynı sunucudan bir başka kullanıcının sizin SESSION değerlerinizi bilmesi gerekir. $_SESSION['login'] = '1'; $_SESSION['tip'] = 'admin'; header('Location: http://hackleneceksite.com/admin.php');

Bu işlemi yapmak için öncelikle karşı sitenin sizin SESSION değerlerinizi bilmesi gerekir. Eğer aynı sunucuda olurlarsa SESSION değerleri yüzünden siteniz hacklenir. O yüzden, SESSION yüzünden scriptiniz hacklenirse, hemen aynı sunucuda olan bir başka kullanıcı sayesinde hacklendiğini bilmenizde fayda var. SESSION’da bu tip uygulamaları yapmayın yaparsanız zararlı olursunuz. Evet, arkadaşlar demek ki artık ne yapacakmışız? COOKIE, SESSION, GET, POST gibi dışarıdan veri aldığımızda muhakkak ama muhakkak verileri süzecekmişiz. IFRAME Virüsü ve Kurtuluşu IFRAME virüsü nasıl bulaşır öncelikle ona bir göz atalım. Crack’li FTP programlarından veya sunucunuza bulaşmış bir virüs ise sunucunuzdan sayfalarınıza bulaşır. • • • •

Nerelere bulaşır? index, home, main, default kelimeleri geçen tüm dosyalarınıza bulaşır. Kurtuluşu nedir? Crackli ftp programlarını kaldırın, FTP şifrenizi değiştirin, dosyalarınızın içinde bulaşan kodları silin, Windows’un kendi FTP bağlantısını kullanın. Eğer sorun çözülmezse format atın tekrar baştan itibaren aynı işlemleri yapın. Yine sorun çözülmezse hosting sağlayıcınızla görüşün ve onlar çözsünler sorununuzu.

Bu sorun genelde cuteFTP tipi crackli veya normal FTP programlarından bulaşır. O yüzden korunmak için bu tür programları kullanmayın. Bir de CSRF(Cross Site Request Forgery) vardır hack yöntemi ancak, şu dönemde CSRF yiyen scriptler kaldığını zannetmem. Kalsa bile çok eski

scriptlerdendir yiyenler. Bu açık da, mesela bir html sayfası oluşturdunuz diyelim. Şöyle diyelim; http://hackleneceksite.com/my_profil...=profiledelete gibi bir adresimiz olsun ve bu adreste post edilen bilgiler; http://hackleneceksite.com/my_profil...te&submit=true adresine yönlendirilsin. Sayfa içinde de

böyle birer input olsun. Bu adreste siteden memnun değil isek sitenin bize tanıdığı bir hak olsun profilimizi silmek için. Burada posttan gelen check true ise ve email girilmiş ise, hemen profili silme işlemine geçiyor diyelim. O zaman biz de bir form oluşturalım bir html sayfasında şu şekilde; Biz eğer kullanıcının bilgilerinden emailini biliyorsak;
<script>document.hack.submit();

Şeklinde oluşturduğumuz html sayfasını kaydedelim ve tarayıcıda çalıştıralım. Çalışınca ne olur derseniz, tabi ki profil silinir çünkü gördüğünüz gibi, profil bilgilerini posttan alıyor. Tabi bunu ben sadece bir örnek olarak verdim, daha da açılabilir bu örnek tabi ki... Mesela phpbb için eski bir CSRF PM silme açığı;
<script>document.hack.submit();

Tabi bunlardan kurtulmak için muhakkak kendiniz, COOKIE veya SESSION ile name ve pass ekleyip oradan verileri SQL de sorgulatmanız gerekmektedir. Yoksa böyle basit işlem hataları yüzünden scriptinizde hasar ciddi olabilir. Ve geri dönülemez de olabilir.

Related Documents

Php
November 2019 9
Php
October 2019 10
Php
November 2019 13
Php
June 2020 22
Php
November 2019 46

More Documents from ""

May 2020 30
May 2020 5
May 2020 1
May 2020 1
May 2020 1
May 2020 1