hacktricks/pentesting-web/browser-extension-pentesting-methodology/README.md

40 KiB
Raw Blame History

Tarayıcı Uzantısı Pentest Metodolojisi

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

HackTricks'ı desteklemenin diğer yolları:

Temel Bilgiler

Tarayıcı uzantıları JavaScript ile yazılır ve tarayıcı tarafından arka planda yüklenir. Kendi DOM'una 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 tehlikeye atabilir.

Ana Bileşenler

Uzantı düzenleri en iyi görselleştirildiğinde üç bileşenden oluşur. Her bileşeni detaylı olarak inceleyelim.

http://webblaze.cs.berkeley.edu/papers/Extensions.pdf

İçerik Betikleri

Her içerik betiğinin tek bir web sayfasının DOM'una doğrudan erişimi vardır ve bu nedenle potansiyel olarak kötü niyetli girdilere maruz kalabilir. Ancak, içerik betiği, uzantı çekirdeğine mesaj gönderme yeteneği dışında hiçbir izne sahip değildir.

Uzantı Çekirdeği

Uzantı çekirdeği, uzantının çoğu ayrıcalığı/erişimi içerir, ancak uzantı çekirdeği yalnızca XMLHttpRequest ve içerik betikleri aracılığıyla web içeriğiyle etkileşime geçebilir. Ayrıca, uzantı çekirdeğinin ana makineye doğrudan erişimi yoktur.

Yerel İkili

Uzantı, kullanıcının tam ayrıcalıklarıyla ana makineye erişebilen yerel bir ikiliye izin verir. Yerel ikili, Flash ve diğer tarayıcı eklentileri tarafından kullanılan standart Netscape Eklenti Uygulama Programlama Arayüzü (NPAPI) aracılığıyla uzantı çekirdeği ile etkileşime geçer.

Sınırlar

{% hint style="danger" %} Kullanıcının tam ayrıcalıklarını elde etmek için bir saldırganın, içerik betiğinden uzantı çekirdeğine ve uzantı çekirdeğinden yerel ikiliye kötü niyetli girdi geçirmesini ikna etmesi gerekir. {% endhint %}

Uzantının her bileşeni, birbirinden güçlü koruyucu sınırlarla ayrılmıştır. Her bileşen ayrı bir işletim sistemi işlemi içinde çalışır. İçerik betikleri ve uzantı çekirdekleri, çoğu işletim sistemi hizmetine erişilemeyen kum havuzu işlemlerinde çalışır.

Ayrıca, içerik betikleri, ayrı bir JavaScript yığınında çalışarak ilişkili web sayfalarından ayrı tutulur. İçerik betiği ve web sayfası, aynı temel DOM'a erişebilir, ancak ikisi hiçbir zaman JavaScript işaretçilerini değiş tokuş etmez, bu da JavaScript işlevselliğinin sızmasını önler.

manifest.json

Bir Chrome uzantısı, .crx dosya uzantısına sahip bir ZIP klasörüdür. Uzantının çekirdeği, düzeni, izinleri ve diğer yapılandırma seçeneklerini belirten klasörün kökünde bulunan manifest.json dosyasıdır.

Örnek:

{
"manifest_version": 2,
"name": "My extension",
"version": "1.0",
"permissions": [
"storage"
],
"content_scripts": [
{
"js": [
"script.js"
],
"matches": [
"https://example.com/*",
"https://www.example.com/*"
],
"exclude_matches": ["*://*/*business*"],
}
],
"background": {
"scripts": [
"background.js"
]
},
"options_ui": {
"page": "options.html"
}
}

content_scripts

İçerik betikleri, kullanıcı eşleşen bir sayfaya gezindiğinde yüklenir, bizim durumumuzda https://example.com/* ifadesine uyan herhangi bir sayfa ve *://*/*/business* regexine uymayanlar. Sayfanın kendi betikleri gibi çalışırlar ve sayfanın Belge Nesne Modeli (DOM)ne keyfi erişime sahiptirler.

"content_scripts": [
{
"js": [
"script.js"
],
"matches": [
"https://example.com/*",
"https://www.example.com/*"
],
"exclude_matches": ["*://*/*business*"],
}
],

include_globs ve exclude_globs kullanarak daha fazla URL eklemek veya hariç tutmak da mümkündür.

Bu, depolama API'sını kullanarak uzantının depolamasından message değerini almak için bir açıklama düğmesi ekleyecek bir örnek içerik betiğidir.

chrome.storage.local.get("message", result =>
{
let div = document.createElement("div");
div.innerHTML = result.message + " <button>Explain</button>";
div.querySelector("button").addEventListener("click", () =>
{
chrome.runtime.sendMessage("explain");
});
document.body.appendChild(div);
});

