Python Software Security ~ Host Header İnjection #DevSecOps ~ Arge

Suppressor

Request Uzmanı
16 Kas 2022
1,224
761
always, everywhere
p0qbke2.png



umBqNLP.png


Selamlar, ben Suppressor. Bugün Flask uygulamalarında Host header injection zafiyetini ele alacağım.

Konu Başlıkları:
  1. HTTP Headers (Başlık)
  2. Zafiyetin Kaynaklanma Sebebi
  3. Zafiyetin Flask Kodu İle Gösterilmesi
  4. Zafiyetin Giderilmesi
  5. PoC

umBqNLP.png


HTTP Headers (Başlık)
HTTP başlıkları, hem HTTP isteklerinde hem de yanıtlarında isteğin meta bilgilerini taşıyan bilgilerdir.
Bu meta bilgileri, isteğin gideceği adres, kabul edilen yanıt tipi ve tarayıcının bizi tanıması için çerez (cookie) bilgileri gibi örnekler içerir.

Örnek olarak, bazı HTTP başlıkları şunlardır:
  1. Host: Bulunduğumuz web adresinin domain ismini veya IP adresini belirtir.
  2. Accept: Tarayıcının kabul edeceği içerik türlerini belirtir.
  3. Location: Web uygulamasında yönlendirme durumlarında (status 301, 302) yeni adresin neresi olduğunu belirtir.


umBqNLP.png


Zafiyet Neden Kaynaklanıyor
Host header injection zafiyeti, HTTP host başlığının manipüle edilmesiyle ortaya çıkar.
Eğer bir Flask uygulaması dinamik olarak Host başlığını site üzerinden çekiyorsa, her site farklı bir domain veya IP adresine sahip olduğu için bu başlık kullanıcının kontrolü dışında değiştirilebilir. Saldırganlar bu durumu kötüye kullanarak uygulamanın istemeden başka bir sunucuya veya hizmete yönlendirilmesine neden olabilirler.


ctf0sk9.png


Zafiyetli kaynak kodu


Python:
@app.route("/host")
def index():
    global mainurl
    host = request.host
    mainurl = "http://" + host + "/response.html"
    return redirect(mainurl)
 

@app.route('/response.html')
def responsehtml():
    return render_template('response.html',reponse="yönlendirildi", urladersi="Yölendirme Adresi" + " ~ " + mainurl)
 

if __name__ == "__main__":
    app.run(debug=True)



umBqNLP.png


Gerekli kütüphanelerin programa import edilmesi.



Python:
from flask import Flask, redirect, render_template, request

app = Flask(__name__)

Kütüphanlerin kullanım alanları

redirect:


redirect, Flask uygulamalarında kullanıcıyı başka bir URL'ye yönlendirmek için kullanılan bir fonksiyondur. Örneğin, bir formun başarıyla gönderilmesi durumunda kullanıcıyı teşekkür sayfasına yönlendirmek için redirect kullanabiliriz.

render_template:

render_template, Flask'in temel özelliklerinden biridir ve HTML dosyalarını Flask uygulamasına entegre etmemizi sağlar. Bu yöntem sayesinde, dinamik içeriklerle dolu HTML dosyalarını oluşturabilir ve kullanıcılara sunabiliriz. Örneğin, bir kullanıcı giriş sayfası veya ürün listesi gibi yapılandırılmış bir HTML sayfası oluşturmak için render_template kullanılır.


request:

request, Flask uygulamalarında kullanıcıdan gelen verileri almak veya veri transferi yapmak için kullanılır. Örneğin, HTTP istek başlıklarını (headers) veya form verilerini almak için kullanılabilir.


umBqNLP.png


Route dekoratörü ile /host dizinine bir yönlendirme yapılacağını belirtir.index adında bir fonksiyon oluşturulması.Her fonksiyonda kullanabilmek için mainurl adında global bir değişken tanımlanması.host adında bir değişkenin tanımlanması ve request kullanarak sunucudaki host başlığının çekilmesi.Yönlendirilecek URL adresinin oluşturulması.redirect fonksiyonu ile URL adresine yönlendirilmesi.



