You are browsing the archive for Clustering.

Enter Sandbox – part 15: The muddy, heavy water world of atomic formats…

September 22, 2017 in Batch Analysis, Clustering, Malware Analysis, Reversing, Sandboxing

Sample analysis process typically covers looking at the most common forensic suspects including mutexes, event names, and atoms. However, there is one more sub-artifact sitting on the same bench with the last one I have listed… one that often escapes the scrutiny of sandboxes and malware analysts – the clipboard format.

The clipboard format is registered using the RegisterClipboardFormat function – it allows applications to interchange data as long as they understand the format. The registration is implemented with the use of atoms as explained in this presentation.

Sandboxes and analysts inspecting the calls to RegisterClipboardFormat can use the received data in many ways. It can help to determine a file type of the sample, its modules, detect a family of a malware/adware, or perhaps a programming framework, and in some cases heuristically detect capabilities of the tested sample. I have listed a few example clipboard formats below. If you look at it one set that immediately stands out are Delphi clipboard formats:

  • Delphi Picture
  • Delphi Component
  • ControlOfs<HEX-STRING> (f.ex. ControlOfs00400000000007A8)

Finding these in the API calls or even in memory is a good indication that there is a Delphi application running.

The same goes for ATL samples:

  • WM_ATLGETCONTROL
  • WM_ATLGETHOST

There are also malware-adware-specific formats e.g.:

  • AmInst__Runing
  • yimomotoTec Picture
  • yimomotoTec Component
  • PowerSpider
  • RinLoggerInstance
  • SatoriWM_SetNetworkShareableFlag
  • Transfer_File_Success_Doyo
  • 180StartDownload

… RAT-related formats:

  • WinVNC.Update.Mouse
  • WinVNC.Update.DrawRect
  • WinVNC.Update.CopyRect
  • WinVNC.AddClient.Message
  • UltraVNC.Viewer.FileTransferSendPacketMessage

… test formats:

  • Hey, this is unicough single instance test
  • UWM_GAMETESTCMD_{75AEED17-2310-4171-94C6-08AC4438E814}_MSG
  • Message.My.Super.Puper.Test.Program.XXX
  • KSDB_TEST: Message communciation between Agent and its TEST host client.
  • FONT-TEST

… various functionality-related formats:

  • WM_HTML_GETOBJECT
  • RasDialEvent
  • EXPLORER.EXEIsDebuggerPresentExEdLl
  • winmm_devicechange
  • WM_HOOKEX_RK
  • UWM_KEYHOOK_MSG-968C3043-1128-43dc-83A9-55122C8D87C1
  • Transfer_File_Success_Doyo
  • 3rdeye_tb_hacking_dll
  • keyhook_msg

… P2P programs formats:

  • EMULE-{4EADC6FC-516F-4b7c-9066-97D893649570}
  • KazaaNewSearch

… possible hints on programmer’s mother tongue:

  • Karte ziehen
  • querodarmeucu

…random:

  • trhgtehgfsgrfgtrwegtre
  • frgjbfdkbnfsdjbvofsjfrfre
  • hgtrfsgfrsgfgregtregtr
  • gsegtsrgrefsfsfsgrsgrt

A short list of top 30 formats I collected from my sampleset:

 46894 TaskbarCreated
 30020 commdlg_FindReplace
 27886 Delphi Picture
 27886 Delphi Component
 27491 commdlg_help
 13920 WM_ATLGETCONTROL
 13914 WM_ATLGETHOST
 11000 3
  8395 commctrl_DragListMsg
  7445 1
  6909 WM_GETCONTROLNAME
  5475 FileName
  5020 Embedded Object
  4899 Link Source
  4885 Rich Text Format
  4787 Object Descriptor
  4652 commdlg_ColorOK
  4576 OwnerLink
  4574 Embed Source
  4569 Link Source Descriptor

Enter Sandbox – part 14: Reading the old Delphi Scrolls…

March 16, 2017 in Batch Analysis, Clustering, File Formats ZOO, Reversing, Sandboxing

