SQL Injection Nedir?Ares'in kullandigi yöntem

Death_AngeL

Banned
Katılım
27 Haz 2005
Mesajlar
602
Reaction score
0
Puanları
0
Arkadaslar SQL Injection birçok hacker kullandigi sql açiklarindan yararlanarak sayfaya index atma veya index teki yazilari degistirme gibi islerde kullanilan bir sql uygulamasidir.Bunu Sitemizde Ares abimiz ve birkaç kisi daha kullanmaktadir.Ama bunu kullanmadan önce ne oldugunu ögrenelim.Bu dökümani microsoft akademilerinde verilen makalelerden aldim.

Veri tabanında çalıştırılacak olan komutları sql cümlecikleri ile parça parça oluşturmak ne yazık ki, bir çok kişinin tercih ettiği bir yöntemdir. Oysa ki ekran tarafında hiç bir sql cümleciği bulunmamalıdır. Bu altyapısal bir problemdir. Kullanıcının girdiği bir bilgiye göre sql cümleciğini oluşturmak güvenlik açısından çok büyük problemler yaratmaktadır. Kullanıcı kendisinden bilgi beklenen yerde her türlü ifadeyi girebilir. Örneğin, yaşını yazmasını istediğiniz bir kullanıcı yaşını yazması gereken yere adını yazabiliyor, ve program çalışma zamanında hata vermesi durumunda bu yazılımı geliştiren kişilerin bir hatası olarak yorumlanıyor. Bu noktada yazılım geliştirici kullanıcının girdiği tüm bilgilerin geçerlilik kontrollerini yapmak zorundadır. Bu geçerlilik kontrolleri için ASP.NET’te validator (doğrulayıcı) kontrolleri tanımlanmıştır ve doğrusu bu kontrolleri kullanarak kullanıcının girdiği bilgilerinin geçerliliği denetlemektir.

Kullanıcının yaş beklenen yere adını yazması oldukça masum bir hatadır. Eğer ki kullanıcıdan alınan bilgiyi olduğu gibi SQL cümleciğinin içine ekleyip kullanıyorsanız, daha büyük sorunlarınız var demektir. Çok basit anlamda bir konsol uygulaması geliştirelim. Bu konsol uygulamasında kullanıcıdan bir kullanıcı adı ve şifre alalım. Kullanıcı adı ve karşılık gelen şifrelerimizi de alışageldiği üzere veri tabanında “Users” tablosunda saklayalım. Sistemimizde tanımlı kullanıcılar şu şekilde tanımlanmış olsun:
sql5we.png

Öncelikle sistemimizde tanımlı şifrelere bir eleştiri getirelim. Sistemimizdeki şifrelerin hiç biri yeterince güvenli değil. Sadece “admin” kullanıcısının şifresi biraz güvenilir kabul edilebilir ancak kullanıcı adının şifrenin içinde tekrarlanması hatalı bir yaklaşımdır. Uygulamamızı ise şu şekilde geliştirmiş olalım:
 
Kod:
C#
using System;
using System.Data;
using System.Data.SqlClient;

namespace SampleApp
{
    class Sample
    {
        static string ConnectionString
        {
            get
            {
                return @"Data Source=.;Initial Catalog=SampleDB;
Integrated Security=true";
            }
        }
        static bool AuthenticateUser(string username,string password)
        {
            SqlConnection cn = null;
            try
            {
                cn =new SqlConnection(ConnectionString);
                SqlCommand cmd = 
                    new SqlCommand(@"select count(*) as c from Users 
where userID='"+
                    username+"' and password='"+password+"'",cn);
                cn.Open();
                object oResult= cmd.ExecuteScalar();
                if (oResult!=null && oResult!=DBNull.Value)
                {
                    return (int)oResult>0;
                }
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.Message);
                
            }
            finally
            {
                if (cn!=null && cn.State!=ConnectionState.Closed)
                    cn.Close();
            }
            return false;

        }
        static void Main() 
        {
            Console.Write("Kullanıcı Adı : ");
            string username= Console.ReadLine();
            Console.Write("Şifre : ");
            string password = Console.ReadLine();
            if( AuthenticateUser(username,password))
            {
                Console.WriteLine("Şifre Doğrulandı !!!");
                Console.WriteLine("Merhaba "+username);
            }
            else
            {
                Console.WriteLine("Şifre Doğrulanamadı !!!");
                Console.WriteLine(
"Kullanıcı Adı ve Şifrenizi Kontrol ediniz..");
            }
        }
    }
}
VB.NET
Imports System
Imports System.Data
Imports System.Data.SqlClient

Module SampleApp
    ReadOnly Property ConnectionString() As String
        Get
            Return "Data Source=.;Initial Catalog=SampleDB; _
