Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
fpicker — Набор инструментов для внутрипроцессного фаззинга на основе Frida с прокси AFL++, отдельными активным/пассивным режимами и обменом через разделяемую память для высокопроизводительного поиска уязвимостей с управлением покрытием на различных платформах. | Kitploit
Инструменты/GitHubGitHub/ttdennis/fpicker
Динамический анализ (песочница)Анализ уязвимостейЭксплуатацияФаззингАнализ Бинарных Файлов
GitHubttdennis/fpicker

fpicker

Набор инструментов для внутрипроцессного фаззинга на основе Frida с прокси AFL++, отдельными активным/пассивным режимами и обменом через разделяемую память для высокопроизводительного поиска уязвимостей с управлением покрытием на различных платформах.

Репозиторий
296341 год назадПроверено Kitploit

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

fpicker

Логотип Fpicker

fpicker — это набор инструментов для фаззинга на основе Frida, который предлагает различные режимы фаззинга для внутрипроцессного фаззинга, такие как режим AFL++ или пассивный режим трассировки. Он должен работать на всех платформах, поддерживаемых Frida.

  • Инструкция по установке
  • Сборка и запуск
  • Создание обвязки для фаззинга
  • Режимы и конфигурация

Некоторую справочную информацию, а также мысли и идеи, стоящие за fpicker, можно найти в статье в блоге, которую я написал.

Fpicker основан на предыдущих разработках ToothPicker, созданных в ходе моей магистерской диссертации. Большая часть fpicker была разработана в рабочее время у моего работодателя (ERNW).

Требования и установка

Необходимо для запуска fpicker:

  • frida_compile для компиляции скрипта обвязки в один JS-файл
  • frida-core-devkit для соответствующей платформы, доступный в релизах Frida на GitHub.
    • В зависимости от целевой платформы сохраните библиотеку как libfrida-core-ios.a, libfrida-core-macos.a или libfrida-core-linux.a.
    • То же самое касается заголовочных файлов (frida-core.h). Сохраните их как frida-core-linux.h или frida-core-ios.h в зависимости от платформы.
    • Makefile был сделан таким образом, чтобы вы могли собирать для разных систем на одной системе (например, вашей хост-системе и телефоне).
    • Если вы предпочитаете использовать конкретную версию, отредактируйте Makefile соответствующим образом.
    • Чтобы обновиться до последней версии, просто выполните update_frida_version.sh перед сборкой.

Требуется только при работе в режиме AFL++:

  • AFL++
    • на macOS:
      • Соберите с CFLAGS="-DUSEMMAP=1".
    • на iOS:
      • Соберите с CFLAGS="-DUSEMMAP=1 -DTARGET_OS_IOS".

Сборка и запуск

Fpicker можно собрать для macOS, iOS или Linux. Makefile в настоящее время поддерживает сборку только для iOS на macOS, но вполне возможно собрать fpicker с использованием инструментария iOS на Linux.

В зависимости от желаемой цели выполните:

root@kitploit:~
make fpicker-macos
make fpicker-ios
make fpicker-linux

для сборки fpicker.

После сборки fpicker необходимо также собрать обвязку для фаззинга:

Примеры различных вариантов фаззинга см. в папке examples. Общий подход следующий:

  • Создайте пользовательскую обвязку для цели (например, examples/test/test.js) (см. здесь для получения дополнительной информации об обвязках)
  • Скомпилируйте пользовательскую обвязку с помощью frida-compile: frida-compile test.js -o harness.js

Теперь fpicker может начать фаззинг. Точная команда сильно зависит от конфигурации и настройки. Ниже приведено несколько примеров. Они в основном соответствуют примерам из папки examples.

  • Запуск fpicker в качестве прокси AFL++, подключающегося к целевому процессу для фаззинга определённой функции в процессе:
root@kitploit:~
afl-fuzz -i examples/test-network/in -o ./examples/test-network/out -- \\
    ./fpicker --fuzzer-mode afl -e attach -p test-network -f ./examples/test-network/harness.js
  • Запуск fpicker в автономном режиме, подключающегося к серверу и запускающего клиентскую программу для отправки входных данных фаззинга:
root@kitploit:~
./fpicker --fuzzer-mode standalone -e attach -p server-process -f harness.js --input-mode cmd \\
    --command "./client-send @@" -i indir -o outdir
  • Запуск fpicker в автономном режиме, подключающегося к серверу, фаззинг внутри процесса с пользовательской командой мутатора:
root@kitploit:~
./fpicker --fuzzer-mode active --communication-mode shm -e attach -p server-process -f harness.js \\
    -i indir -o outdir --standalone-mutator cmd --mutator-command "radamsa"
  • Запуск fpicker в пассивном режиме, подключающегося к серверу, сбор покрытия и полезных нагрузок:
root@kitploit:~
./fpicker --fuzzer-mode passive --communication-mode send -e attach -p server-process -o outdir -f harness.js
  • Запуск fpicker в автономном режиме, подключающегося к запущенному процессу на удалённом устройстве, фаззинг внутри процесса с пользовательской командой мутатора:
root@kitploit:~
./fpicker --fuzzer-mode active -e attach -p test -D remote -o examples/test/out/ -i examples/test/in/ \\
    -f fuzzer-agent.js --standalone-mutator cmd --mutator-command "radamsa"

Создание обвязки для фаззинга

Каждая цель требует собственной обвязки для фаззинга. Самая важная часть этой обвязки — определение точки входа для Stalker от Frida, которая фактически определяет, в каком месте вставляется инструментация. В режиме in-process это просто. Функция обычно является той, которая вызывается на каждой итерации фаззинга. Однако это может быть и другая функция.

Минималистичная реализация обвязки (в режиме command) может выглядеть так:

root@kitploit:~
// Import the fuzzer base class
const Fuzzer = require("harness/fuzzer.js");

// The custom fuzzer needs to subclass the Fuzzer class to work properly
class TestFuzzer extends Fuzzer.Fuzzer {
    constructor() {
        // The constructor needs to specify the address of the targeted function and a NativeFunction
        // object that can later be called by the fuzzer.

        const FUZZ_FUNCTION_ADDR = Module.getExportByName(null, "FUZZ_FUNCTION");
        const FUZZ_FUNCTION = new NativeFunction(
            FUZZ_FUNCTION_ADDR,
            "void", ["pointer", "int64"], {
        });

        super("test", FUZZ_FUNCTION_ADDR, FUZZ_FUNCTION);
    }
}

const f = new TestFuzzer();
exports.fuzzer = f;

Эта обвязка настраивает инструментацию на отслеживание функции FUZZ_FUNCTION. Инструментация начинается при входе в эту функцию и завершается при её возврате. Эту функцию следует выбирать тщательно, так как она ресурсоёмка, и чем больше (потенциально неважных) частей процесса инструментировано, тем медленнее становится фаззер. Конечно, это компромисс между скоростью и желаемым покрытием. Кроме того, в настоящее время фаззер поддерживает только функции, которые вызываются только один раз за одну итерацию фаззинга, т.е. функция не должна вызываться более одного раза в течение одного тестового случая, иначе информация о покрытии может стать ненадёжной.

При использовании режима in-process в скрипте фаззера требуется ещё одна функция: метод fuzz. Он будет вызываться на каждой итерации. Он будет вызван с двумя параметрами: указателем на буфер и длиной буфера. Наша примерная целевая функция принимает два параметра: указатель на буфер и его длину. Таким образом, мы можем просто передать параметры, которые получаем в методе fuzz.

root@kitploit:~
fuzz(payload, len) {
    this.target_function(payload, parseInt(len));
}

В пассивном режиме необходимо указать обратный вызов, который обрабатывает требуемые данные. Фаззер ожидает получить буфер полезной нагрузки и его длину. В зависимости от целевой функции, которую фаззят, эти данные необходимо извлечь. В следующем примере у нас снова есть функция с двумя параметрами: указатель на буфер и его длина. Параметр args содержит все потенциальные параметры, которые получает целевая функция, поэтому параметр длины (в нашем случае второй) можно получить через args[1]. Затем мы считываем буфер как Uint8Array и отправляем его обратно фаззеру с помощью метода sendPassiveCorpus.

root@kitploit:~
passiveCallback(args) {
    const len = args[1];
    const data = new Uint8Array(Memory.readByteArray(args[0], parseInt(len)));

    // this encodes the data and sends it back to the fuzzer
    this.sendPassiveCorpus(data, len);
}

Если цель требует некоторой подготовки перед началом фаззинга, fpicker предоставляет метод prepare, который вызывается во время инициализации фаззера. Подготовка может включать установку состояния, например, создание экземпляра объекта. Такая функция подготовки может выглядеть следующим образом:

root@kitploit:~
prepare() {
  // the object can be attached to the fuzzer instance so that it can be used within the
  // fuzz() method later on.
  this.required_object = call_native_function_that_creates_object();
}

Режимы и конфигурация

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

Режим фаззера

Fpicker имеет три различных режима фаззинга: режим AFL++, автономный активный режим и автономный пассивный режим:

  • Режим AFL++: В режиме AFL++ fpicker действует как прокси между AFL++ и целевым процессом. Используя возможности инструментации Frida, битовая карта покрытия AFL заполняется во время фаззинга цели входными данными, сгенерированными AFL++.

  • Автономный активный режим: В автономном активном режиме фаззер использует сводки вызовов Stalker от Frida для сбора покрытия в виде базовых блоков, которые выполняются в течение итерации. Это не ново и ранее реализовывалось в различных формах. Однако в сочетании с некоторыми другими настройками фаззера это может дать различные преимущества. Это также хорошая альтернатива, если AFL++ неприменим или нежелателен в данной среде или случае.

  • Автономный пассивный режим: Пассивный режим — это скорее трассировщик, чем фаззер. По сути, он делает то же самое, что и автономный активный режим. Однако он не отправляет собственные входные данные. Он просто подключается к определённой функции и собирает покрытие. Как только обнаруживается новое покрытие, сохраняются как покрытие, так и входные данные.

Режим ввода

Хотя fpicker в основном разработан как внутрипроцессный фаззер, он также поддерживает фаззинг через внешнюю команду. Для этого fpicker предлагает два режима ввода.

  • Режим ввода «Внутри процесса»: В режиме ввода «внутри процесса» обвязка напрямую вызывает указанную функцию в целевом процессе. Фаззер отправляет полезную нагрузку обвязке, а обвязка подготавливает полезную нагрузку таким образом, чтобы можно было вызвать целевую функцию.

  • Режим ввода CMD: В режиме ввода команды полезная нагрузка перенаправляется внешней команде. Это полезно, если подготовка параметров или другого состояния при прямом вызове целевой функции слишком сложна. Сбор покрытия по-прежнему должен быть привязан к определённой функции. Возможно, есть клиент, которому можно передать полезную нагрузку, которая затем запускает целевую функцию.

Режим связи

Режим связи определяет, как внедрённая обвязка взаимодействует с фаззером. Это во многом зависит от целевого приложения. Frida предоставляет API для отправки и получения сообщений от внедрённого агентского скрипта. Этот тип связи довольно затратен. Одним из факторов является то, что передаваемое сообщение необходимо кодировать в JSON. Поэтому отправка двоичных данных проста. В связи с этим fpicker предлагает второй режим связи — через разделяемую память. Однако это работает только в том случае, если можно установить разделяемую память между фаззером и целевым приложением, что означает, что этот режим нельзя использовать, когда цель подключена к хосту фаззера через USB. В режиме ввода CMD режим связи относится только к тому, как информация о покрытии передаётся обратно фаззеру, а не к тому, как отправляется полезная нагрузка, поскольку это делегируется внешней команде.

  • Режим связи Send: В режиме связи отправки полезная нагрузка отправляется с использованием механизма вызова RPC от Frida. Это позволяет фаззеру выполнять функцию JavaScript внутри внедрённого скрипта обвязки. Эта функция внутри обвязки может затем выполнить все необходимые приготовления для вызова целевой функции. После возврата из целевой функции сбор покрытия прекращается, и обвязка может сообщить фаззеру, что итерация завершена. Это делается путём отправки информации о покрытии обратно фаззеру с помощью API отправки Frida.

  • Режим связи SHM: В режиме связи через разделяемую память фаззер и скрипт обвязки взаимодействуют через разделяемую память и семафоры. Буфер в разделяемой памяти используется для отправки полезной нагрузки и получения информации о покрытии. Вместо отправки и получения два компонента используют ожидание и отправку сигнала семафору. В зависимости от системы и цели это даёт значительный прирост производительности. Особенно потому, что двоичная полезная нагрузка записывается в память один раз и не требует кодирования, декодирования или копирования в другие области памяти. К сожалению, этот режим иногда приводит к низкой стабильности при работе с AFL++. Пока неясно, почему.

Режим выполнения

Режим выполнения может быть spawn или attach. Это довольно очевидно. fpicker может либо подключиться к запущенному процессу, либо породить процесс. Одно из основных различий между двумя режимами заключается в том, что в случае сбоя подключённой цели fpicker не будет пытаться перезапустить её.

Автономный мутатор

В автономном режиме fpicker предлагает три различные стратегии мутации входных данных. Если говорить мягко, мутация входных данных, безусловно, имеет много возможностей для улучшения.

  • Автономный мутатор NULL: Этот мутатор не мутирует полезную нагрузку и просто возвращает копию той же полезной нагрузки. В основном для тестирования. В остальном не очень полезен.

  • Автономный мутатор Rand: Очень плохой случайный мутатор. Он просто случайным образом заменяет значения в случайных местах исходной полезной нагрузки. Он не изменяет длину полезной нагрузки.

  • Автономный мутатор Custom: Этот мутатор может вызывать внешнюю команду для мутации полезных нагрузок. Он записывает полезную нагрузку в stdin и получает мутированную полезную нагрузку из stdout. Из-за неглубокой реализации он оказывает значительное влияние на производительность.

USB-устройства

При использовании опции -D usb Frida выберет первое локальное USB-устройство, например iPhone или телефон Android.

Сетевые устройства

С помощью опции -D remote можно фаззить процесс, запущенный на сетевом устройстве. Для этого удалённое устройство должно запускать frida-server. В качестве примера конфигурации используйте SSH с переадресацией портов, чтобы привязать порт прослушивания frida-server по умолчанию (27042) на удалённом устройстве к сокету на локальном клиенте.

root@kitploit:~
ssh -N [email protected] -L 127.0.0.1:27042:127.0.0.1:27042

На iPhone можно также использовать iproxy для перенаправления порта через USB-соединение. Это может быть особенно полезно при запуске Frida на нестандартном порту на неджейлбрейкнутом устройстве с помощью гаджета Frida. При работе с гаджетом Frida единственным доступным процессом будет процесс с именем Gadget, независимо от имени целевого приложения.

root@kitploit:~
iproxy 27042 27042

Затем используйте frida-ps для проверки конфигурации, выведя список процессов на удалённом устройстве:

root@kitploit:~
frida-ps -R
Скачать инструмент