Win32:PcClient-ZE

Posted at 2010/03/21 16:28 // in Malware // by 엔신

clip_image001[4]

http://www.virustotal.com/ko/analisis/a593b6f89f8a5c62c8c2201d78353877df3c3905a952466b8814f04a8de35fd4-1268745275

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

1. 악성코드 전달

clip_image001

이메일의 스팸필터에 안걸리고 세나사진이 전달되었다. 다운로드 받았더니 '스키장 사진들.exe' 파일이 존재한다. 당연히 악성코드라는 느낌이 왔고, 검사하였더니 위와 같은 진단 결과가 나왔다.

2. Unpacking

일단 UPX로 packing되어 있어서 unpacking하였다. 사실 오랜만에 MUP 할려고 하다 보니 방법이 기억이 나지 않아서 좀 헤맸다. UPX MUP 방법 참조하시길.

3.코드 시작

00401780 55 PUSH EBP

00401781 8BEC MOV EBP,ESP

00401783 6A FF PUSH -1

00401785 68 00214000 PUSH 스키장_?00402100

0040178A 68 06194000 PUSH 스키장_?00401906 ; JMP to msvcrt._except_handler3

0040178F 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]

00401795 50 PUSH EAX

00401796 64:8925 00000000 MOV DWORD PTR FS:[0],ESP

이 악성코드 프로그램은 MFC로 만들어진 코드라서 실제로는 위 지점이 실제 OEP에서는 Exception Handler를 먼저 설치하고 진행이 되지만, 똑똑한 IDA는 이러한 MFC 진행 부분을 제외하고 아래와 같이 WinMain이 있는 실제 소스부터 보여준다.

clip_image002

실제 소스코드에서는 GetSystemDirectoryA 함수를 이용하여 시스템 디렉토리("C:\Windows\System32")를 구한 값에 "\fywd.dll" 문자열을 결합한다.

4. 악성코드 DLL 파일 저장

clip_image003

결합한 문자열의 DLL 파일을 생성하기 위해 FindResourceA, SizeofResource, LoadResource, GlobalAlloc, LockResource, GlobalFree 함수를 이용한다(CALL 00401580). 세부적으로는 0x65 ID를 갖는 DLL 리소스를 찾아서 리소스를 로드하고 GlobalAlloc 함수를 이용하여 메모리 상에 악성코드 데이터를 할당한다.

clip_image004

GlobalAlloc 함수를 이용하여 메모리에 할당한 악성코드 영역을 CreateFileAWriteFile 함수를 이용하여 파일로 저장한다(CALL 004014E0).

5. 프로세스 생성

그 후 CreateProcessA 함수를 이용하여 "\Program Files\Internet Explorer\iexplore.exe"를 hide 상태로 실행시킨다.(ShowWindow = FALSE)

clip_image005

실제로 익스플로러 프로세스가 실행 중이지만, 작업표시줄에는 익스플로러가 나타나지 않는다.

6. DLL Injection

clip_image006

VirtualAllocEx 함수로 생성한 프로세스에 메모리를 할당하고, WriteProcessMemory 함수를 써서 데이터를 쓴다. 어떤 데이터가 들어가는지 확인해보니 "C:\WINDOWS\system32\fywd.dll" 라는 문자열 29Byte만 들어가고 있다.

clip_image007

그 후 GetModuleHandleA 함수로 Kernel32의 LoadLibraryA 모듈을 핸들값을 리턴 받는다. 그리고 나선 GetProcAddress 함수로 LoadLibraryA 함수의 메모리 어드레스를 리턴받는다.

마지막으로 CreateRemoteThread 함수를 이용하여 생성한 ixplore.exe 프로세스에서 LoadLibraryA 함수를 쓰레드로 실행시킨다. 그 매개변수가 되는 DLL이 "C:\WINDOWS\system32\fywd.dll"의 데이터가 있는 메모리 영역이다(VirtualAllocEX으로 문자열 넣은 곳). (DLL Injection)

여기서 중요한 것은 DLL 파일을 동적으로 분석하는 것은 IDA와 같은 프로그램을 이용하여 정적 분석하면 되지만 동적 분석하기 위해서는 해당 스레드가 실행되는 순간에 break를 걸어서 멈춰야 한다.

참고사항

clip_image008

OllyDBG의 경우 Debugging Options -> Events 탭에 보면 Break on new thread 메뉴를 통하여 스레드 생성 시점에 브레이크를 걸 수 있다. 그러면 해당 쓰레드 시작점부터 동적 분석이 가능해진다. 단 이 이벤트를 항상 켜둘 경우 상당히 자주 브레이크 포인트를 걸리게 되므로 사용시에만 설정하고 다시 해제하는 것이 좋다.