Python:
@app.route("/host")
def index():
    host = request.host
    global mainurl
    mainurl = "http://" + host + "/response.html"
    return redirect(mainurl)




Bu kod tam olarak ne iş yapıyor derseniz, localhost/host adresine gittiğinizde sizi localhost/response.html adında bir dizine yönlendiriyor. Peki, bu dizine gelince ne oluyor derseniz? Ekrana yönlendirilen adresi yazdırıyor.

Python:
@app.route('/response.html')
def responsehtml():
    return render_template('response.html',reponse="yönlendirildi", urladersi="Yölendirme Adresi" + " ~ " + mainurl)

"EE, zafiyet nerede" gibi sorularınız varsa, tam olarak burada.
Python:
host = request.host
mainurl = "http://" + host + "/response.html"

Burada host adresi statik bir şekilde girilmediği için Flask uygulaması, host başlığını çalıştırıldığı sunucuya göre dinamik olarak çektiği için bu manipülasyona açık hale geliyor.
ctf0sk9.png


Zafiyeti Önleme Aşaması
Normal şartlar altında URL kısmı (host) dinamik bir şekilde çekildiği için programın elinde net bir kaynak yoktu ve manipüle edilebiliyordu. Ama biz bu sefer host kısmını statik bir şekilde verdik ve artık programın bir kaynağı olduğu için manipülasyona kapalı hale geldi.
Python:
@app.route("/host")
def index():
    global mainurl
    host = "127.0.0.1:5000"
    mainurl = "http://" + host + "/response.html"
    return redirect(mainurl)


Zafiyetsiz Kod
Python:
from flask import Flask, redirect, render_template, request

app = Flask(__name__)

 

@app.route("/host")
def index():
    global mainurl
    host = "127.0.0.1:5000"
    mainurl = "http://" + host + "/response.html"
    return redirect(mainurl)
 

@app.route('/response.html')
def responsehtml():
    return render_template('response.html',reponse="yönlendirildi", urladersi="Yölendirme Adresi" + " ~ " + mainurl)
 

if __name__ == "__main__":
    app.run(debug=True)

ctf0sk9.png



PoC

Göründüğü üzere /host dizinine giderken Burp Suite ile attığım isteği yakaladım ve şu anlık bir sorun gözükmüyor, istediğim adrese beni yönlendiriyor.
nts1pmz.PNG


~
  • "Ama burada host başlığını değiştirirsem, ne gibi bir değişiklik olacak? Tekrar bakalım."
  • "Göründüğü üzere host adresi kendi localhost'um değil, attacker.com oldu."


44ql03t.PNG


umBqNLP.png



Saldırı vektörü kısmında, eskiden okuduğum bazı makaleleri örnek vereceğim.

Host Header İnjection - Geleceği Yazanlar
~
portswigger


# Arge Ekibi ~ DevSecOps Birimi
@ExeOweR @Hea7 @Bunjo @teux

umBqNLP.png


p0qbke2.png
 

LydexCoding

Moderasyon Ekibi Çaylak
24 May 2024
388
126
:)
p0qbke2.png



umBqNLP.png


Selamlar, ben Suppressor. Bugün Flask uygulamalarında Host header injection zafiyetini ele alacağım.

Konu Başlıkları:
  1. HTTP Headers (Başlık)
  2. Zafiyetin Kaynaklanma Sebebi
  3. Zafiyetin Flask Kodu İle Gösterilmesi
  4. Zafiyetin Giderilmesi
  5. PoC

umBqNLP.png


HTTP Headers (Başlık)
HTTP başlıkları, hem HTTP isteklerinde hem de yanıtlarında isteğin meta bilgilerini taşıyan bilgilerdir.
Bu meta bilgileri, isteğin gideceği adres, kabul edilen yanıt tipi ve tarayıcının bizi tanıması için çerez (cookie) bilgileri gibi örnekler içerir.

