
x86 프로세서 퍼저
: x86 프로세서 퍼저
sandsifter는 시스템적으로 머신 코드를 생성하여 프로세서의 명령어 세트를 검색하고 실행 중 이상 징후를 모니터링함으로써, x86 프로세서에서 숨겨진 명령어와 하드웨어 버그를 감사합니다. sandsifter는 모든 주요 공급업체의 비밀 프로세서 명령어, 디스어셈블러·어셈블러·에뮬레이터에 널리 퍼진 소프트웨어 버그, 엔터프라이즈 하이퍼바이저의 결함, 그리고 x86 칩의 무해한 하드웨어 버그와 보안에 치명적인 하드웨어 버그를 발견했습니다.
수많은 x86 프로세서가 존재하는 상황에서, 이 도구의 목표는 사용자가 자신의 시스템에서 숨겨진 명령어와 버그를 확인할 수 있게 하는 것입니다.
프로세서에 대한 기본 감사를 실행하려면:
sudo ./sifter.py --unk --dis --len --sync --tick -- -P1 -t

컴퓨터는 이상 명령어가 있는지 체계적으로 스캔됩니다. 위쪽 절반에서는 sandsifter가 현재 프로세서에서 테스트 중인 명령어를 볼 수 있습니다. 아래쪽 절반에서는 sandsifter가 발견한 이상 징후를 보고합니다.
검색은 프로세서의 속도와 복잡성에 따라 몇 시간에서 며칠이 걸립니다. 완료되면 다음 명령으로 결과를 요약합니다:
./summarize.py data/log

