custom packer 분석하다가, 블로깅도 뜸했고 해서 그냥 다운로더까지 분석해서 올려봅니다. ㅎ

단순 다운로더구요, 다형성 크립터로 보호되어있으며 원본 이미지 날림, 방화벽 우회도 하고 뭐 그렇습니다.

막상 다운로드하는 대상은 링크가 끊겨있어서 분석하지 못했고, 분석대상은 다운로더 자체의 행위입니다.

시작해볼까요?






일단 virus total에 올린 결과는 이와 같스뷘다.




진단명이 다양하죠? 같은 엔진을 쓰는 회사는 진단명이 같기도 하고 그러네요.

몇몇회사는 팩 자체를 잡는것으로 보이구요
(packed, xpack, krunchy등.. 다만 krunchy는 얘가 아닌 다른 팩인데 -_-; 잘못잡는듯 싶네요)

진단명이 제각각입니다. worm, trojan, backdoor, 등등.

요즘은 백신들이 다 샘플을 자동처리하기 때문에 진단명이 별 의미가 없습니다.

그럼 직접 분석해보죠.

일단 팩이 돼있나 봅시다.

"죄송..뭔지 몰겠다능.."


peid는 모르겠다고 하네요. 코드를 봐야죠.

일단 tls callback을 사용하나 확인해보고



저는 코드가 더러우면(disasm이 많이 깨져있으면) ida를, 깨끗하면 올리를 씁니다.

그리고 컴파일드 코드를 볼땐 둘다쓰죠-_-;;

진짜 crt은 ida가 flirt 작살이고, api정보와 디버깅능력은 olly가 더 맘에 듭니다.

jmp to xx 도 잘 보여주고요. dll 파싱능력도 좋고

플러그인도 좋고 뭐 그래서 큰 프로그램 볼 땐 둘다 동시에 쓰기도 합니다.

메인 flow는 ida로 따라가며 동시에 구간분석은 olly로 하곤 하죠.

이 패커는 이름없는 패커로, 단순히 복호화만 계속 해나가다 어느순간 원하는 작업을 합니다.

좋은 '디버거'가 필요하므로 올리면 필요충분입니다.


"ollydbg 출동!"





ep code입니다. 더 보면



다형성 크립터이며 단순 루프를 돌며 하단을 복호화하고, 복호화 한 곳은 또 그 아래를 복호화하고..

이런식으로 쭉 이어져있습니다.






저 위로 분기하는 jb 가 복호화 루프입니다. 복호화 루프는 죄다 위로 뛰는 jb더군요.

저 아래부분을 hwbp걸고 run하면







저렇게 복호화가 됩니다.

저런 루프가 수십개(ㅆㅂ)있었습니다.

그 부분은 생략!




다형성 복호화 부분을 지나면 아래 부분이 나옵니다.


자 뭔가 할것같은 코드입니다.

peb를 얻고, kernel32.dll의 imagebase를 얻어 함수에 넘깁니다.



함수에선 뭘할까요?



GetProcAddress 함수 포인터를 찾는군요.

import를 세팅해주기 위한거겠죠.







다시돌아와서, 이미지 바깥에 VirtualAlloc을 받은 다음에 image내의 특정 부분을 alloc받은 곳으로 복사합니다.

그리고 그곳으로 jmp 하는군요..




뛴 곳에서는 자기 자신의 image를 UnmapViewOfFile 해버립니다.

즉 자신exe를 메모리상에서 날려버리는거죠.





VirtualFree까지 합니다.





다시 그곳에 팩된놈을 놓으려는 거죠. 다시 0x400000에 Alloc합니다.




그리고 원본으로 보이는 값을 복사해넣습니다. 원본이 메모리상에 복구되었네요.









이제 원본이 쓰는 함수와 dll들을 import해줍니다.








패커의 영역은 여기까지입니다. 이제 oep로 jmp하죠.


이 놈을 덤프뜨고 importRec 해줘서 원본으로 unpack했습니다.


virus total에 돌려볼까요?


원본을 잡는 놈은 거의 없습니다.

안랩, 안티버, KAV(그 엔진을 쓰는 F-Secure), 맥어피, 트렌드 정도군요

