3. Web for Pentester
PentesterLab tarafından geliştirilmiş olan Web for
Pentester uygulamasının lisans örneğine şuradan
ulaşabilirsiniz.
4. Giriş
Günümüzde kurumların, şirketlerin ve bireylerin
hizmetlerini sunabilmek için kullandıkları en önemli
araçlardan biri web uygulamalarıdır. Web
uygulamalarında oluşabilecek zafiyetler kullanıcılara
veya diğer web uygulamalarında oluşabilecek
zararlara yol açabilir.
5. Giriş
Web uygulamalarında oluşabilecek zafiyetlerin yol
açabileceği zararlar
▸ Bilgi sızıntıları
▸ Bilgi kayıpları
▸ İtibar kayıpları
▸ Maddi zararlar
olarak özetlenebilir.
6. Web Uygulama Güvenliğine Giriş
Web uygulama güvenliğini anlayabilmek için ilk
önce Web’in nasıl işlediğini bilmemiz gerekir. En
basitinde, istemci sunucuya bir istek gönderir,
sunucu da gönderilen isteğe bağlı olarak istemciye
bir cevap gönderir. Bu haberleşme HTTP(Hyper Text
Transfer Protocol) kuralları dahilinde olur. Çoğu web
sitesi, IP adresinin 80. portunu kullanarak istemci ile
bir TCP bağlantısı kurar.
7. Web Uygulama Güvenliğine Giriş
Örneğin google.com sitesine erişmek istediğimizde
GET /index.php HTTP/1.1
Host: google.com
User-Agent: Google Chrome
gibi bir istek gidecektir. GET isteğinin dışında POST
HEAD gibi birçok HTTP istek türü bulunmaktadır.
8. Web Uygulama Güvenliğine Giriş
Bu istek karşılığında sunucu da belirtilen adreste
bulununan web sayfası kullanıcıya geri döndürülür.
Örnek olarak login formunun kullanıcıya
sunulduğunu ve kullanıcıdan bilgilerini girerek giriş
isteğini göndermesini inceleyelim.
9. Web Uygulama Güvenliğine Giriş
Kullanıcı adına ‘admin’ şifreye de ‘123456’ girdiğimiz
takdirde oluşacak GET isteği alttaki gibi olacaktır.
POST /login.php HTTP 1/1
HOST: ornek.com
User-Agent: Google Chrome
username=admin&password=123456
10. Web Uygulama Güvenliğine Giriş
Bir saldırgan, gönderdiğimiz kullanıcı adı ve parola
kısmına, sıradan bir kullanıcının aksine zararlı bir
takım kodlar göndererek uygulamada beklenmedik
durumlara yol açıp, çeşitli zararlar oluşturabilir. Bu
tür saldırılara ‘injection’ saldırıları denmektedir.
Önümüzdeki örneklerde bu tarz saldırılara ve
türlerine değineceğiz.
11. Web Uygulama Güvenliğine Giriş
Bu sunumda üzerinde duracağımız web uygulama
zafiyetlerinden bazıları
▸ Cross Site Scripting (XSS)
▸ SQL Injection
▸ File Include Saldırıları
▸ Directory Traversal
▸ Code Injection
12. Web Uygulama Güvenliğine Giriş
Web for pentester sanal makinesine tarayıcınızla
ulaştığınızda alacağınız ekran şu şekilde olacaktır.
13. SQL Injection
SQL Injection zafiyeti, veri tabanı kullanan uygulamalarda görülen bir
zafiyet çeşididir. Saldırgan, kullanıcıdan alınan girdi kısımlarına kendi
oluşturduğu zararlı SQL sorguları girerek veri tabanında beklenmedik
ve istenmedik durumlara yol açabilir. SQL dili birçok veri tabanında
ortak olarak kullanıldığı için oldukça sık karşılaşılan bir zafiyet türüdür.
Saldırgan bir kişi, SQL Injection zafiyetini kullanarak
• Önemli bilgiler çalabilir.
• Verileri ve/veya veri tablolarını silebilir.
• Kullanıcılar siteyi ziyaret ettiğinde çalışacak zararlı kodlar enjekte
edebilir.
Şimdi örneklerle SQL Injection zafiyetini inceleyelim.
14. SQL Injection
İlk örnekte karışımıza yukarıdaki gibi bir sayfa gelmekte. Adres
çubuğunda ise ?name=root gibi bir ifade gördüğümüze göre,
denemelerimize başlayabiliriz.
?name=root1 yazdığımız zaman karşımıza bir kayıt gelmemekte
buradan name ile gönderdiğimiz veri ile veri tabanında bir eşleştirme
işlemi yapıldığını söyleyebiliriz.
?name=root’’ ifadesini yazdığımız zaman yine bir kayıt alamıyoruz.
?name=root’ yazdığımız zaman karşımıza hiçbir şey gelmemekte. Bu
durumda hayati bir noktaya bastığımızı söyleyebiliriz.
15. SQL Injection
Aldığımız bu tepkiden arkada çalışan kodun;
SELECT * FROM kullanicilar WHERE name='[ÖRNEK]';
gibi olduğunu anlayabiliyoruz. Bu durumda
• ?name=root’ AND ‘1’ = ‘1
• ?name=root’ OR ‘1’ = ‘1
• ?name=root’ %23
İfadeleri ile kullanıcılarla ilgili sonuçlar döndürebiliriz. %23(#) ifadesi MYSQL’de
yorum satırı anlamına gelir bu yüzden sonrasından gelen ifadeleri geçersiz kılar
ve bu şekilde söz dizim hatalarından kurtulmayı sağlar.
16. SQL Injection
İkinci örnekte ?name=root’ or ‘1’ = ‘1 ifadesi ile istediğimiz sayfaya
erişemiyoruz ve ERROR NO SPACE uyarısı ile karşılaşıyoruz. Uyarı mesajından
da anlayacağımız gibi boşluk kullanılmamız istenmiyor. Bu önlemi atlatabilmek
için boşluk karakteri yerine tab ifadesini(encoded olarak) kullanabiliriz.
Göndereceğimiz isteği
?name=root’%09or%09’1’=‘1
şeklinde yaptığımızda kullanıcılar tablosunun tüm üyelerini görebiliyoruz.
17. SQL Injection
Üçüncü örnekte ?name=root’%09or%09‘1’=‘1 kullandığımızda da uyarı mesajı
alıyoruz. Önlem olarak tab ve boşluk karakterleri engellenmiş durumda. Böyle bir
durumda ise bypass yöntemi olarak yorum satırlarını kullanabiliriz. Vereceğimiz
girdi;
?name=root'/**/or/**/'1'='1
şeklinde olduğunda yine kullanıcıları göreceğimiz sayfaya erişebiliyoruz.
18. SQL Injection
Dördüncü örnekte ise gönderilen değerler tırnaklar içine alınmamış, doğrudan
integer olarak gönderilmekte. Yani göndereceğimiz değere tırnak koymamız
bilgilere erişmemizi sağlamayacak ve istenmedik bir durumla karşılaşacağız.
Ancak sorgu doğrudan integer bir değer vasıtası ile yapıldığı için, tırnak
koymadan;
?id=3-1
?id=2#
gibi ifadeler kullanmamız aynı sonucu döndürecektir. Tüm kullanıcılara
erişebilmek içinse;
?id=2 or 1=1 ifadesini kullanabiliriz.
19. SQL Injection
Altıncı örnekte ise ?id=2' şeklindeki kullanımlarında hata mesajı alıyoruz ancak ?id='2
kullanımında bize hiçbir şey döndürülmemekte. Buradan, yapılan sorguda, girilen değerin
sonuna bakılarak bir integer kontrolü yapıldığını anlayabiliriz.
?id=2 or 1=1
değerini girdiğimiz zaman, girdinin son değeri yine integer olduğu için bir hata döndürmeyecek
ve kullanıcı bilgilerine ulaşılacaktır.
Yedinci örnekte ise yine bir integer kontrolü yapılmakta, ancak bu sefer sadece sonu değil,
tüm satırdaki ifade kontrol edilmekte. Tüm satırda integer kontrolü yapıldığı için, bu tür bir
önlemi atlatabilmemiz için bir alt satıra geçmemiz yeterli olacaktır. n olarak adlandırdığımız
new line ifadesini encoded bir şekilde girdimizi verdiğimiz zaman, tüm kullanıcıları geri dönüş
olarak alacağız.
id=2%0Aor 1=1
20. SQL Injection
Sekizinci örnekte, adres çubuğuna bakar bakmaz bir ORDER BY listelemesi
olduğunu tahmin edebiliyoruz. ORDER BY kullanımında tırnak işareti ile ilgili bir
kullanım olmadığı için herhangi bir şekilde tırnak konumu bir dönüş
sağlamayacaktır. MySQL de ORDER BY ile sıralama yaparken kullanım
ORDER BY name
ya da
ORDER BY `name`
şeklindedir. Böyle bir sorgunun manipülasyonu için öncelikle ters tırnak ile
parametre kısmından kurtulmalı, sonrasında kalan ters tırnak içinse yorum satırı
olan # ifadesini encoded olarak yazmamız gerekir.
21. SQL Injection
Örnek olarak;
?order=name` DESC %23
ifadesini kullandığımızda kullanıcılar tersten sıralanmış halde karşımıza
gelecektir. Bu tür durumlarda saldırgan belirgin bir sonuç elde edemese de, SQL
Injection zafiyetinin varlığını keşfedebilir.
Dokuzuncu örnekte ise sekizinci örnekle aynı şekilde, ancak ORDER BY
`name` yerine ORDER BY name şeklinde bir kullanım var. Bu yüzden ters tırnak
koymadan yine aynı sonucu elde edebiliriz. Vereceğimiz girdi;
?order=name DESC %23 olduğunda yine aynı sonucu elde edeceğiz.
22. SQL Injection’dan Korunma
SQL Injection çok ciddi hasarlara yol açabilecek bir zafiyet türüdür.
Korunabilmek için alınabilecek önlemlerden biri SQL ifadelerini parametre
kullanarak göndermektir. Örnek olarak aşağıdaki JDBC kodu SQL Injection
saldırılarına karşı güvenlidir.
SQL Injection’a karşı güvenli olmayan bir örnek olarak;
String sql = "SELECT * FROM users WHERE email = ? ";
ResultSet results = stmt.executeQuery(sql, email);
String sql = "SELECT * FROM users WHERE email = '" + email + "'";
ResultSet results = stmt.executeQuery(sql);
23. Bir başka korunma yöntemi olarak Object Relational Mapping(ORM) frameworklerinde
bulunan veri manipüle teknikleri kullanılabilir. ORM araçlarının birçoğu, geliştiriciler yerine SQL
sorgularını arkaplanda kendileri oluştururlar. Örneğin Ruby on Rails framework’ünde bulununa
şu kod dizisi SQL Injection saldırılarına karşı güvenlidir.
Ancak ORM kullanımı otomatik olarak SQL Injection saldırılarına karşı güvenlik sağlamaz.
Veritabanı üzerinde yapılacak olan karmaşık sorguların oluşturulması gerektiğinde, birçok
ORM aracı SQL ifadeleri oluşturmaya izin verirler. Bu durumlarda geliştiricilerin yapabileceği
SQL sorguları aşağıdaki örnekteki gibi SQL Injection’a karşı korumasız olabilir.
SQL Injection’dan Korunma
def current_user(email)
User.find_by_email(email)
end
def current_user(email)
User.where("email = '" + email + "'")
end
25. Cross Site Scripting (XSS)
Cross Site Scripting, zararlı scriptlerin web uygulamarına enjekte
edilmesi ile gerçekleştirilen bir saldırı çeşididir. Saldırgan, web
uygulamasına enjekte edeceği zararlı scriptler ile
▸ Oturum ele geçirme saldırısı düzenleyebilir
▸ Hassas bilgiler elde edebilir
▸ Sosyal medya sitelerine solucanlar yayabilir
▸ Dolandırıclık yapabilir.
XSS oldukça sık rastlanılan bir zafiyet türüdür. Google, Yandex gibi
büyük firmalarda dahi XSS açıklarına rastlanılmaktadır.
26. Cross Site Scripting (XSS)
XSS zafiyetinin üç türü bulunmaktadır;
1. Reflected(Yansımalı) XSS: Etkisinin direkt olarak görülebildiği ve
diğer kullanıcılara etkisi olmayan XSS türüdür.
2. Stored(Saklı) XSS: Bu türde enjekte edilen kod uygulamanın arka
kısmında saklanır, dolayısı ile diğer kullanıcıların etkilenebilme
ihtimali ortaya çıkar. Reflected XSS’e göre daha tehlikelidir.
3. DOM Based XSS: En tehlikeli XSS türüdür. Enjekte edilen kodun
cevabı direkt olarak dönmez, tarayıcı sayfayı tekrar yorumladığında
dinamik olarak çalıştırılır. DOM Based XSS ile hedef sayfanın
kodları değiştirilebilir, zararlı yazılımlar yüklenebilir, kullanıcılar farklı
sayfalara yönlendirilebilir.
27. Cross Site Scripting (XSS)
İlk örnekte karşımıza önceki örneklerdeki gibi bir ekran gelmekte. SQL
Injection örneklerimizde olduğu gibi name’e farklı bi parametre verip,
kurcalamaya başlayabiliriz.
28. Cross Site Scripting (XSS)
Adres çubuğundaki name=hacker kısmında hacker yerine farklı bir
değer girdiğimizde sitenin bize döndürdüğü mesajın değiştiğini
görebiliyoruz.
Bu değer yerine, XSS zafiyetlerinin tespitinde bize yeterli olacak ufak
bir javascript kodu yazalım.
29. Cross Site Scripting (XSS)
Yukarıdaki uyarıyı aldığımıza göre, uygulamada XSS zafiyeti olduğunu
söyleyebiliriz. Ne olduğunu daha iyi anlayabilmek için, JavaScript
kodunu girmeden önce ve sonra sayfanın kaynak kodlarına bakalım.
30. Cross Site Scripting (XSS)
Kaynak kodlarında da gördüğümüz gibi, name kısmına verilen değer direkt
olarak sayfaya enjekte edilebilmekte. Saldırgan isterse, JavaScript kodları yerine
HTML kodları da enjekte edebilir. Enjekte edilen kodlara göre sayfanın cevabı yine
değişiklik gösterecektir. Diğer örnekler ile devam edelim.
31. Cross Site Scripting (XSS)
İkinci örnekte ise, alınan bazı önlemlerden dolayı aynı JavaScript kodu
ile uyarı alamıyoruz. Bu örnekte bir filtreleme yapılmakta, bu sefer
kodumuzu bazı harf yada harfleri büyük yazarak denediğimizde yine
istenilen cevabı alabiliyoruz. Verebileceğimiz kodlara bir örnek;
<scRipt>alert(1)</scRipt>
Üçüncü örnekte ise, büyük-küçük harf önlemi bulunmakta. Biraz
kurcaladığımızda, önlem olarak <script> betiğinin silindiğini
görebiliyoruz.
32. Cross Site Scripting (XSS)
<script> betiğini, başka bir <script> betiği içinde verdiğimiz takdirde
yine istenilen uyarıyı görebiliyoruz. Verilecek kod;
<script<script>>alert(1);</script</script>>
Dördüncü örnekte, script ifadesi verildiğinde kullanıcıya hata
verilmekte. Buradan geliştiricinin bir kara liste(blacklist) yaklaşım ile
script kelimesini yasakladığını anlayabiliyoruz. Ancak JavaScript kodları
script betiklerinden ibaret değil, farklı girdiler deneyerek yine istenilen
cevabı alabiliyoruz. Örnek verilebilecek kod;
<img src=‘olmayanresim' onerror='alert(1)' />
33. Cross Site Scripting (XSS)
Beşinci örnekte ise alert ifadesi engellenmiş durumda. Farklı bir
fonksiyon olarak confirm verdiğimizde yine aynı uyarıyı alabileceğiz.
Vereceğimiz kod;
<script>confirm(1);</script>
Altıncı örnekte sayfanın kaynak koduna baktığımızda, name’e girilen
değerin tırnak içine alındığını görüyoruz. Bu durumda SQL Injection
örneklerinde kullandığımız tekniğe benzer bir şekilde değer
verdiğimizde, uyarıyı alabileceğiz.
hacker";alert(1);"
Yedinci örnekte ise çift tırnak ifadesi yerine tek tırnak ifadesi
kullanılmış. Aynı kodu tek tırnak ile yazdığımızda bu önlemi de atlatmış
oluyoruz.
34. Cross Site Scripting (XSS)
Sekizinci örnekte ise farklı bir sayfa ile karşılaşıyoruz. Kaynak koduna
baktığımızda, form elementinin action kısmına direkt olarak URL değeri
gelmekte.
URL değerinde çift tırnak ile action’ı kapatıp, istediğimiz kodları enjekte
ettiğimizde, yine alıştığımız o uyarıyı görebileceğiz. URL’in son kısmına
vereceğimiz girdi;
/"><script>alert(1)</script>
35. Cross Site Scripting (XSS)
Dokuzuncu örnekte bir DOM Based XSS zafiyeti bulunmaktadır.
Kaynak kodunu incelediğimizde
document.write(location.hash.substring(1));
kısmı gözümüze çarpmakta. Buradaki javascript fonksiyonu sayesinde,
sayfa her yorumlanışında, URL’de bulunan # ifadesinden sonra gelen
kısmı alınıp, dinamik olarak istemci tarafında(client side) sayfa içine
yazılmakta. Böyle bir durumda, # ifadesinden sonra gelen kısım
kullanılarak sayfa manipüle edilebilebilir. # karakterinden sonra
verebileceğimiz örnek kod;
<script>alert(1)</alert>
36. XSS’ten Korunma
XSS zafiyetinden korunabilmek için en geçerli yöntemlerden biri HTML
entitiy encoding teknikleri kullanarak " # & ' ( ) ; / < > gibi karakterlerin
encode edilmesidir. Modern framework’lerin birçoğu otomatik olarak bu
kodlamaları yapmaktadır.
Diğer bir yaklaşım olarak Beyaz Liste(White List) kullanılabilir ve
sadece istenilen değerler kabul edilebilir. Örnek olarak, uygulamada
kullanıcıdan ülkesi istendiğinde, kullanıcıdan kendi girdisini yazmasını
istemek yerine Drop Down List kullanılabilir.
XSS’ten korunma üzerine detaylı olarak OWASP’ın XSS Prevention
Cheat Sheet dökümanına bakabilirsiniz.
https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Preventi
on_Cheat_Sheet
37. “
Directory Traversal
Directory traversal, izin verilmeyen dizinlere erişim sağlanması olarak
özetlenebilir. Bu saldırı türü, uygulamanın göstermesi gereken
dizinlerden başka dizinlere de ulaşabilmeyi hedefler. Saldırgan, URL
kısmında verilen parametreleri manipüle ederek sistemde bulunan
hassas dizinlere ve dosyalara erişebilir. Directory Traversal oldukça
ciddi hasarlara yol açabilecek bir saldırı türüdür. Şimdi örneklerle bu
saldırı türünü daha iyi anlayalım.
38. “
Directory Traversal
Örnekler kısmında karşımıza birer resim çıkıyor ve herhangi bir link
bulunmamakta. Birinci örnekte bulunuan resme sağ tıklayıp adresine
baktığımızda ise IP adresinden hemen sonra gördüğümüz ifade
aşağıdaki gibi.
/dirtrav/example1.php?file=hacker.png
file= ifadesinden sonra ./ koyduğumuzda da aynı resmi görebiliyorsak,
burada Directory Traversal zafiyetinin bulunduğunu söyleyebiliriz.
Bildiğiniz gibi Linux/Unix sistemlerde ../ ifadesi bir üst dizini ifade eder,
ve en üst dizine(root) ulaştıktan sonra koyduğunuz ../ ifadesi herhangi
bir işe yaramaz, root dizinine erişmiş olursunuz.
39. “
Directory Traversal
Oldukça hassas bilgiler içeren /etc/passwd dosyasına ulaşabilmek için
verebileceğimiz örnek girdi;
/dirtrav/example1.php?file=../../../../../../../etc/passwd
Aldığımızı sonuç aşağıdaki gibi olacaktır;
40. “
Directory Traversal
İkinci örnekte ise dosyanın adresi doğrudan gösterilmekte. Ancak
doğrudan file kısmına /etc/passwd yazdığımızda herhangi bir şey
göremiyoruz. Bu kısımda basit bir PHP kontrolünün olması muhtemel.
Ancak bir önceki örnekte verdiğimiz girdiyi ‘hacker.png’ kısmı olmadan
girdiğimizde yine passwd dosyasına ulaşıyoruz.
Üçüncü örnekte ise ‘hacker’ dosyasının bir uzantısı görünmüyor,
direkt olarak ismi ile gösterilmekte. Uzantı olarak .png sunucu taraflı
kodda eklenmekte ve böylelikle hacker.png gösterilmektedir. Yani
önceki örneklerde verdiğimiz girdi sunu tarafında
../../../../../../../etc/passwd.png olarak gözükmekte. Bu önlemi de PHP’de
NULL BYTE olarak adlandırılan %00 ifadesi ile atlatabiliriz. %00
ifadesinden sonra gelen eklerden kurtulmuş olacağız ve böylelikle
etc/passwd dizinine erişebilmiş olacağız. Vereceğimiz girdi;
/dirtrav/example3.php?file=../../../../../../../etc/passwd%00
41. “
Directory Traversal’dan Korunma
Directory Traversal saldırılarından korunma yollarından ilki kullanıcı
girdilerini filtrelemektir. Dosya isimlerini, belirlenen güvenli
karakterlerden başka karakterler kullanmadan adlandırmak ve bu
dosyalara yapılabilecek referansları sadece belirlenen güvenli
karakterler ile olmasını sağlamak, uygulamanın güvenliğine büyük fayda
sağlayacaktır.
Başka bir yol olarak, üçüncü parti güncel bir Content Management
System(İçerik Yönetim Sistemi) de, uygulamayı Directory Traversal
saldırılarından koruyacaktır.
42. File Include
File Include saldırısı saldırganın hedef web uygulamasına bir dosya
dahil etmesine ya da hedef web uygulamasının kendinde olan ama
sunmadığı bir dosyayı görüntüleyebilmesine denir. Kullanıcıdan alınan
girdilerin kontrol edilmemesi sonucu oluşan ‘dosya dahil etme’
saldırıları, Directory Traversal gibi ciddi problemlere yol açabilecek bir
saldırı türüdür. Local File Include ve Remote File Include olarak ikiye
ayrılmaktadır. LFI zafiyetinde lokalde bulunan bir dosya okunur ve
yorumlanır. RFI zafiyetinde ise uzaktan bir dosya alınır ve yorumlanır.
PHP’de varsayılan olarak uzaktan dosya alımı kapalıdır, ancak bazı
uygulamalarda özel olarak açılmış olabilir. Örneklere geçerek bu zafiyeti
daha iyi anlamaya çalışalım.
43. File Include
İlk örnekte, intro.php yerine farklı bir girdi verdiğimizde, bize oldukça
faydalı bilgiler veren bir uyarı görüyoruz. Bu uyarıdan
• /var/www/fileincl/example1.php yolunu
• Kullanılan fonksiyonun include() olduğunu
• Verdiğimiz girdinin herhangi bir kontrol yapılmadan
kullandılığını(örnek olarak introD.php)
bilgilerini alıyoruz. Girdi kontrolü olmadığı için DT örneklerinde
kullandığımız ../../../../../etc/passwd girdisini vererek yine passwd
dosyasına ulaşabiliriz.
Vereceğimiz girdi https://www.google.com.tr/ gibi bir adres olduğunda
ise sayfanın bunu çalıştırdığını görüyoruz, buradan da RFI zafiyetinin
olduğunu anlayabilmekteyiz.
44. File Include
İkinci örnekte, yine farklı bir girdi verdiğimizde sunuc tarafında
girdimize .php eklendiğini görüyoruz. Bu önlemi de daha önce
öğrendiğimiz NULL BYTE karakteri ile aşabilir ya da direkt olarak .php
uzantısı olmadan bir php dosyası vererek aynı sonuca ulaşabiliyoruz.
File Include’tan Korunma
DT saldırılarında olduğu gibi, File Include saldırılarında da kullanıcı
girdilerinin kontrol edilmesi gereklidir.
45. Code Injection
Bir başka Injection zafiyeti olan Code Injection, kullanıcıdan alınan
girdilerin kontrol edilmemesinden kaynaklanan bir zafiyet çeşididir.
Mantık olarak SQL Injection ile çok benzer olan Code Injection, son
derece tehlikeli bir zafiyettir. Nasıl SQL Injection zafiyetinde girdi olarak
SQL kodları veriliyorsa, Code Injection zafiyetinde de kullanılan
programlama dilinde kodlar verilir. Web for Pentester uygulaması PHP
ile yazıldığı için, biz de girdilerimizi PHP kodları kullanarak vereceğiz.
Birinci örnekte name’e verilen değer sunucu tarafında ekrana
bastırılacak şekilde ayarlanmış, ve sonuna üç tane ünlem işareti
konulmuş. Name’e verilen hacker ifadesinin sonuna çeşitli özel
karakterler koyarak bir tür hata almaya çalıştığımızda, çift tırnağın
işimizi gördüğünü anlıyoruz. Bu uygulamada bu hatayı çift tırnakla
almamız sizi yanıltmasın, kullanılan dile göre tek tırnak veya başka bir
karakterle de aynı hatayı elde edebilirdik.
46. Code Injection
name=hacker’ın sonuna " karakterini ekledikten sonra, ; ifadesi ile ilk
ifadeyi sonlandırıp, arkasına istediğimiz kodları yazdığımızda bu kodlar
sunucuda çalışacak ve yazdığımız kodlara göre bize dönüş verecektir.
Örnek olarak bir şeyler yazdırmaya çalışalım, vereceğimiz girdi;
hacker"; echo " gercekten mi?";//
olduğunda ekrana " hello hacker gercekten mi? " yazdığını görüyoruz.
Kodun sonuna eklediğimiz çift slash (//) kalan kodları yorum satırları
olarak görmesini sağlamakta ve kodumuz gerektiği gibi çalışmakta.
Zafiyet tespitinden sonra sunucu tarafında gerçekleştirilebilecekler
kullanılan program diline ve saldırganın hayal gücüne bağlı.
47. Code Injection
İkinci örnekte yine çift tırnak kullandığımızda, kullanılan PHP
fonksiyonun usort olduğunu görüyoruz. Usort fonksiyonu SQL de
bulunan ORDER BY ile oldukça benzer bir fonksiyon. Kısa bir araştırma
sonucunda usort’un nasl çalıştığını gördükten sonra, kodumuzu enjekte
edebiliriz.
?order=id);}echo"Uyariya%20ragmen%20calismakta";//
Aldığımız uyarıya rağmen echo ile verdiğimiz değer ekrana basılmakta.
48. Code Injection
Üçüncü örnekte oynamalar yaparken, pattern değerine farklı bir değer
gönderdiğimizde bir uyarı alıyoruz ve buradan kullanılan fonksiyonu
preg_replace() olduğunu görüyoruz. Bu fonksiyonun kullanımı;
preg_replace ( $şablon , $yenisi , $konu)
Yine araştırmamız sonucunda, preg_replace() fonksiyonunda bir özel
durum olarak şablon ifadesinden sonra /e kullanıldığında ‘yenisi’ ile
gelen ifadeler PHP tarafından fonksiyon olarak yorumlandığını
öğreniyoruz. Buna uygun olarak vereceğimiz girdi;
new=phpinfo()&pattern=/lamer/e&base=Hello%20lamer
Olduğunda phpinfo() fonksiyonunu çalıştırarak sistem hakkında bilgi
sahibi olabiliyoruz. Buradan sonra istenilen sistem komutları çalıştılıp
farklı sonuçlar elde edilebilir.
49. Code Injection
Dördüncü örnekte denemelerimizi yaparken, tek tırnak kullandığımızda
bir hata alıyoruz ve bu hatadan kullanılan fonksiyonun assert() olduğunu
öğreniyoruz. Sözdizim yapısını bozduğumuz zaman, geriye kalan tek
şey istediğimiz şekilde tekrardan düzeltmek. Yine fonksiyonun nasıl
çalıştığı hakkında yaptığımız araştırmadan sonra vereceğimiz girdiyi
oluşturuyoruz;
hacker'.phpinfo().‘
sonucunda sistem bilgisini yine ekrana yazdırmış olduk.
50. Code Injection’dan Korunma
Code Injection zafiyeti bulunan bir uygulamayı istismar etmek
-senaryoya bağlı olaraktan- kısmen zordur. Ancak istismar başarılı
olarak gerçekleştiğinde ciddi hasarlara yol açabilecek bir zafiyet türüdür.
Korunma bazında güncel web servislerinin kullanılmasının yanında
diğer Injection saldırılarında kullanılan ‘Input Validation’ yani kullanıcı
girdi kontrolüne son derece önem verilmelidir.
51. Command Injection
Command Injection saldırısı, sistem komutlarını girdi olarak alan bir
uygulamanın gerekli filtrelemeleri yapmaması durumunda ortaya çıkar.
Bir çok web uygulama zafiyetinde olduğu gibi Command Injection’da da
gerekli kontroller sağlanmadığı takdirde ciddi zararlara yol açabilecek bir
zafiyet türüdür. Command Injection saldırılarında, uygulamanın üzerinde
çalıştığı işletim sistemine göre, çalıştırılan komutlarda farklılık
gösterecektir. Web for pentester uygulaması Linux üzerinde çalıştığı
için, örneklerimizi Linux komutlarıyla deneyeceğiz.
52. Command Injection
Birinci örnekte, 127.0.0.1 adresine PING atıldığını görüyoruz. URL’de
bulunan ip= parametresine bu adres girildikten sonra uygulama
çalıştırılmış, bu bilgiyle biz de denemelerimize başlayabiliriz. Bu örnekte
herhangi bir önlem alınmadığı için istenilen komutu sistem üzerinde
çalıştırabiliyoruz. Örnek olarak daha önce kullandığımız bir girdi verelim;
ip=127.0.0.1;cat /../../../../etc/passwd
Etc/passwd dosyasını bu şekilde okumuş olduk. Dilendiği takdirde
başka Linux komutları da anı şekilde çalıştırılabilir.
53. Command Injection
İkinci örnekte ise IP adresinin kontrolü yapılmakta. IP değerinin sonuna
herhangi bir karakter girdiğimizde aldığımız hatadan bunu
anlayabiliyoruz. Ancak buradaki koruma tek satıra uygulanmakta, %0a
karakteri ile alt satıra geçtiğimizde, istediğimiz komutu vererek bu
önlemi de atlatmış oluyoruz.
ip=127.0.0.1%0acat /../../../../etc/passwd
Verdiğimiz girdi ile yine etc/passwd dosyasını görüntüleyebilmiş olduk.
54. Command Injection
Üçüncü örnekte de, ikinci örnekte kullandığımız girdiyi verdiğimiz
zaman, bir redirect(yönlendirme) işlemine tabi tutulduğunu görüyoruz.
İstek sonucunda URL’imiz yine ip=127.0.0.1 olarak kalmakta. Bu
durumda tarayıcımız üzerinden verdiğimiz girdilerin çalışıp
çalışmadığını göremiyoruz. İşlerin nasıl ilerlediğini görebilmek için bir
GET isteği yollayalım.
Bu işlem için ben telnet kullanacağım, dilerseniz başka araçlar da
kullanılabilir. Verilecek komut;
telnet ‘web for pentester IP adresi’ 80
56. Command Injection
Geliştiricinin redirect işlemini kullanmasına rağmen, bu işlemin
çalıştırılan kodlara bir etkisinin olmadığını görebiliyoruz. Burada
alınabilecek bir yöntem olarak, ‘header’ fonksiyonunun kullanımından
sonra ‘die’ fonksiyonu kullanılabilir. Bu şekilde ilk işlemden sonra verilen
ikinci komut işleme alınmayacak ve olası zararlı komutlar sistemde
çalıştırılamayacaktır.
57. LDAP Injection
LDAP(Lightweight Directory Access Protocol) TCP/IP üzerinde çalışan
dizin servislerini sorgulamaya ve değiştirmeye yarayan bir protokoldür.
LDAP saldırıları kullanıcıdan alınan LDAP ifadelerini istismar edilerek
gerçekleştirilir. Diğer injection saldırılarında olduğu gibi kullanıcı
girdilerinin kontrol edilmesi ile önüne geçilebilecek bir saldırı türüdür.
LDAP’in kendine öz sözdizim(syntax) yapısına sahiptir.
58. LDAP Injection
Birinci örnekte URL’den anlayacağımız gibi bir LDAP sunucusuna
bağlanıyoruz ancak görülen o ki girilen bilgiler yanlış ve bununla ilgili
bize bir hata döndürülmüş. Bazı LDAP sunucuları, NULL Bind denilen
bağlantı şekline izin vermektedirler. Örnek ldap_bind fonksiyonu;
$ldapusername= ‘username’;
$ldappass= ‘password’;
$ldapbind = ldap_bind($ldapconnect, $ldapusername, $ldappass);
Olarak verilebilir. Ancak ‘username=&password=‘ olarak girdi vermek
işe yaramayacak, çünkü bu şekilde username ve password’ü boşluk
olarak iletmiş oluyoruz. Burada parametreleri sildiğimizde null değer
döndürmüş olacağız ve girişimiz onaylanmış olacak.
59. LDAP Injection
İkinci örneği çözebilmemiz için LDAP’in sözdizim yapısına bakmamız gerekiyor.
LDAP ile bir üye getirirken kullanılan yapı aşağıdaki gibidir.
(cn=[INPUT])
* karakteri LDAP’te sonu tamamlamak için kullanılabilir. Örneğin a* karakteri a ile
başlayan tüm katarları gösterir. Username kısmına ‘hacke*’ koyduğumuzda hacker
olarak tanındığımızı göreceksiniz. Bunun sebebi, giridimizi hacke ifadesinden
sonra gelebilecek tüm ihtimalleri kabul edecek şekilde ayarlamış olmamız. SQL
Injection’da kullandığımız boolean mantığını(OR 1=1) kullanarak girdimizi
ayarlarsak, herhangi bir şifre verip, hacker olarak giriş yapabiliriz. Örnek girdi;
name=hacker)(cn=*))%00&password=artikonemlidegil
Görüldüğü gibi hacker dan sonra gelen cn ifadesine ne verirsek verelim kabul
edeceği şekilde ayarladık.%00 ifadesi ile de sonrasında gelen ifadeleri geçersiz
kılmış olduk.
60. LDAP Injection’dan Korunma
LDAP Injection saldırılarından korunmanın yolu da diğer Injection
saldırılarında olduğu gibi kullanıcı girdi kontrolüdür. Bu saldırı türüne
karşı alınması gereken ilk yöntem doğru LDAP encode fonksiyonlarını
kullanarak istenmeyen değerleri egale etmektir. Ek olarak LINQtoAD
gibi istenmeyen değerleri engelleyen framework’ler kullanılabilir. Daha
fazla korunma yöntemi için OWASP’ın LDAP Injection Prevention Cheat
Sheet’ine bakabilirsiniz.
61. File Upload
Herhangi bir formda dosya yüklenebilen sitelerde bulunabilen File
Upload(Dosya Yükleme) saldırıları, sunucu üzerinde kod çalıştırmaya
yol açabilip, uygulamaya ciddi zararlar verme potansiyeline sahiptirler.
Web for Pentester uygulaması PHP üzerinde çalıştığı için, biz de
örneklerde .php uzantılı uygulamalar upload ederek, sunucu üzerinde
bir takım ataklar gerçekleştireceğiz.
62. File Upload
Birinci örnekte herhangi bir koruma bulunmamakta, bu yüzden kendi
isteğimize göre bir php dosyası oluşturup, upload edeceğiz ve php
dosyamızda bulunan kodlarımızı sunucu üzerinde çalıştırabileceğiz.
Örnek olarak vereceğim php dosyası şu şekilde olacak.
63. File Upload
PHP dosyamızı yükledikten sonra bizi dosyamıza gönderen linke
tıklıyoruz. Bu noktada bir uyarı aldığımızı görmekteyiz ancak bu çok da
önemli değil. Artık ?cmd= ile komutlarımızı vererek sunucu üzerinde
istediğimizi yapabiliriz. Örnek olarak passwd dosyasını yazdıralım.
64. File Upload
İkinci örnekte ise dosya uzantısını php yapamıyoruz. Burada blacklist
yaklaşımı kullanılmış ve blakclist yaklaşımının güvenilir olmadığından
daha önce bahsetmiştik. Aynı dosyanın sonunu php?, php3, php4,
phtml gibi değiştirerek upload edebilir ve kodumuzu sunucu üzerinde
çalıştırabiliriz. PHP yorumlayıcısının kabul ettiği herhangi bir uzantı
işimizi görmeye yetecektir.
File upload saldırılarından korunabilmek için, dosya uzantılarında
whitelist yaklaşımı kullanılabilir ancak her zaman bu yaklaşım yeterli
olmayacaktır. Dosyanın içindeki header kısmından içerik tipinin kontrol
edilmesi veya dosya tipi kontrol eden uygulamaların kullanılması file
upload saldırılarından korunmakta önemli rol oynayacaktır.
65. XML Injection
Extensible Markup Language(Genişletilebilir İşaretleme Dili) Injection
saldırıları, uygulamaya XML dökümanlarının enjekte edilmesi ile
gerçekleşir. Eğer bir dosya URI olarak tanımlanıyorsa, olağanın dışı bir
konfigürasyon yapılmadığı sürece XML çözümleyicileri bu dosyalara
erişim sağlayıp çözümleme yapacaktır. Bu durumun görüldüğü
uygulamalarda XML Injection saldırıları sık görülmektedir ve bu
saldırılar ile ilgili sistemde yetki kazanılabilir veya kullanım dışı bırakma
saldırıları gerçekleştirilebilir.
66. XML Injection
Birinci örneğimizde URL’de bir xml belirteci ile karşılaşıyoruz. XML
belirtecinden sonra gelen ifadeye, kendi oluşturduğumuz XML dosyasını
verdiğimiz takdirde, istediğimiz XML kodlarını çalıştırabileceğiz. Örnek
olarak /etc/passwd dosyasını yazdırmayı deneyelim. Vereceğimiz XML
dosyası:
<!DOCTYPE test [<!ENTITY XMLi SYSTEM
"file:///etc/passwd">]><test>&XMLi;</test>
Tabi bu kodu vermeden önce gerekli encoding işlemlerini de yapmamız
gerek. Ardından oluşturduğumuz XML dosyasında /etc/passwd
dosyasını yazdırıyoruz ve bu dosyayı referans ederek çağırdığımızda,
passwd dosyasını bize ekranda yansıtacaktır.
68. XML Injection
İkinci örnekte name’e verilen değerimiz Xpath sorgusuna girdi olarak
alınmış. Daha önce görmüş olduğumuz SQL Injectiondaki durum,
burada da söz konusu. XML’i veritabanı, Xpath’ı da SQL olarak
düşünebilirsiniz. Bu durumda Xpath sorgusunu manipüle ederek
istediğimiz değişiklikleri yapabiliriz.
Name=hacker kısmının sonuna bir tırnak koyduğumuzda hata
almaktayız. Artık hikayenin sonunu da tahmin edebiliriz.
Hacker’ or ‘1’=‘1
girdisini verdiğimizde, olası tüm cevapları görebiliyoruz.
69. XML Injection’dan Korunma
XML Injection saldırılarından korunmanın yolu da diğer injection
saldırıları gibi kullanıcıdan alınan girdilerin kontrolünden geçmektedir.
Bu kontrollerin daha verimli bir şekilde yapılabilmesin için XML
kütüphanelerinde bulunan fonksiyonlardan faydalanılabilir. Dahası için
ilgili OWASP makalesine bakılabilir.