Örnek olarak, bazı HTTP başlıkları şunlardır:
  1. Host: Bulunduğumuz web adresinin domain ismini veya IP adresini belirtir.
  2. Accept: Tarayıcının kabul edeceği içerik türlerini belirtir.
  3. Location: Web uygulamasında yönlendirme durumlarında (status 301, 302) yeni adresin neresi olduğunu belirtir.


umBqNLP.png


Zafiyet Neden Kaynaklanıyor
Host header injection zafiyeti, HTTP host başlığının manipüle edilmesiyle ortaya çıkar.
Eğer bir Flask uygulaması dinamik olarak Host başlığını site üzerinden çekiyorsa, her site farklı bir domain veya IP adresine sahip olduğu için bu başlık kullanıcının kontrolü dışında değiştirilebilir. Saldırganlar bu durumu kötüye kullanarak uygulamanın istemeden başka bir sunucuya veya hizmete yönlendirilmesine neden olabilirler.


ctf0sk9.png


Zafiyetli kaynak kodu


Python:
@app.route("/host")
def index():
    global mainurl
    host = request.host
    mainurl = "http://" + host + "/response.html"
    return redirect(mainurl)
 

@app.route('/response.html')
def responsehtml():
    return render_template('response.html',reponse="yönlendirildi", urladersi="Yölendirme Adresi" + " ~ " + mainurl)
 

if __name__ == "__main__":
    app.run(debug=True)



umBqNLP.png


Gerekli kütüphanelerin programa import edilmesi.



Python:
from flask import Flask, redirect, render_template, request

app = Flask(__name__)

Kütüphanlerin kullanım alanları

redirect:


redirect, Flask uygulamalarında kullanıcıyı başka bir URL'ye yönlendirmek için kullanılan bir fonksiyondur. Örneğin, bir formun başarıyla gönderilmesi durumunda kullanıcıyı teşekkür sayfasına yönlendirmek için redirect kullanabiliriz.

render_template:

render_template, Flask'in temel özelliklerinden biridir ve HTML dosyalarını Flask uygulamasına entegre etmemizi sağlar. Bu yöntem sayesinde, dinamik içeriklerle dolu HTML dosyalarını oluşturabilir ve kullanıcılara sunabiliriz. Örneğin, bir kullanıcı giriş sayfası veya ürün listesi gibi yapılandırılmış bir HTML sayfası oluşturmak için render_template kullanılır.


request:

request, Flask uygulamalarında kullanıcıdan gelen verileri almak veya veri transferi yapmak için kullanılır. Örneğin, HTTP istek başlıklarını (headers) veya form verilerini almak için kullanılabilir.


umBqNLP.png


Route dekoratörü ile /host dizinine bir yönlendirme yapılacağını belirtir.index adında bir fonksiyon oluşturulması.Her fonksiyonda kullanabilmek için mainurl adında global bir değişken tanımlanması.host adında bir değişkenin tanımlanması ve request kullanarak sunucudaki host başlığının çekilmesi.Yönlendirilecek URL adresinin oluşturulması.redirect fonksiyonu ile URL adresine yönlendirilmesi.



Python:
@app.route("/host")
def index():
    host = request.host
    global mainurl
    mainurl = "http://" + host + "/response.html"
    return redirect(mainurl)




Bu kod tam olarak ne iş yapıyor derseniz, localhost/host adresine gittiğinizde sizi localhost/response.html adında bir dizine yönlendiriyor. Peki, bu dizine gelince ne oluyor derseniz? Ekrana yönlendirilen adresi yazdırıyor.

Python:
@app.route('/response.html')
def responsehtml():
    return render_template('response.html',reponse="yönlendirildi", urladersi="Yölendirme Adresi" + " ~ " + mainurl)

"EE, zafiyet nerede" gibi sorularınız varsa, tam olarak burada.
Python:
host = request.host
mainurl = "http://" + host + "/response.html"

Burada host adresi statik bir şekilde girilmediği için Flask uygulaması, host başlığını çalıştırıldığı sunucuya göre dinamik olarak çektiği için bu manipülasyona açık hale geliyor.
ctf0sk9.png


