Browser Extension Pentesting Methodology
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)
Tarayıcı eklentileri JavaScript ile yazılır ve tarayıcı tarafından arka planda yüklenir. Kendi DOM yapısına sahiptir ancak diğer sitelerin DOM'larıyla etkileşimde bulunabilir. Bu, diğer sitelerin gizliliğini, bütünlüğünü ve erişilebilirliğini (CIA) tehlikeye atabileceği anlamına gelir.
Eklenti düzenleri en iyi şekilde görselleştirildiğinde görünür ve üç bileşenden oluşur. Her bir bileşeni derinlemesine inceleyelim.
Her içerik scripti, tek bir web sayfasının DOM'una doğrudan erişime sahiptir ve bu nedenle potansiyel olarak kötü niyetli girdilere maruz kalır. Ancak, içerik scriptinin eklenti çekirdeğine mesaj göndermenin dışında başka bir izni yoktur.
Eklenti çekirdeği, eklentinin çoğu ayrıcalıklarını/erişimini içerir, ancak eklenti çekirdeği yalnızca XMLHttpRequest ve içerik scriptleri aracılığıyla web içeriğiyle etkileşimde bulunabilir. Ayrıca, eklenti çekirdeğinin ana makineye doğrudan erişimi yoktur.
Eklenti, kullanıcının tam ayrıcalıklarıyla ana makineye erişebilen bir yerel ikiliyi destekler. Yerel ikili, Flash ve diğer tarayıcı eklentileri tarafından kullanılan standart Netscape Eklenti Uygulama Programlama Arayüzü (NPAPI) aracılığıyla eklenti çekirdeği ile etkileşimde bulunur.
Kullanıcının tam ayrıcalıklarını elde etmek için, bir saldırganın eklentiyi kötü niyetli girdileri içerik scriptinden eklentinin çekirdeğine ve eklentinin çekirdeğinden yerel ikiliye geçirmesi için ikna etmesi gerekir.
Eklentinin her bir bileşeni, güçlü koruyucu sınırlarla birbirinden ayrılmıştır. Her bir bileşen, ayrı bir işletim sistemi sürecinde çalışır. İçerik scriptleri ve eklenti çekirdekleri, çoğu işletim sistemi hizmetine kapalı olan sandbox süreçlerinde çalışır.
Ayrıca, içerik scriptleri, ilişkili web sayfalarından ayrı bir JavaScript yığını içinde çalışarak ayrılır. İçerik scripti ve web sayfası, aynı temel DOM'a erişime sahiptir, ancak ikisi asla JavaScript işaretçilerini değiş tokuş etmez, bu da JavaScript işlevselliğinin sızmasını önler.
manifest.json
Bir Chrome eklentisi, .crx dosya uzantısına sahip bir ZIP klasörüdür. Eklentinin çekirdeği, klasörün kökünde bulunan manifest.json
dosyasıdır ve bu dosya düzen, izinler ve diğer yapılandırma seçeneklerini belirtir.
Örnek:
content_scripts
İçerik betikleri, kullanıcı eşleşen bir sayfaya gittiğinde yüklenir, bu durumda https://example.com/*
ifadesine uyan ve *://*/*/business*
regex'ine uymayan herhangi bir sayfa. Sayfanın Belge Nesne Modeli (DOM) üzerinde keyfi erişime sahip olarak sayfanın kendi betikleri gibi çalışırlar.
Daha fazla URL eklemek veya çıkarmak için include_globs
ve exclude_globs
kullanmak da mümkündür.
Bu, uzantının depolama alanından message
değerini almak için depolama API'sini kullanan bir açıklama butonu ekleyecek örnek bir içerik betiğidir.
Bu butona tıklandığında, içerik betiği tarafından uzantı sayfalarına bir mesaj gönderilir; bu, runtime.sendMessage() API kullanılarak gerçekleştirilir. Bu, içerik betiğinin API'lere doğrudan erişimindeki sınırlamadan kaynaklanmaktadır; storage
bu istisnalardan biridir. Bu istisnaların ötesindeki işlevler için, içerik betiklerinin iletişim kurabileceği uzantı sayfalarına mesajlar gönderilir.
Tarayıcıya bağlı olarak, içerik betiğinin yetenekleri biraz farklılık gösterebilir. Chromium tabanlı tarayıcılar için yetenekler listesi Chrome Geliştiricileri belgelerinde mevcuttur; Firefox için ise MDN ana kaynak olarak hizmet etmektedir. Ayrıca, içerik betiklerinin arka plan betikleriyle iletişim kurma yeteneğine sahip olduğu ve bu sayede eylemler gerçekleştirebildiği ve yanıtları iletebildiği de dikkate değerdir.
Chrome'da içerik betiklerini görüntülemek ve hata ayıklamak için, Chrome geliştirici araçları menüsüne Seçenekler > Daha fazla araç > Geliştirici araçları üzerinden veya Ctrl + Shift + I tuşlarına basarak erişilebilir.
Geliştirici araçları görüntülendikten sonra, Kaynak sekmesine tıklanmalı ve ardından İçerik Betikleri sekmesi seçilmelidir. Bu, çeşitli uzantılardan çalışan içerik betiklerinin gözlemlenmesini ve yürütme akışını izlemek için kesme noktaları ayarlamayı sağlar.
İçerik Betikleri zorunlu değildir; ayrıca dinamik olarak enjekte etmek ve web sayfalarına programatik olarak enjekte etmek de mümkündür; bu, tabs.executeScript
aracılığıyla gerçekleştirilir. Bu, aslında daha detaylı kontroller sağlar.
Bir içerik betiğinin programatik olarak enjekte edilmesi için, uzantının betiklerin enjekte edileceği sayfa için host izinlerine sahip olması gerekmektedir. Bu izinler, uzantının manifestosunda talep edilerek veya geçici olarak activeTab aracılığıyla güvence altına alınabilir.
Tıklama ile bir JS dosyası enjekte et:
Tıklamada bir fonksiyon enjekte et:
Daha fazla URL'yi dahil etmek veya hariç tutmak için include_globs
ve exclude_globs
kullanmak da mümkündür.
run_at
run_at
alanı JavaScript dosyalarının web sayfasına ne zaman enjekte edileceğini kontrol eder. Tercih edilen ve varsayılan değer "document_idle"
'dır.
Olası değerler şunlardır:
document_idle
: Mümkün olduğunda
document_start
: css
'den herhangi bir dosya yüklendikten sonra, ancak başka bir DOM oluşturulmadan veya başka bir script çalıştırılmadan önce.
document_end
: DOM tamamlandıktan hemen sonra, ancak resimler ve çerçeveler gibi alt kaynaklar yüklenmeden önce.
manifest.json
aracılığıylaservice-worker.js
aracılığıyla
background
İçerik betikleri tarafından gönderilen mesajlar, uzantının bileşenlerini koordine eden merkezi bir rol üstlenen arka plan sayfası tarafından alınır. Özellikle, arka plan sayfası uzantının ömrü boyunca devam eder, doğrudan kullanıcı etkileşimi olmadan gizlice çalışır. Kendi Belge Nesne Modeli (DOM) vardır, bu da karmaşık etkileşimler ve durum yönetimi sağlar.
Ana Noktalar:
Arka Plan Sayfası Rolü: Uzantının sinir merkezi olarak hareket eder, uzantının çeşitli parçaları arasında iletişim ve koordinasyonu sağlar.
Süreklilik: Kullanıcıya görünmez, ancak uzantının işlevselliği için hayati bir öneme sahip sürekli bir varlıktır.
Otomatik Oluşturma: Açıkça tanımlanmadığı takdirde, tarayıcı otomatik olarak bir arka plan sayfası oluşturur. Bu otomatik oluşturulan sayfa, uzantının manifestosunda belirtilen tüm arka plan betiklerini içerecek şekilde, uzantının arka plan görevlerinin kesintisiz çalışmasını sağlar.
Tarayıcının açıkça belirtilmediğinde otomatik olarak bir arka plan sayfası oluşturma kolaylığı, gerekli tüm arka plan betiklerinin entegre edilmesini ve çalışmasını sağlar, uzantının kurulum sürecini kolaylaştırır.
Örnek arka plan betiği:
It uses runtime.onMessage API to listen to messages. When an "explain"
message is received, it uses tabs API to open a page in a new tab.
To debug the background script you could go to the extension details and inspect the service worker, this will open the developer tools with the background script:
Tarayıcı uzantıları çeşitli türde sayfalar içerebilir:
Eylem sayfaları, uzantı simgesine tıklandığında açılır.
Uzantının yeni bir sekmede yükleyeceği sayfalar.
Seçenek Sayfaları: Bu sayfa tıklandığında uzantının üstünde görüntülenir. Önceki manifestte benim durumumda bu sayfaya chrome://extensions/?options=fadlhnelkbeojnebcbkacjilhnbjfjca
adresinden veya tıklayarak erişebildim:
Bu sayfaların arka plan sayfaları gibi kalıcı olmadığını, ihtiyaç üzerine dinamik içerik yüklediklerini unutmayın. Bununla birlikte, arka plan sayfasıyla belirli yetenekleri paylaşırlar:
İçerik Betikleri ile İletişim: Arka plan sayfasına benzer şekilde, bu sayfalar içerik betiklerinden mesaj alabilir, uzantı içinde etkileşimi kolaylaştırır.
Uzantıya Özgü API'lere Erişim: Bu sayfalar, uzantı için tanımlanan izinlere tabi olarak uzantıya özgü API'lere kapsamlı erişim sağlar.
permissions
& host_permissions
permissions
ve host_permissions
manifest.json
dosyasındaki girişlerdir ve tarayıcı uzantısının hangi izinlere sahip olduğunu (depolama, konum...) ve hangi web sayfalarında geçerli olduğunu gösterir.
Tarayıcı uzantıları bu kadar ayrıcalıklı olabileceğinden, kötü niyetli bir uzantı veya ele geçirilmiş bir uzantı, saldırgana hassas bilgileri çalmak ve kullanıcıyı gözetlemek için farklı yollar sağlayabilir.
Bu ayarların nasıl çalıştığını ve nasıl kötüye kullanılabileceğini kontrol edin:
BrowExt - permissions & host_permissionscontent_security_policy
Bir içerik güvenlik politikası, manifest.json
içinde de tanımlanabilir. Eğer tanımlıysa, açık olabilir.
Tarayıcı uzantı sayfaları için varsayılan ayar oldukça kısıtlayıcıdır:
Daha fazla bilgi için CSP ve potansiyel bypass'lar hakkında kontrol edin:
Content Security Policy (CSP) Bypassweb_accessible_resources
Bir web sayfasının bir Tarayıcı Uzantısının sayfasına, örneğin bir .html
sayfasına erişebilmesi için, bu sayfanın manifest.json
dosyasındaki web_accessible_resources
alanında belirtilmesi gerekir.
Örneğin:
Bu sayfalara şu URL'ler üzerinden erişilebilir:
Kamu uzantılarında extension-id erişilebilir:
Ancak, manifest.json
parametresi use_dynamic_url
kullanılıyorsa, bu id dinamik olabilir.
Burada bir sayfa belirtilse bile, Content Security Policy sayesinde ClickJacking'e karşı korunmuş olabilir. Bu nedenle, bir ClickJacking saldırısının mümkün olduğunu onaylamadan önce bunu (frame-ancestors bölümü) kontrol etmeniz gerekir.
Bu sayfalara erişim izni verilmesi, bu sayfaları potansiyel olarak savunmasız ClickJacking hale getirir:
BrowExt - ClickJackingBu sayfaların yalnızca uzantı tarafından yüklenmesine izin vermek ve rastgele URL'ler tarafından yüklenmesine izin vermemek, ClickJacking saldırılarını önleyebilir.
web_accessible_resources
ve uzantının diğer sayfaları da arka plan betikleriyle iletişim kurma yeteneğine sahiptir. Bu nedenle, bu sayfalardan biri XSS'ye karşı savunmasızsa, daha büyük bir güvenlik açığı açabilir.
Ayrıca, yalnızca web_accessible_resources
içinde belirtilen sayfaları iframe'ler içinde açabileceğinizi, ancak yeni bir sekmeden uzantının ID'sini bilerek herhangi bir sayfaya erişmenin mümkün olduğunu unutmayın. Bu nedenle, aynı parametreleri kötüye kullanan bir XSS bulunursa, sayfa web_accessible_resources
içinde yapılandırılmamış olsa bile kötüye kullanılabilir.
externally_connectable
docs gereği, "externally_connectable"
manifest özelliği, hangi uzantıların ve web sayfalarının uzantınıza runtime.connect ve runtime.sendMessage aracılığıyla bağlanabileceğini belirtir.
Eğer externally_connectable
anahtarı uzantınızın manifestosunda belirtilmemişse veya "ids": ["*"]
olarak belirtilmişse, tüm uzantılar bağlanabilir, ancak hiçbir web sayfası bağlanamaz.
Eğer belirli ID'ler belirtilmişse, örneğin "ids": ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]
, yalnızca o uygulamalar bağlanabilir.
Eğer eşleşmeler belirtilirse, o web uygulamaları bağlanabilecektir:
Eğer boş olarak belirtilmişse: "externally_connectable": {}
, hiçbir uygulama veya web bağlantı kuramayacaktır.
Burada belirtilen daha az uzantı ve URL, saldırı yüzeyinin daha küçük olacağı anlamına gelir.
Eğer bir web sayfası XSS veya ele geçirme için externally_connectable
içinde belirtilmişse, bir saldırgan arka plan betiğine doğrudan mesaj gönderebilir, İçerik Betiğini ve CSP'yi tamamen atlayarak.
Bu nedenle, bu çok güçlü bir atlatmadır.
Ayrıca, eğer istemci kötü niyetli bir uzantı yüklerse, bu uzantının savunmasız uzantıyla iletişim kurmasına izin verilse bile, izin verilen bir web sayfasına XSS verisi enjekte edebilir veya WebRequest
veya DeclarativeNetRequest
API'lerini kötüye kullanarak hedef bir alan üzerindeki istekleri manipüle edebilir ve bir sayfanın JavaScript dosyası isteğini değiştirebilir. (Hedef sayfadaki CSP'nin bu saldırıları önleyebileceğini unutmayın). Bu fikir bu yazıdan gelmektedir.
İçerik betiği ile web sayfası arasında iletişim kurmak için genellikle post mesajları kullanılır. Bu nedenle, web uygulamasında genellikle window.postMessage
fonksiyonuna yapılan çağrıları ve içerik betiğinde window.addEventListener
gibi dinleyicileri bulacaksınız. Ancak, uzantının da bir Post Mesajı göndererek web uygulamasıyla iletişim kurabileceğini (bu nedenle webin bunu beklemesi gerektiğini) veya sadece webin yeni bir betik yüklemesini sağlayabileceğini unutmayın.
Genellikle uzantı içinde bir mesaj göndermek için chrome.runtime.sendMessage
fonksiyonu kullanılır (genellikle background
betiği tarafından işlenir) ve bunu almak ve işlemek için bir dinleyici chrome.runtime.onMessage.addListener
çağrısı ile tanımlanır.
Ayrıca, tekil mesajlar göndermek yerine sürekli bir bağlantı kurmak için chrome.runtime.connect()
kullanmak da mümkündür, bu, aşağıdaki örnekte olduğu gibi mesajlar göndermek ve almak için kullanılabilir:
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)