본문 바로가기

[PROGRAMMING]/▶Python

악성코드 샘플 수집스크립트 mwcrawler.py 윈도우 버전으로 포팅하기(B)

<블로그 포스팅용>

상세 분석

등록된 웹사이트 URL을 기반으로 악성코드를 수집하는 mwcrawler.py를 windows 버전으로 포팅한 것입니다.

실행방법은 윈도우에서 더블클릭으로 실행하여 메뉴를 선택하면 수집이 시작됩니다.

메뉴중에 1번은 프록시 IP/PORT를 설정해서 수집을 할 수 있고 2번은 기존과 동일하게 선택과 동시에 바로 수집을 합니다.

수집된 파일의 저장되는 경로는 C:\malware\unsorted\디렉토리 형태로 저장됩니다.

-

스샷과 코드 수정한부분 등록 할 예정

-

코드 수정

1. 프록시서버를 사용하는 환경을 위하여 프록시 IP/PORT를 세팅할 수 있도록 수정했습니다.

2. magic 모듈을 제거하고 읽어들인 파일의 바이너리 데이터를 기반으로 exe, dll, sys, pdf, doc 등의 확장자를 검증하도록 pefile모듈을 사용하여 작성했습니다

3.일반적인 PE외의 charicteristics값중에 reserve나 debug등이 있을 경우 special PE 디렉토리에 저장하도록 수정했습니다.

4. 파일이 저장되는 경로를 윈도우경로로 수정했습니다.

5. 저장되는 경로가 잘못되어 발생하는 오류를 수정했습니다.

 

코드 수정 계획

1. 현재 디버깅용으로 수정하지 않아서 디버깅용 로그는 따로 관리하도록 할 계획입니다.(현재는 육안으로 보기에는 좀 지저분합니다 오류는 아니에요 ㅎㅎ;;)

2. 모든 URL이 페이지 수와 상관없이 21회 반복되는 문제를 동적으로 탐색하도록 수정할 계획입니다.

3. Thug 모듈을 제거할 계획입니다.

 

소스코드


 

win_mwclawler.py

  

위의 코드는 기존에있던 mwcrawler.py에서 윈도우에서 실행되되록 수정한 win_mwcrawler.py 입니다.

빨간박스로 체크된 부분이 제가 수정한 부분입니다.

우선 첫번째로 mwcrawler.py소스를 실행시키면 모듈관련해서 에러가 발생이 되는데요.

모듈이 없는 경우가 대부분이고 모듈선언이 잘못된 경우입니다.

 

첫번째 오류로 BeautifulSoup 관련해서 오류가 발생합니다. 만약 BeautifullSoup 모듈이 없다면 설치를 해야합니다.

하지만 제 시스템에는 모듈을 설치한 상태였기 때문에 모듈 미설치로 인한 오류는 아니고 모듈이름이 잘못되어 발생한 오류 입니다.

즉 from BeautifullSoup import BeautifullSoup as bs -> from bs4 import BeautifulSoup as bs 와같이 변경하면 됩니다.

 

그리고 두번째 에러는 import magic 모듈이 없다는 에러였습니다.

해당 모듈을 사용하는 부분을 확인해보니 다음과 같은 코드로 함수로 구현하여 사용 하고있었습니다.

 

def gettype(file):

ms = magic.open(magic.MAGIC_NONE)

ms.load()

return ms.buffer(file)

 

함수 이름이 gettype으로 이름만 봐도 어떤의도로 사용되어지는지 짐작할 수 있었습니다.

파일을 인자로 gettype(file) 함수를 호출하여 파일을 함수에 넣어 버리면 파일타입이 리턴되겠구나 예상했는데 비슷한거 같습니다.

https://pypi.python.org/pypi/python-magic/ 에서 확인하면 파일타입을 확인 할 수 있는 모듈로 나와있습니다.

그래서 이 모듈을 windows버전에서 설치하고 사용한 사례가 있어 몇번의 시도끝에 설치는 성공적으로 했으나 윈도우에 설치된 magic모듈의 코드내용과

wmcrawler.py모듈에서 사용된 모듈의 코드내용이 서로 일치하지 않아 에러가 발생합니다.