Zafiyeti Önleme Aşaması
Normal şartlar altında URL kısmı (host) dinamik bir şekilde çekildiği için programın elinde net bir kaynak yoktu ve manipüle edilebiliyordu. Ama biz bu sefer host kısmını statik bir şekilde verdik ve artık programın bir kaynağı olduğu için manipülasyona kapalı hale geldi.
Python:
@app.route("/host")
def index():
    global mainurl
    host = "127.0.0.1:5000"
    mainurl = "http://" + host + "/response.html"
    return redirect(mainurl)


Zafiyetsiz Kod
Python:
from flask import Flask, redirect, render_template, request

app = Flask(__name__)

 

@app.route("/host")
def index():
    global mainurl
    host = "127.0.0.1:5000"
    mainurl = "http://" + host + "/response.html"
    return redirect(mainurl)
 

@app.route('/response.html')
def responsehtml():
    return render_template('response.html',reponse="yönlendirildi", urladersi="Yölendirme Adresi" + " ~ " + mainurl)
 

if __name__ == "__main__":
    app.run(debug=True)

ctf0sk9.png



PoC

Göründüğü üzere /host dizinine giderken Burp Suite ile attığım isteği yakaladım ve şu anlık bir sorun gözükmüyor, istediğim adrese beni yönlendiriyor.
nts1pmz.PNG


~
  • "Ama burada host başlığını değiştirirsem, ne gibi bir değişiklik olacak? Tekrar bakalım."
  • "Göründüğü üzere host adresi kendi localhost'um değil, attacker.com oldu."


44ql03t.PNG


umBqNLP.png



Saldırı vektörü kısmında, eskiden okuduğum bazı makaleleri örnek vereceğim.

Host Header İnjection - Geleceği Yazanlar
~
portswigger


# Arge Ekibi ~ DevSecOps Birimi
@ExeOweR @Hea7 @Bunjo @teux

umBqNLP.png


p0qbke2.png
Ellerinize sağlık hocam :)
 

P4$A

Uzman üye
13 Tem 2021
1,497
2,840
23
";-alert(1)-//
Kod doğru ama impacti yok, severity 0.001 sana daha öncede açıklamışmıydım bilmiyorum. Sadece yönlendirme atıyorsun bu tarz tespitlerde o da self zaten sadece sende var, bir işe yaramıyor açıkçası sadece bir yere location ile yönlendirmesi evet host header alanını manipüle ettiğini gösterir lakin self olduğu için çöp başka senaryolar denemelisin diye düşünüyorum.
 

Suppressor

Request Uzmanı
16 Kas 2022
1,224
761
always, everywhere
Eline sağlık, Ruby ve ben seni tebrik ediyoruz.
Ellerinize sağlık hocam :)
Eline, emeğine sağlık kardeşim
Elinize sağlık Sec Tayfa PHP tabanlı konular da gelecek mi
Emeğinize sağlık
Yorumlarınız için teşekkürler.

Kod doğru ama impacti yok, severity 0.001 sana daha öncede açıklamışmıydım bilmiyorum. Sadece yönlendirme atıyorsun bu tarz tespitlerde o da self zaten sadece sende var, bir işe yaramıyor açıkçası sadece bir yere location ile yönlendirmesi evet host header alanını manipüle ettiğini gösterir lakin self olduğu için çöp başka senaryolar denemelisin diye düşünüyorum.
Bu zafiyeti ilk öğrendiğim zaman bana da garip gelmişti. İnsanların bunu abartarak söylemesi, self olduğundan ötürü diyecek sözüm yok, Doğru. Birimin yeni açılması ve biraz yoğun olmam sebebiyle böyle bir konuyu açmayı tercih ettim. İlerleyen süreçte farklı zafiyetleri de ele almayı düşünüyorum. Yine de yorumun ve eleştirin için teşekkürler abi.
 

NMSHacking

Üye
4 Haz 2023
196
53
p0qbke2.png



