본문 바로가기

My Study/Malware&Vulnerabilities

745.exe 바이러스 분석

뭐 바이러스 분석을 해본 경험이 없고 주말에 심심하던 찰나 잠깐 분석해봤습니다. 
그냥 제가 잠깐 볼려고 쓴거라.. 읽어도 도움 될만한건 없는거 같네요;;
드라이버 로드 시키고 바이러스 안꺼지게 하려고 인젝션 하는거는 사용된 기술이고
주 목적은 어떤 서버로 나의 OS정보를 보내고 어떤 문자열을 recv할탠데.. 서버가 죽었는지 내용은 안오네요;
이 바이러스는 우리 학교에서 보안사고가 났을 때 이 바이러스 샘플을 얻었었습니다.

먼저 리버싱을 제가 그렇게 잘하는 것도 아니고 무조건 파일을 열어서 분석을 해보기 전에 시스템 모니터링 툴을 가지고 이 바이러스가 대충 어떠한 일을 하는지 정도는 알아보기로 했습니다.
사용한 툴은.. TCPview, Cport, SysAnalyzer, ProcessExplorer를 사용했습니다.

깨끗한? 테스트를 위해 인터넷과 통신할 수 있는 모든 프로세스를 종료 시키고 실험을 했습니다. 백신도 전부 끄구요~!

일단 실행시킨 파일명은 745.exe입니다. 하지만 프로세스 목록을 보니 745가 살아있다가 몇초후 system.exe가 띄워지면서 
745.exe는 죽어버립니다. 예상 시나리오로는 745.exe파일이 system.exe파일을 생성시키고 꺼져버리는거 같습니다.
system.exe파일은 시스템 모니터링 툴로 본 결과 통신은 하고있었습니다.

ProcessExplorer로보니 system.exe가 켜져있고 Cport로 본결과 1227 로컬 포트를 통해 85.17.138.130에게 무언가를 보내고 있습니다. 또 같이 테스트를 할때 켜 놓은 SysAnalyzer도 봐보겠습니다.

TCPview로 봐보니 역시나 통신을 하고 있고 옆에화면을 보니 3개의 IP가 잡히고 DNS Requests를 보니
사이트가 있습니다. sex.pornoturkiye.com??? 쫌.. 좋은 사이트는 아닌거 처럼 보이는군요. 이제 저런 사이트들과 통신을 한다는 정보를 가지고 분석을 시도해봤습니다. 먼저 745.exe파일을 열어보았습니다. 간단히 UPX패킹이 되어있었습니다.
그건 그냥 언패킹 하고 분석을 하겠습니다.

먼저 분석을 하기전에 어떠한 함수들이 쓰였는지, 어떠한 문자열이 사용됬는지부터 보고 시작합니다.

응?? 함수가 하나도 없네요. data 디렉토리에서 export, import 테이블을 보겠습니다.

사용되는 함수가 하나도 없는건 아닐탠데 이거 참..
일단 이에 대한 내용을 분석해본 결과 EP에서 가장 처음 호출하는 함수에서 각 dll에 대한 정보를 가지고 필요한 함수들을 가져옵니다. 가장 처음으로는 kernel32.dll의 베이스 주소를 얻어왔습니다. 얻어오는 부분입니다.

먼저 PEB구조체 정보에서 PPEB_LDR_DATA로 다시 들어와 
InInitializationOrderModuleList값을 읽게 됩니다.
InInitializationOrderModuleList에서 이제 Kernel32.dll 모듈의 정보를 담고 있는 구조체를 찾습니다.
( 가장 처음 만나게 되는 dll은 ntdll 모듈 구조체, 그 다음이 Kernel32.dll )
찾으면 Kernel32.dll의 베이스 주소를 얻어오는 역할을 하는 부분입니다. 
저도 잘 몰랐는데 FS:[30] 은 PEB에서 어떠한 정보를 가져오는 것은 알고 있었기 때문에 찾아본것입니다.

