Enter Sandbox – part 1: All APIs are equal, but some APIs are more equal than others
May 29, 2015 in Batch Analysis, Clustering, Malware Analysis
I am going to start a new series about sandbox and sandbox evasions. I will utilize data I gathered over last 10 years together with an experience of actually getting my hands dirty and coding my own monitor from the scratch. I actually never considered it a real sandbox, as it does way much more, but I’ll use ‘sandbox’ here, cuz everyone already knows what it is.
Creating a good sandbox is a very challenging task. Not only it’s technically challenging, but you also need to be very selective. One such area where you have to be really specific about what you do is a list of APIs that you need to intercept, because:
- if you miss some – you may lose vital information from the report, or fail to intercept one of many ‘escape’ mechanisms that modern malware utilizes for evasion purposes (heaven’s gate, tricks to launch code under a different process while at the same time fooling the sandbox/av monitor that nothing is going on, etc.)
- if you monitor too much – you will get a headache trying to understand the output
There are many ‘schools’ of what to intercept. Some people prefer kernel-mode hooks and monitor stuff on a high-level (or, a low-level, depending where we observe it from). They ‘see’ everything, but they miss context of the execution (process, thread, window procedure, etc.). The user-mode monitoring fans are better off when it comes to the context, but they may miss the more complex stuff. In some approaches the monitoring of APIs/services is also supported by extra checks e.g. $MFT, Registry analysis pre- and post-session, and outside-sandbox analysis of disk/file system/memory. Plus, of course network stuff.
I am personally a big fan of user-mode only monitoring. It worked for me for last 10 years pretty well, and while it may miss stuff I believe that wherever evasive or kernel mode stuff is involved you need to simply get your hands dirty and do manual analysis. This btw. is actually the fun part of the malware analyst job 🙂
Note: I am mainly talking about the manual, in-depth analysis of malware and not general-purpose sandbox that is commercially ‘required’ to ‘see’ it all. This is actually quite a headache to manage and I do not envy sandbox companies that need to worry about it.
Okay. So, if we focus on user-mode monitoring we definitely need to know what to monitor.
One approach that can be taken to figure out what APIs to monitor is…very naive statistics – naive, because based on a simple principle and this is the topic I will cover today.
Most of malware nowadays is either packed, or somehow protected. Once it executes, the wrapper launches the actual payload and during this phase it often resolves the APIs. Later on it may inject stuff into other processes, some more APIs may get resolved, and so on and so forth. It can get pretty messy.
Now, there are plenty of methods to resolve the APIs including leveraging the GetProcAddress and/or LdrGetProcedureAddress, or simply walking through the export tables of respective libraries and finding the required API addresses. You can also do pattern searching, brute-force and some fancy algorithmic API address discovery, but these are exotic cases and we don’t need to care for them.
I mentioned that this is going to be about naive statistics – this is why we will only look at GetProcAddress. All we need is data.
As long as we execute a large number of samples while we monitor this particular API we can get a nice, and quite a fair representation of popularity of certain APIs. These APIs need to be screened manually and then a subset of them can be selected for monitoring.
So, looking at results of 150K+ sandboxed samples I came up with the following list of APIs (top 100 are listed):
KERNEL32.dll CloseHandle
KERNEL32.dll WriteFile
KERNEL32.dll GetModuleHandleA
KERNEL32.dll ExitProcess
KERNEL32.dll GetLastError
KERNEL32.dll VirtualAlloc
KERNEL32.dll GetProcAddress
KERNEL32.dll VirtualFree
KERNEL32.dll Sleep
KERNEL32.dll LoadLibraryA
KERNEL32.dll SetFilePointer
KERNEL32.dll ReadFile
KERNEL32.dll CreateFileA
KERNEL32.dll WaitForSingleObject
KERNEL32.dll GetModuleFileNameA
KERNEL32.dll FlsFree
KERNEL32.dll FlsGetValue
KERNEL32.dll FlsSetValue
KERNEL32.dll FlsAlloc
KERNEL32.dll MultiByteToWideChar
KERNEL32.dll GetTickCount
KERNEL32.dll FreeLibrary
KERNEL32.dll CreateThread
KERNEL32.dll FindClose
KERNEL32.dll GetFileSize
KERNEL32.dll GetCurrentProcess
KERNEL32.dll GetCurrentThreadId
KERNEL32.dll HeapAlloc
KERNEL32.dll WideCharToMultiByte
ADVAPI32.dll RegCloseKey
KERNEL32.dll GetCurrentProcessId
KERNEL32.dll GetStdHandle
KERNEL32.dll HeapFree
KERNEL32.dll VirtualProtect
KERNEL32.dll DeleteCriticalSection
USER32.dll GetSystemMetrics
KERNEL32.dll LoadResource
KERNEL32.dll LeaveCriticalSection
KERNEL32.dll GetCommandLineA
KERNEL32.dll InitializeCriticalSection
KERNEL32.dll EnterCriticalSection
KERNEL32.dll GlobalAlloc
KERNEL32.dll LocalFree
KERNEL32.dll OpenProcess
KERNEL32.dll TerminateProcess
KERNEL32.dll LockResource
KERNEL32.dll SizeofResource
KERNEL32.dll DeleteFileA
KERNEL32.dll GetModuleFileNameW
KERNEL32.dll SetLastError
KERNEL32.dll SetEndOfFile
KERNEL32.dll RtlUnwind
KERNEL32.dll GetProcessHeap
KERNEL32.dll GetStartupInfoA
KERNEL32.dll GlobalFree
KERNEL32.dll TlsSetValue
KERNEL32.dll DeleteFileW
KERNEL32.dll TlsGetValue
KERNEL32.dll CreateFileW
KERNEL32.dll lstrlenA
KERNEL32.dll GetModuleHandleW
KERNEL32.dll GetSystemTimeAsFileTime
KERNEL32.dll GlobalUnlock
KERNEL32.dll CreateProcessA
KERNEL32.dll InterlockedDecrement
KERNEL32.dll SetUnhandledExceptionFilter
KERNEL32.dll SetEvent
KERNEL32.dll DecodePointer
KERNEL32.dll IsProcessorFeaturePresent
KERNEL32.dll LocalAlloc
KERNEL32.dll UnhandledExceptionFilter
KERNEL32.dll GlobalLock
KERNEL32.dll SetFileTime
KERNEL32.dll RaiseException
KERNEL32.dll CreateMutexA
KERNEL32.dll SetErrorMode
KERNEL32.dll FindFirstFileA
KERNEL32.dll ResumeThread
KERNEL32.dll EncodePointer
KERNEL32.dll InterlockedIncrement
KERNEL32.dll GetTempPathA
KERNEL32.dll GetFileType
ADVAPI32.dll RegOpenKeyExA
KERNEL32.dll GetACP
KERNEL32.dll GetVersionExA
KERNEL32.dll CreateToolhelp32Snapshot
KERNEL32.dll GetCPInfo
KERNEL32.dll GetFileAttributesW
USER32.dll GetMonitorInfoA
KERNEL32.dll SystemTimeToFileTime
USER32.dll MessageBoxA
KERNEL32.dll GetVersion
KERNEL32.dll IsDebuggerPresent
USER32.dll EnumDisplayMonitors
KERNEL32.dll FlushFileBuffers
KERNEL32.dll GetTempPathW
KERNEL32.dll lstrcpyA
KERNEL32.dll HeapReAlloc
KERNEL32.dll ReleaseMutex
KERNEL32.dll TlsAlloc
Comments are closed.