Last updated
Last updated
단순히 잘못되었거나 예상치 못하거나 임의적일 수 있는 데이터를 프로그램에 입력으로 제공하는 퍼징은 대규모 시스템에서 버그를 찾을 수 있는 매우 효과적인 방식이며 소프트웨어 개발 수명 주기의 중요한 부분이기도 합니다.
Android의 빌드 시스템은 LLVM 컴파일러 인프라 프로젝트 프로젝트의 를 포함하는 방식으로 퍼징을 지원합니다. 테스트 LibFuzzer는 테스트 아래의 기능과 연결되어 있으며, 퍼징 세션 도중에 발생하는 모든 입력 선택, 변형 및 충돌 보고를 처리합니다. LLVM의 새니타이저는 메모리 손상 감지 및 코드 범위 측정항목을 돕는 데 사용됩니다.
이 도움말은 Android의 libFuzzer를 소개하고 계측화된 빌드를 수행하는 방법에 대해 설명하며, fuzzer를 쓰고 실행하고 맞춤설정하는 내용까지 담고 있습니다.
기기에서 제대로 작동하는 이미지를 실행하려면 를 다운로드하고 기기를 플래시하면 됩니다. 또는 AOSP 소스 코드를 다운로드하고 아래의 설정 및 빌드 예시를 따를 수 있습니다.
도움말: 자세한 설정 정보는 섹션을 참조하세요. 안내에 따라 빌드 환경을 하고 소스를 하고 Android를 빌드하세요(까지).
이 예시에서는 타겟 기기가 Pixel (taimen
)이고 이미 USB 디버깅 (aosp_taimen-userdebug
)에 대한 준비를 마쳤다고 가정합니다. 에서 다른 Pixel 바이너리를 다운로드할 수 있습니다.
퍼즈 타겟을 실행하는 첫 단계는 새로운 시스템 이미지를 가져오는 것입니다. 적어도 최신 버전의 Android를 사용하는 것이 좋습니다.
다음을 실행하여 초기 빌드를 수행합니다.
다음 명령어로 부트로더를 잠금 해제하고 새로 컴파일된 이미지를 플래시합니다.
이제 타겟 기기를 libFuzzer 퍼징에 사용할 수 있습니다.
Android의 libFuzzer를 사용하여 포괄적인 fuzzer를 작성하는 과정을 보여주려면 다음과 같은 취약한 코드를 테스트 사례로 사용하세요. 이는 fuzzer를 테스트하여 모든 부분이 올바르게 작동하는지 확인하고 충돌 데이터가 어떤 모습인지를 보여줄 수 있도록 도와줍니다.
다음은 테스트 함수입니다.
이 테스트 fuzzer를 빌드하고 실행하는 방법은 다음과 같습니다.
Fuzz 대상은 빌드 파일 및 fuzz 타겟 소스 코드라는 두 파일로 구성됩니다. 파일을 추가하려는 라이브러리 옆의 위치에 파일을 만듭니다. fuzzer에 퍼징의 역할을 설명하는 이름을 지정하세요.
libFuzzer를 사용하여 퍼즈 타겟을 작성합니다. 퍼즈 타겟은 지정된 크기의 데이터 blob를 취하여 퍼징하려는 함수에 전달하는 함수입니다. 다음은 취약한 테스트 함수를 위한 기본 fuzzer입니다.
Android의 빌드 시스템에 fuzzer 바이너리를 생성하도록 지시합니다. fuzzer를 빌드하려면 이 코드를 Android.bp
파일에 추가합니다.
fuzzer를 타겟에서 실행하기 위해 만들려면 (기기):
호스트에서 fuzzer를 실행하기 위해 fuzzer를 만들려면 다음 안내를 따르세요.
편의를 위해 fuzz 대상의 경로와 바이너리의 이름을 포함하는 일부 셸 변수를 정의합니다 (앞에서 작성한 빌드 파일에서).
이러한 단계를 수행하면 fuzzer가 빌드됩니다. fuzzer의 기본 위치(이 예시의 경우 Pixel 빌드)는 입니다.
$ANDROID_PRODUCT_OUT/data/fuzz/$TARGET_ARCH/$FUZZER_NAME/$FUZZER_NAME(기기의 경우)
호스트의 경우 $ANDROID_HOST_OUT/fuzz/$TARGET_ARCH/$FUZZER_NAME/$FUZZER_NAME
Android.bp 빌드 파일에 추가합니다.
퍼징할 라이브러리가 호스트되는 경우에만 적용할 수 있습니다.
빌드된 fuzzer 바이너리를 실행하여 호스트에서 fuzzer를 실행합니다.
adb
을(를) 사용하여 기기에 복사하겠습니다.
이러한 파일을 기기의 디렉터리에 업로드하려면 다음 명령어를 실행합니다.
다음 명령어로 기기에서 테스트 fuzzer를 실행합니다.
그러면 아래 예시 출력과 유사한 출력의 결과로 이어집니다.
예시 출력에서는 충돌이 10행의 fuzz_me_fuzzer.cpp
에 의해 발생했습니다.
이는 데이터가 길이 3인 경우 아주 단순한 out-of-bounds입니다.
fuzzer를 실행한 후에는 출력이 충돌의 결과로 이어지는 경우가 자주 발생하며, 문제의 입력은 corpus에 저장되어 ID를 부여받습니다. 이는 예시 출력에서 crash-0eb8e4ed029b774d80f2b66408203801cb982a60
입니다.
기기에서 뒤잡을 때 비정상 종료 정보를 검색하려면 이 명령어를 실행하여 비정상 종료 ID를 지정합니다.
테스트 사례를 올바른 디렉터리에 저장하려면 위의 예시와 같이 corpus 폴더를 사용하거나 artifact_prefix 인수(예: ~-artifact_prefix=/data/fuzz/where/)를 사용합니다. my/crashes/go`).
호스트에서 퍼징하면 fuzzer가 실행 중인 로컬 폴더의 비정상 종료 폴더에 비정상 종료 정보가 표시됩니다.
기기를 플래시하려면 을 사용하여 기기를 fastboot 모드로 부팅합니다.
도움말: libfuzzer 출력을 읽는 방법은 를 참조하세요.
libFuzzer에 대한 자세한 내용은 를 참조하세요.
Android 사이트 참고