umBqNLP.png


Selamlar, ben Suppressor. Bugün Flask uygulamalarında Host header injection zafiyetini ele alacağım.

Konu Başlıkları:
  1. HTTP Headers (Başlık)
  2. Zafiyetin Kaynaklanma Sebebi
  3. Zafiyetin Flask Kodu İle Gösterilmesi
  4. Zafiyetin Giderilmesi
  5. PoC

umBqNLP.png


HTTP Headers (Başlık)
HTTP başlıkları, hem HTTP isteklerinde hem de yanıtlarında isteğin meta bilgilerini taşıyan bilgilerdir.
Bu meta bilgileri, isteğin gideceği adres, kabul edilen yanıt tipi ve tarayıcının bizi tanıması için çerez (cookie) bilgileri gibi örnekler içerir.

Örnek olarak, bazı HTTP başlıkları şunlardır:
  1. Host: Bulunduğumuz web adresinin domain ismini veya IP adresini belirtir.
  2. Accept: Tarayıcının kabul edeceği içerik türlerini belirtir.
  3. Location: Web uygulamasında yönlendirme durumlarında (status 301, 302) yeni adresin neresi olduğunu belirtir.


umBqNLP.png


Zafiyet Neden Kaynaklanıyor
Host header injection zafiyeti, HTTP host başlığının manipüle edilmesiyle ortaya çıkar.
Eğer bir Flask uygulaması dinamik olarak Host başlığını site üzerinden çekiyorsa, her site farklı bir domain veya IP adresine sahip olduğu için bu başlık kullanıcının kontrolü dışında değiştirilebilir. Saldırganlar bu durumu kötüye kullanarak uygulamanın istemeden başka bir sunucuya veya hizmete yönlendirilmesine neden olabilirler.


ctf0sk9.png


Zafiyetli kaynak kodu


Python:
@app.route("/host")
def index():
    global mainurl
    host = request.host
    mainurl = "http://" + host + "/response.html"
    return redirect(mainurl)
 

@app.route('/response.html')
def responsehtml():
    return render_template('response.html',reponse="yönlendirildi", urladersi="Yölendirme Adresi" + " ~ " + mainurl)
 

if __name__ == "__main__":
    app.run(debug=True)



umBqNLP.png


Gerekli kütüphanelerin programa import edilmesi.



Python:
from flask import Flask, redirect, render_template, request

app = Flask(__name__)

Kütüphanlerin kullanım alanları

redirect:


redirect, Flask uygulamalarında kullanıcıyı başka bir URL'ye yönlendirmek için kullanılan bir fonksiyondur. Örneğin, bir formun başarıyla gönderilmesi durumunda kullanıcıyı teşekkür sayfasına yönlendirmek için redirect kullanabiliriz.

render_template:

render_template, Flask'in temel özelliklerinden biridir ve HTML dosyalarını Flask uygulamasına entegre etmemizi sağlar. Bu yöntem sayesinde, dinamik içeriklerle dolu HTML dosyalarını oluşturabilir ve kullanıcılara sunabiliriz. Örneğin, bir kullanıcı giriş sayfası veya ürün listesi gibi yapılandırılmış bir HTML sayfası oluşturmak için render_template kullanılır.


request:

request, Flask uygulamalarında kullanıcıdan gelen verileri almak veya veri transferi yapmak için kullanılır. Örneğin, HTTP istek başlıklarını (headers) veya form verilerini almak için kullanılabilir.


umBqNLP.png


Route dekoratörü ile /host dizinine bir yönlendirme yapılacağını belirtir.index adında bir fonksiyon oluşturulması.Her fonksiyonda kullanabilmek için mainurl adında global bir değişken tanımlanması.host adında bir değişkenin tanımlanması ve request kullanarak sunucudaki host başlığının çekilmesi.Yönlendirilecek URL adresinin oluşturulması.redirect fonksiyonu ile URL adresine yönlendirilmesi.