그래서 magic모듈의 기능이 파일타입을 체크하는 모듈이므로 해당되는 코드부분과 모듈 선언부분을 주석처리 하고 파일타입을 체크할 수 있는 모듈을 직접 작성했습니다.

작성한 모듈이름은 filecheck.py이고 관련 내용은 뒤에서 설명하겠습니다.

 

그리고 프록시 서버를 경유하여 외부 인터넷망과 연결할 경우 프록시 세팅을 가능하도록 ProxySetting함수를 만들고 프록시를 세팅한 header를 리턴하도록 구현하여 parse함수에

인자로 전달합니다.

parse함수는 프록시가 세팅된 header로 Request하고 BeautifullSoup모듈을 이용하여 Response데이터를 파싱할 수 있도록 수정하였습니다.

 

그리고 decisor 함수에서 리눅스 경로로 지정된 부분을 윈도우 디렉토리 형태로 변환 하였으며, 에러를 리턴한 URL과 커넥션을 성공한 URL을 구분하고 time모듈을 이용하여 각각 에러와 커넥션한 시간을 로그형태로 저장하도록 변경하였습니다.

 

그리고 SaveLogData,TimeAndLogSave,Gettiime함수를 만들어 저장되는 형태를 각각HTML 데이터로 저장하도록 하고 각 값들을 MD5(Virustotal과 연결), 악성코드URL, 샘플이 저장된 하드디스크 경로를 하이퍼링크로 만들어 저장할 수 있도록 구현했습니다.

  

filecheck.py

 

[그림.2]

 

mwcraler.py 원본 파일에서 사용되던 magic모듈 사용이 어렵기 때문에 파일체크를 할 수 있도록 간단히 만들었습니다.

기능은 각각 파일타입의 특성에따라 간단히 체크할 수 있도록 구현했습니다.

바이너리에서 'PE'시그니처를 찾고 찾은 위치에서부터 IMAGE_FILE_HEADER의 Charicteristics 값을 체크하여 exe파일인지 dll파일인지 체크하도록 했습니다.

 

그림추가

 

EXE파일과 DLL의 경우 IMAGE_FILE_HEADER의 Charicteristics 값에 차이가있습니다.

DLL같은경우 0x200 IMAGE_FILE_DLL값이 있고 EXE같은 경우는 0x200 IMAGE_FILE_DLL 값이 들어있지 않습니다.

이러한 차이점을 이용하여 코드로 구현하였습니다.

 

그림추가

 

그리고 SYS파일은 EXE와 DLL과 동일하게 실행파일입니다. 정확히는 드라이버 파일인데요.

이 파일의 특성은 IMPORT Adress Table에 다음과 같은 파일을 필수적으로 갖고있습니다.

ntoskrnl.exe, hal.dll, ndis.sys, bootvid.dll, kdcom.dll을사용 합니다.

해당내용의 확인은 Python의 PEFILE이라는 모듈의 코드를 보면 def is_driver(self)함수의 내용으로 확인 할 수 있습니다.

 

그리고 PDF,DOC,HTML파일을 각각 파일의 특성에 맞게 체크할 수 있도록 구현하였습니다.

 

[그림.3]

 

win_wmclawler.py를 실행하여 한개의 사이트를 대상으로 악성코드 샘플을 모두 수집했다면 수집한 과정의 로그들을 각각 그림.3과 같이 HTML로 저장이 됩니다.

c:\malware\log\14_01_12(2014년1월12일)의 디렉토리이며 하위 디렉토리에 connection_success_log, error_log의 디렉토리에 저장이 됩니다.

그리고 저장된 파일을보면 D140112_T141430_malc0de.com.html(D날짜_T시간(14시14분30초)_로그가 발생된 사이트) 형식으로 저장합니다.

[그림.4]

 

그리고 그림.4와같이 샘플당 1개씩 관련된 데이터를 정리하여 하이퍼링크를 걸어줍니다.

 

 

[그림.5]

 

MD5항목은 MD5해쉬값으로 Virustotal에 검색할 수 있도록 URL을 연결하여 악성코드 정보를 검색할 수 있습니다.

 

 

 

[그림.6]

 

그리고 URL은 악성코드가 다운된 URL을 하이퍼링크로 걸어 다시 다운받을 수 있게 했습니다.

