it-swarm-tr.com

Çok baytlı karakter sömürüsü - PHP / MySQL

Birisi beni MySQL için çok baytlı karakter istismarları hakkında bazı bilgiler içeren bir bağlantıya yönlendirebilir mi? Bir arkadaşım dikkatimi çekti, ama internette çok fazla bilgi bulamadım.

20
Matthew S

Özet. Evet, sorun, bazı karakter kodlamalarında (UTF-8 gibi), tek bir karakterin birden çok bayt olarak temsil edilmesidir. Bazı programcıların SQL enjeksiyonunu önlemeye çalışmasının bir yolu, SQL sorgularına eklemeden önce güvenilmeyen girdideki tüm tek tırnaklardan kaçmaktır. Bununla birlikte, birçok standart alıntıdan kaçış işlevi, veritabanının tek bir karakterin birkaç baytı doldurabileceğinden habersiz, girdilerini bir bayt dizisi olarak kullanacağı ve işleyeceği karakter kodlamasından habersizdir. Bu, tırnaktan kaçış işlevinin dizeyi veritabanından farklı şekilde yorumladığı anlamına gelir. Sonuç olarak, alıntıdan kaçma işlevinin, veritabanının tek bir alıntıyı çok baytlı kodlaması olarak yorumlayacağı dizenin bölümlerinden kaçamayabileceği bazı durumlar vardır; veya istemeden çok baytlık bir karakter kodlamasını, daha önce bulunmayan tek bir tırnak işareti içerecek şekilde parçalayabilir. Bu nedenle, çok baytlı karakter açıkları, programcı girdilerini veritabanına yeterince kaçtıklarını düşünse bile saldırganlara SQL enjeksiyon saldırıları yapmaları için bir yol sağlar.

Etki. Tüm veritabanı bağlantılarını oluşturmak için hazırlanmış/parametrelenmiş deyimler kullanırsanız, güvendesiniz. Çok baytlı saldırılar başarısız olur. (Tabii ki veritabanındaki ve kütüphanedeki hataları engelleme. Ama ampirik olarak, bunlar nadir görünüyor.)

Ancak, güvenilmeyen girdilerden kaçmaya çalışır ve ardından dize birleştirmesini kullanarak dinamik olarak bir SQL sorgusu oluşturmaya çalışırsanız, çok baytlı saldırılara karşı savunmasız olabilirsiniz. Aslında savunmasız olup olmadığınız, kullandığınız kaçış işlevinin, kullandığınız veritabanının, veritabanıyla kullandığınız karakter kodlamasının ve muhtemelen diğer faktörlerin belirli ayrıntılarına bağlıdır. Çok baytlı saldırıların başarılı olup olmayacağını tahmin etmek zor olabilir. Sonuç olarak, dize birleştirme kullanarak SQL sorguları oluşturmak kırılgandır ve önerilmez.

Teknik ayrıntılar. Saldırıların ayrıntılarını okumak isterseniz, size saldırıları mükemmel bir şekilde açıklayan bir dizi bağlantı sağlayabilirim detay. Birkaç saldırı var:

  • Tırnak işlevi tarafından ek ters eğik çizgiler/tırnak işaretleri yiyerek UTF-8 ve diğer karakter kodlamalarına yönelik temel saldırılar: bkz. Örn. burada .

  • Sizin için ekstra bir teklif sunmak için alıntı işlevini kandırarak çalışan örneğin GBK'ya yapılan sinsi saldırılar: bkz. Örneğin --- Chris Shiflett'in blog , burada veya - burada .

  • Tek bir fiyat teklifinin kanonik olmayan (uzun bir süre) geçersiz bir kodlamasını kullanarak bir teklifin varlığını gizleyen örneğin UTF-8 saldırıları: bkz. Örn. burada . Temel olarak, tek bir alıntıyı kodlamanın normal yolu tek bir bayt dizisine sığdırır (yani, 0x27). Ancak, veritabanının tek bir alıntı olarak deşifre edebileceği ve 0x27 Baytını veya başka bir şüpheli bayt değerini içermeyen çok baytlı diziler de vardır. Sonuç olarak, standart alıntı-kaçış fonksiyonları bu alıntılardan kaçamayabilir.

20
D.W.

Mutli-bayt saldırıları SQL Injection ile sınırlı değildir. Genel anlamda çok baytlı saldırılar, saldırganın kontrol karakterlerini kaldırdığı bir "bayt tüketimi" durumuna yol açar. Bu, saldırganın tek tırnaklı kontrol karakterini sunduğu klasik ' or 1=1-- 'Un tam tersidir. Mysql için, karakter kodlama problemlerini ele almak üzere tasarlanmış mysql_real_escape_string() vardır. PDO gibi parametreli sorgu kütüphaneleri bu fonksiyonu otomatik olarak kullanacaktır. MySQLi aslında sorgu parametrelerini bir yapı içinde ayrı bir eleman olarak gönderir, bu da problemi tamamen ortadan kaldırır.

Shift-JIS aracılığıyla bir HTML sayfası oluşturulmuşsa, XSS elde etmek için kontrol karakterlerini tüketmek mümkündür. Bunun mükemmel bir örneği, " Bir Karışık Web " (harika kitap!) Sayfa 207'de verilmiştir:

<img src="http://fuzzybunnies.com/[0xE0]">
...this is still a part of the mkarup...
...but the srever dosn't know...
" onload="alert('this will execute!')"
<div>
...page content continues...
</div>

Bu durumda 0xE0 , 3 baytlık bir sembolün başlangıcını gösteren özel bir bayttır. Tarayıcı bu html'yi oluşturduğunda, akan "> Tüketilecek ve tek bir Shift-JIS sembolüne dönüştürülecektir. Saldırgan aşağıdaki girdiyi başka bir değişken aracılığıyla kontrol ederse, kod yürütme elde etmek için bir olay işleyicisi tanıtabilir.

5
rook