Python:
@app.route("/host")
def index():
    host = request.host
    global mainurl
    mainurl = "http://" + host + "/response.html"
    return redirect(mainurl)




Bu kod tam olarak ne iş yapıyor derseniz, localhost/host adresine gittiğinizde sizi localhost/response.html adında bir dizine yönlendiriyor. Peki, bu dizine gelince ne oluyor derseniz? Ekrana yönlendirilen adresi yazdırıyor.

Python:
@app.route('/response.html')
def responsehtml():
    return render_template('response.html',reponse="yönlendirildi", urladersi="Yölendirme Adresi" + " ~ " + mainurl)

"EE, zafiyet nerede" gibi sorularınız varsa, tam olarak burada.
Python:
host = request.host
mainurl = "http://" + host + "/response.html"

Burada host adresi statik bir şekilde girilmediği için Flask uygulaması, host başlığını çalıştırıldığı sunucuya göre dinamik olarak çektiği için bu manipülasyona açık hale geliyor.
ctf0sk9.png


Zafiyeti Önleme Aşaması
Normal şartlar altında URL kısmı (host) dinamik bir şekilde çekildiği için programın elinde net bir kaynak yoktu ve manipüle edilebiliyordu. Ama biz bu sefer host kısmını statik bir şekilde verdik ve artık programın bir kaynağı olduğu için manipülasyona kapalı hale geldi.
Python:
@app.route("/host")
def index():
    global mainurl
    host = "127.0.0.1:5000"
    mainurl = "http://" + host + "/response.html"
    return redirect(mainurl)


Zafiyetsiz Kod
Python:
from flask import Flask, redirect, render_template, request

app = Flask(__name__)

 

@app.route("/host")
def index():
    global mainurl
    host = "127.0.0.1:5000"
    mainurl = "http://" + host + "/response.html"
    return redirect(mainurl)
 

@app.route('/response.html')
def responsehtml():
    return render_template('response.html',reponse="yönlendirildi", urladersi="Yölendirme Adresi" + " ~ " + mainurl)
 

if __name__ == "__main__":
    app.run(debug=True)

ctf0sk9.png



PoC

Göründüğü üzere /host dizinine giderken Burp Suite ile attığım isteği yakaladım ve şu anlık bir sorun gözükmüyor, istediğim adrese beni yönlendiriyor.
nts1pmz.PNG


~
  • "Ama burada host başlığını değiştirirsem, ne gibi bir değişiklik olacak? Tekrar bakalım."
  • "Göründüğü üzere host adresi kendi localhost'um değil, attacker.com oldu."


44ql03t.PNG


umBqNLP.png



Saldırı vektörü kısmında, eskiden okuduğum bazı makaleleri örnek vereceğim.

Host Header İnjection - Geleceği Yazanlar
~
portswigger


# Arge Ekibi ~ DevSecOps Birimi
@ExeOweR @Hea7 @Bunjo @teux

umBqNLP.png


p0qbke2.png
Üst düzey bir yazı eline sağlık.
 
Üst

Turkhackteam.org internet sitesi 5651 sayılı kanun’un 2. maddesinin 1. fıkrasının m) bendi ile aynı kanunun 5. maddesi kapsamında "Yer Sağlayıcı" konumundadır. İçerikler ön onay olmaksızın tamamen kullanıcılar tarafından oluşturulmaktadır. Turkhackteam.org; Yer sağlayıcı olarak, kullanıcılar tarafından oluşturulan içeriği ya da hukuka aykırı paylaşımı kontrol etmekle ya da araştırmakla yükümlü değildir. Türkhackteam saldırı timleri Türk sitelerine hiçbir zararlı faaliyette bulunmaz. Türkhackteam üyelerinin yaptığı bireysel hack faaliyetlerinden Türkhackteam sorumlu değildir. Sitelerinize Türkhackteam ismi kullanılarak hack faaliyetinde bulunulursa, site-sunucu erişim loglarından bu faaliyeti gerçekleştiren ip adresini tespit edip diğer kanıtlarla birlikte savcılığa suç duyurusunda bulununuz.