Bu düğmeye tıklandığında içerik betiği tarafından uzantı sayfalarına bir mesaj gönderilir, runtime.sendMessage() API kullanılarak. Bu, içerik betiğinin API'lere doğrudan erişimindeki kısıtlamadan kaynaklanmaktadır, storage bunun istisnalarından biridir. Bu istisnaların ötesindeki işlevsellikler için, içerik betikleriyle iletişim kurabilen uzantı sayfalarına mesajlar gönderilir.

{% hint style="warning" %} İçerik betiğinin yetenekleri tarayıcıya göre biraz değişebilir. Chromium tabanlı tarayıcılar için yetenekler listesi Chrome Geliştiriciler belgelerinde bulunabilir ve Firefox için MDN birincil kaynak olarak hizmet verir.
Ayrıca içerik betiklerinin arka plan betikleriyle iletişim kurma yeteneğine sahip oldukları ve böylece eylemleri gerçekleştirebilecekleri ve yanıtları geri iletebilecekleri unutulmamalıdır. {% endhint %}

Chrome'da içerik betiklerini görüntülemek ve hata ayıklamak için Chrome geliştirici araçları menüsüne Options > More tools > Developer tools veya Ctrl + Shift + I tuşlarına basılarak erişilebilir.

Geliştirici araçları görüntülendikten sonra, Source sekmesine tıklanmalı ve ardından Content Scripts sekmesine tıklanmalıdır. Bu, çeşitli uzantılardan çalışan içerik betiklerinin gözlemlenmesine ve yürütme akışını izlemek için kesme noktaları belirlemeye olanak tanır.

Enjekte edilmiş içerik betikleri

{% hint style="success" %} İçerik Betiklerinin zorunlu olmadığını ve ayrıca dinamik olarak betiklerin enjekte edilebileceğini ve bunların web sayfalarına tabs.executeScript aracılığıyla programatik olarak enjekte edilebileceğini unutmayın. Bu aslında daha ayrıntılı kontroller sağlar. {% endhint %}

Bir içerik betiğinin programatik olarak enjekte edilmesi için, uzantının betiklerin enjekte edileceği sayfaya ana bilgisayar izinlerine sahip olması gerekir. Bu izinler, uzantının manifest dosyası içinde talep edilerek veya geçici olarak activeTab aracılığıyla sağlanabilir.

Örnek activeTab tabanlı uzantı

{% code title="manifest.json" %}

{
"name": "My extension",
...
"permissions": [
"activeTab",
"scripting"
],
"background": {
"service_worker": "background.js"
},
"action": {
"default_title": "Action Button"
}
}

{% endcode %}

  • Tıklama olayıyla bir JS dosyası enjekte etmek:
// content-script.js
document.body.style.backgroundColor = "orange";

//service-worker.js - Inject the JS file
chrome.action.onClicked.addListener((tab) => {
chrome.scripting.executeScript({
target: { tabId: tab.id },
files: ["content-script.js"]
});
});
  • Tıklama olayına bir fonksiyon enjekte edin:
//service-worker.js - Inject a function
function injectedFunction() {
document.body.style.backgroundColor = "orange";
}

chrome.action.onClicked.addListener((tab) => {
chrome.scripting.executeScript({
target : {tabId : tab.id},
func : injectedFunction,
});
});

Betik İzinleri ile Örnek

// service-workser.js
chrome.scripting.registerContentScripts([{
id : "test",
matches : [ "https://*.example.com/*" ],
excludeMatches : [ "*://*/*business*" ],
js : [ "contentScript.js" ],
}]);

// Another example
chrome.tabs.executeScript(tabId, { file: "content_script.js" });

Daha fazla URL eklemek veya hariç tutmak için include_globs ve exclude_globs kullanmak da mümkündür.

İçerik Betikleri 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.

Mümkün olan değerler şunlardır:

  • document_idle: Mümkün olduğunda
  • document_start: css dosyalarından sonra, ancak diğer DOM oluşturulmadan veya başka bir betik ç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 üzerinden

{
"name": "My extension",
...
"content_scripts": [
{
"matches": ["https://*.example.com/*"],
"run_at": "document_idle",
"js": ["contentScript.js"]
}
],
...
}

service-worker.js aracılığıyla

chrome.scripting.registerContentScripts([{
id : "test",
matches : [ "https://*.example.com/*" ],
runAt : "document_idle",
js : [ "contentScript.js" ],
}]);

arkaplan

İçerik komutları tarafından gönderilen mesajlar, uzantının bileşenlerini koordine etmede merkezi bir rol oynayan arkaplan sayfası tarafından alınır. Önemli bir şekilde, arkaplan sayfası uzantının ömrü boyunca varlığını sürdürür, doğrudan kullanıcı etkileşimi olmadan gizlice çalışır. Kendi Document Object Model (DOM) 'a sahiptir, karmaşık etkileşimlere ve durum yönetimine olanak tanır.