일반적으로 프로세서에서 수백만 개의 문서화되지 않은 명령어가 발견되지만, 이들은 대개 소수의 서로 다른 그룹으로 분류됩니다. 이상 징후를 분류한 후, summarize 도구는 각 명령어를 문제 범주에 할당하려고 시도합니다:
'Q'를 눌러 종료하고 시스템 스캔의 텍스트 기반 요약을 얻습니다:
스캔 결과는 도구가 자동으로 분류하기 어려운 경우가 있으며 수동 분석이 필요할 수 있습니다. 결과 분석에 도움이 필요하면 ./data/log 파일을 [email protected]으로 보내 주세요. 이 로그에는 /proc/cpuinfo에서 가져온 프로세서 제조사, 모델, 개정판 외에 개인 정보는 포함되지 않습니다.
sandsifter로 스캔한 결과 수십 개의 opcode 범주에 걸친 문서화되지 않은 프로세서 기능, 엔터프라이즈 하이퍼바이저의 결함, 거의 모든 주요 디스어셈블리 및 에뮬레이션 도구의 버그, 그리고 프로세서 자체에 보안 취약점을 열어주는 치명적인 하드웨어 버그가 발견되었습니다.
결과에 대한 자세한 내용은 프로젝트 백서에서 확인할 수 있습니다.
(TODO: 여기에 상세 결과 목록)
sandsifter를 사용하려면 먼저 Capstone 디스어셈블러를 설치해야 합니다: http://www.capstone-engine.org/. Capstone은 일반적으로 다음과 같이 설치할 수 있습니다:
sudo apt-get install libcapstone3 libcapstone-dev
sudo pip install capstone
sandsifter는 다음과 같이 빌드할 수 있습니다:
make
그런 다음 다음과 같이 실행합니다.
sudo ./sifter.py --unk --dis --len --sync --tick -- -P1 -t
플래그는 --flag로 sifter에 전달하고, -- -f로 injector에 전달합니다.
예:
sudo ./sifter.py --unk --dis --len --sync --tick -- -P1 -t
Sifter 플래그:
--len
search for length differences in all instructions (instructions that
executed differently than the disassembler expected, or did not
exist when the disassembler expected them to
--dis
search for length differences in valid instructions (instructions that
executed differently than the disassembler expected)
--unk
search for unknown instructions (instructions that the disassembler doesn't
know about but successfully execute)
--ill
the inverse of --unk, search for invalid disassemblies (instructions that do
not successfully execute but that the disassembler acknowledges)
--tick
periodically write the current instruction to disk
--save
save search progress on exit
--resume
resume search from last saved state
--sync
write search results to disk as they are found
--low-mem
do not store results in memory
Injector 플래그:
-b
mode: brute force
-r
mode: randomized fuzzing
-t
mode: tunneled fuzzing
-d
mode: externally directed fuzzing
-R
raw output mode
-T
text output mode
-x
write periodic progress to stderr
-0
allow null dereference (requires sudo)
-D
allow duplicate prefixes
-N
no nx bit support
-s seed
in random search, seed value
-B brute_depth
in brute search, maximum search depth
-P max_prefix
maximum number of prefixes to search
-i instruction
instruction at which to start search (inclusive)
-e instruction
instruction at which to end search (exclusive)
-c core
core on which to perform search
-X blacklist
blacklist the specified instruction
-j jobs
number of simultaneous jobs to run
-l range_bytes
number of base instruction bytes in each sub range
m: 모드 - sifter의 검색 모드(무차별 대입, 무작위, 터널)를 변경합니다
q: 종료 - sifter를 종료합니다
p: 일시정지 - 검색을 일시정지하거나 재개합니다
스캔은 네 가지 검색 알고리즘을 지원하며, 명령줄에서 설정하거나 단축키로 전환할 수 있습니다.
sudo
최상의 결과를 얻으려면 도구를 root 사용자로 실행해야 합니다. 프로세스가 주소 0에 페이지를 메모리에 매핑하려면 root 권한이 필요하기 때문입니다. 이 페이지는 많은 명령어가 메모리 접근 시 세그폴트(seg-fault)를 일으키는 것을 방지하여 더 정확한 오류 분석을 가능하게 합니다.
프리픽스
명령어 검색 깊이의 주요 제한 요소는 탐색할 prefix 바이트 수입니다. 각 추가 prefix 바이트는 검색 공간을 약 10배 증가시킵니다. -P 플래그로 prefix 바이트 수를 제한하세요.
색상
sifter의 인터페이스는 256색 터미널용으로 설계되었습니다. 터미널에 따라 세부 사항은 크게 다르지만, 대략 다음과 같이 설정할 수 있습니다:
export TERM='xterm-256color'
GUI
인터페이스는 터미널 크기가 최소한 특정 크기 이상이라고 가정합니다. 인터페이스가 제대로 렌더링되지 않으면 터미널 크기를 늘려 보세요. 일반적으로 터미널 글꼴 크기를 줄이면 됩니다.
경우에 따라 그래픽 프런트엔드 없이 도구를 실행하는 것이 바람직하거나 필요할 수 있습니다. 이 경우 injector를 직접 실행하면 됩니다:
sudo ./injector -P1 -t -0
직접 injector를 실행한 결과를 필터링하려면 grep을 사용할 수 있습니다. 예:
sudo ./injector -P1 -r -0 | grep '\.r' | grep -v sigill
이 명령은 프로세서와 디스어셈블러가 명령어 길이에 대해 의견이 일치하지 않았지만(grep '.r') 성공적으로 실행된(grep -v sigill) 명령어를 검색합니다.
대상 지정 퍼징
많은 경우 퍼저를 특정 대상으로 지정하는 것이 유용합니다. 예를 들어, 에뮬레이터가 반복되는 'lock' prefix(0xf0) 주변에 결함이 있다고 의심된다면 -i 및 -e 플래그로 퍼저가 이 명령어 공간 영역을 검색하도록 지정할 수 있습니다:
sudo ./sifter.py --unk --dis --len --sync --tick -- -t -i f0f0 -e f0f1 -D -P15
레거시 시스템
훨씬 오래된 시스템(i586급 프로세서, 저메모리 시스템)을 스캔하려면 sifter에 --low-mem 플래그를, injector에 -N 플래그를 전달하세요:
sudo ./sifter.py --unk --dis --len --sync --tick --low-mem -- -P1 -t -N
스캔이 너무 빨리 완료되는 경우(예: 몇 초 만에 완료)는 일반적으로 스캔 중인 프로세서에 이러한 플래그가 필요하기 때문입니다.
32비트 vs. 64비트
기본적으로 sandsifter는 호스트 운영 체제의 비트 수준을 대상으로 빌드됩니다. 그러나 일부 명령어는 32비트 프로세스에서 실행될 때와 64비트 프로세스에서 실행될 때 동작이 다릅니다. 이러한 시나리오를 탐색하려면 64비트 시스템에서 32비트 sandsifter를 실행하는 것이 유용할 때가 있습니다.
64비트 시스템에서 32비트 sandsifter를 빌드하려면 Capstone을 32비트로 설치해야 합니다. 자세한 방법은 에서 확인할 수 있습니다.
sandsifter는 Christopher Domas(@xoreaxeaxeax)의 연구 프로젝트입니다.
그런 다음 sandsifter를 32비트 아키텍처용으로 빌드해야 합니다:
make CFLAGS=-m32
이렇게 하면 64비트 시스템에서 32비트 명령어 공간을 탐색할 수 있습니다.