Sandboxing regular PE (not .NET) files is easy and tricky at the same time. API monitoring is trivial. What is not is not is this:

  • The crazy number of API functions (Native, Win32)
  • Function calls that are a bit harder to monitor, because the functionality is delivered via a complex maze of virtual tables f.ex. COM
  • Monitoring of functions or methods that are placed on a higher level of abstraction f.ex. scripts (AutoIT, VBS, VBA), as well as installers (f.ex. NullSoft)
  • The variety of library functions that are included inside the executables (statically)

The last item on the list requires a bit more attention.

Hooking API, or intercepting their calls any other way is relatively easy as long as you know where they are (and perhaps can handle the stolen bytes well since some malware is using this trick). With code embedded directly inside the executable there is no import table, no list of pointers of any kind, no virtual tables, no RTTI, nothing. Of course, using tools like IDA, or a good disassembly library, or perhaps instrumented execution it may be possible to determine the exact location of these functions, but it’s a pretty complex and time consuming task, especially for commercial sandboxes that must run FAST.

On top of that, there is another issue. The code is not located at a fixed address, but can be placed all over the place. No, I am not talking about ASLR. I am talking about wrappers that use RunPE to run executables from memory. If you intercept Windows API calls, running programs via RunPE doesn’t make a difference – the APIs will eventually be executing from a known location inside the system libraries in memory. With relocated code the statically linked functions need to be found _every_ time the executable is loaded, mapped to a different processes, or simply relocated (direct code inject, process hollowing, some unpackers, etc.). Yes, for the malware that spawns a number of child processes and plays with RunPE a number of times during the session it will significantly slow down the tagging of functions in memory.

So… after a bit of scaremongering let’s have a look at a very good example.

The enfant terrible of programs that are truly annoying for analysis are Delphi executables (and all the other brands of Delphish executables f.es. Embarcadero). They rely heavily on the custom Delphi libraries and as such are hard to understand no matter whether they are debugged, or disassembled. Of course, there exist good decompilers that can help a lot, and flirt signatures for Delphi executables do a lot of magic during static program analysis as well. However, I am not aware of any of the available sandboxes or monitors doing dynamic analysis of Delphi code during the run-time.

I remember the moment when I tested the first Delphi function hooking that I implemented a few years ago. My mind was blown. The sudden insight into the program business logic that the hooking gave me was incredible… !!!

I hope this functionality will be implemented in commercial sandboxes soon. There is a tremendous amount of metadata just waiting to be discovered…

Let’s have a look at a couple of examples – the one below shows a progressive parsing of the config for a trojan:

LStrPos |, <someip>|1337|IPKServer|IPKMutex|encpassword|-1|AdobeART.exe|AdobeART|-1|
LStrPos |, <someip>|1337|IPKServer|IPKMutex|encpassword|-1|AdobeART.exe|AdobeART|-1|
LStrPos |, <someip>|1337|IPKServer|IPKMutex|encpassword|-1|AdobeART.exe|AdobeART|-1|
LStrPos |, 1337|IPKServer|IPKMutex|encpassword|-1|AdobeART.exe|AdobeART|-1|
LStrPos |, 1337|IPKServer|IPKMutex|encpassword|-1|AdobeART.exe|AdobeART|-1|
LStrPos |, 1337|IPKServer|IPKMutex|encpassword|-1|AdobeART.exe|AdobeART|-1|
LStrPos |, IPKServer|IPKMutex|encpassword|-1|AdobeART.exe|AdobeART|-1|
LStrPos |, IPKServer|IPKMutex|encpassword|-1|AdobeART.exe|AdobeART|-1|
LStrPos |, IPKServer|IPKMutex|encpassword|-1|AdobeART.exe|AdobeART|-1|
LStrPos |, IPKMutex|encpassword|-1|AdobeART.exe|AdobeART|-1|
LStrPos |, IPKMutex|encpassword|-1|AdobeART.exe|AdobeART|-1|
LStrPos |, IPKMutex|encpassword|-1|AdobeART.exe|AdobeART|-1|
LStrPos |, encpassword|-1|AdobeART.exe|AdobeART|-1|
LStrPos |, encpassword|-1|AdobeART.exe|AdobeART|-1|
LStrPos |, encpassword|-1|AdobeART.exe|AdobeART|-1|
LStrPos |, -1|AdobeART.exe|AdobeART|-1|
LStrPos |, -1|AdobeART.exe|AdobeART|-1|
LStrPos |, -1|AdobeART.exe|AdobeART|-1|
LStrPos |, AdobeART.exe|AdobeART|-1|
LStrPos |, AdobeART.exe|AdobeART|-1|
LStrPos |, AdobeART.exe|AdobeART|-1|
LStrPos |, AdobeART|-1|
LStrPos |, AdobeART|-1|
LStrPos |, AdobeART|-1|
LStrPos |, -1|
LStrPos |, -1|
LStrPos |, -1|
LStrPos |,