Ana Noktalar:

  • Arkaplan Sayfa Rolü: Uzantı için sinir merkezi olarak hareket eder, uzantının çeşitli parçaları arasında iletişimi ve koordinasyonu sağlar.
  • Kalıcılık: Kullanıcı için görünmez ancak uzantının işlevselliği için ayrılmaz olan sürekli bir varlıktır.
  • Otomatik Oluşturma:ıkça tanımlanmazsa, tarayıcı otomatik olarak bir arkaplan sayfası oluşturacaktır. Bu otomatik oluşturulan sayfa, uzantının manifestosunda belirtilen tüm arkaplan betiklerini içerecek ve uzantının arkaplan görevlerinin sorunsuz çalışmasını sağlayacaktır.

{% hint style="success" %} Tarayıcı tarafından otomatik olarak bir arkaplan sayfası oluşturulması (açıkça belirtilmediğinde) sağlanan kolaylık, gerekli tüm arkaplan betiklerinin entegre edilmiş ve operasyonel olduğundan emin olur, uzantının kurulum sürecini basitleştirir. {% endhint %}

Örnek arkaplan betiği:

chrome.runtime.onMessage.addListener((request, sender, sendResponse) =>
{
if (request == "explain")
{
chrome.tabs.create({ url: "https://example.net/explanation" });
}
})

İletileri dinlemek için runtime.onMessage API kullanır. Bir "açıkla" ileti alındığında, bir sayfayı yeni bir sekmede açmak için tabs API kullanır.

Arka plan betiğini hata ayıklamak için uzantı ayrıntılarına gidip hizmet işçisini inceleyebilirsiniz, bu arka plan betiği ile geliştirici araçları açacaktır:

Seçenek sayfaları ve diğerleri

Tarayıcı uzantıları çeşitli türde sayfalar içerebilir:

  • Eylem sayfaları, uzantı simgesine tıklandığında bir ılır menüde gösterilir.
  • Uzantının yeni bir sekmede yükleyeceği sayfalar.
  • Seçenek Sayfaları: Bu sayfa, tıklanıldığında uzantının üstünde görüntülenir. Önceki manifeste bu sayfaya chrome://extensions/?options=fadlhnelkbeojnebcbkacjilhnbjfjca adresinden veya tıklayarak erişebildim:

Bu sayfalar arka plan sayfaları gibi kalıcı değildir, gerektiğinde dinamik içerik yüklerler. Bununla birlikte, bu sayfalar arka plan sayfasıyla bazı yetenekleri paylaşırlar:

  • İçerik Betikleriyle İletişim: Arka plan sayfasına benzer şekilde, bu sayfalar içerik betiklerinden iletiler alabilir, uzantı içinde etkileşimi kolaylaştırır.
  • Uzantıya Özgü API'lere Erişim: Bu sayfalar, uzantıya özgü API'lere kapsamlı erişime sahiptir, uzantı için tanımlanan izinlere tabidir.

permissions ve host_permissions

permissions ve host_permissions, tarayıcı uzantısının sahip olduğu izinleri (depolama, konum...) ve hangi web sayfalarında olduğunu belirtecek olan manifest.json dosyasındaki girişlerdir.

Tarayıcı uzantıları çok ırı yetkilendirilebileceğinden, kötü niyetli veya tehlikeye maruz kalan bir uzantı saldırganın duyarlı bilgileri çalması ve kullanıcıyı izlemesi için farklı yöntemler sağlayabilir.

Bu ayarların nasıl çalıştığını ve nasıl kötüye kullanılabileceğini kontrol edin:

{% content-ref url="browext-permissions-and-host_permissions.md" %} browext-permissions-and-host_permissions.md {% endcontent-ref %}

content_security_policy

Bir içerik güvenlik politikası ayrıca manifest.json içinde de belirtilebilir. Tanımlanmışsa, savunmasız olabilir.

Tarayıcı uzantısı sayfaları için varsayılan ayar oldukça kısıtlayıcıdır:

script-src 'self'; object-src 'self';

CSP ve olası bypass'lar hakkında daha fazla bilgi için şu adrese bakın:

{% content-ref url="../content-security-policy-csp-bypass/" %} content-security-policy-csp-bypass {% endcontent-ref %}

web_accessible_resources

Bir web sayfasının, örneğin bir .html sayfasının bir Tarayıcı Eklentisinin bir sayfasına erişebilmesi için, bu sayfanın manifest.json dosyasındaki web_accessible_resources alanında belirtilmesi gerekir.
Örnek:

{
...
"web_accessible_resources": [
{
"resources": [ "images/*.png" ],
"matches": [ "https://example.com/*" ]
},
{
"resources": [ "fonts/*.woff" ],
"matches": [ "https://example.com/*" ]
}
],
...
}

Bu sayfalara şu URL'den erişilebilir:

chrome-extension://<extension-id>/message.html

Genel uzantılarda uzantı kimliği erişilebilir:

Ancak, manifest.json parametresi use_dynamic_url kullanılıyorsa, bu kimlik dinamik olabilir.

{% hint style="success" %} Burada bir sayfa belirtilmiş olsa bile, İçerik Güvenlik Politikası sayesinde ClickJacking saldırısına karşı korunmuş olabilir. Bu nedenle, bir ClickJacking saldırısının mümkün olup olmadığını doğrulamadan önce bunu da kontrol etmeniz gerekmektedir (frame-ancestors bölümü). {% endhint %}

Bu sayfalara erişime izin verilmesi, bu sayfaları potansiyel olarak ClickJacking saldırısına karşı savunmasız hale getirir:

{% content-ref url="browext-clickjacking.md" %} browext-clickjacking.md {% endcontent-ref %}

{% hint style="success" %} Bu sayfaların yalnızca uzantı tarafından yüklenmesine ve rastgele URL'ler tarafından yüklenmesine izin verilmemesi, ClickJacking saldırılarını önleyebilir. {% endhint %}

{% hint style="danger" %} web_accessible_resources sayfaları ve uzantının diğer sayfaları da arka plan betiklerine erişebilir. 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çabilirsiniz, ancak yeni bir sekmeden uzantıdaki herhangi bir sayfaya erişmek mümkündür. 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. {% endhint %}

externally_connectable

Belgelerne göre, "externally_connectable" manifest özelliği, runtime.connect ve runtime.sendMessage aracılığıyla uzantınıza hangi uzantıların ve web sayfalarının bağlanabileceğini belirtir.

  • Eğer externally_connectable anahtarı uzantınızın manifestinde belirtilmemişse veya "ids": ["*"] olarak belirtilmişse, tüm uzantılar bağlanabilir, ancak hiçbir web sayfası bağlanamaz.
  • Eğer belirli kimlikler belirtilmişse, örneğin "ids": ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"], yalnızca bu uygulamalar bağlanabilir.
  • Eğer eşleşmeler belirtilmişse, bu web uygulamaları bağlanabilir:
"matches": [
"https://*.google.com/*",
"*://*.chromium.org/*",
  • Eğer boş olarak belirtilmişse: "externally_connectable": {}, hiçbir uygulama veya web bağlanamayacak.

Burada belirtilen daha az uzantı ve URL olduğunda, saldırı yüzeyi daha küçük olacaktır.

{% hint style="danger" %} Eğer XSS'e duyarlı veya ele geçirilebilir bir web sayfası externally_connectable içinde belirtilmişse, saldırgan mesajları doğrudan arka plan betiğine gönderebilecek, İçerik Betiği ve CSP'sini tamamen atlayarak.

Bu nedenle, bu çok güçlü bir atlatmadır.

Ayrıca, istemci yanlış bir uzantı yüklerse, hatta savunmasız uzantıyla iletişime izin verilmiyorsa, izin verilen bir web sayfasına XSS verisi enjekte edebilir veya hedeflenen bir alan üzerinde istekleri manipüle etmek için WebRequest veya DeclarativeNetRequest API'larını kötüye kullanabilir, bir sayfanın bir JavaScript dosyasının isteğini değiştirir. (Hedeflenen sayfadaki CSP bu saldırıları önleyebilir). Bu fikir bu yazıdan gelmektedir. {% endhint %}

İletişim özeti

Uzantı <--> Web Uygulaması

İçerik betiği ile web sayfası arasında mesajlaşmak için genellikle mesajlar kullanılır. Bu nedenle, web uygulamasında genellikle window.postMessage işlevine yapılan çağrılar bulunur ve içerik betiğinde window.addEventListener gibi dinleyiciler bulunur. Bununla birlikte, uzantı ayrıca Web Uygulaması'na Post Message göndererek iletişim kurabilir (ve bu nedenle web bunu beklemelidir) veya web sayfasını yeni bir betik yüklemeye zorlayabilir.

Uzantı içinde

Genellikle chrome.runtime.sendMessage işlevi, bir mesajı uzantı içinde göndermek için kullanılır (genellikle arka plan betiği tarafından işlenir) ve bunu almak ve işlemek için bir dinleyici chrome.runtime.onMessage.addListener çağrılarak bildirilir.

Tek bir mesaj göndermek yerine kalıcı bir bağlantıya sahip olmak için chrome.runtime.connect() kullanmak da mümkündür, aşağıdaki örnekte olduğu gibi mesajlar göndermek ve almak için kullanılabilir:

chrome.runtime.connect() örneği ```javascript var port = chrome.runtime.connect();

// Listen for messages from the web page window.addEventListener("message", (event) => { // Only accept messages from the same window if (event.source !== window) { return; }

// Check if the message type is "FROM_PAGE" if (event.data.type && (event.data.type === "FROM_PAGE")) { console.log("Content script received: " + event.data.text); // Forward the message to the background script port.postMessage({ type: 'FROM_PAGE', text: event.data.text }); } }, false);

// Listen for messages from the background script port.onMessage.addListener(function(msg) { console.log("Content script received message from background script:", msg); // Handle the response message from the background script });

</details>

Ayrıca, bir arka plan betiğinden belirli bir sekmede bulunan bir içerik betiğine mesaj göndermek mümkündür, burada mesajı göndermek için **`chrome.tabs.sendMessage`** fonksiyonunu çağırmanız gerekecektir ve mesajı göndermek için **sekme kimliğini** belirtmeniz gerekecektir.

### `externally_connectable` izin verileninden uzantıya

**`externally_connectable` yapılandırmasında izin verilen web uygulamaları ve harici tarayıcı uzantıları**, şu şekilde istek gönderebilir:
```javascript
chrome.runtime.sendMessage(extensionId, ...

Nerede uzantı Kimliği'nin belirtilmesi gerektiğinde.

Web ↔︎ İçerik Betiği İletişimi

İçerik betiklerinin çalıştığı ortamlar ve ana sayfaların bulunduğu ortamlar birbirinden ayrılmış olup, izolasyonu sağlar. Bu izolasyona rağmen, her ikisi de sayfanın Belge Nesne Modeli (DOM) ile etkileşimde bulunma yeteneğine sahiptir, ortak bir kaynak. Ana sayfanın içerik betiği ile iletişim kurabilmesi veya içerik betiği aracılığıyla dolaylı olarak uzantı ile iletişim kurabilmesi için, her iki tarafın da erişebildiği DOM'u iletişim kanalı olarak kullanması gerekmektedir.

Mesaj Gönderme

{% code title="içerik-betiği.js" %}

// This is like "chrome.runtime.sendMessage" but to maintain the connection
var port = chrome.runtime.connect();

window.addEventListener("message", (event) => {
// We only accept messages from ourselves
if (event.source !== window) {
return;
}

if (event.data.type && (event.data.type === "FROM_PAGE")) {
console.log("Content script received: " + event.data.text);
// Forward the message to the background script
port.postMessage(event.data.text);
}
}, false);

{% endcode %}

{% code title="örnek.js" %}

document.getElementById("theButton").addEventListener("click", () => {
window.postMessage(
{type : "FROM_PAGE", text : "Hello from the webpage!"}, "*");
}, false);

{% endcode %}

Güvenli bir Post Message iletişimi, alınan iletiyi doğrulamalıdır, bunu şu şekilde kontrol edebiliriz:

  • event.isTrusted: Bu, yalnızca olayın bir kullanıcı eylemi tarafından tetiklendiğinde True olur
  • İçerik betiği, kullanıcının belirli bir eylem gerçekleştirmesini bekliyor olabilir
  • köken alanı: yalnızca belirli bir alan adı beyaz listesinden bir ileti bekliyor olabilir.
  • Eğer bir regex kullanılıyorsa, çok dikkatli olunmalıdır
  • Kaynak: received_message.source !== window iletişim Betiğin dinlediği pencereden geldiğini kontrol etmek için kullanılabilir.

Önceki kontroller, gerçekleştirilmiş olsa bile, savunmasız olabilir, bu nedenle aşağıdaki sayfada potansiyel Post Message atlamalarını kontrol edin:

{% content-ref url="../postmessage-vulnerabilities/" %} postmessage-vulnerabilities {% endcontent-ref %}

Iframe

Başka bir iletişim yolu olası bir şekilde Iframe URL'leri aracılığıyla olabilir, bir örnek bulabilirsiniz:

{% content-ref url="browext-xss-example.md" %} browext-xss-example.md {% endcontent-ref %}

DOM

Bu "tam olarak" bir iletişim yolu değil, ancak web ve içerik betiği web DOM'a erişebilir. Dolayısıyla, eğer içerik betiği bazı bilgileri okuyorsa, web DOM'a güveniyorsa, web bu verileri değiştirebilir (çünkü web'e güvenilmemeli veya web XSS'e duyarlı olabilir) ve İçerik Betiği tehlikeye girebilir.

Ayrıca, bir DOM tabanlı XSS örneğiyle bir tarayıcı uzantısını tehlikeye atmak için bir örnek bulabilirsiniz:

{% content-ref url="browext-xss-example.md" %} browext-xss-example.md {% endcontent-ref %}

İçerik Betiği ↔︎ Arkaplan Betiği İletişimi

Bir İçerik Betiği, runtime.sendMessage() veya tabs.sendMessage() fonksiyonlarını kullanarak bir kereye mahsus JSON-serileştirilebilir bir ileti gönderebilir.

Yanıtı işlemek için dönen Promise'ı kullanın. Ancak, geriye dönük uyumluluk için hala bir geri çağrıyı son argüman olarak iletebilirsiniz.

Bir içerik betiğinden bir istek göndermek şöyle görünür:

(async () => {
const response = await chrome.runtime.sendMessage({greeting: "hello"});
// do something with response here, not outside the function
console.log(response);
})();

Uzantı'dan bir istek gönderme (genellikle bir arka plan betiği). Seçilen sekmedeki içerik betiğine mesaj gönderme örneği:

// From https://stackoverflow.com/questions/36153999/how-to-send-a-message-between-chrome-extension-popup-and-content-script
(async () => {
const [tab] = await chrome.tabs.query({active: true, lastFocusedWindow: true});
const response = await chrome.tabs.sendMessage(tab.id, {greeting: "hello"});
// do something with response here, not outside the function
console.log(response);
})();

Alıcı tarafında, mesajı işlemek için bir runtime.onMessage olay dinleyicisi kurmanız gerekmektedir. Bu, içerik betiği veya uzantı sayfasından aynı şekilde görünmektedir.

// From https://stackoverflow.com/questions/70406787/javascript-send-message-from-content-js-to-background-js
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
console.log(sender.tab ?
"from a content script:" + sender.tab.url :
"from the extension");
if (request.greeting === "hello")
sendResponse({farewell: "goodbye"});
}
);

