0. 개요

1. 사용

.... 1.1 폴더

2. 제작

.... 2.1 툴

.... 2.2 라이브러리

.... 2.3 패턴 파일

.... 2.4 시그니처 생성

.... 2.5 충돌 처리

3. 플러그인 및 파이썬 스크립트

4. 기타

.... 4.1 링크

.... 4.2 TODO

.... 4.3 예시

.... 4.4 델파이





0. 개요

  IDA Pro로 분석하다 보면 디버거에서는 보지 못했던 기능을 확인할 수 있는데 자동으로 파악한 함수들의 이름을 붙여주는 것이다. 사실 대부분의 프로그램들이 DLL을 사용하는 방식으로 제작되기 때문에 즉 /MD로 컴파일되어 제공되기 때문에 IDA Pro에서 확인해주는 함수들은 C 런타임 초기화와 관련된 내용들 뿐일 것이다. 간단하게 말하면 Main()을 호출하기 전의 Stub 코드들에서 사용하는 함수들이다. 물론 리버싱에 익숙하지 않은 경우라면 이러한 Stub 코드들에도 익숙하지 않기 때문에 어느 정도는 도움을 받을 수 있다.


  분석하다 보면 이러한 Stub 코드들 외에도 기본적인 함수들 예를들면 memset(), memcpy() 또는 rand() 등의 함수들처럼 컴파일러가 최적화 과정을 통해 코드에 통합해주는 함수들도 볼 수 있다. 지금까지는 C나 C++의 경우였고 델파이 같이 순수하게 정적으로 링크되어 제공되는 함수들의 경우에는 많은 도움을 받을 수 있다. 물론 델파이는 특이한 경우로서 IDR이라는 디컴파일러를 이용하면 더 많은 도움을 받을 수 있는데 이것은 다른 문서에서 정리한다. IDA Pro는 반이 못되게 겨우 분석해 주는데 방식의 차이로 인한 결과로 보인다.


  물론 이외에도 정말 많은 도움을 받을 수 있는 기능이다. 개인적으로는 악성코드가 OpenSSL 같은 암호화 라이브러리를 정적으로 링크하여 사용하는 경우 분석하기 정말 어려워지기 때문에 미리 한번 DB를 만들어 놓을까 하는 생각으로 공부하게 되었다. 이것은 뒤에서 예를 들어서 설명하겠다.


  Flirt의 원리에 대해서도 추가하자면 함수의 처음 32바이트에서 패턴을 추출하여 이것을 시그니처로 만드는 방식이다. 물론 패턴이 동일하다면 충돌이 나기도 한다. 큰 라이브러리라면 매우 많은 충돌이 발생하는 것을 확인할 수 있을 것이다.





1. 사용

  Flirt 기능의 경우에는 사용하는 방식도 알아야 한다. 간단한 경우에는 IDA Pro에서 로드할 때 자동으로 인식해서 적용시켜 주지만 직접 제작한 경우나 인식하지 못할 때는 수동으로 인식시켜 주어야 할 필요가 있다.


[ File - Load file - FLIRT signature file ... ]


  이 버튼을 누르면 IDA Pro에서 제공되는 여러 시그니처 파일들을 확인할 수 있다. 시그니처 파일은 확장자가 .sig이며 설치 디렉터리에서 sig 디렉터리를 찾으면 확인할 수 있다. 또한 "Signatures" 창을 켜면 현재 적용된 시그니처 윈도우가 나와 시그니처를 확인할 수 있다. 개인적으로 "Shift + F5"를 누른 후 나오는 시그니처 창에서 마우스 오른쪽 버튼을 클릭하여 고르는 방식이 가장 편한것 같다.


  IDA Pro가 바이너리를 제대로 인식하였다면 이미 적용된 시그니처들을 볼 수 있을 것이다. 먼저 각 시그니처에 대한 설명도 필요해 보인다. 여기서는 VC++로 제작된 바이너리 기준으로 설명할 것이다. 개인적으로는 IDA Pro에서 제공되는 FLIRT가 가장 질이 좋은 것 같다.


vc32rtf : 일반적인 32비트 애플리케이션의 경우 적용되며 앞에서 설명했던 Stub 관련 내용이나 최적화 시에 정적으로 링크되는 CRT 관련 함수들에 대한 시그니처

vc64rtf : 64비트 버전

vcseh : 이유는 모르겠지만 예외 처리와 관련해서 시그니처를 따로 제공한다.

vc64seh : 64비트 버전

vc64_14, vcucrt : VC++ 버전 14부터는 Universal CRT 등의 개념으로 인해 많은 변화가 생겼다. 그래서 추가적인 시그니처를 제공하는 것으로 보인다. 관련 내용은 다음 링크를 [ http://sanseolab.tistory.com/17 ] 확인하자.


  참고로 여기에서 적은 vc32rtf 같은 이름은 .sig 파일의 이름이며 시그니처 창에서는 간단한 설명도 볼 수 있다. 뒤에서 제작할 때 설명을 넣는 부분도 설명할 것이다.


  위의 내용은 VC++로 제작된 바이너리만 설명하였지만 델파이나 여러 다른 컴파일러도 제공하며 적어도 수 십개는 되기 때문에 상황에 맞게 적용하면 될 것이다.



1.1 폴더

  x86이나 x64 아키텍처의 경우에는 sig 폴더 즉 루트 폴더에 그대로 두면 Flirt를 로드할 때 인식이 되지만, 다른 아키텍처들의 경우에는 해당 아키텍처에 해당하는 폴더에 위치시켜야 인식이 가능하다. arm이나 mips 같은 경우에는 해당 폴더가 이미 존재하기 때문에 (관련 시그니처도 소수 존재한다) 그곳에 위치시키면 되지만 여기에 없는 아키텍처의 경우 다음과 같이 이름을 짓고 이 폴더에 위치시켜야 한다.


- arm 폴더 : ARM

- mips 폴더 : mips

- ppc 폴더 : powerpc

- sh3 폴더 : sh4

- sparc 폴더 : sparc

- mc68 폴더 : m68k





2. 제작

  이미 제공되는 것을 적용하는 것은 간단하지만 이 문서의 주된 내용은 Flirt를 직접 만드는 것이다. 앞에서도 말했듯이 필요한 경우가 생기기 때문에 미리 만들어 놓던지 그때 그때 환경에 맞게 제작하는 방식을 알아놓는다면 분석에 매우 도움이 될 것이다.


  기본적인 방식은 라이브러리에서 패턴을 추출하고 이것을 이용해 시그니처를 만드는 것이다. 여기서는 차레대로 툴, 라이브러리, 패턴 추출, 시그니처 생성으로 설명할 것이며 플러그인을 이용하여 필요한 함수만 추출하는 경우는 따로 정리하기로 하겠다.



2.1 툴

  제작에 필요한 도구는 헥스레이 사의 홈페이지에서 다운로드 받을 수 있는 Flair라는 도구이다. 여기에도 여러가지 툴이 있지만 사용해본 것은 패턴을 추출하는데 사용되는 pcf.exe와 패턴을 이용해 시그니처를 제작하는데 사용되는 sigmake.exe이다. 직접 사용해 보면서 설명하도록 하겠다.



2.2 라이브러리

  기본적으로 시그니처를 만들 라이브러리 파일이 필요하다. 라이브러리 파일이란 .lib 파일로서 .dll과 상응하는 개념이다. 지금 생각해보니 이것을 읽을 정도면 당연히 알고 있을 것이므로 설명이 필요 없을것 같다. 인터넷에는 원하는 라이브러리가 소스 코드나 dll로 제공되는 경우는 많이 있어도 .lib으로 제공하는 경우는 잘 없는 것 같다. 그래서 코드를 직접 .lib으로 제작해야 하는 경우가 많다.


  제작 시에는 .lib을 선택해야 할 것이고 옵션도 /MT, /MTd를 이용하여 정적으로 링크해야 한다. 참고로 악성코드가 릴리즈 모드로 개발할지 디버그 모드로 개발할지 모르므로 두 종류를 모두 준비해야 한다. 사실 시그니처라는 것이 좀 그렇다. OpenSSL을 예로 들자면 이것의 버전별로도 .lib 파일을 준비해야 하며 release, debug 모드로도 준비해야 하고 마지막으로 컴파일러의 버전별로도 결과가 다를 수 있으므로 이것도 따로 버전별로 준비해야 완벽한 시그니처가 생성될 수 있을 것이다. 이러한 것들을 각각 하나씩 시그니처로 생성해도 되며 통합해서 생성해도 되는데 무엇이 더 좋을지는 상황에 따라 판단해야 할 것으로 보인다.


  추가적으로 가끔씩 마주칠 수 있는 에러가 있다. pcf를 이용해 .lib 파일에서 패턴 파일을 생성하려고 할 때 어떤 .obj 파일이 "not a coff module"이라며 계속 에러가 뜨는 상황이 있을 수 있다. 이 경우에는 .lib을 컴파일 할 때 옵션 중에서 "/GL"을 해제해야 한다. 아마 최적화 때문에 생기는 에러로 보인다.



2.3 패턴 파일

  이제 각 버전별로 .lib 파일을 확보하였을 것이다. 이것을 이용해 .pat이라는 패턴 파일을 생성한다. 사용법은 간단하다. 위의 에러가 나오지 않는 이상 다음의 명령어를 사용하면 된다. 각각의 .lib 파일에 대해서 다음의 명령어를 이용해 .pat 파일을 생성하자. 결과는 myLib.pat 파일이 될 것이다.


> pcf.exe  myLib.lib


  우리는 coff 파일인 .lib의 패턴을 따기 위해 pcf를 사용하였지만 리눅스의 elf 파일이라면 pelf.exe(최신 버전의 경우 pelf.rtb 추가)를 사용하면 되고 확인해보지는 않았지만 plb.exe라는 파일도 존재한다. 그리고 IDA Pro가 리눅스 버전을 지원하듯이 Flair 툴도 리눅스 용 바이너리가 존재한다.


  .pat 파일은 아래와 같은 형태로 메모장으로도 볼 수 있다. 앞에서도 설명한 것처럼 처음 32바이트에서 추출한 패턴인 것을 확인할 수 있다.

 

--------------------------------------------------------------------

558BEC8B450825FFFFFF7F5DC3...................................... 00 0000 000D :0000 _curlx_ultosi 

558BEC8B450825FFFFFF7F5DC3...................................... 00 0000 000D :0000 _curlx_uztosi 

558BEC8B45085DC3................................................ 00 0000 0008 :0000 _curlx_uztoul 

558BEC8B45085DC3................................................ 00 0000 0008 :0000 _curlx_uztoui 

558BEC8B450825FFFFFF7F5DC3...................................... 00 0000 000D :0000 _curlx_sltosi 

558BEC8B45085DC3................................................ 00 0000 0008 :0000 _curlx_sltoui 

--------------------------------------------------------------------


  참고로 pelf.exe 사용 시 다음과 같은 에러가 발생할 수 있다.

> pelf.exe mips_libc.a

Fatal [C:\Users\sanseolab\Desktop\arm_libc.a] (clone.o): Unknown relocation type 10 (offset in section=0x44).

Use -r switch or edit pelf.rtb to process it.


  이 경우에는 다음과 같은 옵션을 추가해서 사용해야 한다. (위 에러 로그 중 type 10을 보자)

> pelf.exe -r10:0:0 arm_libc.a


  그리고 pelf.exe가 지원하는 아키텍처가 그렇게 많은 편은 아닌것 같다. 물론 x86, x64 외에 arm, mips 정도까지는 지원한다.



2.4 시그니처 생성

  이제 원하는 .pat 파일을 생성했니 이것을 이용하여 .sig 파일 즉 시그니처 파일을 만들어 보자.


> sigmake.exe -nmyLib myLib.pat myLib.sig


  옵션 -n 뒤에 붙은 문자열은 설명이다. 앞에서도 언급했듯이 시그니처 창을 켤 때 설명 부분에서 볼 수 있는 부분이다. 이름을 붙이지 않으면 "Unnamed sample library"라고 붙는데 파일 이름만으로 모든 설명을 충족시키기 어렵기 때문에 설명을 꼭 넣는 것을 추천한다.


  이것은 간단한 방식이고 조금 더 실제처럼 .sig 파일을 생성해 보겠다.


> sigmake.exe  -n"MSVC C Standard Library x86 Release and Debug v15" "libcmt_15_msvc_x86.pat"+"libcmtd_15_msvc_x86.pat"  cmt_v15_rd_x86.sig


  "MSVC C Standard Library x86 Release and Debug v15"는 설명 부분이며 libcmt_15_msvc_x86.pat 파일과 libcmtd_15_msvc_x86.pat 파일을 + 기호로 더하여 cmt_v15_rd_x86.sig라는 시그니처 파일을 생성하였다.


  이 경우에는 기본 아키텍처라서 별 다른 옵션은 주지 않았지만 아키텍처 별로 추가 옵션을 주어야 한다. 옵션은 -p 다음에 숫자를 붙여서 주면 되며 sigmake.exe -hp 명령을 통해 아키텍처에 맞는 번호를 확인할 수 있다.


  참고로 .pat 파일이야 텍스트 형태이기 때문에 직접 수정이 가능하지만 .sig 파일은 특정한 포맷이 있다. 어느 부분에 버전 정보가 위치하는지는 알 수 없지만, 최신 버전의 sigmake.exe로 생성한 .sig 파일은 과거 버전의 IDA Pro에서는 인식할 수 없다. 물론 과거 버전으로 만든 것을 최신 버전의 IDA Pro에서 인식하는 것은 가능하다.



2.5 충돌 처리

  거의 대부분의 경우 sigmake로 시그니처를 생성할 때 Collision이 발생할 것이다. 이것은 각각의 함수들에서 추출한 패턴이 동일할 경우에 발생한다. 이 경우 myLib.exc 라는 파일이 만들어진 것을 볼 수 있다. 이것을 메모장으로 열어보자.


--------------------------------------------------------------------

;--------- (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


_myFunc_1                              02 BB34 33D283F82B7416508B0668........50E8........83C40CBA4300000033C08B

_myFunc_2                        02 BB34 33D283F82B7416508B0668........50E8........83C40CBA4300000033C08B


_OurFunc_1                                      00 0000 558BEC668B45085DC3..............................................

_OurFunc_2                                      00 0000 558BEC668B45085DC3..............................................

--------------------------------------------------------------------


  myFunc_1과 myFunc_2라는 함수가 초기 루틴이 비슷해서인지 충돌이 발생하였고 ourFunc_1, 2 함수도 마찬가지이다. 이 경우에는 각각의 저 함수들 중에서 하나를 선택을 하거나 아니면 주석으로 보여주게 하거나 또는 모두 무시할 수도 있다.


  예를들어 myFunc_1로만 보여줘도 충분하다고 생각하는 경우에는 "_myFunc_1 ... "의 라인 첫 부분에 + 기호를 붙인다. 즉 "+_myFunc_1 ... "와 같은 형태가 될 것이다. 또는 그냥 이 부분을 무시해버릴 수도 있다. 그대로 둔다면 시그니처는 생성되지 않을 것이다. - 기호의 경우에는 헷갈리지만 Flirt를 적용시킬 때 이름에 적용시키지 않고 대신 주석으로 달아준다고 한다. 마지막으로 앞의 4줄짜리 주석을 지운다. 다음 예제는 첫 번쨰 충돌은 선택을 하고 두 번째는 무시하기로 결정하였다고 가정하였을 때이다.


--------------------------------------------------------------------

+_myFunc_1                              02 BB34 33D283F82B7416508B0668........50E8........83C40CBA4300000033C08B

_myFunc_2                        02 BB34 33D283F82B7416508B0668........50E8........83C40CBA4300000033C08B


_OurFunc_1                                      00 0000 558BEC668B45085DC3..............................................

_OurFunc_2                                      00 0000 558BEC668B45085DC3..............................................

--------------------------------------------------------------------


  이제 앞의 명령어를 그대로 입력하면 .sig 파일이 생성된 것을 확인할 수 있다. 실수로 처리하지 못한 부분이 있다면 앞의 .exc 파일의 뒷 부분에 4줄 짜리 주석과 그 부분만 추가되어 있는 것을 볼 수 있는데 이것도 마찬가지로 주석 제거와 선택 또는 무시를 하면 시그니처가 정상적으로 생성된다.


  참고로 OpenSSL의 시그니처를 딸 때 보면 수 십개인지 수 백개인지 모를 양의 충돌이 발생하는 것을 볼 수 있다. 개인적으로 이 라이브러리를 충분히 공부한 후에야 제대로 된 선택을 할 수 있을 것으로 보인다.


  그리고 충돌보다는 자주 보이지 않는 에러이지만 다음과 같은 에러메시지도 가끔 볼 수 있다.

"myLib.pat (71): bad pattern"


  이 경우는 myLib.pat 파일에서 71번째 라인, 즉 해당 라인에 존재하는 특정 함수의 시그니처가 잘못된 패턴이라는 것을 의미한다. 가끔씩 나오는 에러로 보이는데, 함수 하나 정도는 포기한다는 생각으로 해당 라인을 지우면 에러를 없애고 계속 진행할 수 있다.





3. 플러그인 및 파이썬 스크립트

  아까 시그니처 생성 방식을 설명할 때 "기본적으로" .lib 파일을 이용해서 만든다고 하였다. 하지만 정말 유용하게 사용할 수 있는 플러그인이 존재한다. 


  우리는 IDA Pro에서 파악한 함수에 이름을 붙일 수 있다. "idb2pat"이라는 플러그인은 이렇게 이름 붙인 함수를 또는 함수들을 선택해서 그것만 패턴을 파악하여 .pat 파일을 만들어 줄 수 있다. 전체 생성 기능도 있지만 "User Selected Function" 기능이 정말 유용해 보인다. 어떤 악성코드가 특정 라이브러리를 정적으로 링크했는데 파악한 함수들만 시그니처를 따고 싶은 경우에 쉽게 .pat 파일을 생성할 수 있다.


  게다가 .sig 파일이 아니라 .pat 파일이므로 이렇게 딴 패턴들을 모아서 나만의 시그니처를 만들 수도 있다. 이 방식은 간단한데다가 필요한 것만 선택할 수 있고 소스 코드를 몰라도 되므로 최고의 방식이라고 생각한다.


  하지만 단점이 있는데 32비트 버전만 지원한다는 점이다. 그래도 소스 코드가 오픈되어 있으므로 직접 수정할 수 있을 것이다.


  개인적으로는 위의 툴 보다는 FireEye의 FLARE 팀에서 위의 플러그인을 참고해서 개발한 IDA Pro 파이썬 스크립트가 더 좋아보인다. 이것은 64비트도 지원해 주며 ida2pat.py라는 이름으로 다음 링크에서 다운로드 받을 수 있다. 참고로 IDA Pro 7.0 업그레이드에 맞춰서 업데이트되었기 때문에 이 버전보다 낮은 버전의 IDA Pro를 사용 중이라면 스크립트도 이전 버전을 다운받아서 사용하자.

https://github.com/fireeye/flare-ida/blob/master/python/flare/idb2pat.py ]





4. 기타

4.1 링크

  직접 만드는 것은 불편하므로 이미 존재하는 것들의 링크를 올리겠다.


[ https://github.com/Maktm/FLIRTDB ]

  Boost, OpenSSL, VC++ 14 Runtime 등의 라이브러리에 대해서 시그니처를 제공해 준다. 각 버전별로 수 십개가 있지만 .pat 파일 및 .exc 파일도 제공해 주므로 직접 통합하여 사용할 수 있다.


[ https://github.com/push0ebp/sig-database ]

  위의 링크보다 많지는 않지만 OpenSSL 등 여러 시그니처들을 제공해 준다.



4.2 TODO

  사실 라이브러리를 정적으로 링크하면 용량이 굉장히 커지기 때문에 일반 프로그램들 뿐만 아니라 악성코드들도 이러한 방식을 그다지 많이 사용하지는 않는 것 같다. 그래도 혹시나 모를 일을 대비해서 제작해 볼 만한 것을 찾아보았다.


- 라이브러리 : Tor (요즘 악성코드는 토르를 이용해 C&C 서버와 연결하는 경우가 있다고 한다. 제작 가능 여부는 불분명), Curl, Wget, mbedTLS(ARM의 암호화 라이브러리. 어떤 랜섬웨어에서 사용되었다고 한다)


- 언어 : golang과 같이 기본적으로 정적으로 링크되는 언어.



4.3 예시

  랜섬웨어 중에서 TeslaCrypt가 있는데 특정 버전에서 OpenSSL을 정적으로 링크하였다고 한다. 운좋게 샘플을 구해 시그니처를 적용시켜 보니 약 40여개가 매치되는 것을 확인하였다. 아직 OpenSSL 라이브러리를 이용한 개발에 익숙하지 않아서 필요한 함수들 위주로 충분히 인식되었는지 여부는 판단하기 어렵지만 이정도면 충분히 쓸만한 기능이라고 생각한다.



4.4 델파이

  델파이와 관련해서는 다음 링크를 참고한다. [ http://sanseolab.tistory.com/56 ]




'악성코드 분석' 카테고리의 다른 글

Process Hollowing 및 응용  (0) 2018.03.02
델파이 바이너리 분석 방법론  (1) 2018.02.25
Anti-AV와 Anti-VM (Sandbox)  (1) 2017.12.30
COM, OLE, .NET Frame work 등의 개념 및 사용  (0) 2017.12.18
exeinfo PE 사용법  (1) 2017.12.17
Posted by SanseoLab

블로그 이미지
Malware Analyst
SanseoLab

태그목록

공지사항

Yesterday
Today
Total

달력

 « |  » 2024.4
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30

최근에 올라온 글

최근에 달린 댓글

글 보관함