This example shows a comparison of characters and the string ‘apocalypse’ can be read from a series of string comparisons:

LStrCmp2 (substring=a, string=|)
LStrCmp2 (substring=p, string=|)
LStrCmp2 (substring=o, string=|)
LStrCmp2 (substring=c, string=|)
LStrCmp2 (substring=a, string=|)
LStrCmp2 (substring=l, string=|)
LStrCmp2 (substring=y, string=|)
LStrCmp2 (substring=p, string=|)
LStrCmp2 (substring=s, string=|)
LStrCmp2 (substring=e, string=|)

Another example almost instantly tells me that the program requires a command line parameter:

WStrCmp (substring=, string=/debug)

What about Delphi-based Anti-routines? This is a whole new unexplored of area !!!

LStrPos (substring=SNIFFER, string=EXPLORER.EXE)

LStrPos (substring=WINDUMP, string=EXPLORER.EXE)

LStrPos (substring=NETPRYER, string=EXPLORER.EXE)

And last example – DarkComet config processing:

LStrCmp (substring=, string=GENCODE)
LStrCmp (substring=MUTEX, string=GENCODE)
LStrCmp (substring=SID, string=GENCODE)
LStrCmp (substring=FWB, string=GENCODE)
LStrCmp (substring=NETDATA, string=GENCODE)
LStrCmp (substring=GENCODE, string=GENCODE)
LStrCmp (substring=\, string=\)
LStrCmp (substring=, string=NETDATA)
LStrCmp (substring=MUTEX, string=NETDATA)
LStrCmp (substring=SID, string=NETDATA)
LStrCmp (substring=FWB, string=NETDATA)
LStrCmp (substring=NETDATA, string=NETDATA)
LStrCmp (substring=, string=SID)
LStrCmp (substring=MUTEX, string=SID)
LStrCmp (substring=SID, string=SID)
LStrCmp (substring=, string=MUTEX)
LStrCmp (substring=MUTEX, string=MUTEX)
LStrCmp (substring=, string=EDTPATH)
LStrCmp (substring=MUTEX, string=EDTPATH)
LStrCmp (substring=SID, string=EDTPATH)
LStrCmp (substring=FWB, string=EDTPATH)
LStrCmp (substring=NETDATA, string=EDTPATH)
LStrCmp (substring=GENCODE, string=EDTPATH)
LStrCmp (substring=OFFLINEK, string=EDTPATH)
LStrCmp (substring=, string=EDTPATH)
LStrCmp (substring=, string=COMBOPATH)
LStrCmp (substring=MUTEX, string=COMBOPATH)
LStrCmp (substring=SID, string=COMBOPATH)
LStrCmp (substring=FWB, string=COMBOPATH)
LStrCmp (substring=NETDATA, string=COMBOPATH)
LStrCmp (substring=GENCODE, string=COMBOPATH)
LStrCmp (substring=OFFLINEK, string=COMBOPATH)
LStrCmp (substring=, string=COMBOPATH)
LStrCmp (substring=, string=11)
LStrCmp (substring=, string=-1)
LStrCmp (substring=, string=0)
LStrCmp (substring=, string=1)
LStrCmp (substring=, string=2)
LStrCmp (substring=, string=3)
LStrCmp (substring=, string=4)
LStrCmp (substring=, string=5)
LStrCmp (substring=, string=6)
LStrCmp (substring=, string=7)
LStrCmp (substring=, string=8)
LStrCmp (substring=, string=9)
LStrCmp (substring=, string=10)
LStrCmp (substring=, string=GENCODE)
LStrCmp (substring=MUTEX, string=GENCODE)
LStrCmp (substring=SID, string=GENCODE)
LStrCmp (substring=FWB, string=GENCODE)
LStrCmp (substring=NETDATA, string=GENCODE)
LStrCmp (substring=GENCODE, string=GENCODE)
LStrCmp (substring=00df86ce377d71e66cb2451c446fede8, string=)
LStrCmp (substring=, string=INSTALL)
LStrCmp (substring=MUTEX, string=INSTALL)
LStrCmp (substring=SID, string=INSTALL)
LStrCmp (substring=FWB, string=INSTALL)
LStrCmp (substring=NETDATA, string=INSTALL)
LStrCmp (substring=GENCODE, string=INSTALL)
LStrCmp (substring=OFFLINEK, string=INSTALL)
LStrCmp (substring=, string=INSTALL)
LStrCmp (substring=, string=1)
LStrCmp (substring=, string=FAKEMSG)
LStrCmp (substring=MUTEX, string=FAKEMSG)
LStrCmp (substring=SID, string=FAKEMSG)
LStrCmp (substring=FWB, string=FAKEMSG)
LStrCmp (substring=NETDATA, string=FAKEMSG)
LStrCmp (substring=GENCODE, string=FAKEMSG)
LStrCmp (substring=OFFLINEK, string=FAKEMSG)
LStrCmp (substring=, string=FAKEMSG)
LStrCmp (substring=, string=1)
LStrCmp (substring=, string=PDNS)
LStrCmp (substring=MUTEX, string=PDNS)
LStrCmp (substring=SID, string=PDNS)
LStrCmp (substring=FWB, string=PDNS)
LStrCmp (substring=NETDATA, string=PDNS)
LStrCmp (substring=GENCODE, string=PDNS)
LStrCmp (substring=OFFLINEK, string=PDNS)
LStrCmp (substring=, string=PDNS)
LStrCmp (substring=, string=FILEATTRIB)
LStrCmp (substring=MUTEX, string=FILEATTRIB)
LStrCmp (substring=SID, string=FILEATTRIB)
LStrCmp (substring=FWB, string=FILEATTRIB)
LStrCmp (substring=NETDATA, string=FILEATTRIB)
LStrCmp (substring=GENCODE, string=FILEATTRIB)
LStrCmp (substring=OFFLINEK, string=FILEATTRIB)
LStrCmp (substring=, string=FILEATTRIB)
LStrCmp (substring=, string=DIRATTRIB)
LStrCmp (substring=MUTEX, string=DIRATTRIB)
LStrCmp (substring=SID, string=DIRATTRIB)
LStrCmp (substring=FWB, string=DIRATTRIB)
LStrCmp (substring=NETDATA, string=DIRATTRIB)
LStrCmp (substring=GENCODE, string=DIRATTRIB)
LStrCmp (substring=OFFLINEK, string=DIRATTRIB)
LStrCmp (substring=, string=DIRATTRIB)
LStrCmp (substring=, string=CHIDEF)
LStrCmp (substring=MUTEX, string=CHIDEF)
LStrCmp (substring=SID, string=CHIDEF)
LStrCmp (substring=FWB, string=CHIDEF)
LStrCmp (substring=NETDATA, string=CHIDEF)
LStrCmp (substring=GENCODE, string=CHIDEF)
LStrCmp (substring=OFFLINEK, string=CHIDEF)
LStrCmp (substring=, string=CHIDEF)
LStrCmp (substring=, string=1)
LStrCmp (substring=, string=CHIDED)
LStrCmp (substring=MUTEX, string=CHIDED)
LStrCmp (substring=SID, string=CHIDED)
LStrCmp (substring=FWB, string=CHIDED)
LStrCmp (substring=NETDATA, string=CHIDED)
LStrCmp (substring=GENCODE, string=CHIDED)
LStrCmp (substring=OFFLINEK, string=CHIDED)
LStrCmp (substring=, string=CHIDED)
LStrCmp (substring=, string=1)
LStrCmp (substring=, string=BIND)
LStrCmp (substring=MUTEX, string=BIND)
LStrCmp (substring=SID, string=BIND)
LStrCmp (substring=FWB, string=BIND)
LStrCmp (substring=NETDATA, string=BIND)
LStrCmp (substring=GENCODE, string=BIND)
LStrCmp (substring=OFFLINEK, string=BIND)
LStrCmp (substring=, string=BIND)
LStrCmp (substring=, string=1)
LStrCmp (substring=, string=PLUGS)
LStrCmp (substring=MUTEX, string=PLUGS)
LStrCmp (substring=SID, string=PLUGS)
LStrCmp (substring=FWB, string=PLUGS)
LStrCmp (substring=NETDATA, string=PLUGS)
LStrCmp (substring=GENCODE, string=PLUGS)
LStrCmp (substring=OFFLINEK, string=PLUGS)
LStrCmp (substring=, string=PLUGS)
LStrCmp (substring=, string=1)
LStrCmp (substring=, string=PERSINST)
LStrCmp (substring=MUTEX, string=PERSINST)
LStrCmp (substring=SID, string=PERSINST)
LStrCmp (substring=FWB, string=PERSINST)
LStrCmp (substring=NETDATA, string=PERSINST)
LStrCmp (substring=GENCODE, string=PERSINST)
LStrCmp (substring=OFFLINEK, string=PERSINST)
LStrCmp (substring=, string=PERSINST)
LStrCmp (substring=, string=1)
LStrCmp (substring=, string=SH1)
LStrCmp (substring=MUTEX, string=SH1)
LStrCmp (substring=SID, string=SH1)
LStrCmp (substring=FWB, string=SH1)
LStrCmp (substring=NETDATA, string=SH1)
LStrCmp (substring=GENCODE, string=SH1)
LStrCmp (substring=OFFLINEK, string=SH1)
LStrCmp (substring=, string=SH1)
LStrCmp (substring=, string=1)
LStrCmp (substring=, string=SH3)
LStrCmp (substring=MUTEX, string=SH3)
LStrCmp (substring=SID, string=SH3)
LStrCmp (substring=FWB, string=SH3)
LStrCmp (substring=NETDATA, string=SH3)
LStrCmp (substring=GENCODE, string=SH3)
LStrCmp (substring=OFFLINEK, string=SH3)
LStrCmp (substring=, string=SH3)
LStrCmp (substring=, string=1)
LStrCmp (substring=, string=SH4)
LStrCmp (substring=MUTEX, string=SH4)
LStrCmp (substring=SID, string=SH4)
LStrCmp (substring=FWB, string=SH4)
LStrCmp (substring=NETDATA, string=SH4)
LStrCmp (substring=GENCODE, string=SH4)
LStrCmp (substring=OFFLINEK, string=SH4)
LStrCmp (substring=, string=SH4)
LStrCmp (substring=, string=1)
LStrCmp (substring=, string=SH5)
LStrCmp (substring=MUTEX, string=SH5)
LStrCmp (substring=SID, string=SH5)
LStrCmp (substring=FWB, string=SH5)
LStrCmp (substring=NETDATA, string=SH5)
LStrCmp (substring=GENCODE, string=SH5)
LStrCmp (substring=OFFLINEK, string=SH5)
LStrCmp (substring=, string=SH5)
LStrCmp (substring=, string=1)
LStrCmp (substring=, string=SH6)
LStrCmp (substring=MUTEX, string=SH6)
LStrCmp (substring=SID, string=SH6)
LStrCmp (substring=FWB, string=SH6)
LStrCmp (substring=NETDATA, string=SH6)
LStrCmp (substring=GENCODE, string=SH6)
LStrCmp (substring=OFFLINEK, string=SH6)
LStrCmp (substring=, string=SH6)
LStrCmp (substring=, string=1)
LStrCmp (substring=, string=SH7)
LStrCmp (substring=MUTEX, string=SH7)
LStrCmp (substring=SID, string=SH7)
LStrCmp (substring=FWB, string=SH7)
LStrCmp (substring=NETDATA, string=SH7)
LStrCmp (substring=GENCODE, string=SH7)
LStrCmp (substring=OFFLINEK, string=SH7)
LStrCmp (substring=, string=SH7)
LStrCmp (substring=, string=1)
LStrCmp (substring=, string=SH8)
LStrCmp (substring=MUTEX, string=SH8)
LStrCmp (substring=SID, string=SH8)
LStrCmp (substring=FWB, string=SH8)
LStrCmp (substring=NETDATA, string=SH8)
LStrCmp (substring=GENCODE, string=SH8)
LStrCmp (substring=OFFLINEK, string=SH8)
LStrCmp (substring=, string=SH8)
LStrCmp (substring=, string=1)
LStrCmp (substring=, string=SH9)
LStrCmp (substring=MUTEX, string=SH9)
LStrCmp (substring=SID, string=SH9)
LStrCmp (substring=FWB, string=SH9)
LStrCmp (substring=NETDATA, string=SH9)
LStrCmp (substring=GENCODE, string=SH9)
LStrCmp (substring=OFFLINEK, string=SH9)
LStrCmp (substring=, string=SH9)
LStrCmp (substring=, string=1)
LStrCmp (substring=, string=SH10)
LStrCmp (substring=MUTEX, string=SH10)
LStrCmp (substring=SID, string=SH10)
LStrCmp (substring=FWB, string=SH10)
LStrCmp (substring=NETDATA, string=SH10)
LStrCmp (substring=GENCODE, string=SH10)
LStrCmp (substring=OFFLINEK, string=SH10)
LStrCmp (substring=, string=SH10)
LStrCmp (substring=, string=1)
LStrCmp (substring=, string=MULTIBIND)
LStrCmp (substring=MUTEX, string=MULTIBIND)
LStrCmp (substring=SID, string=MULTIBIND)
LStrCmp (substring=FWB, string=MULTIBIND)
LStrCmp (substring=NETDATA, string=MULTIBIND)
LStrCmp (substring=GENCODE, string=MULTIBIND)
LStrCmp (substring=OFFLINEK, string=MULTIBIND)
LStrCmp (substring=, string=MULTIBIND)
LStrCmp (substring=, string=1)
LStrCmp (substring=, string=MULTIPLUGS)
LStrCmp (substring=MUTEX, string=MULTIPLUGS)
LStrCmp (substring=SID, string=MULTIPLUGS)
LStrCmp (substring=FWB, string=MULTIPLUGS)
LStrCmp (substring=NETDATA, string=MULTIPLUGS)
LStrCmp (substring=GENCODE, string=MULTIPLUGS)
LStrCmp (substring=OFFLINEK, string=MULTIPLUGS)
LStrCmp (substring=, string=MULTIPLUGS)
LStrCmp (substring=, string=1)
LStrCmp (substring=, string=FWB)
LStrCmp (substring=MUTEX, string=FWB)
LStrCmp (substring=SID, string=FWB)
LStrCmp (substring=FWB, string=FWB)
LStrCmp (substring=0, string=1)
LStrCmp (substring=, string=GENCODE)
LStrCmp (substring=MUTEX, string=GENCODE)
LStrCmp (substring=SID, string=GENCODE)
LStrCmp (substring=FWB, string=GENCODE)
LStrCmp (substring=NETDATA, string=GENCODE)
LStrCmp (substring=GENCODE, string=GENCODE)
LStrCmp (substring=, string=PERS)
LStrCmp (substring=MUTEX, string=PERS)
LStrCmp (substring=SID, string=PERS)
LStrCmp (substring=FWB, string=PERS)
LStrCmp (substring=NETDATA, string=PERS)
LStrCmp (substring=GENCODE, string=PERS)
LStrCmp (substring=OFFLINEK, string=PERS)
LStrCmp (substring=, string=PERS)
LStrCmp (substring=, string=1)
LStrCmp (substring=, string=PWD)
LStrCmp (substring=MUTEX, string=PWD)
LStrCmp (substring=SID, string=PWD)
LStrCmp (substring=FWB, string=PWD)
LStrCmp (substring=NETDATA, string=PWD)
LStrCmp (substring=GENCODE, string=PWD)
LStrCmp (substring=OFFLINEK, string=PWD)
LStrCmp (substring=, string=PWD)
LStrCmp (substring=, string=OFFLINEK)
LStrCmp (substring=MUTEX, string=OFFLINEK)
LStrCmp (substring=SID, string=OFFLINEK)
LStrCmp (substring=FWB, string=OFFLINEK)
LStrCmp (substring=NETDATA, string=OFFLINEK)
LStrCmp (substring=GENCODE, string=OFFLINEK)
LStrCmp (substring=OFFLINEK, string=OFFLINEK)
LStrCmp (substring=1, string=1)
LStrCmp (substring=Unknow, string=Unknow)