Öne çıkarılan örnekte, sendResponse() senkron bir şekilde yürütüldü. sendResponse()'un asenkron yürütülmesi için onMessage olay işleyicisini değiştirmek için return true; eklemek hayati önem taşır.

Birden fazla sayfanın onMessage olaylarını alacağı senaryolarda, belirli bir olay için sendResponse()'u yürüten ilk sayfa yanıtı etkili bir şekilde iletebilecek tek sayfa olacaktır. Aynı olaya yönelik herhangi bir sonraki yanıt dikkate alınmayacaktır.

Yeni uzantılar oluşturulurken, tercih, geri aramalar yerine söz verilere doğru olmalıdır. Geri aramaların kullanımıyla ilgili olarak, sendResponse() fonksiyonu yalnızca senkron bağlam içinde doğrudan yürütülüyorsa veya olay işleyicisi asenkron bir işlemi belirtiyorsa geçerli kabul edilir. Hiçbir işleyicinin true döndürmemesi durumunda veya sendResponse() fonksiyonu bellekten kaldırılırsa (çöp toplama), sendMessage() fonksiyonuyla ilişkilendirilen geri arama varsayılan olarak tetiklenecektir.

Bellek/Kod/Pano'da Hassas Bilgiler

Bir Tarayıcı Uzantısı, belleğinde hassas bilgiler saklıyorsa, bu bilgiler dökülebilir (özellikle Windows makinelerinde) ve bu bilgiler için arama yapılabilir.

Bu nedenle, Tarayıcı Uzantısının belleği güvenli kabul edilmemeli ve kimlik bilgileri veya mnemonik ifadeler gibi hassas bilgiler saklanmamalıdır.

Tabii ki, kod içine hassas bilgiler koymayın, çünkü bu bilgiler genel olacaktır.

Tarayıcıdan belleği dökmek için işlem belleğini dökme veya tarayıcı uzantısının ayarlarına gitmek için İçeriği İncele -> Bellek bölümünde Anlık Görüntü Al ve hassas bilgileri aramak için CTRL+F tıklayın.

Dahası, mnemonik anahtarlar veya şifreler gibi son derece hassas bilgilerin panoya kopyalanmasına izin verilmemeli (veya en azından birkaç saniye içinde panodan kaldırılmalıdır), çünkü panoyu izleyen işlemler bunları alabilir.

Bir Uzantının Tarayıcıya Yüklenmesi

  1. Tarayıcı Uzantısını indirin ve açın
  2. chrome://extensions/ adresine gidin ve Geliştirici Modu'nu etkinleştirin
  3. Paketlenmemiş Yükleyin düğmesine tıklayın

Firefox'da about:debugging#/runtime/this-firefox adresine gidin ve Geçici Eklenti Yükle düğmesine tıklayın.

Mağazadan kaynak kodunu alma