[그림.7]

 

그리고 System Direcroy Open:Click기능 입니다.

각각 악성코드의 샘플의 저장 디렉토리  C:\malware\unsorted\exe\해쉬값(디렉토리) 형식으로 저장이 되고 해쉬값 디렉토리 밑에 샘플이 저장이됩니다.

이때 시스템 디렉토리의 경로를 하이퍼링크로 걸어 확인할 수 있도록 구현했습니다.

[그림.8]

 

다음은 Connection Error Log 입니다.

이부분은 간단히 에러가 발생된 시간과 에러코드 그리고 에러가 발생한 URL을 보여줍니다.

win_wmcrawler.py(windows version)와 wmcrawler.py(linux version원본파일)에서 동일하게 Request할때 403 에러가 발생하는 경우가 생깁니다.

그러나 URL을 브라우저를 통해 직접 접근해보면 악성코드는 정상적으로 다운이 되어지는데요.

테스트결과 이부분의 문제점이 urllib2로 구현할때 헤더세팅이 잘못 된것으로 보여집니다.

urllib2.request할때 웹서버에서 정상적인 요청이 아닐경우 403에러로 다운을 하지 못하는 경우가 발생하는것 같습니다.

[그림.9]

마지막으로 악성코드를 수집한 화면입니다.

해쉬값으로 검증하여 동일한 파일이 있는지 체크하기 때문에 파일이 중복되는 경우는 없습니다.

 


기능 추가

 

악성코드를 분석하기 위해 샘플을 수집하고 수집된 수많은 샘플들을 일일이 오픈하여 동적분석을 하거나 PEVIEW로 확인하여 예측하고 정리하기는 많은 시간이 소요됩니다.

그래서 기존의 win_wmcrawler.py를 수정하여 기능을 추가하였습니다.

악성코드 분석을 공부하시는 분들에게는 샘플을 쉽게 확보하고 골라서 분석할 수 있는 즐거움이 있을것같습니다. ㅎㅎ


[그림.11]

우선 기존의 악성코드를 수집하는 win_mwcrawler에는 수집한 파일을 대상으로 파일사이즈 및 실행파일에 대한 정보가 없었는데 이번에 그 기능들을 추가하여 수집한 샘플들의 정보를 확인하는데 있어서 시간을 단축 할 수 있도록 수정 하였습니다. 

수정한 win_mwcrawler 실행하고 악성코드 샘플들을 수집하고 나면 그림.11과 같이 각 악성코드 샘플마다 분석을 진행하게 되는데 파이썬 모듈인 Pefile을 사용하여 개발 하였습니다.

우선 처음 악성코드를 수집하게 되면 각 파일의 정보들 Date, FileType,MD5,URL,Filesize를 수집한 후에 해당 악성코드를 별도로 작성한 peinfo.py로 넘어가서 이곳에서 pefile모듈을 불러와 악성코드의 PE구조를 분석하고 리포트 하도록 동작합니다.


[그림.12]

 

악성코드가 PE분석이 완료되면 리포트 되는 형식은 다음과 같습니다.

IMAGE_DOS_HEADER
IMAGE_NT_HEADER
IMAGE_FILE_HEADER
IMAGE_OPTIONAL_HEADER
IMAGE_DATA_DIRECTORIES
IMAGE_SECTION_HEADERS
IMPORT_INFORMATION

 

헤더정보들과 IMPORT 정보들만 확인 가능하게 구현했고 IMPORT_INFORMATION 항목에서 악성코드가 사용되는 함수들을 확인 할 수있기 때문에 저 항목을 통해 대략 어떤 성향의 악성코드인지 파악하고 샘플을 분류할 수 있습니다.

다음은 각각 항목들을 클릭 했을때의 리포트 결과입니다.


[그림.13 IMAGE_OPTIONAL_HEADER]


[그림.14 IMAGE_DATA_DIRECTORIES]

[그림.15 IMAGE_SECTION_HEADER]


[그림.16 IMPORT_INFORMATION]

 [그림.17 peinfo.py]





 

실행시 주의사항: 백신의 실시간탐지 기능을 정지하고 돌려야합니다.