Talking to dridex (part 0) - inside dropper --- Dridex represents one of the most interesting malware family one can find in the wild. It was descried in various places before, it even earns a decoder in hybrid-analysis. Shortly after that authors change how it is stored ;] I read few publication about didex, but when i sat down and started writing code communicating with bots, it turns out authors changed few important pieces, So i roll my slaves up and sat down to IDA, this series will decument every painfull step i had to make to finally be able to talk with dridex Intro. --- Dridex mostly come to us as spam contains .doc with few macros, responsible for downloading dropper, one can quickly analyze it using oledump.py and starring for some time in vbscript, or just run it in sandbox and got dropped files;] After unpacking boring packer, lets get into juicy parts. We are presented with small stage1 dropper, written by someone who either just learn how to write object-oriented code or is still learning. Purpose of dropper is to download main binary from C&C and inject it to explorer,plus some boring initialization stuff. CFG extraction. --- First lets take a look how to find C&C addresses. In older samples there was PE section called .sdata and it contains xored xml-document with all of interesting data, 85.25.238.9:8843 91.142.221.195:5445 46.37.1.88:473 About week ago it changed, no more .sdata :( - data sits in plain sight somewhere in memory structured as follow struct cfg_t { int field_0; unsigned __int16 botnet; unsigned __int8 count; char unknown; ip_addr cnc[count]; }; struct ip_addr { char ipaddr[4]; __int16 port; }; using yara signature like this: $new_get_cnc = { E8 [4] BE [4] 8D ?? 5B 83 C4 1C 0F [3] 08 0F [3] 09 0F [3] 0A 0F [3] 0B 0F [3] 0C } we can easily locate address where it is used and pull those data Ok, now we have to find a code that calls those addresses. after going back-and-froward with references we stumble across function presented at [0] Here is a little digression, if you don't know it already dridex uses encoded strings and run-time api resolving to make our life harder. Fortunately nothing fancy, simple xor https://gist.github.com/mak/dccb5f579a3d1e0b0180#file-dridex_decode-py Back to businesses, despite whats in every report first communication is not encrypted with xor but with RC4, keys are stored somewhere in binary encoded as any other string, they are different per botnet but otherwise don't seems to change that often, for botnet 220 key is: ub9sKhcvsePZXuFC4HRw8KjFSIVUxsdAJXFyVP3Acl7HYL9KQBzETBzFvk2FlxeHZFBljIPps21W armed with cnc addresses and key, we can create a message, Dridex authors were kind enough not to use any fancy binary format, just plain xml (sometimes gziped but we got to that part later...) message looks something like this: where `unique` is a bot name, created as shown in [1], `botnet` is a 2 bytes value hidden in confing, name corresponds to request we'd like to do. Most basic requests is `list` which obtains list of nodes. After decrypting response, using RC4 with the same key, we got something like this, Apts4+yozUR8Nbcan9dOya6yFIq6mxfdnJjlydF+uAELwWrIEIcvQIkk1mPURXr25/IwtnDW9l4s36C10iL0O6H3sJ1xhnUvcLN7ccjZU+RNySaj6YYSALvTBcGfNreUusy1ESLHKscAq4LJqzNy3UoB6fHLyJkULKhVFpKnogyKQEt4lctDeIpAS3iKQwb3205JWYYEZMwTJQEzS9B29XQK6aa1VsPxFd31tsa7IPRFldSbdDgUVQmVq35rDX5nJNAfOYttztqNC8etW0oDIxrkEzMJedOrGIIvAnMUtdjDeIouPdceNNhiLzkGY3q6gQoV8pwkCQsSrwltmFOmbyW9l6Vx+XWBiD8wOROQS3iK base64-encoded string is copied without decoding and dealed with in next stage. next command is `bot` and is responsible for downloading main dll base64-string There is no philosophy, base64-encoded string is being decoded and loaded into memory, what is interesting is how it is done. It's normal in malware world to apply extra layer of protection to files stored in local system, for example Tinba is additionally xoring it's configuration file with bot id. But non-writen rule of how malware works, is that every code is passed through memory in clear text, as one can guessed this not a case;] Indeed, dridex'es method of injecting into another process is quite nice[2]. It consists of two stub loaders, first responsible of decoding real payload, (again just xor) second is used as a simple pe-loader which make possible to run PE files, without syscalls like LoadLibrary or CreateProcess. This is clearly visiable in any memory tracer, [37ceca4ac82d0ade9bac811217590ecd.bin - 3980][3952]called[pre] NtOpenProcess(1212) = 1276 - C:\WINDOWS\Explorer.EXE ... [37ceca4ac82d0ade9bac811217590ecd.bin - 3980][3952]called[pre] NtWriteVirtualMemory(Explorer.EXE,1fe0000,459264) src: 932e90 ... [37ceca4ac82d0ade9bac811217590ecd.bin - 3980][3952]called[pre] NtWriteVirtualMemory(Explorer.EXE,b20000,2552) src: 12f348 ... [37ceca4ac82d0ade9bac811217590ecd.bin - 3980][3952]called[pre] NtWriteVirtualMemory(Explorer.EXE,b209f8,2460) sr c: 415020 ... [37ceca4ac82d0ade9bac811217590ecd.bin - 3980][3952]called[post] NtAllocateVirtualMemoryx(SELF,1900000,12288,MEM_COMMIT|MEM_RESERVE, RWX --- ) [37ceca4ac82d0ade9bac811217590ecd.bin - 3980][3952]called[post] NtAllocateVirtualMemoryx(SELF,1910000,65536,MEM_COMMIT, RW- --- ) Whats important with further analysis is that it relays quite heavy on loader metadata, which is somehow model to resemble legit PE, which is obviously not since it missed almost every part of it beside typical MZ-PE signature. 0000000: 4d5a 0000 0000 0000 0000 0000 0000 0000 MZ.............. 0000010: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000020: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000030: 0000 0000 0000 0000 0000 0000 4000 0000 ............@... 0000040: 5045 0000 0000 0000 0000 0000 0000 0000 PE.............. 0000050: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000060: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000070: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000080: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000090: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ Main dll is obviusly packed, but i left to the reader as a homework, since this is the end of introduction - cya in next part, mak sample used, 37ceca4ac82d0ade9bac811217590ecd [0] http://www.cert.pl/wp-content/uploads/dridgetcnc.png [1] http://www.cert.pl/wp-content/uploads/driduniqe.png [2] http://www.cert.pl/wp-content/uploads/dridprepl.png