Bir Chrome uzantısının kaynak kodu çeşitli yöntemlerle elde edilebilir. Aşağıda her seçenek için detaylııklamalar ve talimatlar bulunmaktadır.

Komut Satırı Aracılığıyla ZIP Olarak Uzantıyı İndirme

Bir Chrome uzantısının kaynak kodu, komut satırını kullanarak ZIP dosyası olarak indirilebilir. Bu, curl'ün belirli bir URL'den ZIP dosyasını almasını ve ardından ZIP dosyasının içeriğini bir dizine çıkarmasını içerir. İşte adımlar:

  1. "extension_id"'yi gerçek uzantı kimliğiyle değiştirin.
  2. Aşağıdaki komutları çalıştırın:
extension_id=your_extension_id   # Replace with the actual extension ID
curl -L -o "$extension_id.zip" "https://clients2.google.com/service/update2/crx?response=redirect&os=mac&arch=x86-64&nacl_arch=x86-64&prod=chromecrx&prodchannel=stable&prodversion=44.0.2403.130&x=id%3D$extension_id%26uc"
unzip -d "$extension_id-source" "$extension_id.zip"

CRX Viewer websitesini kullanın

https://robwu.nl/crxviewer/

CRX Viewer uzantısını kullanın

Başka bir pratik yöntem, açık kaynaklı bir proje olan Chrome Extension Source Viewer'ı kullanmaktır. Bu uzantıyı Chrome Web Mağazası'ndan yükleyebilirsiniz. Görüntüleyicinin kaynak kodu GitHub deposunda bulunmaktadır.

Yerel olarak yüklenen uzantının kaynağını görüntüleyin

Yerel olarak yüklenen Chrome uzantıları da incelenebilir. İşte yapmanız gerekenler:

  1. "Profile Path" alanını bulmak için chrome://version/ adresine giderek Chrome yerel profil dizinine erişin.
  2. Profil dizini içindeki Extensions/ alt klasörüne gidin.
  3. Bu klasör genellikle okunabilir bir formatta kaynak kodlarıyla birlikte tüm yüklenmiş uzantıları içerir.

Uzantıları tanımlamak için ID'lerini isimlerine eşleyebilirsiniz:

  • Her uzantının ID'lerini görmek için about:extensions sayfasında Geliştirici Modunu etkinleştirin.
  • Her uzantının klasörü içindeki manifest.json dosyası, uzantıyı tanımanıza yardımcı olan okunabilir bir name alanı içerir.

Bir Dosya Arşivleyici veya Açıcı Kullanın

Chrome Web Mağazasına gidin ve uzantıyı indirin. Dosyanın uzantısı .crx olacaktır. Dosya uzantısını .crx'den .zip'e değiştirin. ZIP dosyasının içeriğini çıkarmak için WinRAR, 7-Zip vb. gibi herhangi bir dosya arşivleyicisini kullanın.

Chrome'da Geliştirici Modunu Kullanın

Chrome'u açın ve chrome://extensions/ adresine gidin. Sağ üstte "Geliştirici modunu" etkinleştirin. "Paketlenmemiş uzantıyı yükle..." seçeneğine tıklayın. Uzantının dizinine gidin. Bu işlem kaynak kodu indirmez, ancak zaten indirilmiş veya geliştirilmiş bir uzantının kodunu görüntülemek ve değiştirmek için kullanışlıdır.

Güvenlik Denetim Listesi

Tarayıcı Uzantıları sınırlı saldırı yüzeyine sahip olsa da, bazıları zayıflıklar veya potansiyel sıkılaştırma iyileştirmeleri içerebilir. En yaygın olanlar şunlardır:

  • Mümkün olduğunca az permissions isteği yapın.
  • Mümkün olduğunca az host_permissions yapın.
  • Güçlü bir content_security_policy kullanın.
  • externally_connectable'ı mümkün olduğunca sınırlayın, gerekli değilse ve mümkünse varsayılan olarak bırakmayın, {} belirtin.
  • Burada XSS'ye veya ele geçirmeye açık olan bir URL belirtilmişse, bir saldırganın arka plan betiklerine doğrudan mesaj göndermesine izin verilecektir. Çok güçlü bir atlatma.
  • Mümkün olduğunca web_accessible_resources'ı sınırlayın, mümkünse boş bırakın.
  • Eğer web_accessible_resources yoksa, ClickJacking için kontrol edin.
  • Eğer uzantıdan web sayfasına herhangi bir iletişim varsa, iletişimde oluşan XSS zafiyetlerini kontrol edin.
  • Post Mesajları kullanılıyorsa, Post Mesaj zafiyetlerini kontrol edin.
  • İçerik Betiği DOM detaylarına erişiyorsa, bunların web tarafından değiştirilmesi durumunda XSS tanımlamayın.
  • Bu iletişimin aynı zamanda İçerik Betiği -> Arka plan betiği ile iletişimde olması durumunda özel bir vurgu yapın.
  • Tarayıcı Uzantısı kodunun içinde hassas bilgiler saklanmamalıdır.
  • Tarayıcı Uzantısı belleğinde hassas bilgiler saklanmamalıdır.