아무튼 위와 같은 방법으로 Kernel32.dll의 베이스 주소를 가져오게 되고 필요한 함수들의 주소를 쭉쭉 찾아서
.data섹션에 전부 넣고 있습니다. Kernel32.dll만 사용하는 것이 아니라 여러 dll을들 가져오고 그 dll에서 함수 주소를 가져오는 방법을 썼습니다. 그래서 뽑아낸 함수 목록 입니다.
이제 나머지 dll들도 많이 있는데 나머지는 kernel32.dll에서 얻은 GetMouleHandle, LoadLibrary함수를 사용해
dll정보를 가져오는 방법을 사용하고 있습니다.

00409648  7C809BD7  ?€|   kernel32.CloseHandle
0040964C  7C8286D6  ??    kernel32.CopyFileA
00409650  7C81D827  '?|   kernel32.CreatePipe
00409654  7C80236B  k#€|  kernel32.CreateProcessA
00409658  7C8104BC  ??    kernel32.CreateRemoteThread
0040965C  7C865B1F  [?   kernel32.CreateToolhelp32Snapshot
00409660  7C8106C7  ??    kernel32.CreateThread
00409664  7C81CAFA  憲?    kernel32.ExitProcess
00409668  7C80C0E8  窩€|   kernel32.ExitThread
0040966C  7C80DE85  끴€|   kernel32.GetCurrentProcess
00409670  7C8099B0  컳€|   kernel32.GetCurrentProcessId
00409674  7C8097B8  툠€|   kernel32.GetCurrentThreadId
00409678  7C81AB3B  ;쳛|   kernel32.GetExitCodeProcess
0040967C  7C8115CC  ??    kernel32.GetFileAttributesA
00409680  7C93FE01  ?|   ntdll.RtlGetLastWin32Error
00409684  7C80B55F  _?|   kernel32.GetModuleFileNameA
00409688  7C80B731  1?|   kernel32.GetModuleHandleA
0040968C  7C80AE30  0?|   kernel32.GetProcAddress
00409690  7C801EF2  ?€|   kernel32.GetStartupInfoA
00409694  7C812B6E  n+?   kernel32.GetVersionExA
00409698  7C82134B  K?   kernel32.GetWindowsDirectoryA
0040969C  7C801D7B  {€|  kernel32.LoadLibraryA
004096A0  7C801D53  S€|  kernel32.LoadLibraryExA
004096A4  7C8309D1  ??    kernel32.OpenProcess
004096A8  7C82FBF0  終?    kernel32.OpenThread
004096AC  7C860817  ?   kernel32.PeekNamedPipe
004096B0  7C864DF5  ??    kernel32.Process32First
004096B4  7C864F68  hO?   kernel32.Process32Next
004096B8  7C801812  €|  kernel32.ReadFile
004096BC  7C83290F  )?   kernel32.ResumeThread
004096C0  7C802446  F$€|  kernel32.Sleep
004096C4  7C83974A  J뾻|   kernel32.SuspendThread
004096C8  7C801E1A  €|  kernel32.TerminateProcess
004096CC  7C86503A  :P?   kernel32.Thread32First
004096D0  7C8650EE  ??    kernel32.Thread32Next
004096D4  7C809B02  ?|   kernel32.VirtualAllocEx
004096D8  7C809B92  뮎€|   kernel32.VirtualFreeEx
004096DC  7C80BA30  0?|   kernel32.VirtualQueryEx
004096E0  7C801AD4  ?€|   kernel32.VirtualProtect
004096E4  7C801A61  a€|  kernel32.VirtualProtectEx
004096E8  7C80A164  d?|   kernel32.WideCharToMultiByte
004096EC  7C810E17  ?   kernel32.WriteFile
004096F0  7C802213  "€|  kernel32.WriteProcessMemory
004096F4  7C81CB23  #?|   kernel32.TerminateThread
004096F8  7C801A28  (€|  kernel32.CreateFileA
004096FC  7C80A4B7  랠€|   kernel32.QueryPerformanceCounter
00409700  7C82FA36  6?|   kernel32.QueryPerformanceFrequency
00409704  7C80932E  .?|   kernel32.GetTickCount
00409708  7C80D2F2  珍€|   kernel32.GetLocaleInfoA
0040970C  7C80FDBD  쐬€|   kernel32.GlobalAlloc
00409710  7C80FFA9  ?€|   kernel32.GlobalLock
00409714  7C80FF12  €|  kernel32.GlobalUnlock
00409718  7C830D64  d.?   kernel32.lstrcmpA
0040971C  7C8312D5  ??    kernel32.TransactNamedPipe
00409720  7C835DE2  ??    kernel32.GetTempPathA
00409724  7C831EC5  ??    kernel32.DeleteFileA
00409728  7C82C330  0횂|   kernel32.SetPriorityClass
0040972C  7C809AE1  ?€|   kernel32.VirtualAlloc
00409730  7C80AC6E  n?|   kernel32.FreeLibrary
00409734  7C83089D  ??    kernel32.CreateEventA
00409738  7C802530  0%€|  kernel32.WaitForSingleObject
0040973C  7C85981A  쁾|   kernel32.SetSystemTime
00409740  7C80E9CF  卷€|   kernel32.CreateMutexA
00409744  7C8024B7  ?€|   kernel32.ReleaseMutex
00409748  7C8623AD  ??    kernel32.WinExec
0040974C  7C814F7A  zO?   kernel32.GetSystemDirectoryA
00409750  7C8214CB  ??    kernel32.GetDriveTypeA
00409754  7C812812  (?   kernel32.SetFileAttributesA
00409758  77F5EFFC  誨?    advapi32.AdjustTokenPrivileges
0040975C  77F7C208  차w   advapi32.LookupPrivilegeValueA
00409760  77F5797B  {y?   advapi32.OpenProcessToken
00409764  77F5EAD7  裏?    advapi32.RegSetValueExA
00409768  77F7BCC3  체?    advapi32.RegCreateKeyA
0040976C  77F5D8EE  敵?    advapi32.RegNotifyChangeKeyValue
00409770  77F56C17  l?   advapi32.RegCloseKey
00409774  77F57842  Bx?   advapi32.RegOpenKeyExA
00409778  77F5ECD5  礪?    advapi32.RegDeleteValueA
0040977C  77F57AAB  쳚?    advapi32.RegQueryValueExA
00409780  77F5E9E4  昻?    advapi32.RegCreateKeyExA
00409784  719E3FED  ?엚    ws2_32.WSACleanup
00409788  719E6A55  Uj엚   ws2_32.WSAStartup
0040978C  719F1040  @웥   ws2_32.accept
00409790  719E4480  €D엚   ws2_32.bind
00409794  719E3E2B  +>엚   ws2_32.closesocket
00409798  719E2E53  S.엚   ws2_32.ntohs
0040979C  719E3F50  P?엚   ws2_32.ioctlsocket
004097A0  719E8CD3  ?엚    ws2_32.listen
004097A4  719E676F  og엚   ws2_32.recv
004097A8  719E4C27  'L엚   ws2_32.send
004097AC  719E4211  B엚   ws2_32.socket
004097B0  719E2EE1  ?엚    ws2_32.inet_addr
004097B4  719E4A07  J엚   ws2_32.connect
004097B8  719E5355  US엚   ws2_32.gethostbyname
004097BC  719E45C1  핬엚    ws2_32.inet_ntoa
004097C0  719E2EAD  ?엚    ws2_32.ntohl
004097C4  719E2EAD  ?엚    ws2_32.ntohl
004097C8  719E30A8  ?엚    ws2_32.select
004097CC  719E5449  IT엚   ws2_32.gethostname
004097D0  719E4521  !E엚   ws2_32.setsockopt
004097D4  719EE491  묇엚    ws2_32.gethostbyaddr
004097D8  719F0B68  h웥   ws2_32.getpeername
004097DC  77D307EA  ??    user32.MessageBoxA
004097E0  77D10277  w?   user32.OpenClipboard
004097E4  77D10D96  ??    user32.EmptyClipboard
004097E8  77D10F9E  ??    user32.SetClipboardData
004097EC  77D10265  e?   user32.CloseClipboard
004097F0  77D4CA7E  ~桿w   user32.BlockInput
004097F4  77D042ED  ??    user32.SetForegroundWindow
004097F8  77D0B112  귈w   user32.SetFocus
004097FC  77D0AF56  V?w   user32.ShowWindow
00409800  77D0F3C2  찝?    user32.SendMessageA
00409804  77D46783  긣?    user32.keybd_event
00409808  77D1E4C0  잤?    user32.VkKeyScanA
0040980C  77CFA8AD  ??    user32.wsprintfA
00409810  77D1214A  J!?   user32.FindWindowExA
00409814  77D082E1  ??    user32.FindWindowA
00409818  77D09313  볂w   user32.IsWindow
0040981C  77D01B3B  ;?   user32.RegisterDeviceNotificationA
00409820  77D0C17E  ~죗w   user32.DefWindowProcA
00409824  77D0EA5E  ^慰w   user32.RegisterClassA
00409828  77D0E4A9  ⒳?    user32.CreateWindowExA
0040982C  77D0772B  +w?   user32.GetMessageA
00409830  77CF8BF6  ??    user32.TranslateMessage
00409834  77CF96B8  툟?    user32.DispatchMessageA
00409838  76EE757A  zu?   dnsapi.DnsFlushResolverCache
0040983C  76EE76AD  춚?    dnsapi.DnsFlushResolverCacheEntry_A
00409840  7E6EBC8B  떬n~   urlmon.URLDownloadToFileA
00409844  7D621150  Pb}  shell32.ShellExecuteA
00409848  7D60AC11  ?}   shell32.SHGetFolderPathA
0040984C  76992A53  S*셶   ole32.CoInitialize
00409850  7699057E  ~셶   ole32.CoCreateInstance
00409854  7698EE46  F?v   ole32.CoUninitialize
00409858  77BDC407  캭w   msvcrt.malloc
0040985C  77BF7CE5  ?퓑    msvcrt.strtok
00409860  77BEF931  1夏w   msvcrt.sprintf
00409864  77BF1B72  r퓑   msvcrt.sscanf
00409868  77BCBF18  옘w   msvcrt.atoi
0040986C  77BFA995  빀퓑    msvcrt.clock
00409870  77BDC21B  쩍w   msvcrt.free
00409874  77BEF010  助w   msvcrt.fopen
00409878  77BF11FB  ?퓑    msvcrt.fread
0040987C  77BF0AB1  ?퓑    msvcrt.fclose
00409880  71A54DC2  헜쩻    mpr.WNetCancelConnection2A
00409884  71A54AC4  횶쩻    mpr.WNetAddConnection2A

이제 분석에 필요한 API함수들에 브포를 전부 걸어놓고 실행을 시키면서 분석을 했습니다.
그나마 가장 빨리 분석할 수 있는 방법 같습니다.
하지만 이 파일에서는 특별한 것은 찾을 수 없었고 단순히
745.exe파일을 이름을 system.exe파일로 바꿔서 system32 폴더에 생성시키고 있었습니다.
그리고 system.exe 파일을 실행시키고 있었습니다. 그리곤? 끝나버리더군요.
( 분석하면서 스샷을 못찍어서 그냥 이 부분은 말로 넘어가겠습니다. 그닥 스샷까지 찍을 필요는 없는 부분이라서요;;
사용된 함수라고 해봤자.. CreateFile, CopyFile, SetFileAttributes, WinExec 이런 함수들이었습니다. )

우리가 진짜 분석해야될 파일은 745.exe가 아닌 system.exe파일 인거 같습니다.
참.. 745파일에서 또 하나 해주고 있던게 있습니다.

바로 시스템 시간을 2090년 1월 1일 오전 10시 1분 00초로 바꾸더군요..

이제 system.exe파일을 분석하겠습니다.
분석을 들어가는데 745.exe파일과 같은 파일이므로 아까 같이 함수를 전부 얻어온 후 브포를 걸고 분석을 해야되겠죠.
제가 분석을 원하는 함수들에 브포를 걸어두고 시작했습니다.

=============그림 없음..===================
00402B71  |.  FF15 60974000 CALL DWORD PTR DS:[409760]               ;  advapi32.OpenProcessToken
0012FCBC   FFFFFFFF  |hProcess = FFFFFFFF
0012FCC0   00000028  |DesiredAccess = TOKEN_QUERY|TOKEN_ADJUST_PRIVILEGES
0012FCC4   0012FCC8  \phToken = 0012FCC8

00402B86  |.  FF15 5C974000 CALL DWORD PTR DS:[40975C]               ;  advapi32.LookupPrivilegeValueA
0012FCBC   00000000  |SystemName = NULL
0012FCC0   004095CC  |Privilege = "SeDebugPrivilege"
0012FCC4   0012FCCC  \pLocalId = 0012FCCC

00402BBB  |.  FF15 58974000 CALL DWORD PTR DS:[409758]               ;  advapi32.AdjustTokenPrivileges
0012FCB0   00000074  |hToken = 00000074 (window)
0012FCB4   00000000  |DisableAllPrivileges = FALSE
0012FCB8   0012FCD4  |pNewState = 0012FCD4
0012FCBC   00000010  |PrevStateSize = 10 (16.)
0012FCC0   00000000  |pPrevState = NULL
0012FCC4   00000000  \pRetLen = NULL
SeDebugPrivilege로 권한 변경, 실행 중인 응용프로그램의 프로세스 핸들을 얻을 수 있다고 합니다.
OpenProcess로 얻어올수 있는데 ...

ntdll.ZwSystemDebugControl 의 주소 얻어옴
유저모드 ring3에서 ring 0의 값들을 읽어오기도 하고 포트로 직접 데이터를 가져오기도 보내기도 할 수 있다.

004028C0  |.  FF15 8C964000 CALL DWORD PTR DS:[40968C]               ;  kernel32.GetProcAddress
0012FCB0   009D0000  |hModule = 009D0000 (ntkrnlpa)
0012FCB4   0040A5E0  \ProcNameOrOrdinal = "KeServiceDescriptorTable"

00402AA1  |.  FF15 28974000 CALL DWORD PTR DS:[409728]               ;  kernel32.SetPriorityClass
0012FCD8   FFFFFFFF  |hProcess = FFFFFFFF
0012FCDC   00000100  \Priority = REALTIME_PRIORITY_CLASS
자기 프로세스 우선순위 최고로 높힘

00402AB4  |.  E8 4EFFFFFF   CALL system.00402A07
앵?? BSOD 에러!
INT 2E
보통은 SYSENTER로 들어가는데 아주 옛날에 만들어진 바이러스 인가??
하지만.. 해당 부분 트레이스 하지 않고 실행시키면 BSOD에러 뜨지 않음..뭐지..

끝나고 아무튼 다시 우선순위 Normal로 내림

"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"
부팅후 자동 로그온하게 하는 곳에 레지값 설정

00401BE4  |.  FF15 4C964000 CALL DWORD PTR DS:[40964C]               ;  kernel32.CopyFileA
0012FCF4   00409B34  |ExistingFileName = "C:\Documents and Settings\Administrator\바탕 화면\system.exe"
0012FCF8   0040AD30  |NewFileName = "C:\WINDOWS\system32\7775524"
0012FCFC   00000000  \FailIfExists = FALSE
7775524라는 파일을 생성. 하지만 이 파일명은 바이러스를 새로 실행할때마다 바뀌게 됨
7775524파일은 system.exe와 100% 동일. 하지만 확장자 없음.

CreateToolhelp32Snapshot, Process32First, lstrcmp, Process32Nest 함수를 사용해
explorer.exe가 현재 프로세스에 있는지 확인. 즉, 바탕화면이 띄워져 있는지 확인.
해당 함수에서 바탕화면 존재시 0x454리턴. 0x454는 explorer.exe의 프로세스 ID
바탕화면 핸들 얻어옴. 
explorer.exe에 인젝션 한다.
먼저
VirtualAllocEx로 첫번째 인자는 바탕화면 핸들을 전달하는걸로 봐서 바탕화면의 가상메모리 공간에 영역 확보
WriteProcessMemory로 system.exe에서 사용된 API함수들 넣음.
그 다음으로 넣는 것은 system.exe 절대 경로.. system.exe가 꺼지면 바로 키기 위함 인가?? ^^
또 다시 WriteProcessMemory로 넣고 있는게 있다.
004010FF  55 8B EC 51 51 6A 00 68 80 00 00 00 6A 03 6A 00  U뗭QQj.h€...jj.
0040110F  6A 00 68 00 00 00 80 8B 45 08 83 C0 04 50 8B 45  j.h...€딢꺚P딢
0040111F  08 8B 00 FF 90 B0 00 00 00 89 45 F8 6A 01 58 85  ?맧...덭?X
0040112F  C0 0F 84 8E 00 00 00 8B 45 08 05 08 01 00 00 50  ?꼶...딢..P
0040113F  6A 00 6A 00 8B 45 08 8B 00 FF 90 F8 00 00 00 89  j.j.딢?먾...
0040114F  45 FC 8B 45 08 8B 00 FF 50 38 3D B7 00 00 00 74  E?E?P8=?..t
0040115F  3A FF 75 F8 8B 45 08 8B 00 FF 10 FF 75 FC 8B 45  :u?E?u?E
0040116F  08 8B 00 FF 90 FC 00 00 00 FF 75 FC 8B 45 08 8B  ?멄...u?E
0040117F  00 FF 10 6A 00 8B 45 08 83 C0 04 50 8B 45 08 8B  .j.딢꺚P딢
0040118F  00 FF 90 00 01 00 00 33 C0 EB 2C FF 75 FC 8B 45  .?..3잼,u?E
0040119F  08 8B 00 FF 90 FC 00 00 00 FF 75 FC 8B 45 08 8B  ?멄...u?E
004011AF  00 FF 10 68 B8 0B 00 00 8B 45 08 8B 00 FF 50 78  .h?..딢?Px
004011BF  E9 67 FF FF FF 33 C0 C9 C2 04 00 55 8B EC 51     ?3읠?.U뗭Q
처음 시작 부분 55 8BEC 이부분만 봐도 알수 있을꺼같다. 어떠한 소스이다. 함수 프롤로그네..
소스코드는 올디에서 어셈으로 보기하면 알 수 있다. 하지만 이 함수를 쓰기 위해 [ebp+8] 이런 부분이 있는걸로 보아..
이 함수를 호출할때 어떠한 인자가 사용됬는지도 알아야 할꺼같다. 직접 바탕화면 프로세스를 까야될꺼같네요.
제대로 분석할 마음이 없어서.. 이 부분은 패스하겠습니다. 아무튼 바탕화면 프로세스에 무언가를 인젝션하는..
DLL Injection같은 경우는 백신에서 잘 잡기 때문에 역시나 코드 인젝션을 한거 같습니다.

C:\Documents and Settings\Administrator\Local Settings\Temp 폴더에 43282.sys파일 생성 ( 생성시마다 파일명 계속 바뀜 )
해당 드라이버 로드. 
이 드라이버가 어떠한 일을 하는지는 분석 안함.;;

그 후 소켓 통신......
직접 함수를 분석해도 되고 올디 소켓 트레이스 플러그인 사용해 간단히 분석
별 내용없다.. recv 부분에서도 PING :index.html 이러한 문자열만 받아온다.
오래지난 바이러스라 해당 서버가 막힌듯...

너무 할일 없어서... 그냥 써본것입니다. 읽을건 딱히 없네요.
실력도 많이 쌓이면 그 때부터 제대로 바이러스 분석하는 것을 올려볼 생각입니다.



'My Study > Malware&Vulnerabilities' 카테고리의 다른 글

CodeEngn Malware Analysis Level5  (0) 2010.05.04
CodeEngn Malware Analysis Level4  (0) 2010.04.28
CodeEngn Malware Analysis Level3  (0) 2010.04.27
CodeEngn Malware Analysis Level2  (0) 2010.04.27
CodeEngn Malware Analysis Level1  (0) 2010.04.18