• 19-10-2009, 02:09:29
    #10
    Üyeliği durduruldu
    session kontrolu olursa curl işe yaramaz. deneyin görün
  • 19-10-2009, 02:25:46
    #11
    Yanılıyorsunuz
    @devturkeli burda haklı
    Neden ?
    İlk önce session nasıl çalışır onu söyliyeyim
    Session ID diye birşey vardır bildiğiniz üzere. Bu ID cookie vasıtası ile kullanıcıya aktarılır ve her istekte bu ID sunucuya tekrar gönderilir. Bu sayafada oturumun(session) kalıcı olmasını sağlar. (Eğer çerezler kapalı ise oturumunuz sürekli değişecektir. Deneyin ve görün).
    Bu yüzden curl ile rahatlıkla aşılabilir. Nasıl mı ?
    curl ile karşı tarafa istenildiği gibi başlık(header) yollanıyor. Bunun içinde session id bilgiside yollanıyor. Bu yüzden session id, her istekde random olarak bir değer alırsa oturum sürekli değişeceğinden dolayı bu hiç bir işe yaramaz.
    Daha iyi ne önerebilirsin ?
    IP bazlı kontrol
    IP bazlı kontrol aşılabilir mi ?
    Evet. Elinizde proxy listeniz var ise buda aşılır.

    Umarım açıklayıcı olmuştur.
  • 19-10-2009, 02:48:21
    #12
    Üyeliği durduruldu
    ah mustafa ben anlatamayacağım bunlara mustafa

    kaydet test.php
    <?php
    session_start();
    $sid = session_id();
    if ($_POST['sid'] == $sid)
    {
        if (!$_SESSION['hede'])
        {
            fwrite(fopen("a.txt", "a"), "hede\n");
            echo 'Yazı Eklendi.';
        }
        else
        {
            echo 'Flood girişimi!';
        }
    }
    $_SESSION['hede'] = 'hede';
    ?>
    kaydet flood.php
    <?php
    function getir($site)
    {
        $fakeSID=md5(mt_rand(1,9999));
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $site);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_COOKIE, "PHPSESSID=$fakeSID");
        curl_setopt($ch,CURLOPT_POST, true);
        curl_setopt($ch,CURLOPT_POSTFIELDS,"sid=$fakeSID");
        $data = curl_exec($ch);
        curl_close($ch);
        return $data;
    }
    echo getir('http://p/test.php');
    ?>
    İlk önce normal browserden session kontrollü ve session korumalı(?) test.php yi çalıştırın. a.txt dosyası yazıldıktan sonra session hafızaya kaydedildiği için, session kontrolü sayesinde 2. bir işleme izin vermeyecek ve ekrana Flood girişimi! yazacaktır.

    Şimdi flood.php yi çalıştırın seri bir şekilde sayfanızı sürekli yenileyin. a.txt dosyanızı açın bir yığın hede yazısını görürsünüz.

    Anlatmak istediğim sessionid kontrol falan tıraş. Curl ile fake sessionid oluşturuluyor hafızaya alınıyor test.php deki session kontrolüde, curlun kaydettiği fakesessionid ile yine post ile yolladıgım aynı fakesessionid i eşleştiriyor, eşit oldugu için dediğiniz güvenlik tırt kalıyor.
  • 19-10-2009, 10:35:13
    #13
    Üyeliği durduruldu
    devturkeli adlı üyeden alıntı: mesajı görüntüle
    ah mustafa ben anlatamayacağım bunlara mustafa
    devturkeli nin uygulama mantigi aynen gecerli. sessionda token gibi bir paremetre tutmuyorsaniz session id olmasinin bir engelleyici etkisi olmaz.

    php güvenliği ile ilgili video serisi yapiyorum inş bitince hepsini anlatcam
  • 20-10-2009, 22:03:32
    #14
    BHCoder adlı üyeden alıntı: mesajı görüntüle
    session kontrolu olursa curl işe yaramaz. deneyin görün
    Curl ile session kontrolünü çok rahat aşarsın..

    devturkeli, 2 üstteki son mesajın ve zone.org ile alakalı verdiğin linkte ancak kokulusilginin verdiği kodu aşarsın, en altta Yns de demiş ki; "yine curl ve regexp yardimiyla sayfaya istek yapilip hidden input'un degeri alinip, ondan sonra sayfaya post edilirse senin korumada caresiz kaliyor", demiş, ama maalesef yanılmış.

    Üyelik kontrollü bir sistemde flood kontrolü basit bir şekilde engellenebilir fakat direk ziyaretçiden alınacak veriler en iyi IP kontrolü ile engellenebilir, bunun harici diğer yöntemlerle engelleme yapılırsa curl ile aşılabilir, fakat IP bazlı bir engelleme yapılırsa ancak dnmtnk'nin de dediği gibi ya random proxy kullanacaksınız ya da modeme reset atacaksınız

    Az sonra bunun ile ilgili bir betik yazıp paylaşacağım, token kontrollü olsun istediğiniz gibi, o betiği aşacak kodu paylaşırsanız fazla söze gerek kalmamış olur böylece
  • 20-10-2009, 22:23:44
    #15
    Üyeliği durduruldu
    ben session id için demedim .tamam arkadaş haklı ama sessiona bir parametre verilmesi durumunda.veya ip bazlı yapıldığında güvenli.
  • 20-10-2009, 22:55:25
    #16
    Evet kodumuz aşağıdaki gibi, güvenlik kodu yok, 30 saniye içinde yada sizin belirleyeceğiniz bir süre kadar yeniden mesaj yazılmasını engeller, bu engeli ancak curl ile random proxy kullanarak ya da modeminiz 30 saniye içinde yeni bir ip alıyorsa resetleyip öyle aşabilirsiniz (benim modem 20 saniyede yeni ip alıyor mesela), ayrıca dışarıdan direk post gönderimini engellemek için gizli bir hidden input ile key gönderiyoruz, buna CSRF koruması da deniyor, kıracak olan varsa buyursun kırsın, bizde yeni birşey öğrenmiş oluruz.

    (Ufak tefek hatalar olabilir, inceden inceye kontrol etmedim.)

    Tablo:

    CREATE TABLE messages (
      id int(11) NOT NULL auto_increment,
      message text NOT NULL,
      name varchar(25) NOT NULL,
      ip varchar(15) NOT NULL,
      time timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
      PRIMARY KEY  (id)
    );

    Dosya (herhangi bir isimle kaydedin)

    <?php
    session_start();
    @setlocale(LC_ALL, 'turkish');
    // connect
    mysql_connect('localhost','root','0000') or die (mysql_error());
    mysql_select_db('flood') or die (mysql_error());
    // settings
    $floodtime = 30;
    $charlimit = 100;
    ###################################################################################################
    if(empty($_REQUEST['flood']))
    {
    $ip = $_SERVER['REMOTE_ADDR'];
    $_SESSION['ip'] = $ip;
    $time = time();
    $key = md5($ip).md5(microtime());
     
    if(!isset($_SESSION['key'])){
    $_SESSION['key'] = $key;
    }
     echo '
     <h4>Flood Koruması</h4>
     <form method="POST" action="'.$_SERVER['PHP_SELF'].'?flood=message">
     İsim :&nbsp;&nbsp;&nbsp;&nbsp;<input type="text" name="name"><br />
     Mesaj : <textarea name="message" rows="10" cols="30"></textarea>
     <input type="hidden" name="key" value="'.$key.'"><br /><hr />
     * Mesajınız en çok '.$charlimit.' karakter olabilir.<br />
     * Yeniden mesaj gönderme süresi : '.$floodtime.' sn.<br /><hr />
     <input type="submit" value="Send Message">
     </form>
     ';
    }
     
    ###################################################################################################
     
    if($_REQUEST['flood']=='message')
    {
     if(empty($_POST['key']) || empty($_SESSION['key']) || $_POST['key'] != $_SESSION['key'])
     {
      die ('<a href="'.$_SERVER['PHP_SELF'].'">Yeni flood denemesi yap!</a>');
     }
     elseif(empty($_POST['name']) || empty($_POST['message']))
     {
      header('Refresh:3 url='.$_SERVER['PHP_SELF']);
      die ('Lütfen boş alan bırakmayınız !');
     }
     elseif($charlimit < strlen($_POST['message']))
     {
      header('Refresh:3 url='.$_SERVER['PHP_SELF']);
      die ('Mesajınız en çok '.$charlimit.' karakter olabilir.');
     }
     else
     {
      $sql = mysql_query("SELECT * FROM messages WHERE ip = '$_SESSION[ip]' ORDER BY time DESC LIMIT 1") or die (mysql_error());
      $res = @mysql_fetch_row($sql);
      $dbtime = strtotime($res['4']);
      $nowtime = time();
      if(($nowtime - $dbtime) < $floodtime)
      {
       header('Refresh:3 url='.$_SERVER['PHP_SELF']);
       die ('Yeniden mesaj gönderebilmek için '.($floodtime - ($nowtime - $dbtime)).' saniye beklemelisiniz !');
      }
      else
      {
       header('Refresh:3 url='.$_SERVER['PHP_SELF']);
       $message = mysql_real_escape_string(strip_tags(trim($_POST['message'])));
       $name = mysql_real_escape_string(strip_tags(trim($_POST['name'])));
       mysql_query("INSERT INTO messages (message,name,ip,time) VALUES ('$message','$name','$_SESSION[ip]',NOW())") or die ('Bir problem oldu, daha sonra tekrar deneyiniz.');
       echo 'Mesajınınız eklendi..<br /><a href="'.$_SERVER['PHP_SELF'].'">Başka mesaj ekle!</a>';
      }
     }
    }
    ?>
  • 21-10-2009, 00:25:55
    #17
    Kimlik doğrulama veya yönetimden onay bekliyor.
    Enigmatic adlı üyeden alıntı: mesajı görüntüle
    Evet kodumuz aşağıdaki gibi, güvenlik kodu yok, 30 saniye içinde yada sizin belirleyeceğiniz bir süre kadar yeniden mesaj yazılmasını engeller, bu engeli ancak curl ile random proxy kullanarak ya da modeminiz 30 saniye içinde yeni bir ip alıyorsa resetleyip öyle aşabilirsiniz (benim modem 20 saniyede yeni ip alıyor mesela), ayrıca dışarıdan direk post gönderimini engellemek için gizli bir hidden input ile key gönderiyoruz, buna CSRF koruması da deniyor, kıracak olan varsa buyursun kırsın, bizde yeni birşey öğrenmiş oluruz.
    (Ufak tefek hatalar olabilir, inceden inceye kontrol etmedim.)
    Tablo:
    CREATE TABLE messages (
      id int(11) NOT NULL auto_increment,
      message text NOT NULL,
      name varchar(25) NOT NULL,
      ip varchar(15) NOT NULL,
      time timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
      PRIMARY KEY  (id)
    );
    Dosya (herhangi bir isimle kaydedin)
    <?php
    session_start();
    @setlocale(LC_ALL, 'turkish');
    // connect
    mysql_connect('localhost','root','0000') or die (mysql_error());
    mysql_select_db('flood') or die (mysql_error());
    // settings
    $floodtime = 30;
    $charlimit = 100;
    ###################################################################################################
    if(empty($_REQUEST['flood']))
    {
    $ip = $_SERVER['REMOTE_ADDR'];
    $_SESSION['ip'] = $ip;
    $time = time();
    $key = md5($ip).md5(microtime());
    if(!isset($_SESSION['key'])){
    $_SESSION['key'] = $key;
    }
     echo '
     <h4>Flood Koruması</h4>
     <form method="POST" action="'.$_SERVER['PHP_SELF'].'?flood=message">
     İsim :&nbsp;&nbsp;&nbsp;&nbsp;<input type="text" name="name"><br />
     Mesaj : <textarea name="message" rows="10" cols="30"></textarea>
     <input type="hidden" name="key" value="'.$key.'"><br /><hr />
     * Mesajınız en çok '.$charlimit.' karakter olabilir.<br />
     * Yeniden mesaj gönderme süresi : '.$floodtime.' sn.<br /><hr />
     <input type="submit" value="Send Message">
     </form>
     ';
    }
    ###################################################################################################
    if($_REQUEST['flood']=='message')
    {
     if(empty($_POST['key']) || empty($_SESSION['key']) || $_POST['key'] != $_SESSION['key'])
     {
      die ('<a href="'.$_SERVER['PHP_SELF'].'">Yeni flood denemesi yap!</a>');
     }
     elseif(empty($_POST['name']) || empty($_POST['message']))
     {
      header('Refresh:3 url='.$_SERVER['PHP_SELF']);
      die ('Lütfen boş alan bırakmayınız !');
     }
     elseif($charlimit < strlen($_POST['message']))
     {
      header('Refresh:3 url='.$_SERVER['PHP_SELF']);
      die ('Mesajınız en çok '.$charlimit.' karakter olabilir.');
     }
     else
     {
      $sql = mysql_query("SELECT * FROM messages WHERE ip = '$_SESSION[ip]' ORDER BY time DESC LIMIT 1") or die (mysql_error());
      $res = @mysql_fetch_row($sql);
      $dbtime = strtotime($res['4']);
      $nowtime = time();
      if(($nowtime - $dbtime) < $floodtime)
      {
       header('Refresh:3 url='.$_SERVER['PHP_SELF']);
       die ('Yeniden mesaj gönderebilmek için '.($floodtime - ($nowtime - $dbtime)).' saniye beklemelisiniz !');
      }
      else
      {
       header('Refresh:3 url='.$_SERVER['PHP_SELF']);
       $message = mysql_real_escape_string(strip_tags(trim($_POST['message'])));
       $name = mysql_real_escape_string(strip_tags(trim($_POST['name'])));
       mysql_query("INSERT INTO messages (message,name,ip,time) VALUES ('$message','$name','$_SESSION[ip]',NOW())") or die ('Bir problem oldu, daha sonra tekrar deneyiniz.');
       echo 'Mesajınınız eklendi..<br /><a href="'.$_SERVER['PHP_SELF'].'">Başka mesaj ekle!</a>';
      }
     }
    }
    ?>
    Kodun oldukça güvenli fakat bir kaç eksik var.
    $_SERVER['PHP_SELF']
    xss açığı oluşturur.
    bknz. Temizlemek lazım kullanmadan önce.
    xss açığı olunca sayfadaki key değeri çok rahat alınabilinir ve kullanıcının haberi olmadan veri postlanabilinir.
    CSRF için key yerine referrer kontrolü yapmak daha iyi olur, çünkü javascript ile sahte referrer gönderilemez.
  • 21-10-2009, 16:50:03
    #18
    S4l1h adlı üyeden alıntı: mesajı görüntüle
    Kodun oldukça güvenli fakat bir kaç eksik var.
    $_SERVER['PHP_SELF']
    xss açığı oluşturur.
    bknz. Temizlemek lazım kullanmadan önce.
    xss açığı olunca sayfadaki key değeri çok rahat alınabilinir ve kullanıcının haberi olmadan veri postlanabilinir.
    CSRF için key yerine referrer kontrolü yapmak daha iyi olur, çünkü javascript ile sahte referrer gönderilemez.
    Kodu genel kullanım için vermedim zaten, herkesin kendine göre çeşitli güvenlik fonksiyonları var, kullanmak isteyen elbette güvenlik önlemlerini alacak.

    Key değeri elbette çok basitçe alınabilir, buradaki key değerinin amacı adres satırına direk POST yapılmasını engellemek içindir, yani saldırgan önce ilk önce formu mutlaka ziyaret etmelidir, CURL ile rahatça key değeri alınıp POST gönderilebilir ama tek sefer, ard arda gönderim belirlenen süre kadar yapılamaz, yapılabilmesi için mutlaka ip değişilmesi gerekir.

    Birde şu cümleyi hiç anlamadım;

    Alıntı
    CSRF için key yerine referrer kontrolü yapmak daha iyi olur, çünkü javascript ile sahte referrer gönderilemez.
    CURL ile referer kontrolü basitçe aşılabiliyor biliyorsunuz, javascriptin konuyla alakasını anlamadım ?