Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
fpicker — Frida 기반의 인프로세스 퍼징 스위트로, AFL++ 프록시, 독립형 능동/수동 모드, 공유 메모리 통신을 통해 플랫폼 전반에서 고성능 커버리지 기반 취약점 발견을 지원합니다. | Kitploit
도구/GitHubGitHub/ttdennis/fpicker
Dynamic Analysis (Sandboxing)Vulnerability AnalysisExploitationFuzzingBinary Analysis
GitHubttdennis/fpicker

fpicker

Frida 기반의 인프로세스 퍼징 스위트로, AFL++ 프록시, 독립형 능동/수동 모드, 공유 메모리 통신을 통해 플랫폼 전반에서 고성능 커버리지 기반 취약점 발견을 지원합니다.

저장소 보기
2963451년 전Kitploit 검토 완료

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

fpicker

Fpicker logo

fpicker는 Frida 기반의 퍼징 스위트로, AFL++ 모드나 수동 추적 모드와 같은 다양한 퍼징 모드를 프로세스 내 퍼징(in-process fuzzing)을 위해 제공합니다. Frida가 지원하는 모든 플랫폼에서 실행되어야 합니다.

  • 설치 지침
  • 빌드 및 실행
  • 퍼징 하네스 만들기
  • 모드 및 설정

fpicker의 배경 정보와 생각 및 아이디어는 제가 쓴 블로그 포스트에서 확인할 수 있습니다.

Fpicker는 제 석사 논문 중에 개발된 ToothPicker의 이전 작업을 기반으로 합니다. fpicker의 대부분은 제 고용주(ERNW)에서 근무 시간 중에 개발되었습니다.

요구 사항 및 설치

fpicker 실행에 필요한 항목:

  • frida_compile: 하네스 스크립트를 하나의 JS 파일로 컴파일
  • 해당 플랫폼용 frida-core-devkit은 Frida 릴리스 페이지에서 확인 가능.
    • 대상 플랫폼에 따라 라이브러리를 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은 macOS에서 iOS용 빌드만 지원하지만, Linux의 iOS 툴체인을 사용하여 fpicker를 빌드하는 것도 완전히 가능합니다.

원하는 대상에 따라 다음을 실행하십시오:

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 폴더의 예제에 해당합니다.

  • AFL++ 프록시로 fpicker를 실행하여 대상 프로세스에 연결하고 특정 함수를 프로세스 내에서 퍼징:
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"

퍼징 하네스 만들기

각 대상에는 고유한 퍼징 하네스가 필요합니다. 이 하네스에서 가장 중요한 부분은 Frida의 Stalker 진입 함수를 정의하는 것입니다. 이 함수는 계측이 삽입되는 지점을 결정합니다. 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));
}

passive 모드에서는 필요한 데이터를 처리하는 콜백을 지정해야 합니다. 퍼저는 페이로드 버퍼와 그 길이를 받을 것으로 예상합니다. 대상 함수에 따라 이 데이터를 추출해야 합니다. 다음 예제에서는 버퍼에 대한 포인터와 그 길이라는 두 개의 매개변수를 가진 함수를 다시 사용합니다. 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();
}

모드 및 설정

pficker는 아래에서 설명하는 다양한 모드와 설정을 제공합니다. 이러한 모드의 대부분은 다양한 방식으로 조합될 수 있습니다. 이 섹션의 끝에는 어떤 옵션을 조합할 수 있고 구현 상태가 어떻게 되는지 보여주는 표가 있습니다.

퍼저 모드

Fpicker에는 AFL++ 모드, 독립 실행형 능동 모드, 독립 실행형 수동 모드의 세 가지 퍼징 모드가 있습니다:

  • AFL++ 모드: AFL++ 모드에서 fpicker는 AFL++와 대상 프로세스 간의 프록시 역할을 합니다. Frida의 계측 기능을 사용하여 대상이 AFL++에서 생성된 입력 데이터로 퍼징되는 동안 AFL의 커버리지 비트맵이 채워집니다.

  • 독립 실행형 능동 모드: 독립 실행형 능동 모드에서 퍼저는 Frida의 Stalker 호출 요약을 사용하여 반복 중에 실행되는 기본 블록 형태의 커버리지를 수집합니다. 이것은 새로운 것이 아니며 이전에도 다양한 형태로 구현되었습니다. 그러나 다른 퍼저 설정과 결합하면 다양한 이점을 가질 수 있습니다. 또한 주어진 환경이나 경우에 AFL++를 적용할 수 없거나 원하지 않을 때 좋은 대안입니다.

  • 독립 실행형 수동 모드: 수동 모드는 퍼저라기보다는 트레이서에 가깝습니다. 기본적으로 독립 실행형 능동 모드와 동일한 작업을 수행합니다. 그러나 자체 입력을 보내지 않습니다. 단지 특정 함수에 연결하여 커버리지를 수집합니다. 새로운 커버리지가 관찰되면 커버리지와 입력이 모두 저장됩니다.

입력 모드

Fpicker는 주로 프로세스 내 퍼저로 설계되었지만 외부 명령을 통한 퍼징도 지원합니다. 이를 위해 fpicker는 두 가지 입력 모드를 제공합니다.

  • 프로세스 내 입력 모드: 프로세스 내 입력 모드에서 하네스는 대상 프로세스의 지정된 함수를 직접 호출합니다. 퍼저는 페이로드를 하네스로 보내고 하네스는 대상 함수를 호출할 수 있도록 페이로드를 준비합니다.

  • CMD 입력 모드: 명령 입력 모드에서 페이로드는 외부 명령으로 리디렉션됩니다. 이는 대상 함수를 직접 호출할 때 매개변수나 다른 상태를 준비하기 너무 복잡할 때 유용합니다. 커버리지 수집은 여전히 특정 함수에 연결되어야 합니다. 페이로드를 제공하면 대상 함수를 트리거하는 클라이언트가 있을 수 있습니다.

통신 모드

통신 모드는 주입된 하네스가 퍼저와 통신하는 방식을 결정합니다. 이는 대상 애플리케이션에 크게 의존합니다. Frida는 주입된 에이전트 스크립트에서 메시지를 보내고 받을 수 있는 API를 제공합니다. 이러한 유형의 통신은 비용이 많이 듭니다. 요인 중 하나는 전송된 메시지를 JSON으로 인코딩해야 한다는 것입니다. 따라서 바이너리 데이터를 보내는 것은 간단합니다. 따라서 fpicker는 공유 메모리를 통한 두 번째 통신 모드를 제공합니다. 그러나 이는 퍼저와 대상 애플리케이션 간에 공유 메모리를 설정할 수 있는 경우에만 작동합니다. 즉, 대상이 USB를 통해 퍼저 호스트에 연결된 경우 이 모드를 사용할 수 없습니다. CMD 입력 모드에서 통신 모드는 페이로드 전송 방식이 아니라 커버리지 정보가 퍼저로 다시 전달되는 방식만을 의미합니다. 페이로드 전송은 외부 명령에 위임되기 때문입니다.

  • Send 통신 모드: Send 통신 모드에서 페이로드는 Frida의 RPC 호출 메커니즘을 사용하여 전송됩니다. 이를 통해 퍼저는 주입된 하네스 스크립트 내에서 JavaScript 함수를 실행할 수 있습니다. 하네스 내부의 이 함수는 대상 함수를 호출하기 위해 필요한 모든 준비를 수행할 수 있습니다. 대상 함수가 반환되면 커버리지 수집이 중지되고 하네스는 Frida의 send API를 사용하여 커버리지 정보를 다시 퍼저로 보내 반복이 완료되었음을 알릴 수 있습니다.

  • SHM 통신 모드: SHM 통신 모드에서 퍼저와 하네스 스크립트는 공유 메모리와 세마포어를 통해 통신합니다. 공유 메모리의 버퍼는 페이로드를 보내고 커버리지 정보를 수신하는 데 사용됩니다. 보내고 받는 대신 두 구성 요소는 세마포어에서 대기 및 게시를 사용합니다. 시스템과 대상에 따라 이는 상당한 성능 향상을 가져옵니다. 특히 바이너리 페이로드가 메모리에 한 번만 기록되고 인코딩 및 디코딩하거나 다른 메모리 위치로 복사할 필요가 없기 때문입니다. 불행히도 이 모드는 AFL++로 실행할 때 안정성이 낮아지는 경우가 있습니다. 아직 이유는 확실하지 않습니다.

실행 모드

실행 모드는 spawn 또는 attach일 수 있습니다. 이는 자명합니다. fpicker는 실행 중인 프로세스에 연결하거나 프로세스를 생성할 수 있습니다. 두 모드 간의 주요 차이점 중 하나는 연결된 대상이 충돌할 경우 fpicker가 다시 생성하려고 시도하지 않는다는 것입니다.

독립 실행형 변이기

독립 실행형 모드에서 fpicker는 세 가지 다른 입력 변이 전략을 제공합니다. 좋게 말하면 입력 변이에는 개선의 여지가 많습니다.

  • NULL 독립 실행형 변이기: 이 변이기는 페이로드를 변이하지 않고 동일한 페이로드의 복사본을 반환합니다. 주로 테스트 목적으로 사용됩니다. 그 외에는 실제로 유용하지 않습니다.

  • Rand 독립 실행형 변이기: 매우 나쁜 무작위 변이기입니다. 원래 페이로드의 무작위 위치에 값을 무작위로 바꾸는 것만 수행합니다. 페이로드 길이는 변경하지 않습니다.

  • 사용자 정의 독립 실행형 변이기: 이 변이기는 외부 명령을 호출하여 페이로드를 변이할 수 있습니다. 페이로드를 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 gadget과 함께 Frida를 실행하는 탈옥되지 않은 장치에서 특히 유용할 수 있습니다. Frida gadget으로 작업할 때 사용 가능한 유일한 프로세스 이름은 대상 앱 이름과 관계없이 Gadget이 됩니다.

root@kitploit:~
iproxy 27042 27042

그런 다음 frida-ps를 사용하여 원격 장치의 프로세스를 나열하여 구성을 확인합니다:

root@kitploit:~
frida-ps -R
도구 다운로드