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

Песочница для JavaScript-стадий декодирования/кодирования; кодек Group-IB из коробки.

Скрипт декодирования — это обычный JavaScript, объявляющий decode(input) и/или encode(input). После сохранения он регистрируется как стадия script:<id> в конвейере декодирования конкретного эндпоинта, наряду со встроенными стадиями (base64, gzip, msgpack, …). Используйте скрипты для проприетарных кодеков тела, которые не покрывают встроенные режимы: зависящие от позиции сдвиги символов, XOR-маски, собственные алфавиты base64, вендорные CRC-обёртки.

[!WARNING] Скрипты реверс-инжинирят вендорные антифрод-кодеки и кодеки бот-защиты. Запускайте их только на трафике систем, которые вам разрешено тестировать.

Написание скрипта

Откройте Settings → Custom decode scripts → New script. Редактор открывается с предзаполненным примером кодека XOR-0x42. Скрипт — это обычный JavaScript-код; объявления верхнего уровня function decode(input) и function encode(input) подхватываются автоматически. Требуется хотя бы одно из двух — скрипт без обоих будет отклонён.

function decode(input) {
  var bytes = helpers.textToBytes(input);
  var out = new Uint8Array(bytes.length);
  for (var index = 0; index < bytes.length; index++) {
    out[index] = bytes[index] ^ 0x42;
  }
  return helpers.bytesToText(out);
}

Аргумент input — это текст, полученный от предыдущей стадии конвейера. Возвращайте строку, Uint8Array (декодируется как UTF-8) или любое другое значение (сериализуется через JSON.stringify с отступом в 2 пробела).

Аргумент helpers предоставляет утилиты для работы с байтами и кодировками:

ХелперНазначение
helpers.textToBytes(text) / helpers.bytesToText(bytes)кодирование / декодирование UTF-8
helpers.bytesToBase64(bytes) / helpers.base64ToBytes(value)base64 (на входе допускаются base64url и пробельные символы)
helpers.bytesToHex(bytes) / helpers.hexToBytes(hex)кодирование / декодирование hex
helpers.crc32(bytes | text)CRC-32 (IEEE, полином 0xedb88320)
helpers.base64Alphabetстрока стандартного алфавита base64

Тестирование и сохранение

В редакторе скриптов вставьте пример полезной нагрузки в Test input, затем нажмите Run decode или Run encode, чтобы выполнить соответствующее направление локально и вывести результат (или Error: …). Нажмите Store script, чтобы сохранить его. Скрипты хранятся в базе данных бэкенда через /api/decode-scripts; размер исходного кода ограничен 64 КиБ, обязательны и имя, и исходный код. Сохранённые скрипты появляются в списке панели и могут быть отредактированы в любой момент; пользовательские скрипты можно удалить кнопкой корзины.

[!NOTE] Песочница — это кооперативная изоляция, а не граница безопасности. Скрипты выполняются внутри области видимости new Function, где опасные глобальные объекты (window, document, globalThis, self, fetch, XMLHttpRequest, WebSocket, localStorage, sessionStorage, indexedDB, navigator, location, Function и прочие) затенены до undefined, а обёртка выполняется в строгом режиме. eval и arguments затенить невозможно. Скрипты — это локальный пользовательский контент с тем же уровнем доверия, что и пользовательский скрипт Frida: запускайте только тот код, который вы написали или проверили сами.

Использование скрипта как стадии конвейера

Зарегистрированные скрипты появляются в редакторе конвейера декодирования — откройте эндпоинт в каталоге API (/docs/ru/api-re/catalog/) и разверните его панель Decode pipeline. В выпадающем списке Add request step / Add response step скрипты перечислены в группе Custom scripts как script: <name>; выбор одного из них добавляет стадию script:<id>. Стадии выполняются по порядку, каждая передаёт результат следующей, а панель предпросмотра отображает декодированный пример с цепочкой шагов в строке происхождения. Конвейер всегда вызывает направление decode скрипта; сбойная стадия (брошенная ошибка или скрипт без функции decode) прерывает конвейер и сообщает об ошибке.

Направление encode — зеркальное отражение: на входе читаемый текст, на выходе тело в wire-формате. Проверьте его кнопкой Run encode на панели скрипта; оно предназначено для формирования тел replay против эндпоинтов с искажённым телом (/docs/ru/replay/workbench/).

Встроенный пакетный кодек Group-IB

Traffic Jam поставляется с эталонной реализацией пакетного антифрод-кодека Group-IB (com.group_ib.sdk.core, из реверса goldapple) в виде первого встроенного плагина. Он встроен в бэкенд (builtin_decode_scripts/groupib_packet.js) и при старте заносится в базу данных с id groupib-packet и именем Group-IB packet (mangle/unmangle + CRC32); в Settings он отмечен бейджем built-in и не может быть удалён, хотя его исходный код можно редактировать (сидирование никогда не перезаписывает существующую строку). TypeScript-копия во фронтенде служит фолбэком на случай, если сервер ещё не сидировал его.

Структура пакета:

base64("004")  +  base64(mangled JSON)  +  base64(big-endian CRC32 of the mangled bytes)
   "MDA0"

Искажение (mangle) — это зависящий от позиции сдвиг символов: каждая кодовая точка сдвигается на table[index % 26] по модулю размера своего диапазона Unicode, в четырёх диапазонах (ASCII, 2-байтовый, 3-байтовый BMP и private-use/суррогатный). decode удаляет пробельные символы, требует обёртку MDA0, проверяет CRC-32 (бросая Group-IB CRC mismatch при подмене) и восстанавливает JSON из искажённого вида. encode искажает, вычисляет CRC и повторно оборачивает — так что decode(encode(x)) === x.

Поскольку плагин — обычный скрипт, он появляется в выпадающем списке конвейера как script:groupib-packet, как и любой пользовательский скрипт.

Режим декодера тела groupib

Отдельно от скриптового плагина встроенный плагин goldapple также регистрирует режим декодирования тела groupib (тот же кодек, но предоставленный как декодер тела плагина, а не встроенный в ядро):

РежимМеткаНаправление
groupibGroupIBпакет → читаемый JSON

Он доступен как режим просмотра тела в инспекторе (/docs/ru/analysis/inspector/) и как шаг конвейера. Он также участвует в автоопределении: сырое тело, чья компактная форма начинается с 004 или MDA0 и декодируется в структурированный текст, распознаётся автоматически. Скриптовый плагин и этот режим реализуют один и тот же кодек; режим — это быстрый путь для просмотра и автоопределения, а скрипт — редактируемая, компонуемая в конвейере форма.

Документация Traffic Jam. Собрано с помощью Hugo.