Araçlar

Tarnish

  • Sağlanan bir Chrome web mağazası bağlantısından herhangi bir Chrome uzantısını çeker.
  • manifest.json görüntüleyici: uzantının manifest dosyasının JSON düzgünleştirilmiş bir sürümünü basitçe görüntüler.
  • Parmakizi Analizi: web_accessible_resources tespiti ve Chrome uzantısı parmakizi JavaScript'inin otomatik oluşturulması.
  • Potansiyel Clickjacking Analizi: web_accessible_resources yönergesi ayarlanmış uzantı HTML sayfalarının tespiti. Bu sayfalar, sayfaların amacına bağlı olarak clickjacking'e karşı potansiyel olarak savunmasız olabilir.
  • İzin Uyarıları Görüntüleyici: bir kullanıcının uzantıyı yüklemeye çalıştığında görüntülenecek tüm Chrome izin uyarılarının bir listesini gösterir.
  • Tehlikeli Fonksiyonlar: bir saldırgan tarafından kötüye kullanılabilecek tehlikeli fonksiyonların konumunu gösterir (örneğin, innerHTML, chrome.tabs.executeScript gibi fonksiyonlar).
  • Giriş Noktaları: uzantının kullanıcı/dış giriş aldığı yerleri gösterir. Bu, bir uzantının yüzey alanını anlamak ve uzantıya kötü niyetli şekilde oluşturulmuş veri göndermek için potansiyel noktaları aramak için kullanışlıdır.
  • Tehlikeli Fonksiyonlar ve Giriş Noktaları tarayıcıları için oluşturulan uyarılar şunları içerir:
  • Uyarıya neden olan ilgili kod parçası ve satır.
  • Sorunun açıklaması.
  • Kodu içeren tam kaynak dosyasını görüntülemek için "Dosyayı Görüntüle" düğmesi.
  • Uyarı verilen dosyanın yolu.
  • Uyarı verilen dosyanın tam Chrome uzantısı URI'si.
  • Dosyanın türü, arka plan sayfası betiği, İçerik Betiği, Tarayıcı Eylemi vb. gibi.
  • Eğer zafiyetli satır bir JavaScript dosyasında ise, dahil edildiği tüm sayfaların yolları ve bu sayfaların türleri, ve web_accessible_resource durumu.
  • İçerik Güvenlik Politikası (CSP) analizcisi ve atlatma kontrolcüsü: Bu, uzantınızın CSP'sindeki zayıflıkları belirleyecek ve beyaz listelenmiş CDN'ler nedeniyle CSP'nizi atlamak için potansiyel yolları aydınlatacaktır.
  • Bilinen Zayıf Kütüphaneler: Bu, bilinen-zayıf JavaScript kütüphanelerinin kullanımını kontrol etmek için Retire.js kullanır.
  • Uzantıyı indirin ve biçimlendirilmiş sürümleri indirin.
  • Orijinal uzantıyı indirin.
  • Uzantının güzelleştirilmiş sürümünü indirin (otomatik olarak düzeltilmiş HTML ve JavaScript).
  • Tarama sonuçlarının otomatik önbelleğe alınması, bir uzantı taraması yapmak ilk kez biraz zaman alabilir. Ancak ikinci kez, uzantının güncellenmediği varsayıldığında sonuçlar önbelleğe alındığı için neredeyse anlık olacaktır.
  • Bağlantılabilir Rapor URL'leri, Tarnish tarafından oluşturulan bir uzantı raporuna başka birine kolayca bağlantı sağlar.

Neto

Proje Neto, Firefox ve Chrome gibi popüler tarayıcılar için tarayıcı eklentilerinin ve uzantılarının gizli özelliklerini analiz etmek ve açığa çıkarmak için tasarlanmış Python 3 paketidir. Bu paket, paketlenmiş dosyaları açmak için süreci otomatikleştirir ve bu özellikleri uzantıdan çıkarmak için ilgili kaynaklardan (örneğin manifest.json, yerelleştirme klasörleri veya JavaScript ve HTML kaynak dosyaları) bu özellikleri çıkarmak için süreci otomatikleştirir.

Referanslar

htARTE (HackTricks AWS Red Team Expert) ile sıfırdan kahramana AWS hacklemeyi öğrenin

HackTricks'i desteklemenin diğer yolları: