0. 개요

1. VBScript

2. Powershell

3. Batch





0. 개요

  VBScript, Powershell, Batch, JScript 등 많은 스크립트들이 악성코드로서 사용된다. 이것들은 기본적으로 스크립트 형태이면서도 윈도우 환경에서 실행 가능하다는 속성을 갖는다. 하지만 이런 특징 외에도 프로그래밍이 쉬워서인지 AutoIt, AutoHotKey 처럼 스크립트로 개발되어 exe 바이너리로 변환된 형태의 악성코드들도 많이 보이는 편이다.


  여기서는 VBScript, Powershell, Batch 스크립트가 exe 바이너리로 변환된 경우 이 바이너리에서 스크립트를 직접 추출하는 디컴파일 방식을 다루려고 한다. AutoIt, AutoHotKey의 경우 각각 [ http://sanseolab.tistory.com/59 ]와 [ http://sanseolab.tistory.com/61 ]에서 다루었다. vbs의 경우 [ http://sanseolab.tistory.com/60 ]에서 간략하게 다루었는데 VbsEdit이라는 프로그램에서 Vbs to Exe라는 컨버터 프로그램을 내부적으로 사용하였기 때문이다. Vbs to Exe는 VBScript 항목에서 더 자세하게 다루기로 한다.





1. VBScript

  Vbs to Exe는 이름과 같이 vbs를 exe로 변환해주는 프로그램이다. 해당 프로그램은 [ http://www.f2ko.de/en/programs.php ]에서 받을 수 있으며 해당 사이트에는 아래에서 설명할 파워셸 컨버터인 Ps1 to Exe, 배치 파일 컨버터인 Bat to Exe도 다운로드 받을 수 있다. 참고로 이 세가지의 변환 프로그램은 모두 원리가 동일하므로 여기에서 자세히 설명한 후 각 항목에서는 간략하게 언급만 하고 넘어가겠다.


  Vbs to Exe의 버전은 3.0.7을 기준으로 한다. 변환 후 생성된 PE를 보면 별다른 특징은 발견할 수 없다. 암호화된 스크립트는 리소스 섹션의 RCDATA에 들어있는데 살펴보면 항목이 4개 정도 존재하며 그 중 하나는 암호화된 스크립트로 보일만 할 길이를 가지고 있다는 것을 확인할 수 있다. 나머지 3개는 너무 짧기 때문에 쉽게 구별할 수 있다. 간단하게 Resource Hacker를 이용해 이 부분을 추출한다.


  미리 말하자면 이것은 RC4 암호화 방식을 이용해 인코딩된 스크립트이다. 그렇기 때문에 이것을 디코딩하기 위해서는 RC4 키가 있어야 한다. 리버싱을 진행하다 보면 어디서인가 RC4 키를 구해서 이 부분을 복호화하는 루틴을 확인할 수 있다. RC4 키 생성 루틴을 추적해서 분석해 보면 결국 RC4 키는 data 섹션의 특정한 값을 이용해 MD5 루틴을 거쳐서 만들어진 md5 해시 값이다. md5 루틴의 경우 루틴이 간단한 편이기도 하고 많은 상수 값들이 사용되기 때문에 검색을 통해서 쉽게 파악할 수 있었다.


  data 섹션에 위치한 이 값은 다음과 같은 부분이다.

[ FF FF FF FF    7F 3B D5 06    xx xx xx xx    BB 8E 8E 91 ]


  xx 부분을 제외한 부분은 항상 같기 때문에 이 부분을 이용해서 검색할 수 있다. 실제로 md5에서 사용되는 인풋은 "7F 3B D5 06  xx xx xx xx" 부분이다. md5는 최소 512비트 즉 0x40 크기의 인풋을 받는데 나머지는 패딩으로 채워지는 것 같다. 개인적으로 md5 루틴을 분석하다가 패딩을 생각하지 못해서 어려움을 겪었기 때문에 참고 사항으로 적어 보았다.


  어쨌든 인풋 0x8 바이트를 추출하던지 해서 MD5를 구해보면 0x10 바이트의 (128비트) 값을 구할 수 있다. md5를 구하는 것은 도구를 이용해도 되지만 온라인에서도 쉽게 획득할 수 있다. [ https://www.fileformat.info/tool/hash.htm ] 이 링크의 경우 0x8 바이트를 파일 형태로 저장한 후 업로드해도 되며 바이너리를 그대로 복사해서 입력해도 md5를 구해주기 때문에 가장 편한 사이트로 보인다. 사실 대부분의 암호화/복호화 사이트들이 입력으로 문자열을 받아서 이렇게 직접 바이너리를 분석하는 입장에서는 매우 불편할 때가 많다.


  md5 값은 "fe6d1fed11fa60277fb6a2f73efb8be2"와 같이 확인할 수 있는데 중요한 점은 이것을 대문자로 변환해야 한다는 것이다. 대문자 변환 후 다음 사이트에서 RC4 디코딩을 진행하자. [ http://rc4.online-domain-tools.com/ ] 아까 RCDATA에서 추출한 파일을 입력하고 키로 대문자로 변환된 md5 값을 입력한 후 Plaintext를 선택하고 Decrypt 버튼을 누르면 복호화된 VBS 명령어들을 확인할 수 있다.


  참고로 이러한 과정 없이 덤프를 떠서 문자열을 추출하면 확인할 수 있다. 디코딩 루틴이 실제 행위 이전인 초기에 진행되기 때문이다. 단점은 덤프를 뜰 때 전체를 뜨던지 해야 하는데 복호화된 문자열이 data 섹션 같은 곳이 아니라 초기 루틴에서 할당된 메모리에 복호화되기 때문에 이 부분을 찾아야 한다.





2. Powershell

  Ps1 to Exe라는 프로그램이며 위의 링크에서 다운로드 받을 수 있고 디컴파일 방식은 동일하다. 확인한 버전은 3.0.6이었다.





3. Batch

  Bat to Exe Converter의 경우도 위와 동일하다. 버전은 3.0..10이었다.


  하지만 Batch 파일의 경우 여러 컨버터가 존재하기 때문에 찾아본 내용들을 같이 추가하기로 한다. 먼저 [ http://bat2exe.net/ ]에서 다운로드 받을 수 있는 bat2exe가 있다. 이것을 이용해 바이너리로 변환한 후 확인해보면 7zip의 SFX 방식을 사용하는 것을 알 수 있다. 또한 압축을 풀어보면 아예 원본 batch 파일을 구할 수 있다.


  다음으로 링크 [ https://softwarebydefault.com/open-source-projects/battoexe/ ] 또는 [ https://archive.codeplex.com/?p=bat2exe ]에서 구할 수 있는 bat2exe 컨버터도 있다. 이것은 약간 특이하게 C# 바이너리 형태로 변환된다. 하지만 C#의 경우 dnSpy를 통해 쉽게 디컴파일이 가능하며 해당 바이너리의 경우도 스크립트를 문자열로 확인할 수 있다.



Posted by SanseoLab



0. 개요

1. yara 룰 변환

2. yara 룰 추가

3. 예제 ( ELF )





0. 개요


  PE의 경우 종류가 많으며 이에 따라 최적의 분석 방식이 달라질 수 밖에 없기 때문에 관련 툴들이 이미 많이 나와 있다. PEid의 경우 지원은 이미 끝났지만 userdb.txt라는 텍스트 파일에 사용자가 직접 시그니처를 추가할 수 있다는 장점이 있다. exeinfo PE의 경우 개발자가 꾸준히 업데이트를 해주며 질적으로도 가장 쓸만해 보인다. 추가적으로 PEiD의 userdb.txt 파일에 대한 스캐닝도 지원하기 때문에 자율성도 존재한다.


  하지만 exeinfo PE의 경우 GUI 툴이라서 자동화가 쉽지 않고 개인적으로 필요한 만큼 업데이트가 빠르고 다양하지도 않으며 userdb.txt 파일을 사용하는 방식도 쉽지 않았다. 물론 모든 것을 직접 만드는 것 보다는 괜찮은 도구를 사용하는 것이 좋지만 yara라는 좋은 툴이 이미 존재하기 때문에 이미 이 yara와 이미 어느 정도 쓸만한 userdb.txt를 기반으로 추가적인 시그니처를 만들어서 그때그때 추가하기로 했다.





1. yara 룰 변환


  이미 만들어진 userdb.txt를 yara 룰로 변환하는 파이썬 스크립트가 있다. userdb.txt는 exeinfo PE에서 제공되는 최신 DB를 사용하였다.

[ https://blog.didierstevens.com/2015/03/18/update-peid-userdb-to-yara-rules-py/ ]


> peid-userdb-to-yara-rules.py userdb.txt -p > userdb_new.yar


  만들어진 yara 룰을 이용해서 테스트를 해보겠다.

> yara32.exe userdb_new.yar example.exe


  사용해 보면서 알게된 점이지만 시그니처가 다양하기도 하고 짧은 것도 존재하다 보니 적어도 몇 개 씩은 걸린다. 개인적으로는 더 가능성이 높더라도 하나의 결과만 나오는 것 보다는 몇 개 정도의 결과를 가지고 판단할 수 있는 방식이 더 괜찮아 보인다.


  참고로 yara에서 맞지 않아서인지 에러가 나오는 시그니처들이 약간 존재하는데 이 정도는 없어도 될 것 같다는 생각에 그 부분들은 삭제하기로 했다.





2. yara 룰 추가


  룰을 어떤 방식으로 추가할지는 본인의 선택일 것인데 개인적으로 Packer나 Protector들에 대한 분류 보다는 AutoIt이나 AutoHotKey 같이 스크립트를 바이너리로 변환한 것들을 인식하고 싶었으며 이러한 바이너리들은 String 만으로도 충분한 결과들을 볼 수 있기 때문에 그냥 간단하게 만들어 보았다. 사실 이렇게 하는 방식은 좋지 않아 보이지만 어차피 하면서 수정해 나가야 하기 때문에 예시로 사용한다.


  다음은 AutoHotKey의 B 버전에 대한 룰이다.


rule new_AutoHotKey_B_x86

{

    meta:

        description = "[AutoHotKey_B_x86]"

        ep_only = "false"

    strings:

        $version = {76 65 72 73 69 6F 6E 3D 22 31 2E 30 2E}

        $autohotkey = {6E 61 6D 65 3D 22 4D 69 63 72 6F 73 6F 66 74 2E 57 69 6E 64 6F 77 73 2E 41 75 74 6F 48 6F 74 6B 65 79 22 0D 0A 09 74 79 70 65 3D 22 77 69 6E 33 32 22}

        $arch = {70 72 6F 63 65 73 73 6F 72 41 72 63 68 69 74 65 63 74 75 72 65 3D 22 58 38 36 22}

    condition:

        $version and $autohotkey and $arch

}


  각각 다음과 같은 문자열들이다. 오토핫키의 x86 버전은 문자열 정보가 리소스 부분에 잘 나와 있어서 직관적으로 사용하였다. (버전의 경우 1.0 대가 B이며 L 버전이 1.1부터 시작한다)


[ version="1.0. ]

[ name="Microsoft.Windows.AutoHotkey"

type="win32" ]

[ processorArchitecture="X86" ]


  ep_only의 경우 여기서는 "false"를 사용했다. 사실 이것은 PEiD에서 사용된 것으로 보이며 실제 yara에서는 이것보다는 condition 부분이 중요하다. "true"를 사용하는 경우 다음과 같이 변수 뿐만 아니라 추가적인 명시가 필요하다.


condition:

    $a at pe.entry_point


  strings 부분은 변수들에 대해 Hex 값을 지정하였다. 중요한 부분은 condition인데 여기서는 2개의 and 연산을 통해 3 변수 모두 충족되어야 하는 것이 조건이다. and 외에도 or, not 등이 사용될 수 있다. 다음은 3가지 변수 모두 충족됨과 동시에 변수 $ansioruni가 존재하지 않아야 하는 조건이다.


condition:

    ($version and $autohotkey and $arch) and (not $ansioruni)





3. 예제 ( ELF )

  다음은 Avast의 Retdec Team에서 공개한 UPX 시그니처의 일부이다.


import "elf"


rule upx_arm_391_lzma

{

meta:

tool = "P"

name = "UPX"

version = "3.91 [LZMA]"

source = "Made by Retdec Team"

pattern = "00000000F04F2DE930D04DE200308DE50030D0E50250D0E501E0D0E500C09DE514308DE55C309DE50040A0E300408CE5004083E514C09DE50130D0E503308CE0"

start = 380

strings:

$1 = { 00 00 00 00 F0 4F 2D E9 30 D0 4D E2 00 30 8D E5 00 30 D0 E5 02 50 D0 E5 01 E0 D0 E5 00 C0 9D E5 14 30 8D E5 5C 30 9D E5 00 40 A0 E3 00 40 8C E5 00 40 83 E5 14 C0 9D E5 01 30 D0 E5 03 30 8C E0 }

condition:

$1 at elf.entry_point + 380

}


  ELF 포맷에 맞게 "elf"를 import해서 자동으로 EP 즉 elf.entry_point를 지정하여 시그니처 범위를 자동으로 Entry Point로 지정할 수 있다.



Posted by SanseoLab



1. 종류

2. 디컴파일

.... 2.1 AutoHotKey_B

.... 2.2 AutoHotKey_L





1. 종류

  오토핫키의 경우 여러 종류가 있다. 공식 홈페이지에서 다운로드 받을 수 있는 공식 버전들부터 살펴보면 버전 1.01.1이 나뉜 것을 볼 수 있다. 이 외에도 아직 알파 버전이지만 2.0도 존재하며 공식 버전은 아니지만 H 버전도 존재한다. 여기서는 B, L 버전만 다룰 것이며 H 버전 및 2.0 버전은 L 버전을 기반으로 하는 것으로 보아 디컴파일 방식은 동일할 것으로 추측하여 제외하기로 한다.


  버전 1.0은 AutoHotKey Basic 또는 AutoHotKey_B로 불린다. 그리고 버전 1.1은 AutoHotKey_L로 불린다. 굳이 같은 공식 버전인데도 이렇게 나뉘는데는 이유가 있다. 2003년 경 원래 개발자가 개발한 버전이 있었는데 조금씩 업데이트 되다 2009년을 마지막으로 안정화되어 이제 추가적인 기능 추가는 없는 상태이다. 이것이 현재 AutoHotKey_B로 불리는 버전이다. AutoHotKey_L 즉 버전 1.1은 다른 개발자가 AutoHotKey_B를 기반으로 기능을 추가해 가고 있는 버전으로서 이후 공식 버전이 되었고 현재도 지속적으로 업데이트 중이다. L 버전은 B 버전을 포함한다.


  공식 버전들 외에도 AutoHotKey_H 버전도 존재한다. [ https://hotkeyit.github.io/v2/ ] 이것은 또 다른 개발자가 AutoHotKey_L 버전을 기반으로 멀티 쓰레딩 등의 기능을 추가한 버전으로서 L 버전의 업데이트에 맞추어 업데이트된다. 또한 L 버전을 포함한다. 


  참고로 H 버전은 이러한 특징 외에도 다른 특징이 있다. C나 파이썬 같은 다른 언어를 이용해 개발하면서 H 버전에서 제공되는 AutoHotKey.dll을 임포트하여 함수를 사용할 수 있는데 이를 통해 타 언어 개발 환경에서도 오토핫키를 사용할 수 있다.





2. 디컴파일

2.1 AutoHotKey_B

  오토핫키는 오토잇(AutoIt)과 비슷하게 Ahk2Exe.exe를 이용해 ahk 소스 코드를 exe 바이너리로 변환할 수 있다. 그리고 변환 시 비밀번호를 입력하여 디컴파일을 방해할 수 있다. 그리고 PE 적인 특징을 보자면 자동으로 upx를 이용해 압축해 준다.


  변환된 바이너리는 exe2aut라는 도구를 이용해 디컴파일을 할 수 있다. 만약 비밀번호가 걸려 있다면 인자로 넣어야 한다. 하지만 구조 상 cmp 문으로 비밀번호를 비교하는 부분을 디버깅을 통해 어셈블리에서 찾을 수 있기 때문에 exe2aut를 수정하여 비밀번호를 추출하는 도구도 존재한다.


[ https://github.com/Kalamity/Exe2AhkPatched ]


  결론적으로 B 버전은 위의 Exe2AhkReturnPassword.exe 또는 Exe2AhkAnyPassword.exe를 통해 디컴파일을 쉽게 진행할 수 있다. 바이너리가 비밀번호에 걸려있지 않은 경우 인자로 바이너리를 넣으면 두 프로그램 모두 ahk 파일을 반환한다. 비밀번호에 걸려있는 경우에는 exe2aut 처럼 두 번째 인자로 비밀번호를 넣으면 된다. 여기까지는 exe2aut와 사용법이 같다.


  Exe2AhkReturnPassword.exe는 바이너리에 비밀번호가 걸려있는 경우 비밀번호를 반환해 준다. 이 비밀번호를 가지고 두 번째 인자로 넣어서 스크립트를 추출할 수 있다. Exe2AhkAnyPassword.exe는 더 간단한데 비밀번호에 걸려있다고 하더라도 비밀번호를 반환하는 것이 아니라 바로 스크립트 추출까지 진행해 준다. 그렇기 때문에 비밀번호의 유무에 상관없이 스크립트를 추출하고 싶다면 Exe2AhkAnyPassword.exe를, 비밀번호를 확인하고 싶다면 Exe2AhkReturnPassword.exe를 사용하면 된다.


  참고로 바이너리는 upx로 패킹된 상태 그대로여야 인식되며 그렇지 않으면 notarc라는 에러가 발생한다.



2.2 AutoHotKey_L

  현재 가장 많이 사용되는 버전으로 보인다. 이 버전은 과거 버전과 달리 PE 파일에, 정확히 말하자면 리소스 섹션의 RCDATA에 스크립트가 그대로 존재하기 때문에 쉽게 추출할 수 있다. 이것은 ANSI 및 Unicode 버전 모두 호환된다. 다음 링크의 파이썬 코드를 이용하자.


[ http://anch0vy.tistory.com/21 ]


  Ahk2exe 사용 시 추가 옵션으로 mpress 패커를 이용한 패킹이 지원된다. mpress.exe를 같은 폴더에 넣고 이 옵션을 체크하면 바이너리 생성 및 생성된 바이너리를 패킹까지 해준다.


  Mpress로 패킹된 경우 리소스 섹션의 RCDATA도 같이 패킹되기 때문에 스크립트를 추출할 수 없으며 mpress를 언패킹해야 가능하다. 먼저 mpress 용 언패커를 찾아보니 찾을 수 없었고 버전도 다양하기 때문에 자동화는 포기했다. 대신 간단하게 바이너리를 실행시킨 후 Attach하면 이미 언패킹이 끝나 있기 때문에 Dump하고 여기서 추출하면 된다.


  또는 간단한 패커이기 때문에 H/W Breakpoint를 이용하여 언패킹 후 덤프를 뜨면 된다. (PUSHAD 이후 스택의 주소들 중 하나에 H/W BP를 걸고 F9를 누르면 JMP문에서 BP가 걸리는 것을 확인할 수 있다. JMP문 바로 위가 POPAD이기 때문. 이후 JMP문 다음부터가 진짜 OEP이다. 여기서는 단지 소스 코드가 위치한 부분만 언패킹되면 되기 때문에 간단하게 덤프 후 스크립트를 추출하면 된다)


  참고로 Dump 한 바이너리의 rcdata를 살펴봐도 보이지 않는다. 그 이유는 일반적으로 패킹 시 리소스 섹션은 제외되며 (rcdata 말고) 언패킹 이후에는 rcdata가 리소스 섹션의 rcdata 부분이 아닌 데이터가 영역 부분에 언패킹되기 때문이다. 하지만 링크의 파이썬 스크립트는 시그니처를 기반으로 하기 때문에 위치와 상관없이 간단하게 스크립트를 추출해 준다.



Posted by SanseoLab
이전버튼 1 이전버튼

블로그 이미지
Malware Analyst
SanseoLab

태그목록

공지사항

Yesterday
Today
Total

달력

 « |  » 2018.5
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 31

최근에 올라온 글

최근에 달린 댓글

글 보관함