Integrated Security=true"
        End Get
    End Property
    Function AuthenticateUser(ByVal username As String, _
    ByVal password As String) As Boolean
        Dim cn As SqlConnection = Nothing
        Try
            cn = New SqlConnection(ConnectionString)
            Dim cmd As New _
            SqlCommand("select count(*) as c from Users  _
where userID='" _
            + username + "' and password='" + password + "'", cn)
            cn.Open()
            Dim oResult As Object = cmd.ExecuteScalar()
            If Not ((oResult Is Nothing Or oResult Is DBNull.Value)) Then
                Return CType(oResult, Integer) > 0
            End If
        Catch ex As Exception
            Console.Write(ex.Message)
        Finally
            If Not ((cn Is Nothing Or cn.State = ConnectionState.Closed)) Then
                cn.Close()
            End If
        End Try
        Return False
    End Function

    Sub Main()
        Console.Write("Kullanıcı Adı : ")
        Dim username As String = Console.ReadLine()
        Console.Write("Şifre : ")
        Dim password As String = Console.ReadLine()
        If (AuthenticateUser(username, password)) Then
            Console.WriteLine("Şifre Doğrulandı !!!")
            Console.WriteLine("Merhaba " + username)
        Else
            Console.WriteLine("Şifre Doğrulanamadı !!!")
            Console.WriteLine("Kullanıcı Adı ve Şifrenizi Kontrol ediniz..")
        End If
    End Sub
End Module
C++.NET
#include "stdafx.h"

#using <mscorlib.dll>

using namespace System;
using namespace System::Data;
using namespace System::Data::SqlClient;

#define ConnectionString S"Data Source=.;Initial Catalog=SampleDB;
Integrated Security=true"

bool AuthenticateUser(String __gc* username,String __gc* password)
{
    SqlConnection __gc* cn = NULL;
    try
    {
        cn =__gc new SqlConnection(ConnectionString);
        SqlCommand __gc* cmd = __gc 
            new SqlCommand(String::Format(
            S"select count(*) as c from Users 
where userID='{0}' and password='{1}'"
            ,username,password),cn);
        cn->Open();
        Object __gc* oResult= cmd->ExecuteScalar();
        if (oResult!=NULL && oResult!=DBNull::Value)
        {
            return Convert::ToInt32(oResult)>0;
        }
        
    }
    catch(Exception __gc* ex)
    {
        Console::WriteLine(ex->Message);
    }
    __finally
    {
        if ((cn!=NULL) && (cn->State != ConnectionState::Closed))
        {
            cn->Close();
        }
    }
    return false;
}
int _tmain()
{
    Console::Write(S"Kullanıcı Adı : ");
    String __gc* username=Console::ReadLine();
    Console::Write(S"Şifre : ");
    String __gc* password=Console::ReadLine();
    if (AuthenticateUser(username,password))
    {
        Console::WriteLine("Şifre Doğrulandı !!!");
        Console::WriteLine(String::Format("Merhaba {0}", username));
    }
    else
    {
        Console::WriteLine("Şifre Doğrulanamadı !!!");
        Console::WriteLine("Kullanıcı Adı ve Şifrenizi Kontrol ediniz..");
    }
    return 0;
}
J#
package SampleApp;

import System.*;
import System.Data.*;
import System.Data.SqlClient.*;

public class SampleMain
{
    public SampleMain()
    {
    }
    /** @property */
    public static String get_ConnectionString()
    {
        return "Data Source=.;Initial Catalog=SampleDB;
Integrated Security=true";
    }
    public static boolean AuthenticateUser(String username,String password)
    {
        SqlConnection cn = null;
        try
        {
            cn =new SqlConnection(get_ConnectionString());
            SqlCommand cmd = 
                new SqlCommand("select count(*) as c from Users 
where userID='"+
                username+"' and password='"+password+"'",cn);
            cn.Open();
            Object oResult= cmd.ExecuteScalar();
            if (oResult!=null && oResult!=DBNull.Value)
            {
                return Convert.ToInt32(oResult) >0;
            }
        }
        catch(System.Exception ex)
        {
            Console.WriteLine(ex.get_Message());
                
        }
        finally
        {
            if (cn!=null && cn.get_State()!=ConnectionState.Closed)
                cn.Close();
        }
        return false;
    }

    /** @attribute System.STAThread() */
    public static void main(String[] args)
    {
        Console.Write("Kullanıcı Adı : ");
        String username= Console.ReadLine();
        Console.Write("Şifre : ");
        String password = Console.ReadLine();
        if( AuthenticateUser(username,password))
        {
            Console.WriteLine("Şifre Doğrulandı !!!");
            Console.WriteLine("Merhaba "+username);
        }
        else
        {
            Console.WriteLine("Şifre Doğrulanamadı !!!");
            Console.WriteLine("Kullanıcı Adı ve Şifrenizi Kontrol ediniz..");
        }
    }
}
 
