퍼ㅍ ㅓ퍼징
대학원 인턴과 INCOGNITO 프로젝트도 그렇고 퍼징과 관련된 것들이 많아서 일단 퍼징이 뭔지부터 다루고 가야겠다.
https://owasp.org/www-community/Fuzzing#
[Fuzzing | OWASP Foundation
Fuzzing on the main website for The OWASP Foundation. OWASP is a nonprofit foundation that works to improve the security of software.
owasp.org](https://owasp.org/www-community/Fuzzing#)
Fuzzing에 대한 기초글은 위의 링크에서 확인했다.
내가 생각하는 퍼징은 코드에서 미처 구현하지 못하였거나, 무작위 값을 넣었을 때 코드에 크래시가 나는 부분을 사람이 직접 다 공격하기는 힘들기에 무작위 값을 넣는 퍼징이라는 작업을 수행하는 것 이다.
실제 OWASP에서도 Fuzzing은 프로그램에 예상치 못한, 잘못된 입력을 주입하여 버그나 취약점, 오류를 식별하는 것은 목적으로 하는 소프트웨어 테스트 기법이다.
그럼 그 퍼징을 어떻게 하냐? 일단 내가 듣기에 퍼징을 공부해보려고 해! 라고 이야기하면 보통 AFL++가 뭔지는 아니? 부터 물어보았다.
AFL에 있는 DOCS 문서이다.
Instrument target
일단 Instrument target, 즉 타깃 프로그램을 계측하고 빌드하는 것 이다.
- SELECT Compiler
컴파일러는 일단 계측이 가능해야한다. 즉 프로그램의 실행 흐름을 관찰 및 기록을 할 수 있어야한다.
- Select Options
퍼징 성능을 높이기 위한 옵션을 고르는 단계
- Select Sanitizer
어떤 취약점을 잡을지 정하는 단계, 취약점에는 UAF, 제어 흐름 위조, 메모리 누수, race condition 등이 있다.
- Modify target
퍼징용 엔트리를 작성한다. fuzzing harness를 작성한다고도 한다. 여기서 harness란?
퍼저가 생성한 바이트 데이터를 실제 프로그램의 로직에 전달해 주는 중간 어댑터 코드
하네스의 예시
#include <stdint.h>
#include <stddef.h>
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
parse_file(data, size);
return 0;
}
| LLVMFuzzerTestOneInput | 퍼저가 자동으로 호출하는 진입점 |
| data | 퍼저가 만든 입력 |
| size | 입력 길이 |
| parse_file() | 테스트하고 싶은 함수 |
Prepare campaign
퍼저가 초기 입력을 준비하는 단계이다.
- Collect inputs
퍼저의 입력 파일들을 모으는 단계이다. 만약 프로토콜 퍼징을 수행하면 정상 패킷을 캡처하고, PDF 퍼징을 수행하면 실제 PDF 문서들을 수집한다.
- Make input corpus unique
입력 파일중에서 의미 없는 중복을 제거하는 단계이다.
- Minimize corpus file
각 입력 파일을 동작은 유지한 채 최대한 작게 줄여서, 퍼징 속도를 증가해주는 단계이다.
Fuzz target
실제로 퍼징을 돌리는 단계이다.
- Run afl-fuzz
퍼저를 실행하고 입력 corpus, 출력 디렉토리, 메모리 제한 등을 설정하는 단계다.
이 단계에서 퍼징 환경과 기본 성능이 결정된다.
- Use multiple cores
여러 개의 퍼저를 동시에 실행해 CPU 코어를 최대한 활용한다. Master는 상태를 관리하고, Secondary는 병렬로 입력을 탐색한다.
- Use multiple machines
여러 서버에서 퍼징을 동시에 돌려 탐색 범위를 확장한다. 각 머신은 결과를 공유하며 대규모 퍼징에 사용된다.
Manage Campaign
- Monitor status
afl-whatsup, afl-plot으로 퍼징 진행 상태를 확인한다.속도, 크래시 수, 커버리지 증가 여부를 모니터링한다.
- Check coverage
afl-showmap, afl-cov로 코드 커버리지를 확인한다. 어디까지 실행됐는지 시각적으로 파악할 수 있다.
- Triage crashes
발견된 크래시를 afl-fuzz -C나 gdb로 분석한다. 중복 크래시는 제거하고 의미 있는 것만 남긴다.
- Optimize campaign
효율 안 나오는 퍼저는 중지하고 설정을 바꾼다. 새 옵션이나 입력으로 다시 퍼징을 돌린다.
이렇게 퍼징의 개념과, AFL++를 사용할 때는 퍼징을 돌리는 순차적인 순서들을 확인해보았다.