얼마나 custom packer의 위력이 대단한지 알 수 있습니다.

모두 못풀고 잡기 급급하단 뜻이죠.

아니, 정정하죠. 저걸로 팩된 애들이 몇 안되니,
저거 하나 풀려고 코드넣기엔 시간/인력/코드 낭비란 말이 더 맞겠네요.
악성코드 제작자가 제대로 짚고 있는 겁니다.
굳이 어려운 packer를 쓰기보다,
단순한 packer를 직접 제작해서 조금 뿌리고 말면
av입장에선 그걸 굳이 풀기는 아깝고, 안풀자니 다 때려박아야하고, 괴롭죠.
새로운 차원의 접근이 필요한 시점이 이미 지나갔습니다.
지금이라도 따라잡아야죠.






자 다시 돌아와서, unpack된 원본을 분석해보죠.


어셈블리로 코딩을 했는지, startup 코드도 없이 아주 oep부터 깔끔하게 작업들어갑니다-_-;;



먼저 문자열을 만듭니다. 문자열은 "svchost.exe 자기자신의경로" 입니다.

즉 svchost.exe(윈도우즈 서비스프로그램입니다.) 를 띄우는데, 인자로 자기자신의 경로를 넘기는거죠.





프로세스를 생성합니다. 생성시 state를 CREATE_SUSPENDED로 넘깁니다.

프로세스를 생성만하고, 메인스레드를 멈춰놓는겁니다.





멈춰놓은 프로세스의 메모리에 write합니다. 자기자신의 image를 write하는겁니다.

즉 svchost.exe 더미를 띄워놓고, 자기자신을 그 속에 주입합니다.





그리고 context를 강제로 바꿔버리고 실행을 합니다. 즉 eip를 401000으로 바꿔버립니다.
code injection이죠.
그 후 ResumeThread해서 스레드가 실행되게 합니다.
그리고 이 프로그램은 종료되네요.
그림으로 보면 다음과 같습니다.



왜 이런 짓을 할까요?
아래 더 보시면 아시겠지만, malicious라고 그림에 표시된 부분이 이 다운로더가 진짜 원하는 작업입니다.
인터넷으로 다른 malware를 받아 실행하는거죠.
근데 인터넷에 접속하는 순간 방화벽이 깔려있으면 거기에 걸리게 됩니다.

그래서 방화벽이 신뢰하는 프로그램(svchost.exe)을 좀비로 내세워 그 프로그램이 인터넷 접속하는 것 처럼 속이는 거죠.


기초적인 방화벽 우회입니다.







그럼 이제 inject된 코드를 봐야겠죠?


역시나 깔~끔하네요 ㅎㅎ



하나하나 봐 나가죠.



네트웍 접속, ShellExecute를 위해 wininet.dll을 임포트합니다.






그 다음은 인자(argv[1])를 받아, 그 경로를 DeleteFileA 합니다.

아까 인자로 뭘 넘겨줬죠?

맞습니다. 다운로더 자신의 경로죠.

즉 자기자신을 지우는 또다른 기법인 셈이죠.






그 다음은 url문자열과 로컬 파일명을 만듭니다. 문자열은 삭제했구요. 링크는 깨졌더군요.






그다음 url에 접속해서 메모리에 읽어들입니다.





그리고 파일을 로컬에 write합니다. 즉 url상의 파일을 하드에 저장하는거죠^^





그 다음 ShellExecuteA로 그 파일을 실행합니다.







그 아래코드는 다음 문자열을 생성합니다. 즉 이 다운로더는 여러개의 파일을 다운로드/실행합니다.

그 문자열을 보니 아래와 같습니다.



모두 링크가 깨져있더군요 ㅎ





그리고 종료..





링크가 살아있다면 그 malware도 볼텐데 아쉬운 맘이 드는군요.

하지만 뭐 널린게 악성코드인데요 (아 슬프다)

담에 또 기회되면 다운로더가 아니라 본체를 분석해보죠.



매번 투덜거리는 거지만 짬을 내 블로깅 하기가 쉽지가 않네요. 귀촤뉘즘~~

그럼 이만.