하지만, 지금 같은 경우는 Process가 다르므로 Break on new module(DLL)이나 break on new thread에 이벤트를 설정하고 진행한다고 하여도 브레이크는 걸리지 않는다.

동적 분석하고 싶다면, hide로 실행중인 ixplore.exe 프로세스를 새로운 디버거 프로세스로 attach한 후 Break on new module 이벤트를 걸어 놓고 Run 상태로 만들어 놓으면 된다. 그러고 나서 다시 원래의 프로세스로 와서 CreateRemoteThread 함수를 실행하면 ixplore.exe가 Attach 되어 있는 디버거에서 Break가 걸릴 것이다. Break가 걸리면 DLL의 OEP로 찾아가서 브레이크를 걸고 진행하여도 되고 IDA에서 한번에 DllMain의 위치를 확인하여 브레이크를 걸고 진행하여도 된다.

DLL 파일의 동적 분석을 위해 다른 디버거를 통해 DLL의 시작점에서 break를 걸어 놓고 진행중이던 기존 "스키장 사진들.exe" 파일의 디버깅을 이어서 진행하겠다.

7. Registy

이번에는 레지스트리 등록과 관련된 함수를 호출하게 된다.(함수 호출 지점 004014AE) 레지스트리 부분은 악성코드의 시작과 관련된 작업을 하게 될 것이다.

clip_image009

레지스트리 부분은 악성코드가 가동될 수 있도록 만드는 내용을 삽입 할 것이다.먼저 "%SystemRoot%\System32\fywd.dll" 의 문자열을 특정 영역(EDI)에 복사해놓는다.

그리고 나서 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\Parameters Key를 Open하고 ServiceDLL Key를 삭제한다.(RegDeleteValueA) 그리고 ServiceDLL 이라는 Key를 다시 생성하여 "%SystemRoot%\System32\fywd.dll" 문자열을 넣는다.

clip_image010

삭제 전(w32time.dll)

clip_image011

삭제 후 추가된 Key(fywd.dll)

윈도우 시각 동기화 부분을 수정하여 악성코드가 실행되도록 변조한 것이다.

8. 악성코드 제거

마지막 단계로 악성코드를 제거하여 흔적을 지우는 단계이다.(004014B3에서 CALL 발생)

clip_image012

GetModulFileNameA 함수를 통해 현재 실행중인 악성코드 "C:\세나 사진\스키장 사진들.exe"의 전체 경로를 찾은 다음, GetShortPathNameA 함수를 통해 "C:\세나~1\스키장~4.exe"처럼 짧은 경로로 줄여준다.

그리고 GetEnvironmentVariableA 함수에 COMSPEC 환경변수를 넣어주어서 "C:\WINDOWS\system32\cmd.exe" 문자열을 얻어 온다. COMSPEC은 기본 명령프롬프트 주소를 리턴 받을 수 있다.

lstrcpyA 함수와 lstrcatA 함수를 이용하여 구해온 문자열을 합쳐 "C:\Windows\sytem32\cmd.exe /c del C:\세나~1\스키장~4.EXE"를 만든다.

GetCurrentProcess 함수를 이용하여 프로세스의 핸들값을 구하고 SetPriorityClass 함수를 이용하여 프로세스의 우선순위를 REALTIME_PRIORITY_CLASS로 변경한다. 그리고 GetCUrrentThread 로 현재 스레드의 핸들값을 구하고 SetThreadPriority 함수를 이용하여 우선순위를 THREAD_PRIORITY_TIME_CRITICAL로 변경한다.

clip_image013

그 후 CreateProcessA 함수의 매개변수로 미리 만들어 놓은 "C:\Windows\sytem32\cmd.exe /c del C:\세나~1\스키장~4.EXE" 문자열을 넣어 기존 악성코드를 지우는 프로세스를 가동시킨다.

그리고 또 다시 SetPriorityClass 함수를 이용하여 우선순위를 IDLE_PRIORITY_CLASS로 만들고 SetThreadPriority 함수를 이용하여 THREAD_PRIORITY_IDLE 상태로 만들고 난 다음 ResumeThread로 정지 상태의 스레드를 가동시킨다.

9.악성코드 실체인 DLL 분석

clip_image014

DllMain에서 보게 되면 CreateThread를 생성하게 되고 별다른 작업을 하지 않는다.

clip_image015