Kullanıcı adı olarak “admin”, şifre olarak da “asdas” gibi bir değer girip sistemin bizi kabul edip etmediğini kontrol edelim. Sistem kullanıcı adı ve şifremizi kabul etmemiştir. Doğru bir davranış göstermiştir. Şimdi kullanıcı adı olarak “admin”, şifre olarak da doğru şifremiz olan “admin123nimda~” girip sistemin bizi kabul edip etmediğini tekrar test edelim. Girdiğimiz kullanıcı adı ve şifre doğru olduğu için sistem bizi kabul edecektir. Şimdi “SQL Injection” kullanarak sistemimizin kimlik denetim mekanizmasını kıralım. Kullanıcı adı olarak “admin” ve şifre olarak da “a’ OR 1=1 --” ifadesini girelim. Sürpriz !! Sistemimiz bizi kabul etti. Peki ama nasıl oldu bu? SQL cümleciği ;
“select count(*) as c from Users where userID='admin' and password='a' or 1=1 --'” şeklinde oluşmuştur. Bu durum da SQL Server, kullanıcı adı admin olan şifresi ‘a’ olan ya da 1=1 olan kullanıcıları getirmektedir. “1=1” her zaman geçerli bir ifade olduğundan şifrenin ‘a’ olmasının ya da olmamasının hiç bir önemi kalmamıştır. Sistemimiz şu an itibariyle hacklenmiştir. Sisteme giren kişinin yapabileceklerini tahmin bile edemezsiniz. Ki bu sistemimize sızmayı başaran bir kullanıcıdır. Kişi şu an sadece sistemimizin kimlik denetim mekanizmasını kırmıştır. Peki sistemimize zarar veremez mi?

Kullanıcı adı olarak “admin” ve şifre olarak da “a’ OR 1=1; DROP TABLE Users --” girilmesi durumunda ne olacaktır. Kullanıcı hem kimlik denetim mekanizmasını kıracak sisteme yönetici olarak giriş yapacaktır hem de sistemimizdeki kullanıcıları tuttuğumuz Users tablosu silinecektir.

Peki bu durumdan kurtulmanın bir yolu yok mudur? Çözüm olarak, kullanıcıların tümünü kod tarafına çekmek ve kodda bu karşılaştırmayı yapmaktan kllancının gireceği “ ' ”, “ -- ” gibi karakterleri silmeye kadar bir çok yöntem önerilmiştir. Ancak en doğrusu, SQL cümleciklerini kod tarafında oluşturmamak bunun yerine “Stored Procedure” kullanmaktır. Bu uygulamayı stored procedure kullanarak yeniden geliştirirseniz sisteminizi kıramadığınızı göreceksiniz. Ancak genel olarak çözümü parametreli sorgular kullanmak şeklinde yorumlamamızın daha doğru olacağı kanısındayım. Ayrıca “DROP TABLE” ya da “DROP DATABASE” gibi komutların çalıştırılması sonucu hoş olmayan sonuçlarla karşılaşmak istemiyorsanız; Veri tabanına bağlanırken kullandığınız kullanıcıları yapılan işlemlere göre ayırın. Sadece veri tabanından okuyacağınız yerlerde sadece ilgili veri tabanına okuma hakkı olan bir SQL Server kullanıcısı ile bağlantınızı kurun. Her veri tabanına erişim için aynı kullanıcı adını kullanmaktan şiddetle kaçının. Sistemleri kırmak ve korumak için yapılması gerekenler detaylarda gizlidir. Detayları atlamamaya özen gösterin. Ayrıca burada sadece bir konsol uygulamasında bu yöntemi denedik. Aynı sorun Windows ve Web uygulamalarında da karşınıza çıkacaktır.
 
user : admin
pass : shutdown --

sqL i kapatır :p
 
death eline sağlık güzel döküman
tşekkürler
be abim o zaman niye sorarsın madem biliyon
:cool:
 
Abi biliyoz da senin kadar iyi bilmiyoz abi ya.Sende bize biraz bilginden katarsan daha fazla bilgili oluruz,daha fazla sey biliriz ve daha fazla seyler yapabilriz.Öyle dimi abicim.
 
kim demiş benim kadar olamadını
belki sen daha iyisin ayrıca konun çok güzel olmuş
kimse iyi değildir
EK bir not olarak
sql server enterprise manager
sorgu cümleciğinden'de
faydalanabilirsiniz
 
A R E S' Alıntı:
kim demiş benim kadar olamadını
belki sen daha iyisin ayrıca konun çok güzel olmuş
kimse iyi değildir

ares abicim iyi wardir daha iyi wardir birde çok iyi wardir... :D benden daha iyi olma asamasindayim...sen o asamayi geçmissin biliyoz önceki konularindan ve önceki sitelerden,yaptiklarindan.bizim daha bir faaliyetimiz yok ama olmasi için gayret gösteriyoz.0nsallah olacak ve burdakilerlede payasacaz bildiklerimizi :D

edit : keskin paylasimin için tesekkürler kardes.Firsat bulursam daha detayli uygulamayi koyacam buraya asama asama yani.Bilgisayar benim degil o yüzden pek birsey yapamiyom :(
 
Death_AngeL' Alıntı:
Firsat bulursam daha detayli uygulamayi koyacam buraya asama asama yani.Bilgisayar benim degil o yüzden pek birsey yapamiyom :(


KARDEŞ SAOL BEKLİYORUZ DEVAMINI
 
Geri
Üst