IDA에는 바이너리를 분석하여 직접 시그니처를 생성하고, 이를 내가 분석 중인 파일에 로드하는 기능을 제공한다. 이를 FLIRT Signature
라 부르며, IDA가 분석하려는 파일의 시그니처를 거의 갖고 있지 않을 때 유용하다.
활용 사례가 궁금하다면, Flare-On 11 CTF Writeup : 7.fullspeed를 참조 바란다.
상황 예시
IDA는 기본적으로 다양한 시그니처 데이터베이스를 갖고 있고, 이를 통해 알려진 함수 등에 적절한 이름을 붙여 분석을 용이하게 한다. 그러나 보유한 시그니처 데이터베이스 범위를 벗어나는 타겟을 분석하는 경우, 시그니처 정보를 제공하지 못한다.
그렇더라도 분석 대상 파일 빌드에 포함된 바이너리 정보를 알고 있다면, 해당 바이너리에서 Signature 정보를 직접 생성하여 사용할 수 있다. 예시로 아래 사례의 경우, String Search를 통해 타겟 파일을 빌드하는 과정에 Bouncy Castle의 commit 83ebf4a805... version
가 포함되었음을 확인하였다.
위 케이스의 경우 다음 3단계를 거쳐 분석 대상에 FLIRT Signature를 적용할 수 있다. 적용 전과 비교하면 꽤 많은 시그니처 정보가 추가된 것을 확인할 수 있다.
1. Bouncy Castle을 직접 빌드
2. 빌드한 바이너리에서 FLIRT Signature를 추출
3. 분석 대상에 FLIRT Signature를 로드
방법
서론이 길었지만 방법은 매우 간단하다. 직접 빌드한 파일을 ida로 연 뒤 File > Produce File > Create Sig File
을 선택하면 된다.(IDA 8.4 기준) 그 결과 .sig
, .pat
파일 등이 생성된다.
이후 분석하려는 파일을 열고, File > Load File > FLIRT Signature file
에서 미리 생성한 .sig
파일을 선택하면 시그니처 정보가 로드된다.
주로 발생하는 에러 및 트러블 슈팅
생성된 .sig
파일이 .pat
보다 심하게 작거나, 분석 대상 파일에 그다지 시그니처 정보가 추가되지 않았다면 시그니처 생성 과정에서 여러 에러가 발생하였을 수 있다. 내 경험적으로는 2개 정도의 케이스가 있다.
1. pat 파일 내 오류 발생 -> 오류를 sig 파일로 변환하는 과정에서 에러 발생
2. 동일한 Signature 다수 -> Collision 발생한 함수 대상 signature 생성하지 않음
pat 오류 수정
먼저 hex-rays.com에서 flair
툴을 다운 받는다.
flair
의 bin
내 sigmake
를 사용한다. $ sigmake {filename}.pat {filename}.sig
pat
파일을 sig
파일로 변환하는 명령어이다.
pat
파일에 오류가 발생한 경우 해당 부분을 sig
파일로 변환하지 못하고, 대신 에러가 발생한 line을 출력한다. 이 때 pat
파일 내 해당 라인을 text 편집하여 삭제하면 된다. 한 줄이 겨우 signature 1개와 대응되므로, 트러블 슈팅을 위해 한 두줄 삭제하는 것 정도는 괜찮다. 당연히 상황에 따라 패치가 가능하다면 패치하면 더 좋다.
Collision Fix
위 $ sigmake {filename}.pat {filename}.sig
가 에러 없이 이루어진 경우, Collision
수를 출력하므로 Collision
규모를 파악할 수 있다. Collision
은 보통 함수의 길이가 짧다거나 하는 이유로, Signature가 고유하게 생성되지 못하고 겹침으로써 발생한다. 바이너리 특성에 의한 것이므로 근본적인 해결은 불가능하다.
이 때 .sig
및 .pat
과 동일 경로에 .exc
가 존재한다. Collision
이 발생한 함수들의 예외 처리를 정의한 파일이다. 파일 최상위 주석을 직접 제거하여야 유효하고, 그 전에는 무효하다. 직접 주석을 제거한 후 다시 sigmake
하면 Collision
처리가 일부 이루어져 sig
파일의 크기가 증가한다. 주석에 적혀있듯 Signature의 주인이 확실한 함수에 대하여 +를 추가하는 등 커스터마이징을 할 수 있다.
;--------- (delete these lines to allow sigmake to read this file)
; add '+' at the start of a line to select a module
; add '-' if you are not sure about the selection
; do nothing if you want to exclude all modules