쓰레드 안으로 들어 오게 되면 또 CreateThread가 있다. 쓰레드 안에 쓰레드로 실행되지만 쓰레드의 경우는 자식 부모관계가 없으므로 오로지 프로세스 아래 쓰레드 집합이 된다.

일단 보면 WSAStartup 함수를 호출한 다음 CreateThread -> WaitForSingleObject -> CloseHandle –> Sleep 으로 15,000 ms 마다 반복적으로 작업을 실행하게끔 하고 있다.

clip_image016

다시 쓰레드 안으로 들어가게 되면 "pass2" 문자열을 출력한다. 그리고 나서 CALL 100F730 함수를 호출하여 특정 도메인을 만들어 낸다.("dltkdgksskfk.3322.org") 하지만 현재에는 DNS 싱크홀 상태이므로 127.0.0.1 도메인을 결과값으로 받게 되어 있다.

그 후 socket을 생성하여 connect 시도 한다. connect 되지 않았다면, ExitThread 함수를 이용하여 스레드를 정지시킨다.

clip_image017

connect 되었다면, GetComputerNameA 함수를 이용하여 컴퓨터이름을 구하고 GetVersionExA 함수를 통해 시스템 Version 정보를 확인한다.

clip_image018

Version 정보를 통하여 각 시스템의 정해놓은 문자열을 복사한다.

clip_image019

현 상황에서는 정해진 문자열을 조합하여 "Win XP SP3 (Build 2600)" 라는 문자열을 만들었고, GlobalMemoryStatus 함수를 이용하여 시스템 메모리량을 체크하고 있다.(여기서는 256MB)

clip_image020

그렇게 파악한 시스템 정보 데이터를 가공하여 send 함수를 통해 열어 놓은 socket을 이용하여 데이터 전송을 시도한다. 전송에 실패한 경우 closesocket으로 socket을 닫아버린다.

clip_image021

강제로 성공하게 한 후 진행하여 보면 recv 함수를 통해 열린 socket을 통해 어떠한 데이터를 전달받게 된다.(실제 서버가 싱크홀로 연결 안되니 지금은 확인이 불가능하다)

역시나 정상적으로 recv 되지 않은 경우 closesocket 함수를 이용하여 소켓을 닫고 정상적으로 받은 경우 계속 진행하게 된다.

정상적인 경우 지금부터 상당히 여러 가지 분기를 만나게 된다.

1000FAFF . 0F84 95020000 JE fywd.1000FD9A

이 지점을 잘 기억해 두는 것이 좋다.

분기가 발생할 경우 CreateThread 함수를 호출하게 되는데, 이 지점은 위쪽에서 먼저 지나온 Socket 함수를 이용하여 소켓을 생성하고 Connect 함수를 이용하여 Connect를 시도하는 지점이다.

반대로 분기가 발생하지 않는 경우,

1000FB0D .^77 BF JA SHORT fywd.1000FACE

또 분기를 만나게 되는데, 여기서 분기가 발생하는 경우 다시 데이터를 받기 위해 recv 함수를 호출하는 지점으로 되돌아 가게 된다. 분기가 발생하지 않는 경우에는 또 매우 다양한 분기를 만나게 된다(1000FB17).

clip_image022

이 분기점에서는 16가지의 경우의 수가 존재하게 된다.(갑자기 짜증이 밀려온다.)

인내심을 갖고, 왼쪽부터 하나씩 확인해보겠다.

첫 번째.

clip_image023

보게 되면 SeShutdownPrivilege 특권을 이용하여 ExitWindowsEx 함수를 호출하고 있다. uFlags 매개변수로 0xC 값을 사용하고 있다. 0xC 값은 (EWX_POWEROFF | EWX_FORCE)를 의미하며 강제로 전원을 끄는 내용을 담고 있다.

두 번째.

clip_image024

두 번째의 경우 uFlags 매개변수로 0x6 값을 사용하고 있다. 이는 EWX_REBOOT | EWX_FORCE를 의미하며 이는 역시 강제 재부팅을 의미한다.

세 번째.

clip_image025

세 번째는 0x4 값을 사용한다. EWX_FORCE 값만 사용하여 강제로 프로세스를 종료시킨다.

네 번째.

이 경우에는 다시 recv 함수를 호출하는 지점으로 돌아가게 된다.

다섯 번째.

clip_image026

이 경우 URLDownloadToCacheFileA 함수를 이용하여 URL에 있는 파일을 캐시파일로 저장한다. 그리고 나서 GetUrlCacheEntryInfoA 함수를 이용하여 정상적으로 리턴 되는지 확인한다. 파일 다운로드를 하여 WinExec 함수를 이용하여 실행시키는 부분이다.

