CSS Injection
Last updated
Last updated
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Eğitim AWS Kırmızı Takım Uzmanı (ARTE) GCP Hacking'i öğrenin ve pratik yapın: HackTricks Eğitim GCP Kırmızı Takım Uzmanı (GRTE)
CSS seçicileri, bir input
öğesinin name
ve value
özniteliklerinin değerleriyle eşleşecek şekilde oluşturulmuştur. Eğer input öğesinin value özniteliği belirli bir karakterle başlıyorsa, önceden tanımlanmış bir dış kaynak yüklenir:
Ancak, bu yaklaşım gizli giriş elemanları (type="hidden"
) ile çalışırken bir sınıra sahiptir çünkü gizli elemanlar arka planları yüklemez.
Bu sınırlamayı aşmak için, ~
genel kardeş kombinatörünü kullanarak bir sonraki kardeş elemanı hedefleyebilirsiniz. CSS kuralı, gizli giriş elemanını takip eden tüm kardeşlere uygulanır ve arka plan resminin yüklenmesine neden olur:
A practical example of exploiting this technique is detailed in the provided code snippet. You can view it here.
CSS Enjeksiyonu tekniğinin etkili olabilmesi için belirli koşulların sağlanması gerekmektedir:
Yük Uzunluğu: CSS enjeksiyon vektörü, oluşturulmuş seçicileri barındıracak kadar uzun yükleri desteklemelidir.
CSS Yeniden Değerlendirmesi: Sayfayı çerçeveleme yeteneğine sahip olmalısınız; bu, yeni oluşturulmuş yüklerle CSS'nin yeniden değerlendirilmesini tetiklemek için gereklidir.
Dış Kaynaklar: Teknik, dışarıda barındırılan resimleri kullanma yeteneğini varsayar. Bu, sitenin İçerik Güvenlik Politikası (CSP) tarafından kısıtlanabilir.
As explained in this post, it's possible to combine the selectors :has
and :not
to identify content even from blind elements. This is very useful when you have no idea what is inside the web page loading the CSS injection.
It's also possible to use those selectors to extract information from several block of the same type like in:
Bunu aşağıdaki @import tekniği ile birleştirerek, gözlemci sayfalardan CSS enjeksiyonu kullanarak çok fazla bilgi sızdırmak mümkün blind-css-exfiltration.
Önceki tekniğin bazı dezavantajları vardır, ön koşulları kontrol edin. Kurbanın birden fazla bağlantı alabilmesi veya CSS enjeksiyonu açık sayfayı iframe'leyebilmesi gerekir.
Ancak, tekniğin kalitesini artırmak için CSS @import
kullanan başka bir akıllı teknik vardır.
Bu ilk olarak Pepe Vila tarafından gösterildi ve şöyle çalışır:
Her seferinde on farklı yük ile aynı sayfayı tekrar tekrar yüklemek yerine (öncekinde olduğu gibi), sayfayı sadece bir kez ve sadece saldırganın sunucusuna bir import ile yükleyeceğiz (bu, kurbana gönderilecek yük):
İthalat, saldırganlardan bazı CSS scriptleri alacak ve tarayıcı bunu yükleyecek.
Saldırganın göndereceği CSS scriptinin ilk kısmı, saldırganların sunucusuna başka bir @import
olacak.
Saldırganların sunucusu bu isteğe henüz yanıt vermeyecek, çünkü bazı karakterleri sızdırmak istiyoruz ve ardından bu ithalatı, sonraki karakterleri sızdırmak için yük ile yanıtlayacağız.
Yükün ikinci ve daha büyük kısmı, bir nitelik seçici sızdırma yükü olacak.
Bu, saldırganların sunucusuna sırrın ilk karakterini ve son karakterini gönderecek.
Saldırganların sunucusu, sırrın ilk ve son karakterini aldıktan sonra, adım 2'de talep edilen ithalata yanıt verecek.
Yanıt, adım 2, 3 ve 4 ile tam olarak aynı olacak, ancak bu sefer sırrın ikinci karakterini ve ardından sondan bir önceki karakteri bulmaya çalışacak.
Saldırgan, sırrı tamamen sızdırana kadar bu döngüyü takip edecek.
Orijinal Pepe Vila'nın bunu istismar etmek için kodunu burada bulabilirsiniz veya neredeyse aynı kodu ama yorumlu burada bulabilirsiniz.
Script, her seferinde 2 karakter keşfetmeye çalışacak (başlangıçtan ve sondan) çünkü nitelik seçici, şunları yapmaya izin veriyor:
Bu, scriptin sırrı daha hızlı sızdırmasına olanak tanır.
Bazen script önek + sonek'in zaten tam bayrak olduğunu doğru bir şekilde tespit etmez ve ileri (önek içinde) ve geri (sonek içinde) devam eder ve bir noktada takılır. Endişelenmeyin, sadece çıktıyı kontrol edin çünkü orada bayrağı görebilirsiniz.
CSS seçicileri ile DOM parçalarına erişmenin diğer yolları:
.class-to-search:nth-child(2)
: Bu, DOM'daki "class-to-search" sınıfına sahip ikinci öğeyi arar.
:empty
seçici: Örneğin bu yazıda** kullanılır:**
Referans: CSS tabanlı Saldırı: @font-face'in unicode-range'ini kötüye kullanma, Hata Tabanlı XS-Search PoC @terjanq tarafından
Genel amaç, kontrol edilen bir uç noktadan özel bir font kullanmak ve metnin (bu durumda, 'A') yalnızca belirtilen kaynak (favicon.ico
) yüklenemediğinde bu fontla görüntülenmesini sağlamak.
Özel Yazı Tipi Kullanımı:
Özel bir yazı tipi, <head>
bölümündeki <style>
etiketi içinde @font-face
kuralı kullanılarak tanımlanır.
Yazı tipinin adı poc
olarak belirlenmiş ve harici bir uç noktadan (http://attacker.com/?leak
) alınmaktadır.
unicode-range
özelliği U+0041
olarak ayarlanmış, bu da belirli Unicode karakteri 'A'yı hedef alır.
Yedek Metin ile Nesne Elemanı:
<body>
bölümünde id="poc0"
olan bir <object>
elemanı oluşturulmuştur. Bu eleman, http://192.168.0.1/favicon.ico
adresinden bir kaynak yüklemeye çalışır.
Bu elemanın font-family
değeri, <style>
bölümünde tanımlandığı gibi 'poc'
olarak ayarlanmıştır.
Eğer kaynak (favicon.ico
) yüklenemezse, <object>
etiketinin içindeki yedek içerik (harf 'A') görüntülenir.
Harici kaynak yüklenemezse, yedek içerik ('A') özel yazı tipi poc
kullanılarak işlenecektir.
:target
psödo-sınıfı, bir URL parçası tarafından hedeflenen bir öğeyi seçmek için kullanılır; bu, CSS Seçicileri Seviye 4 spesifikasyonunda belirtilmiştir. ::target-text
'in, metin parça tarafından açıkça hedeflenmediği sürece hiçbir öğeyi eşleştirmediğini anlamak önemlidir.
Bir güvenlik endişesi, saldırganların Kaydırma ile Metin parçası özelliğini kullanarak, HTML enjeksiyonu yoluyla kendi sunucularından bir kaynak yükleyerek bir web sayfasında belirli metinlerin varlığını doğrulamalarına olanak tanımasıdır. Yöntem, şu şekilde bir CSS kuralı enjekte etmeyi içerir:
Bu tür senaryolarda, sayfada "Administrator" metni varsa, target.png
kaynağı sunucudan talep edilir ve metnin varlığını gösterir. Bu saldırının bir örneği, enjekte edilen CSS'yi bir Scroll-to-text parçasıyla birlikte içeren özel olarak hazırlanmış bir URL aracılığıyla gerçekleştirilebilir:
Burada, saldırı CSS kodunu iletmek için HTML enjeksiyonunu manipüle ediyor ve "Administrator" metnini Scroll-to-text fragment (#:~:text=Administrator
) aracılığıyla hedef alıyor. Metin bulunduğunda, belirtilen kaynak yüklenir ve bu durum istemeden saldırgana varlığını sinyal eder.
Azaltma için aşağıdaki noktalar dikkate alınmalıdır:
Sınırlı STTF Eşleşmesi: Scroll-to-text Fragment (STTF), yalnızca kelimeleri veya cümleleri eşleştirmek üzere tasarlanmıştır, bu nedenle rastgele sırların veya token'ların sızdırılma yeteneğini sınırlamaktadır.
Üst Düzey Tarayıcı Bağlamlarına Kısıtlama: STTF yalnızca üst düzey tarayıcı bağlamlarında çalışır ve iframe'ler içinde işlev görmez, bu da herhangi bir istismar girişimini kullanıcıya daha belirgin hale getirir.
Kullanıcı Etkileşimi Gerekliliği: STTF'nin çalışması için bir kullanıcı etkileşimi gereklidir, bu da istismarların yalnızca kullanıcı tarafından başlatılan gezintilerle mümkün olduğu anlamına gelir. Bu gereklilik, saldırıların kullanıcı etkileşimi olmadan otomatikleştirilme riskini önemli ölçüde azaltır. Bununla birlikte, blog yazısının yazarı, saldırının otomatikleştirilmesini kolaylaştırabilecek belirli koşulları ve geçiş yollarını (örneğin, sosyal mühendislik, yaygın tarayıcı uzantılarıyla etkileşim) belirtmektedir.
Bu mekanizmaların ve potansiyel zayıflıkların farkında olmak, web güvenliğini sağlamak ve bu tür istismar taktiklerine karşı korunmak için anahtardır.
Daha fazla bilgi için orijinal raporu kontrol edin: https://www.secforce.com/blog/new-technique-of-stealing-data-using-css-and-scroll-to-text-fragment-feature/
Bu teknikle bir CTF için istismar kontrol edebilirsiniz.
Belirli unicode değerleri için dış fontlar belirtebilirsiniz ve bu fontlar yalnızca bu unicode değerleri sayfada mevcutsa toplanacaktır. Örneğin:
When you access this page, Chrome and Firefox fetch "?A" and "?B" because text node of sensitive-information contains "A" and "B" characters. But Chrome and Firefox do not fetch "?C" because it does not contain "C". This means that we have been able to read "A" and "B".
Reference: Wykradanie danych w świetnym stylu – czyli jak wykorzystać CSS-y do ataków na webaplikację
Açıklanan teknik, font ligatürlerini kullanarak bir düğümden metin çıkarmayı ve genişlikteki değişiklikleri izlemeyi içerir. Süreç birkaç adımdan oluşur:
Özel Fontların Oluşturulması:
İki karakter dizisini temsil eden bir glif için büyük bir genişlik ayarlayan horiz-adv-x
niteliğine sahip glifler ile SVG fontları oluşturulur.
Örnek SVG glifi: <glyph unicode="XY" horiz-adv-x="8000" d="M1 0z"/>
, burada "XY" iki karakter dizisini belirtir.
Bu fontlar daha sonra fontforge kullanılarak woff formatına dönüştürülür.
Genişlik Değişikliklerinin Tespiti:
Metnin sarılmamasını sağlamak için CSS kullanılır (white-space: nowrap
) ve kaydırıcı stilini özelleştirir.
Farklı bir şekilde stillendirilmiş yatay bir kaydırıcının görünümü, metinde belirli bir ligatürün ve dolayısıyla belirli bir karakter dizisinin mevcut olduğuna dair bir gösterge (oracle) olarak işlev görür.
İlgili CSS:
Sömürü Süreci:
Adım 1: Önemli genişliğe sahip karakter çiftleri için fontlar oluşturulur.
Adım 2: Büyük genişlik glifi (bir karakter çiftinin ligatürü) render edildiğinde, karakter dizisinin varlığını göstermek için kaydırıcı tabanlı bir hile kullanılır.
Adım 3: Bir ligatür tespit edildiğinde, tespit edilen çifti içeren ve bir önceki veya sonraki karakter ekleyen üç karakter dizilerini temsil eden yeni glifler üretilir.
Adım 4: Üç karakter ligatürünün tespiti gerçekleştirilir.
Adım 5: Süreç tekrarlanır, metnin tamamı yavaş yavaş açığa çıkar.
Optimizasyon:
Mevcut <meta refresh=...
ile başlatma yöntemi optimal değildir.
Daha verimli bir yaklaşım, sömürünün performansını artıran CSS @import
hilesini içerebilir.
Reference: PoC using Comic Sans by @Cgvwzq & @Terjanq
Bu hile, bu Slackers thread içinde yayımlandı. Bir metin düğümünde kullanılan karakter seti, tarayıcıda yüklü olan varsayılan fontlar kullanılarak sızdırılabilir: dışarıdan -veya özel- fontlara ihtiyaç yoktur.
Kavram, bir div
'in genişliğini kademeli olarak artırmak için bir animasyon kullanmayı ve bir karakterin bir seferde metnin 'sonek' kısmından 'ön ek' kısmına geçiş yapmasına olanak tanımayı içerir. Bu süreç, metni iki bölüme etkili bir şekilde böler:
Ön Ek: İlk satır.
Sonek: Sonraki satır(lar).
Karakterlerin geçiş aşamaları şu şekilde görünecektir:
C ADB
CA DB
CAD B
CADB
Bu geçiş sırasında, unicode-range trick kullanılarak her yeni karakterin ön ekle birleştiği tespit edilir. Bu, fontu Comic Sans'a değiştirerek gerçekleştirilir; bu font, varsayılan fonta göre belirgin şekilde daha yüksektir ve dolayısıyla dikey bir kaydırıcıyı tetikler. Bu kaydırıcının görünümü, ön ekte yeni bir karakterin varlığını dolaylı olarak ortaya çıkarır.
Bu yöntem, benzersiz karakterlerin görünmesi sırasında tespit edilmesine olanak tanırken, hangi karakterin tekrarlandığını belirtmez, yalnızca bir tekrarın gerçekleştiğini gösterir.
Temelde, unicode-range bir karakteri tespit etmek için kullanılır, ancak dış bir font yüklemek istemediğimiz için başka bir yol bulmamız gerekir. Karakter bulunduğunda, önceden yüklenmiş Comic Sans fontu ile verilir, bu da karakteri büyütür ve kaydırıcıyı tetikler; bu da bulunan karakteri sızdırır.
Check the code extracted from the PoC:
Referans: Bu, bu yazıda başarısız bir çözüm olarak belirtilmiştir
Bu durum, önceki duruma çok benziyor, ancak bu durumda belirli karakterleri diğerlerinden daha büyük yapmak, bir butonun bot tarafından basılmaması veya yüklenmeyecek bir görüntüyü gizlemek gibi bir amaca hizmet ediyor. Böylece eylemi (veya eylemsizliği) ölçebilir ve metin içinde belirli bir karakterin mevcut olup olmadığını bilebiliriz.
Referans: Bu, bu yazıda başarısız bir çözüm olarak belirtilmiştir
Bu durumda, metinde bir karakterin olup olmadığını sızdırmayı, aynı kaynaktan sahte bir font yükleyerek deneyebiliriz:
Eğer bir eşleşme varsa, font /static/bootstrap.min.css?q=1
'den yüklenecektir. Başarılı bir şekilde yüklenmeyecek olsa da, tarayıcı bunu önbelleğe almalıdır ve önbellek olmasa bile, 304 not modified mekanizması vardır, bu nedenle yanıt diğer şeylerden daha hızlı olmalıdır.
Ancak, önbellekli yanıt ile önbelleksiz yanıt arasındaki zaman farkı yeterince büyük değilse, bu faydalı olmayacaktır. Örneğin, yazar şunları belirtti: Ancak, test ettikten sonra, ilk sorunun hızın çok farklı olmaması ve ikinci sorunun botun disk-cache-size=1
bayrağını kullanması olduğunu buldum, bu gerçekten düşünceli.
Referans: Bu, bu yazıda başarısız bir çözüm olarak belirtilmiştir
Bu durumda, bir eşleşme gerçekleştiğinde aynı kaynaktan yüzlerce sahte font yüklemek için CSS'i belirtebilirsiniz. Bu şekilde, ne kadar zaman aldığını ölçebilir ve bir karakterin görünüp görünmediğini bulabilirsiniz:
Ve botun kodu şöyle görünüyor:
Yani, eğer font eşleşmiyorsa, bota erişim sırasında yanıt süresinin yaklaşık 30 saniye olması beklenir. Ancak, bir font eşleşmesi varsa, fontu almak için birden fazla istek gönderilecektir, bu da ağda sürekli bir aktivite olmasına neden olacaktır. Sonuç olarak, durdurma koşulunu tatmin etmek ve yanıt almak daha uzun sürecektir. Bu nedenle, yanıt süresi bir font eşleşmesi olup olmadığını belirlemek için bir gösterge olarak kullanılabilir.
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)