여섯 번째.

clip_image027

ShellExecuteA 함수를 이용하여 특정 URL open 하는 것으로 예상이 된다.(프로그램 실행도 가능하므로) 매개변수로 사용되는 부분은 소켓 통신이 되지 않아 확인이 불가하다.

일곱 번째.

clip_image028

keybd_event 함수를 이용하여 키보드 입력(dwFlags = 0(Key Down))을 발생(ECX)시키는데 그 전과 후에 있는 call 에서는 다음과 같이 Station과 관련된 함수들이 사용되고 있다.

clip_image029

Window Station에 대해서 아는 바가 없으므로 좀 더 공부해야겠다. 대충 판단 내린 것은 SYSTEM 권한으로 스테이션을 변경한 후, 키 입력을 발생시키고 다시 원래 사용자의 권한으로 스테이션을 변경해 놓는 내용으로 추측된다.

여덟 번째.

여덟 번째의 경우 그림을 삽입하지 않겠다 위처럼 keybd_event 함수를 이용하여 키보드 입력(dwFlags = 2(Key Up))을 발생(EDX)시킨다. 이 경우에도 스테이션 변경 작업이 동일하게 사용된다.

아홉 번째.

clip_image030

레지스트리의 w32time.dll이 등록된 키를 제거하고 새로운 키를 설정하는 부분이다. 이 부분은 원래 EXE 파일에도 들어 있는 내용과 동일하다.

열 번째.

clip_image031

이 경우 SetCursorPos 함수를 이용하여 마우스 커서 위치를 임의대로 변경한다.

열한 번째.

clip_image032

역시나 SetCursorPos 함수가 나왔으면 mouse_event 함수가 나올 것이다. 마우스 커서의 위치를 옮긴 다음 dwFlags = 0x2(MOUSEEVENTF_LEFTDOWN)를 발생시켜서 마우스 왼쪽 버튼이 클릭된 상태 이벤트를 발생시킨다.

열두 번째.

clip_image033

mouse_event 함수의 dwFlags = 0x4(MOUSEEVENTF_LEFTUP)를 발생시켜서 마우스 왼쪽 버튼의 클릭됐다가 Up 되는 상태를 발생시킨다.

열 번째, 열한 번째와 열두 번째가 결합되면 마우스의 커서 위치를 이동 후 클릭하게끔 만드는 것이다.

열세 번째.

clip_image034

열세 번째의 경우 더블 클릭을 의미한다.

열네 번째.

마우스 오른쪽 버튼 클릭(버튼이 눌린 상태)이다.

열다섯 번째.

마우스 오른쪽 버튼 클릭 Up이다.

열여섯 번째.

마우스 오른쪽 버튼 더블 클릭을 의미한다.

이 부분은 반복되는 부분이라 간략하게 기재하고 넘어간다.

10. 결론

시스템 종료

시스템 재부팅

프로세스 강제종료

프로그램 다운로드 후 실행

프로그램 실행 또는 웹 페이지 open

키보드 입력

마우스 입력

이 악성코드의 경우 이러한 제어 권한을 취득할 목적으로 만들어 진 것으로 보인다. 또한 시스템 OS Version과 Memory 정보를 수집한다. 현재 거의 모든 백신에서 진단하며 DNS 싱크홀 상태이므로 국내에서는 감염으로 인한 피해 상황은 발생하지 않을 것 같다.

정말 오랜만에 분석해본 악성코드로 생각보다 분석 자체는 수월하게 이뤄졌지만, 소요되는 시간이 오래 걸린 듯 하다.

자료백업용:암호걸려있음


이올린에 북마크하기
2010/03/21 16:28 2010/03/21 16:28

vmware에서 Kernel Debugging 하기

Posted at 2009/01/31 21:45 // in RCE // by 엔신
1.vmware에서 Serial Port 추가.
  use named pipe 선택
  \\.\pipe\com_1 입력

2.c드라이브에 boot.ini 파일에 추가
   multi(0)disk(0)rdisk(0)partition(1)\WINNT="Microsoft Windows 2000 Server Debug" /fastdetect /debugport=COM1 /baudrate=115200

3.부팅시에 해당 모드 선택하고 windbg에서 Kernel Debug 모드 선택하고 Baud Rate:115200, Port:com1 입력하면 연결

이올린에 북마크하기
2009/01/31 21:45 2009/01/31 21:45