Bedep’s DGA: Trading Foreign Exchange for Malware Domains

By: Dennis Schwarz -

As initially researched by Trend Micro [1] [2], Zscaler [1] [2], Cyphort, and Malware don’t need Coffee, the Bedep malware family focuses on ad / click fraud and the downloading of additional malware. ASERT’s first sample dates from September 22, 2014, which is in line with when Trend Micro started seeing it in their telemetry. In early 2015, the family got some more attention when it was being observed as the malware payload for some instances of the Angler exploit kit, leveraging the Adobe Flash Player exploit (CVE-2015-0311) which at the time was a 0day. It was also observed that this newer version was using a domain generation algorithm (DGA) to generate its command and control (C2) domain names.

This post provides some additional notes on the DGA including a proof of concept Python implementation, a look at the two most recent sets of DGA generated domains, and concludes with some sinkhole data.


The following Bedep samples were used for this research:

  • MD5 e5e72baff4fab6ea6a1fcac467dc4351
  • MD5 1b84a502034f7422e40944b1a3d71f29

The former was originally sourced from KernelMode.


I’ve posted a proof of concept (read: works for me) Python implementation of the DGA to ASERT’s Github.

At the time of writing, I’m aware of two DGA configs. Each config contains three constants and a table of magical dwords used throughout the algorithm. The screenshot below highlights the table from the first sample:


Bedep’s DGA starts by downloading an XML file from:


This legitimate web service provides the time zone and local time at latitude zero and longitude zero. The <utctime> timestamp is parsed out and converted to milliseconds since year zero (0000-00-00). Then, 1-3 days are subtracted from it (depending on tick count timing–this feels like an anti-analysis technique) and it is converted to days since year zero. This value will be used in the next step.

Next, Bedep downloads an XML file from:


This legitimate file from the European Central Bank (ECB) contains the last 90 days of “Euro foreign exchange reference rates” and is updated daily. Each date is extracted from the <Cube time=”…”> tags then the days since year zero is calculated for “date minus one”. If the days since value is less than or equal to the value calculated in the first step AND if it falls on a Monday, then the foreign exchange reference rates for “date” are extracted and used. Here’s a visual showing this process:


After testing, my analysis reveals that Bedep updates using “last Tuesday’s” foreign exchange reference rates—where “last Tuesday” refers to “the preceding week’s Tuesday” until “this week’s Thursday”. After this, it means “this week’s Tuesday.”

From here, the algorithm becomes a bit opaque. Various values such as “days since,” the first parsed currency’s abbreviation, the low dword of the first parsed currency’s rate, the magical dword values from the extracted table (noted above), and various other constant and calculated values are transformed a number of times. I wasn’t able to deduce the “big picture” of these transforms, so I’m treating them as a blackbox where the output is the number of domains to generate and three values that that will be used to calculate a modular exponent starting seed. If anyone has more details on this blackbox, please reach out!

The number of domains to generate is 22 for the first config and 28 for the second for a total of 50 domains per set. To generate each domain, the starting seed and foreign exchange reference rates are transformed a number of times to calculate the domain length and the domain characters themselves:


The minimum domain length is 12 and the maximum is 18. I’ve only seen “.com” TLDs so far.


At the time of writing and using the foreign exchange rates from 2015-04-07, here are the eight registered domains from this set:


The first two were registered on 2015-04-13, the next two on 2015-04-11, then 2015-04-10, and the last two on 2015-04-08. All of them used the following registrant info:


This info is inline with what Zscaler observed.

Using the foreign exchange rates from 2015-04-14, here are the domains registered out of the set, so far:

  • (
  • (

The first two were registered on 2015-04-19, then 2015-04-17, and the last two on 2015-04-15. All six used the same registrant noted above.


To get a better idea of how active and widespread the above campaign is, we setup a sinkhole. The sinkhole was and from 2015-04-13 13:47 UTC to 2015-04-16 17:06 UTC (about 3 days) it received phone homes from about 82,127 unique source IPs. The top 10 TLDs of the resolved source IPs were:

  1. net (31578)
  2. com (11952)
  3. de (3193)
  4. mx (2611)
  5. tr (2104)
  6. it (1521)
  7. pl (1500)
  8. fr (1440)
  9. br (1360)
  10. au (1247)
  11. ca (1107)
  12. jp (1054)
  13. es (769)

And, except for Russia, infections were all over the map:



This post has taken a closer look at Bedep’s DGA and the recent campaign around it. Compared to some of the other date based DGAs we’ve looked at in the past, this algorithm is quite a bit more complicated and involved—effectively relying on the foreign exchange markets to generate its C2 domains. Based on the domain registration and sinkhole activity, Bedep is a current and active threat and will likely remain so for the foreseeable future.

MindshaRE: Statically Extracting Malware C2s Using Capstone Engine

By: Jason Jones -

It’s been far too long since the last MindshaRE post, so I decided to share a technique I’ve been playing around with to pull C2 and other configuration information out of malware that does not store all of its configuration information in a set structure or in the resource section (for a nice set of publicly available decoders check out KevTheHermit’s RATDecoders repository on GitHub). Being able to statically extract this information becomes important in the event that the malware does not run properly in your sandbox, the C2s are down or you don’t have the time / sandbox bandwidth to manually run and extract the information from network indicators.


To find C2 info, one could always just extract all hostname-/IP-/URI-/URL-like elements via string regex matching, but it’s entirely possible to end up false positives or in some cases multiple hostname and URI combinations and potentially mismatch the information. In addition to that issue, there are known families of malware that will include benign or junk hostnames in their disassembly that may never get referenced or only referenced to make false phone-homes. Manually locating references and then disassembling using a disassembler (in my case, Capstone Engine) can help to verify that you have found the correct information and avoid any of the junk inserted to throw your analysis off.

For those not familiar, Capstone Engine is a disassembler written by Nguyen Anh Quynh that was first released in 2013. The engine has seen a significant amount of development in that short amount of time and has a good track record of handling some tricky disassembly. Most importantly, it supports most popular programming languages, including Python – my current programming language of choice. One complaint I have with using an on-the-fly disassembler is the lack of symbols, but that can be gotten around by taking the list of imports and addresses from pefile and then checking any memory references against it. All of the PoCs presented expect an image base of 0x400000, but for any production use the actual image base should be parsed out and replaced.


Example: Backoff PoS Malware

Backoff is a recently discovered PoS malware family. I noticed that many of the times the malware was sandboxed, it would not communicate with a C2, but I could see the C2 info in plain-text in the binary or other times when the C2 was down.

Backoff C2 Plain-Text

Backoff C2 Plain-Text

In an attempt to “correctly” locate the C2 information and utilize some Capstone-fu, I crafted a function that first locates hostname- or IP-like strings in the binary, looks for a “mov [register+offset]/<addr> addr” pattern, and then uses capstone to disassemble to obtain the other configuration elements.

Backoff ASM Code to load C2

Backoff ASM Code to load C2

This ends up being useful, since the argument order is not necessarily the same. This doesn’t work for all versions, but does work for most – I have encountered a number that are using a VisualBasic injector or are using an array structure to store the config so the below code will not work. This can be coupled with another piece of code that searches for version-like strings and then disassembles to find the additional campaign name attached to the binary. The code should check to see if a) host,port, URI are defined after the loop and b) if the number of mov instructions encountered before the call was 3. The number of mov’s ends up being important since my code starts with the hostname and the arguments are not always encountered in the same order. If the mov’s are less than 3, then I jump back the appropriate number of mov’s via regex search and then walk the disassembly again to see if I encounter the expected configuration data. This will also help find the backup domains and URLs that are embedded in the malware that may not be seen during a sandbox run even if there is successful communication to the C2. The code is quick and dirty and can easily be improved by validating  some common instructions seen in between, but is presented as-is for this example:

    md = Cs(CS_ARCH_X86, CS_MODE_32)
    md.detail = True
    movs = 0
    host = None
    uri = None
    port = None
    for insn in md.disasm(code, 0x1000):
        if insn.mnemonic == 'mov':
            movs += 1
            if insn.operands[1].type == X86_OP_IMM:
                v = insn.operands[1].value.imm.real
                if v < 65536:
                    port = v
                    x = self.get_string(file,v-0x400000)
                    if URI_REGEX.match(x): uri = x
                    elif DOMAIN_REGEX.match(x): host = x
                    elif IP_REGEX.match(x): host = x
         elif insn.mnemonic == 'call': break 
         if movs == 3: break 

Example: Alina PoS Malware


Alina is a PoS malware family that has been around for awhile. Similar to Backoff, I noticed that many of the sandbox runs did not successfully communicate with the malware when the configuration was viewable.

Alina C2 Strings

Alina C2 Strings

I used a similar process to what I did with Backoff to first locate potential C2 candidates and then search for XREFs and disassemble with capstone. Many times the C2 is stored is pushed onto the stack followed by instructions setting local variables and then a subroutine call. Prior to the push of the C2 and the URI, there is another push that represents the length of the string and can also be used to validate the sequence. Once again, this is a great place to utilize capstone to make sure that anything that is extracted matches up with what is desired.

Alina ASM to load C2

Alina ASM to load C2

This sequence of pushes and calls always seems to be preceded by a call to InitializeCriticalSection, so I first look for that, using a dict built from loading the binary into pefile to get at the import table.. The order that the hostname and the c2 occur in the binary can be flip-flopped, so I allow for that. I do make sure that the next push after the strlen is a string  The code can be extended further to validate that the strlen matches the string I extract from the binary, but this is just a PoC :)

    for i in md.disasm(CODE, push_len_addr):
        if instr_cnt == 0:
            # check for InitializeCriticalSection
            if i.mnemonic == 'call' and \
              impts.get(i.operands[0].mem.disp,'') == 'InitializeCriticalSection':
                print "On the right track..."
        elif i.mnemonic == 'push' and i.operands[0].imm < 0x100:
            strlen = i.operands[0].imm
            str_instr = instr_cnt + 1
            print "Found the strlen push",i.mnemonic,i.op_str
        elif strlen and str_instr == instr_cnt and i.mnemonic == 'push':
            addr = i.operands[0].imm
            if addr == 0x400000+file.find(s):
                print 'found hostname push'
                hostname = get_string(file,addr-0x400000)
                print hostname
                uri = get_string(file,addr-0x400000)
                if URI_REGEX.match(uri): print uri
        instr_cnt += 1


Example: DirtJumper Drive

My last example involves a more complex example. Drive stores its most interesting strings in an encrypted format and does not decrypt all those strings in the same function (for more information see my previous blog post here), instead scattering the calls throughout the binary. In this example, I use the encrypted install name – it always starts with the same characters – to help us locate the decryption function. The decryption function is the function called right after the call  that Xrefs the encrypted install name.

Drive Install Name XRef

Drive Install Name XRef

With the address of the decryption function  known, I use the “k=” string used in the phone-home to help locate the network communication function. This function is where the C2 information is first decrypted and the C2 and the URI are the first two things decrypted in this function. The code can then be walked further down to locate the C2 port, but that code is not shown here.

Drive C2 decryption

Drive C2 decryption

Here’s the first piece of code used to locate the decryption function:

        mov_addr = '\xb8'+struct.pack("<I",0x400000+file.find(s))
        instr_addr = 0x400000+file.find(mov_addr)
        if instr_addr <= 0x400000:
            mov_addr = '\xba'+struct.pack("<I",0x400000+file.find(s))
            instr_addr = 0x400000+file.find(mov_addr)

        # looks for PUSH EBP; MOV EBP, ESP
        func_start = file[:instr_addr-0x400000].rfind('\x55\x8b\xec')
        code = file[func_start:func_start+0x200]
        md = Cs(CS_ARCH_X86, CS_MODE_32)
        md.detail = True
        decrypt_func_next = False
        calls = 0
        for i in md.disasm(code, func_start+0x400000):
            # looking for mov eax, 
            if i.mnemonic == 'mov' and len(i.operands) == 2 \
              and i.operands[0].type == X86_OP_REG and i.operands[0].reg == X86_REG_EAX \
              and i.operands[1].type == X86_OP_IMM and i.operands[1].imm >= 0x400000 \
              and i.operands[1].imm <= 0x500000:
                d = decrypt_drive(get_string(file,i.operands[1].imm-0x400000))
                # validate that this is indeed the install name
                if d.endswith('.exe'):
                    config['install_name'] = d
                    decrypt_func_next = True
            # check for the next call after the install name call
            elif decrypt_func_next and 'install_name' in config \
              and i.mnemonic == 'call' and calls == 1:
                config['decrypt_func'] = i.operands[0].imm
            elif 'install_name' in config and i.mnemonic == 'call':
                calls += 1

Now that the decryption function has been located, the desired C2 information can now be located.

        mov_inst = '\xba'+struct.pack("<I",0x400000+file.find('k='))
        mov_k_addr = 0x400000+file.find(mov_inst)
        # look for PUSH EBP; MOV EBP, ESP
        func_start = file[:instr_addr-0x400000].rfind('\x55\x8b\xec')
        code = file[func_start:func_start+0x200]
        md = Cs(CS_ARCH_X86, CS_MODE_32)
        md.detail = True
        calls = 0
        d = None
        for i in md.disasm(code, func_start + 0x400000):
            # look for mov edx, <addr>
            if i.mnemonic == 'mov' and len(i.operands) == 2 \
              and i.operands[0].type == X86_OP_REG and i.operands[0].reg == X86_REG_EDX \
              and i.operands[1].type == X86_OP_IMM and i.operands[1].imm >= 0x400000 \
              and i.operands[1].imm <= 0x500000:
                d = get_string(file,i.operands[1].imm-0x400000)
            # if call decrypt_func, then decrypt(d)
            elif i.mnemonic == 'call' and i.operands[0].imm == config['decrypt_func'] and d:
                # first call is the c2 host/ip
                if calls == 0:
                    config['host'] = decrypt_drive(d)
                    d = None
                    calls += 1
                # 2nd call is the URI
                elif calls == 1:
                    config['uri'] = decrypt_drive(d)
                    d = None

Future Work

Capstone is a useful tool to have in your toolbox and hopefully the PoC code presented in this post will aid others in the future. For my own future work, I plan to tighten up the code presented and work on getting code for other interesting malware families into something that will be suitable to push out for public release.

Let’s Talk About NewPosThings

By: Dennis Schwarz -

by Dennis Schwarz and Dave Loftus

NewPosThings is a point of sale (PoS) malware family that ASERT has been tracking for a few weeks. It operates similarly to other PoS malware by memory scraping processes looking for credit card track data and then exfiltrating the spoils to a command and control (C2) server. Based on compilation times, it has been in active development since at least October 20, 2013—with the latest timestamp being August 12, 2014. Since we haven’t come across any public details of this family, we’re releasing our malware analysis for posterity and to get ahead of the threat.

The analyzed sample has an MD5 of 4196c67648003a18f61573a77b6d3be6.


Its name comes from an embedded PDB pathname string from the analyzed sample:

C:\Users\Tom\documents\visual studio 2012\Projects\NewPosThings\Release\NewPosThings.pdb


The malware initializes itself as follows:

  • Sets some insecure file flags in the Registry:
    • “LowRiskFileTypes” in “HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\Associations”
    • “1806” in “HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\0”
  • Copies itself to “%APPDATA%\Java\JavaUpdate.exe”
  • Checks whether it is running as 64-bit and if so, exits with a MessageBox of “Use 64bit version.”
  • Kills any existing “JavaUpdate.exe” processes
  • Sets up Registry Run persistence (HKCU\Software\Microsoft\Windows\CurrentVersion\Run) under “Java Update Manager”
  • Executes copied executable passing the original executable’s pathname and “RM” as command line arguments
  • Original process exits

Second copy continues:

  • Deletes original executable
  • Phones home to the C2
  • Searches the Registry for VNC passwords. The following keys and values are checked:
    • HKLM\SOFTWARE\RealVNC\vncserver[Password]
    • HKLM\SOFTWARE\RealVNC\WinVNC4[Password]
    • HKCU\SOFTWARE\RealVNC\WinVNC4[Password]
    • HKCU\Software\TightVNC\Server\[Password]
    • HKCU\Software\TightVNC\Server\[PasswordViewOnly]
    • HKCU\Software\TigerVNC\WinVNC4\[Password]
    • HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Ultravnc2_is1[InstallLocation] (then opens ultravnc.ini looking for “passwd=/passwd2=”)
  • Sets “SeDebugPrivilege” privilege
  • Starts memory scraping thread
  • Starts C2 communications thread
  • Starts key logging thread

C2 Communications

The initial C2 phone home is HTTP POST based and looks like:



Header-wise: there is a bug with Accept as, per the code, it is supposed to be “*/*” and the User-Agent is hardcoded to “Mozilla/4.0(compatible; MSIE 7.0b; Windows NT 6.0)”. The POST parameters break down into:

  • cs – is in base64 and decodes to “insert”
    • The base64 charset used in this malware is “ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_”
    • p – contains Windows version, “+32” is hardcoded (most likely a placeholder for architecture type), and computer name
    • m – the volume serial number of the root drive (used as an identifier)

An example response from the C2 is:



If any VNC passwords were found in the Registry they are exfiltrated to the C2:



The parameters are:

  • cs – base64, decodes to “log”
  • m – the volume serial number of the root drive (used as an identifier)
  • ls – base64, example below
>>> myb64.b64decode("dm5jX3Bhc3N3ZAoK")

The response from the C2 can contain a couple of other commands:

  • “update => url” – update self
  • “install => url” – download and execute
  • “not found” – remove self

Update and install both download to and execute from “%APPDATA%\Java\Explorer.exe”.

Credit Card Track 1 and 2 Memory Scraping Thread

Running in a loop, this thread takes a snapshot of all running processes it has access to on the system. For each process it:

  • Skips if it is a system process, one of:
    • svchost.exe
    • System
    • smss.exe
    • csrss.exe
    • winlogon.exe
    • lsass.exe
    • spoolsv.exe
    • alg.exe
    • wuauclt.exe
  • Skips if the process is the malware itself
  • Reads all accessible read/write memory
  • Parses each byte looking for “^” or “=” – field separators used in credit card track 1 and track 2 data respectfully
  • If there’s a match, further checks are done (track 1 and 2 are checked similarly):
    • Working backwards from the separator looks for 13-20 digits that could make up the Primary Account Number (PAN). Ends at a non-digit start sentinel
    • Checks the possible PAN with the Luhn algorithm—used to validate credit card numbers
    • Checks that the expiration date is reasonable: year is between [20]13 and [20]19 and month starts with a 0 or 1
    • Checks whether rest of the characters after the separator are digits
  • If the checks pan out, the track data is RSA encrypted with an embedded PUBLICKEYBLOB, see IDA screenshot below
  • It is then base64 encoded
    • If RSA encryption fails for whatever reason, the track data is just base64 encoded
  • Encrypted data is stored for later exfiltration to the C2



Credit card track data is exfiltrated very similarly to VNC passwords:



The “ls” parameter decodes to newline-separated entries:

 >>> ls = myb64.b64decode("U2Nhbm5pbmcgc3RhcnRlZAo0MUR1ekN5NF9oOGJiOVpUSDV0blRpWXhUbG5INnB4V0g2OXhZcVBLckJ2SjN0RXlvT1ZaanJnei1EOVpsOURPVTlsYVBnejVpWndkZ3FxUkw3U3RzeEdwVUs1YWwzRHR3aTZvTW9hNjRXWF9LSm9Da0QxRENmTHRwQ1NTTUhvYkNKY3lJVWJJanBBR2hfUWlaMDNYOHRPZUpZTmJrbDRzclptU05qMjlPUmM9CmV2NzA2QXYyZTlKTUpKRmlWZzZOaGMwSE85dlFvNy15RFJ2ZlJ5TmpFVVA0SlVTQU8wYUh3eUFERTVDWWRQVWNYWWhmRThqX0Q0b1I2NnNxejZ1ZzlyVmR2N0c4ZTRPLWdQYW9aVjdVSmJaaS1pN2NWUDJlb3hxb0ZCZTdkZ2pJeWZUNTRNelRDamlqanF4VzV1a080ek1HaThvVUdkUGpEamVoN0RiMEtYQT0K")
 >>> ls.split("\n")
['Scanning started', '41DuzCy4_h8bb9ZTH5tnTiYxTlnH6pxWH69xYqPKrBvJ3tEyoOVZjrgz-D9Zl9DOU9laPgz5iZwdgqqRL7StsxGpUK5al3Dtwi6oMoa64WX_KJoCkD1DCfLtpCSSMHobCJcyIUbIjpAGh_QiZ03X8tOeJYNbkl4srZmSNj29ORc=', 'ev706Av2e9JMJJFiVg6Nhc0HO9vQo7-yDRvfRyNjEUP4JUSAO0aHwyADE5CYdPUcXYhfE8j_D4oR66sqz6ug9rVdv7G8e4O-gPaoZV7UJbZi-i7cVP2eoxqoFBe7dgjIyfT54MzTCjijjqxW5ukO4zMGi8oUGdPjDjeh7Db0KXA=', '']

After the first entry, the rest are base64 and RSA encrypted credit card track data:

 >>> myb64.b64decode("41DuzCy4_h8bb9ZTH5tnTiYxTlnH6pxWH69xYqPKrBvJ3tEyoOVZjrgz-D9Zl9DOU9laPgz5iZwdgqqRL7StsxGpUK5al3Dtwi6oMoa64WX_KJoCkD1DCfLtpCSSMHobCJcyIUbIjpAGh_QiZ03X8tOeJYNbkl4srZmSNj29ORc=")

Credit Card Track 2 Key Logging Thread

The last thread starts by extracting a DLL from an executable resource and writes it to “%APPDATA%\Java\DLLx64.dll”. The filename is hardcoded even though the DLL is 32-bit. The “InstallHooks” export is executed which installs a keyboard hook via the SetWindowsHookEx function. After hook installation, the thread loops looking for Windows messages with an ID of 2023 (sent by the hook function). On receiving the message, a buffer of 400 keystrokes is collected and is searched for track 2 data as above—not particularly sure why the malware is looking for credit card track data in typed input though.

Command and Control Login


Samples and Campaigns

The following are the samples and campaigns known to ASERT:

MD5: 87f6385a4cb0520e19782350c30826bc

C2: hXXp://

Compilation date: 2013-10-20 23:15:49

Notes: I believe this is an earlier development version that differs somewhat from the above analysis. Copies itself to “%APPDATA% \Java\javaj.exe”.


MD5: 3cee6591a0ec2e1e1bdd317ec8777c58

C2: hXXp://

Compilation date: 2013-10-22 00:40:30

Notes: Also an earlier development version using “javaj.exe”.


MD5: ec0e8edbab6575e167689cca533f75f0

C2: hXXp://

Compilation date: 2013-12-21 20:34:39

Notes: Also an earlier development version using “javaj.exe”. This IP has hosted a Citadel C2 at hXXp:// in the past.


MD5: fefeb6a27f34b35a6a43c65c188bcde7

C2: hXXp://

Compilation date: 2014-05-11 10:31:02

Notes: Per Google Translate, “eklemek” is the Turkish word for “adding”.


MD5: 68dbce1053450a4395368835367d20b5

C2: hXXp://

Compilation date: 2014-05-12 19:00:35


MD5: 2576bc49e3c796b5b94695241d0d4359

C2: hXXp://

Compilation date: 2014-05-12 19:03:08


MD5: 3d58e0b2b9303e0bc4bb282c1ee2dd18

C2: hXXp://

Compilation date: 2014-05-15 12:30:47


MD5: 40e556c77948037497b9205932e69b97

C2: hXXp://

Compilation date: 2014-05-15 12:32:05


MD5: 4196c67648003a18f61573a77b6d3be6

C2: hXXp://

Compilation date: 2014-05-20 19:32:42

Notes: Live C2 panel at time of writing. hXXp:// is also a live C2 at the time of writing, but I don’t have the associated sample.


MD5: ae9899722707fc2c9716138580787026

C2: hXXp://

Compilation date: 2014-08-12 15:43:20

Notes: This sample returns to copying to “%APPDATA% \Java\JavaJ.exe”, just using camel-case. The PDB pathname has also changed to “C:\Users\Tom\documents\visual studio 2012\Projects\jsd_12.2\Release\jsd_12.2.pdb” so the author may have rebranded it from “NewPosThings” to “jsd”. At the time of writing, the C2 panel is live and the domain has hosted an Andromeda C2 at hXXp:// in the past.

Yara Rule

We’ve been using the following Yara rule for tagging and hunting:

// newposthings, Dennis Schwarz, Arbor Networks ASERT, September 2014
rule newposthings
    $pdb1 = "C:\\Users\\Tom\\documents\\visual studio 2012\\Projects\\NewPosThings\\Release\\NewPosThings.pdb" nocase
    $pdb2 = "C:\\Final32\\Release\\Final.pdb" nocase
    $pdb3 = "C:\\Users\\Tom\\documents\\visual studio 2012\\Projects\\jsd_12.2\\Release\\jsd_12.2.pdb" nocase
    $str1 = "install =>"
    $str2 = "update =>"
    $str3 = "cs=bG9n&m="
    $str4 = "cs=aW5zZXJ0&p="
    (any of ($pdb*)) or (all of ($str*))


This post has been an analysis of a point of sale malware known as NewPosThings. Its modus operandi is similar to that of other PoS malware where it memory scrapes for credit card track data, does some basic verification with the Luhn algorithm, and then exfiltrates to a command and control server. While it appears to be in active development, the scope and distribution of this threat is currently unknown. ASERT continues to monitor NewPosThings and other PoS malware threats.

Illuminating The Etumbot APT Backdoor

By: Arbor Networks -

The Arbor Security Engineering Response Team (ASERT) has released a research paper concerning the Etumbot malware.

Etumbot is a backdoor used in targeted attacks since at least March 2011. Indicators suggest that Etumbot is associated with the Numbered Panda group, also known as IXEHSE, DynCalc, and APT12.  Although previous research has covered related malware, little has been publicly discussed regarding Etumbot’s capabilities.

Indicators suggest that the Etumbot dropper is delivered via spear phishing and is contained inside an archive file intended to be of interest to the target. The attackers use the Unicode Right to Left Override technique and document icons to disguise malicious executable content as document files. Once the dropper is executed, the backdoor is activated and a distraction file of interest to the target is opened for viewing.  ASERT has observed several Etumbot samples using distraction documents involving Taiwanese and Japanese topics of interest, and has also observed recent development activity which indicates that attack campaigns are ongoing.

Once installed, the backdoor connects to it’s Command & Control server and receives an encryption key. RC4 encryption, along with HTTP transactions intended to blend in with typical traffic are used for backdoor communications. Etumbot’s core functionality allows for the execution of commands and the capability to upload and download files.

Attackers attempt to obfuscate the malware by using a technique known as “byte strings”, also known as “string stacking”. Through the use of ASERT tools, these byte strings are deobfuscated and revealed herein.

A timeline containing distraction documents along with backdoor and dropper indicators to include MD5 hashes, Command & Control server information, file system and process artifacts are included herein. Some use of the HTran connection bouncer has been observed, indicating that selected C&C’s were simply compromised sites used to relay traffic elsewhere.

It is our aim to assist incident response and security teams and to provide meaningful insight into this threat.

Download the full report: ASERT Threat Intelligence Brief 2014-07: Illuminating the Etumbot APT Backdoor

The Best Of Both Worlds – Soraya

By: Matthew Bing -

By Matt Bing & Dave Loftus

Arbor Networks’ ASERT has recently discovered a new malware family that combines several techniques to steal payment card information. Dubbed Soraya, meaning “rich,” this malware uses memory scraping techniques similar to those found in Dexter to target point-of-sale terminals. Soraya also intercepts form data sent from web browsers, similar to the Zeus family of malware. Neither of these two techniques are new, but we have not seen them used together in the same piece of malware.


Soraya begins by injecting itself as a thread on several system processes, including the Windows Shell explorer.exe. The malware maintains persistence by writing a copy of itself into the AppData directory with the name servhost.exe, and setting itself to execute with the registry key HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\WinServHost.

New processes launched from the infected explorer.exe shell, notably web browsers, will have Soraya code injected. The malware does this by hooking calls to the ntdll.dll!NtResumeThread() function, which is responsible for process initialization. The function ntdll!NtQueryDirectoryFile() is also hooked to hide displaying the servhost.exe file. Both of these techniques are similar to functionality found in the Zeus family of malware.

Memory Scraping

One thread on the system is responsible for scraping memory for credit card data. It does this by creating the mutex POSMainMutex to ensure it is the only thread operating. Every 5 seconds, the thread will iterate through the list of processes with Process32Next(), ignoring system processes with names shown in Figure 1. It will check memory regions for each process with VirtualQueryEx(), ignoring those with the PAGE_NOACCESS or PAGE_GUARD values set. Valid memory regions are copied with ReadProcessMemory() and examined for payment card data. The Dexter malware family uses a similar technique.

[System Process]

Figure 1 – Process Names Ignored For Memory Scraping

Soraya will scan memory for patterns matching valid payment card data. It does not use regular expresssions, but matches the format code “B”, patterns of digit strings, and the standard “^” separator as defined in ISO/IEC 7813. One unique aspect of Soraya is that is uses the Luhn algorithm to identify valid credit and debit card numbers, a new technique for memory scraping point-of-sale malware. The Luhn algorithm leverages a simple checksum over credit card numbers to ensure that they are valid. Track 1 and track 2 data are packaged and sent to the command and control (C2) site using the protocol described below as a “mode 5″ message.


Figure 2 – Luhn Algorithm

Form Grabbing

After injecting itself, Soraya will check if the new process is a web browser by locating several unique DLLs. The functions targeted are those responsible for sending POST data, which are intercepted and sent to the C2 as a “mode 4″ message described below. All POST data is captured, not just payment card information.

Internet Explorer has the function wininet!HttpSendRequestW() hooked, and will checkInternetQueryOptionA() with INTERNET_OPTION_URL to see if > 1 byte is being sent. If so, data is copied and exfiltrated.

Firefox has the function nss3!PR_Write hooked. The hooking function will check for the “POST” verb, then exfiltrate data.

Chome has the function nspr4.dll!PR_Write() hooked. The hooking function will also check for the “POST” verb, then exfiltrate data. Soraya will also manually examine chrome.dll and similarly hook unexported functions.

Soraya hooks these functions by overwriting the function prologue with the instructions PUSH and RET, essentially providing a new saved return address and returning to it. As an example, this is what a normal, unhooked version of Firefox’s nss3!PR_Write looks like in WinDBG.


After being injected with Soraya the first 6 bytes of the function are overwritten with PUSH 62042h, the address of the intercept function, and RET which returns to that address.


The intercept function itself at 0x62042 will check if EBX points to the string “POST” at 0x6206A. Before this, it will execute the original PR_Write function by calling the address at 0x640EC.


The code at 0x640EC to execute the original PR_Write function uses a similar technique. The first six bytes of the original PR_Write function were saved and are executed before returning past the 6 bytes of the hook code that now constitute PR_Write.

The first 6 bytes of the original PR_Write function were saved and are executed before returning past the 6 bytes into the original PR_Write function.


Soraya uses this same technique to hook the ntdll.dll!NtResumeThread() and ntdll!NtQueryDirectoryFile() functions, in a very similar fashion to the Citadel malware.

Command and Control Communication

One thread on the system is responsible for communicating with the command and control server. It does this by creating the mutex JDWJDd8a2 and checking in with the C2 every 5 minutes by posting data to a specific URL embedded in the executable. The C2 site and URL are encoded in the executable by XORing with the Unicode string “SorayaV1.1″.

To discourage casual browsing, the C2 backend will only accept messages with a specific User-Agent set. In the samples we’ve identified, this value has been static, which we believe is unique to this particular campaign.

Several HTTP POST variables may be sent to the C2:

mode – Identifies the type of message the malware is sending to the C2
uid – A unique idenifier string generated by the malware, which is stored in the registry at HKCU\SOFTWARE\Microsoft\Soraya2\UID
osname – A hex encoded string of the major version, minor version, service pack version, and “x86″ or “x64″
compname – A hex encoded string of the current username and computer name
browser – One of “FireFox”, “Chrome”, “InternetExplorer” depending on the browser generating the message
url – A hex encoded URL for which data is being submitted
grabbed – Raw data captured by a POST to a URL
compinfo – Same as compname
ccnum – Hex encoded credit card data
type – “Track 1″ or “Track 2″ depending on the data captured
track – Hex encoded raw track data
comid – A numerical job ID set by the C2

The following “mode” values have been identified:

Mode 1 –  Identify a new bot to the C2
Mode 2 – Receive the latest commands from the C2
Mode 3 – Tell C2 that the current job has completed
Mode 4 – Add grabbed form information
Mode 5 – Send skimmed track information to the Command & Control

The thread responsible for C2 communication will send “mode 1″, “2”, and “3” messages. In response to a “mode 2″ check for the latest commands, the server will respond with one of the following:

vweb – Open a URI with ShellExecuteA()
vstealth – Stealthily open a URL invisible to the user with URLDownloadToFileW(tmpfile)
down – Download a file from a URL and execute it
update – Download a from for a URL, respond with a “mode 3″ complete message, spawn a new process with the executable, then self destruct
uninstall – Respond with a “mode 3″ message, then self destruct

When Soraya is installed, it sends a POST request to the C2 server. The request consists of a “mode 1″ message, the operating system version, computer name, and unique UID identifying the bot.


Soraya sends a “mode 2″ message to obtain any pending commands from the C2 server.


Any web browser process infected with Soraya is capable of sending “mode 4″ messages. The thread responsible for memory scraping sends “mode 5″ messages, as seen below:


Web Panel / Backend

Version 1.0 of the Soraya panel consists of the following files:

The login.php page is the administrative login page used for the panel. This file accepts the control panel password sent via the “p” parameter in a GET request. If the login is successful, session variables are set and the administrator is redirected to “statistics.php”.

This file stores session information.

The statistics.php page provides a general overview of any bots that are able to check into the C2. The total number of bots online, the number of infections per country, and the last 25 connections are displayed on this page.


Soraya infections checking into the command and control send POST requests to the file “bot.php”. Soraya is designed to send a specific user-agent that acts as a connection password to the panel. If correct, this file accepts new bot registrations to the panel, requests for new commands that should be executed by Soraya bots, and acknowledgments that commands have been successfully completed. It also accepts stolen form data and track data. All of this information is subsequently stored in the backend database, which is typical of many C2s.

The “commands.php” page is used to send commands to Soraya bots that have registered with the control panel. Commands include the ability to open arbitrary URLs that are visible or not visible to the victim, download and execute files, update a bot, or request that a bot uninstall itself. This page also displays the number of times a bot should perform a particular command, and the total number of times a command has been performed.


This page ends the current session.

The panel password, database information, and connection password used by the malware are defined in this file.

Displays a list of bots that have acquired form data. The bot identifier, IP address, browser used, URL visted, and date form data was received are displayed on this page.

Displays the exfiltrated POST data and their respective URLs.

Displays stolen card numbers, raw track data, the type of track data exfiltrated, and computer name of the compromised machine. This page is also used to save the track data to a dump file using the format “dump-YYYY-mm-dd.txt”. Panel administrators have the ability to delete track data from the database using this page.


Contains miscellanous functions used by other components of the control panel.

The country code of compromised machines are identified when a bot registers with the control panel. This file contains MaxMind GeoIP data that is used to identify the country.

Contains PHP code from MaxMind that is used to map IP addresses of compromised machines to their respective countries.

Payment Card Data

Our analysis of Soraya revealed that thousands of payment cards have been compromised. We were able to acquire track data from one command and control after the attacker temporarily placed the card data in a publicly accessible location.

An analysis of the track 1 data revealed the country of origin of the financial institutions issuing the cards that were compromised:


Our analysis revealed that 65.16% of the payment cards compromised were issued by financial institutions located in the United States. Costa Rican financial institutions were also deeply affected, having issued 21.45% of cards that were compromised. Canadian financial institutions issued 11.20%, South African institutions issued 0.82%, Brazilian and Russian based institutions each issued 0.40%, and institutions in the UK, Poland, Mexico, and Panama each issued 0.14%.


Additionally, we were able to determine the type of many cards compromised by Soraya. Debit cards were the most compromised, representing 63.934% of the track 1 data obtained. Credit cards consisted of 34.153%. We were unable to determine the type of cards for 1.913%.


Soraya has clearly taken inspiration from the Dexter and the Zeus families. The “split brain” functionality of both memory scraping and form grabbing is Soraya’s most unique trait. In past campaigns, memory scrapers have been uniquely targeted at point-of-sale devices and form grabbers have been uniquely targeted at online bank users.


To support further investigation by researchers, below are the MD5 values for samples we’ve identified as Soraya.


The following MD5 hashes are associated with the panel files:

1df57b31a4bca7a1c93ecd50bd8fd8bf auth.php
67a6bf5b9b23c6588c756c2f2a74635c bot.php
c3e9d1dda7f1f71b4e1e2ead7c7406dd commands.php
515232eb815b7bafab57c7cdca437a7a formgrab.php
ff8cc2e792a59d068f35cb3eb2ea69bc funcs.php
b64ea0c3e9617ccd2f22d8568676a325 /inc/GeoIP.dat
d2ba8b27dc886b36e0e8ec10e013d344 /inc/
c94285b73f61204dcee5614f91aaf206 login.php
d9e7f69822821188eac36b82928de2a0 logout.php
e5dadfff0bc1f2113fedcf4eb3efd02f settings.php
22888a7b45adc60593e4fc2fe031be98 statistics.php
ecf98e76c99f926e09246b02e53f2533 style.css
3f391740cbbd9623c4dfb19fb203f5bc trackgrab.php
ea9a242932dfa03084db3895cf798be5 viewlog.php

Trojan.Eclipse — A Bad Moon Rising?

By: Dennis Schwarz -

ASERT’s malware collection and processing system has automatic heuristics that bubble up potentially new and interesting DDoS malware samples into a “for human analysis” queue. A recent member of this queue was Trojan.Eclipse and this post is my analysis of the malware and its associated campaigns.

Analysis was performed on the sample with an MD5 of 0cdd10cd3393d3fe916a55b946c10ad6.

The name Eclipse comes from two places: a mutex named “eclipseddos” and a hardcoded Cookie value used in the command and control (C2) phone home. We’ll see in the Campaign section below that this threat is also known as: shadowbot, gbot3, eclipsebot, Rhubot, and Trojan-Spy.Win32.Zbot.qgxi.

Based on the C2 domain names, GeoIP of the C2 IP addresses, and a social media profile of the owner of one of the C2 domains, I suspect this malware to be Russian in origin. In addition, Eclipse is written in Delphi and empirically Russian malware coders have a certain fondness for this language.

Command and Control

The analyzed binary has a hardcoded C2 domain string. This string is protected from modification by running it through a simple hashing algorithm and comparing it against a hardcoded hash at certain points of the code. The following Python function replicates this algorithm:

 def decrypt(string):
    table1 = "qwertyuiopasdfghjklzxcvbnm.1234567890"
    table2 = "asdfghjklqwertyuiopnbmcvxzeasdfghjklv" 
    out = ""
    for orig_char in string:
        index = table1.find(orig_char)
        if index == -1:
            char = orig_char
            char = table2[index]
        while char in table1[index:]:
            index = table1.find(char)
            char = table2[index]
        out += char

    print out

For example, the domain “” hashes to “zopterrweoxyezpz.”

An example phone home request looks like this:


It is a HTTP GET based C2 protocol where the query string breaks down into the following parameters:

  • bot – 15 random lowercase letters and digits
  • botkey – possibly a hardcoded campaign key
  • os – OS name
  • ram – amount of RAM
  • user – username
  • cpu – estimated CPU speed
  • number of CPUs

After the Host line, the remaining headers are static—note the aforementioned Cookie value. An example phone home response looks like this:


The returned content is a single <base> tag containing base64-encoded data. Once decoded, an XML-like configuration file emerges (newlines added for clarity):

<cmd>stop;</cmd><tcp>GET /index.php HTTP 1.1
Host: $RANDOM$.net
User-agent: $RANDOM$

Another example:

<cmd>type=slow-post; threads=10; timeout=1;; script=/contact-us.php;
port=80;</cmd><tcp>GET /index.php HTTP 1.1
Host: $RANDOM$.net
User-agent: $RANDOM$

Relatively speaking, for a DDoS bot, Eclipse has a fairly rich configuration mechanism. Starting with the <cnfg> tag, it has four possible options:

  • control-timeout – set C2 poll time
  • control-path – set C2 pathname
  • control-domain – set C2 domain
  • stream-timeout – minimum wait time between attack packets, in milliseconds

The <cmd> tag can contain multiple commands delimited by a “\r\n”, and each command has three possible formats: standalone command, command requiring parameters, and a shortcut command. An example of the first format is:


Identified commands in this category are:

  • stop – stop attacks
  • wait – sleep for one day
  • die – exit process

An example of the second format:

<cmd>type=slow-post; threads=10; timeout=1;; script=/contact-us.php; port=80;</cmd>

There are a bunch of types, here are the ones identified:

  • update – update self
  • execute – download and execute
  • tcpint – custom TCP flood
  • browser – HTTP GET flood, look like a web browser
  • dirtjumper – HTTP GET flood
  • sincere – TCP flood
  • http – HTTP GET/POST flood
  • httpspoof – HTTP GET flood with spoofed X-Forwarded-For header
  • slowloris – broken Slowloris attempt
  • tcp – TCP flood
  • udp – UDP flood
  • http-data – HTTP POST flood
  • slow-post – broken slow HTTP POST flood
  • connect – TCP connect flood
  • tcp-oneconnect – TCP flood
  • icmp – broken ICMP echo request flood
  • http-post – referenced in the code, but not implemented

Command parameters depend on the type and include:

  • threads – number of attack threads, defaults to 30
  • timeout – wait time between attack packets, in milliseconds
  • target – target host
  • script – URI path and file
  • port – target port, defaults to 80
  • connint – unknown, defaults to 1
  • dataint – unknown, defaults to 1
  • data – referenced, but unused
  • template – template attacks

Two interesting features here. First, the script parameter can contain variables: $RANDOM$ is replaced with 15 random lowercase letters and digits and $INTEGER$ is replaced with a random integer between 0 and 998.

Second, the template option configures various attacks based on hardcoded templates. They include:

  • nginx – slowloris attack, 30 threads, 10 ms timeout
  • ssh – tcp attack, 45 threads, 10 ms timeout, destination port 22
  • ftp – tcp attack, 45 threads, 10 ms timeout, destination port 21
  • https – tcp attack, 70 threads, 10 ms timeout, destination port 443
  • dns – udp attack, 10 threads, 10 ms timeout, destination port 53

Finally, the shortcut command format looks like this:


This launches an http attack with 100 threads and a timeout of 10 ms.

The <tcp> tag is used in conjunction with the tcpint command and defines a custom TCP flood payload template. The template supports $RANDOM$ variables which are replaced with 15 random lowercase letters and digits.


Campaign-wise, Eclipse can be broken down into roughly four groups: shadowbot, gbot3, eclipsebot, and eclipseddos. The malware implementation used in each campaign varies a bit from what was describe above, but I feel that they’re earlier development versions and warrant being categorized under the same family name.

shadowbot Campaign

The shadowbot campaign was active from July 21, 2013 to August 10, 2013 (using VirusTotal’s first submission timestamp). Its name comes from the use of the shadowbot mutex. Other notable differences include:

  • Use of a shortened query string, “index.php?bot=”, in the C2 phone home
  • Missing Referer and Cookie headers in the C2 phone home
  • Does not use the <base> tag or base64 encoding
  • The <cmd> tag is much simpler and is delimited by “#”s
  • Does not use <cnfg> or <tcp> tags
  • Uses !random instead of $RANDOM$ variables
  • Smaller command set: connect, slow-post, http-data, cs, udp, tcp, and http

Some sample MD5s and C2 URLs:



The last entry in this table is the sample that Microsoft documented at They have named the malware “Win32/Rhubot.A”, but to be honest I couldn’t figure out why or find any good source material on “Rhubot”.

gbot3 Campaign

Next is the gbot3 campaign, which was active from August 9, 2013 to January 1, 2014 VirusTotal time. Its name also comes from the mutex that it sets. The distinguishing features of this version are:

  • As with shadowbot, uses shortened C2 phone home query string, “index.php?bot=”
  • Does not use base64 encoding, but does contain <cmd>, <cnfg>, and <tcp> tags
  • <cmd> is space delimited and still fairly basic
  • Implements “#” shortcut command
  • Implements tcpint command with <tcp> template. The template supports !randomchar, !random-ug, !random-lang, !random-encoding, !random-ac, !random-accept variables instead of $RANDOM$
  • Supports !random instead of $RANDOM$ in URI
  • Command set includes the more novel tcpint, browser, dirtjumper, slow-post, and tcp-oneconnect commands

Some sample MD5s and C2 URLs:



The last entry in this table is the sample referenced in SourceFire VRT’s “MALWARE-CNC Win.Trojan.Rhubot variant outbound connection” rule.

eclipsebot campaign

Third is the eclipsebot campaign, which was active from September 12, 2013 to November 4, 2013. Naming is based on the mutex. Sans some minor changes, this version is very similar to the eclipseddos analyzed in the beginning of the post. Notable features are:

  • Introduction of C2 domain hash check
  • Still uses shortened C2 query string, “index.php?bot=”
  • Introduction of rich <cmd> configuration via type, threads, timeout, target, script, etc. options
  • Has support for attack templates
  • Uses $RANDOM$ and $INTEGER$ variables

Some sample MD5s and C2 URLs:



eclipseddos campaign

The eclipseddos campaign has been active since November 28, 2013 VirusTotal time.

Some sample MD5s and C2 URLs:

0b450a92f29181065bc6601333f01b07 http://


The last two samples in the above table are referenced in the Emerging Threats rule called “ETPRO TROJAN Trojan-Spy.Win32.Zbot.qgxi Checkin”. As with Microsoft’s AV detection, I couldn’t find any source material on why they decided to name it this way.

The Trojan.BlackRev Connection

Back in May 2013, I released a blog post titled “The Revolution Will Be Written in Delphi” that profiled a DDoS bot named Trojan.BlackRev. Since that post, there have been a few updates that provide for a preamble to a possible relationship between Eclipse and BlackRev. On June 5, 2013 the author of BlackRev, going by the handle “silence”, posted to an underground forum saying that he had sold the project:


A few months later on October 4, 2013 on another underground forum, somebody going by the handle “chef” leaked the BlackRev source code:


While tracing one of the Eclipse C2 URLs from the shadowbox campaign:

I came across a C2 URL with a similar URI pathname:

The complete C2 protocol looks like this:


This traffic came from a binary with an MD5 of 8da35de6083aa9aa3859ce65e0e816df and I believe this sample to be a “missing link” between the BlackRev and Eclipse code bases.

In addition to the timeline proximity and the feeling of “code sameness” while reversing engineering, some of the major pieces linking this variant to BlackRev are:

  • The query string used in the phone home
  • Comparison against the “|stop|” string
  • Bot command is pipe “|” delimited
  • Launches the same “bot killer” code in a thread
  • Launches the same “memory reduction” code in a thread
  • Uses a similar random character generator
  • HTTP header overlap in some of the attacks
  • Names a command “antiddos”, which is fairly novel

The major pieces linking it to Eclipse (shadowbot specifically) are:

  • Shared C2 infrastructure
  • HTTP header overlap in the C2 phone home
  • Use of XML-like tags in the phone home response
  • Names a command “nginx”, which is a fairly novel
  • Eclipse variants also contain the same bot killer, memory reduction, and similar random character generation code
  • Name overlap in some of the attacks
  • HTTP header overlap in some of the attacks

With silence’s claim of selling the project and the leak of the source code to the public, it is unclear how or if the threat actors behind the Eclipse and BlackRev campaigns are related. I do feel strongly though that Eclipse is a descendant of the BlackRev code base.


This post has been an analysis of the Trojan.Eclipse family of DDoS bots. This malware is interesting because it has a fairly rich configuration mechanism, some novel attack types, and a nice development trail leading back to the either the Trojan.BlackRev code leak or sale of the project by the author.

ASERT is just ramping up attack monitoring of this family. So far we’ve seen a handful of attacks on a consumer complaint website, a venture capital company, a forum for a Russian town, and a rating site for Russian apartment repairs. Monitoring of the attacks and family continue.

Pretending to be a Zeus Gameover Bot

By: Dennis Schwarz -

Zeus Gameover is a banking trojan that started appearing in the wild sometime in early 2012. As with Citadel, Ice IX, and KINS, it is based on the leaked Zeus trojan source code. The most significant difference between Gameover and its immediate family members is that it uses a peer-to-peer (P2P) network for its command and control (C&C). What also stands out is that there appears to be only one instance of the Gameover botnet, whereas Citadel for example has hundreds of distinct ones.

This post releases some proof of concept code (read: works for me) that helps malware researchers to further understand and also interact with Gameover. More specifically it:

  • Extracts the initial set of P2P peers (starter peers) from a Gameover memory dump
  • Queries each of the starter peers for their “P2P network configuration” file
  • Decrypts and partially parses the configuration into something more human readable
  • Enumerates part of the P2P network

Prior Work

The code is meant to complement the existing body of Gameover malware research. It takes bits and pieces from the following sources and ties them together into something a bit more tangible:

Much appreciation goes to these folks and their work.

Code Availability

Python code will be available on Arbor Network’s GitHub. It depends on the pefile Python module and requires a Gameover memory dump to operate on. The dump used in this demonstration came from a sample that has a MD5 of 216b53fe8c704978468e8bfe1aad1152.

Please note that this is a live malware sample and the code has the ability to connect to and query a live malware C&C network! Stay safe.

Demonstration and Walk-Through

The walk-through data is initialized via:

>>> fp = open(“AML-12420355.rsrc-52307867.dynamic.memdump”, “rb”)
>>> memdump =
>>> fp.close()
>>> from ZeusGameover import ZeusGameover
>>> gameover = ZeusGameover(memdump)


$ python AML-12420355.rsrc-52307867.dynamic.memdump

First off, a hardcoded “sample configuration” file is extracted from the memory dump and de-XOR’d with a key stored in the relocation section (.reloc) of the binary (see the get_memdump_config function). This configuration file contains an RC4 key state used later to decrypt the “P2P network configuration” file:

>>> rc4_key = gameover.get_memdump_rc4_key()
>>> print “”.join(rc4_key).encode(“hex”)

The “sample configuration” file also contains the starter peers used to bootstrap communications with the P2P network (see the get_static_peers function):

static peer #1
ip:, udp port: 6710, rc4 key: c2056f859dd9fdf008507a637a0da568d16f825b

static peer #2
ip:, udp port: 6630, rc4 key: c046b43fbcec2475831083aa56aef3d5b72ceda6

static peer #3
ip:, udp port: 8204, rc4 key: a398bc30c436194c025513cb4bcafc1287460293

Using their respective UDP ports and RC4 keys, each of the starter peers is sent a “version” query to see if the peer is still alive. If so, the query will return version information and a TCP port (see the query_peer_for_version function):

static peer #8
ip:, udp port: 8835, rc4 key: d6c0d41b51dcb4b76205f3ab00f50af4411a22b9
binary version: 70314355, config version: 76101317, tcp port: 2997

If the TCP port is active, it is queried for the “P2P network configuration” file (see the query_peer_for_config and parse_config_response functions):

static peer #9
ip:, udp port: 3415, rc4 key: a5f5957b3acc687da57e5287837ea70c9ef827f6
binary version: 70314355, config version: 76101317, tcp port: 4948
config saved (1033680 actual bytes)

The “P2P network configuration” file is decrypted with the RC4 key state from above and lightly parsed. Parsing includes de-XORing and, if necessary, zlib decompressing the individual data “sections” of the config (see the parse_config function):

$ strings

[start item number: 22003, type: 0x10000001, packed size: 854, unpacked size: 2201]

[start item number: 2, type: 0x40000000, packed size: 36, unpacked size: 36]

[end item number: 2]
[start item number: 3, type: 0x40000000, packed size: 36, unpacked size: 36]

[start item number: 14, type: 0x40000001, packed size: 196, unpacked size: 298]
<script type=”text/javascript” src=”scripts/service?id=7″ language=”JavaScript”></script>S
[end item number: 14]

Over time, the “P2P network configuration” can be queried via new Gameover samples and a timeline of when changes are made and where those changes are start to appear:


$ diff -u jan_25.config.strings jan_28.config.strings
— jan_25.config.strings 2014-01-29 15:59:54.000000000 -0500
+++ jan_28.config.strings 2014-01-29 15:59:41.000000000 -0500

[start item number: 1, type: 0x40000000, packed size: 39, unpacked size: 39]
[end item number: 1]

In addition to the configuration data, the starter peers can be used to further enumerate the P2P network (see the enumerate_peers function):

peer #21
ip:, udp port: 5782, rc4 key: d29e52a567b266b53c8269433c5462c2cf0c4fdd

peer #22
ip:, udp port: 6977, rc4 key: d75dfdb4f96e623546940e8a8c03872e07eed9d2

peer #88
ip:, udp port: 1671, rc4 key: d3526a00abf536c6a1df7d8607c9635c0bd98dc1

peer #89
ip:, udp port: 4714, rc4 key: d27382dbec8a01a3c4b405e063a1c10267313d19

From a set of twenty starter peers and using a breadth first search an interesting pattern emerges:


This graph shows how many total unique peers are at each level of the enumeration. While this certainly does not represent the entire Gameover P2P network, it does start to give an idea of its size and scope. Thanks to Kenny MacDermid for the above idea and help on the visual.


Zeus Gameover is a banking trojan that has been around for a couple of years now. It continues to be very active and as of this writing is in ASERT’s top five of tagged malware samples. This is interesting because Gameover is also a well-researched malware family. Usually the longer a family exists and the more focus the malware research community gives it, the less active the malware becomes. But, Gameover continues to be in the limelight and continues to infect and affect a large number of people and companies across the Internet.

This post hopes to complement and further the existing malware research into Gameover. In addition, it hopes to also assist enterprises and service providers to detect and mitigate infected peers and banks and financial institutions to determine if and how they are being targeted.

A Business of Ferrets

By: Dennis Schwarz -

Trojan.Ferret appeared on my radar thanks to a tweet by @malpush. The tweet revealed a URL that at the time of this writing was pointing to a command and control (C&C) panel that looked like this:


The logo alone convinced me to study this business of ferrets further. Coincidentally (for Arbor), it turns out that this malware is a DDoS bot.

Malware Sample

The sample analyzed can be found at malwr (MD5: 4fa91b76294d849d01655ffb72b30981).

It is written in Delphi and plays the following malware games: UPX packing, string obfuscation, anti-virtual machine, anti-debugging, self-modifying code, and process hollowing.

Based on the Delphi usage and the language used for part of the panel, this bot is likely of Russian origin.


Trojan.Ferret uses two methods of obfuscation; both are a combination of base64 and XOR. Different keys are used for various sections. The first obfuscation method is used mostly for strings and can be decrypted with the following Python function:

def decrypt_strings(msg, key):
  msg_no_b64 = base64.b64decode(msg)

  plain_buf = []
  for i in range(len(msg_no_b64)):
    key_lsb = ord(key[i % len(key)]) & 0xf
    msg_lsb = ord(msg_no_b64[i]) & 0xf

    c = msg_lsb ^ key_lsb
    d = c ^ 0xa

    msg_slsb = ord(msg_no_b64[i]) & 0xf0
    plain_byte = msg_slsb ^ d


  return "".join(plain_buf)

Here are some examples:

>>> decrypt_strings("QG1wZ2xnPj4sZGNk", "12xc3qwfhjeryTTYHH")

>>> decrypt_strings("TG12RGZveGBnSG5mZ2JrQg==", "12xc3qwfhjeryTTYHH")

>>> decrypt_strings("dWpkbXFqZmxi", "mu#X")

>>> decrypt_strings("cn9tY3Nqf2d1", "mu#X")

>>> decrypt_strings("ZXN8djotITgyOyQ0MD4mOD45Jzc5I2NmfS1kaXhzdCx+YXo=", "GMrlZ8t3pypO3423423LpFqCUx")

The second method is used mostly for C&C communications and can be cleaned up with the following Python function:

def decrypt_cnc(msg, key):
  msg_no_b64 = base64.b64decode(msg)

  plain_buf = []
  for offset, enc_byte in enumerate(msg_no_b64):
    plain_byte = ord(enc_byte) ^ ord(key[offset % len(key)])

  return "".join(plain_buf)

Here are some examples:

>>> decrypt_cnc("ChYJCRhta3k=", "x38")
'2.11 USA'

>>> decrypt_cnc("DRhAAA4YeRgIXBgIUBgPVRgKAEs=", "x38")
'5 x86 A 0d 0h 7m 28s'

Command and Control

C&C is HTTP based. Two message types have been identified. The first is message type 0 or the “phone home” and looks like:

POST /hor/input.php HTTP/1.0
User-Agent: Mozilla Gecko Firefox 25
Accept: text/plain
Accept-Encoding: identity
Accept-Language: en-EN,en
Connection: Close
Content-Length: 106
Content-Type: application/x-www-form-urlencoded


Here’s what it looks like decrypted:

m=0&h=18803769021711750776216376939&p=HOME&v=2.11 USA&s=5 x86 A 0d 0h 7m 28s

Its POST parameters are:

  • m – Message type (0)
  • h – Hash based on computer name
  • p – Computer name
  • v – Version and locale
  • s – Windows version, architecture, user type, and uptime

The phone home response looks like:

HTTP/1.1 200 OK
Date: Wed, 04 Dec 2013 14:48:27 GMT
Server: Apache/2.2.15 (CentOS)
X-Powered-By: PHP/5.3.3
Content-Length: 32
Connection: close
Content-Type: text/html; charset=UTF-8


Decrypted, it is the User-Agent used in the request:

>>> decrypt_cnc("dVdCUVRUWRh/XVtTVxh+UUpdXldAGAoN", "x38")
'Mozilla Gecko Firefox 25'

The second message type is 1 or “poll for commands”. It looks like:

POST /hor/input.php HTTP/1.0
User-Agent: Mozilla Gecko Firefox 25
Accept: text/plain
Accept-Encoding: identity
Accept-Language: en-EN,en
Connection: Close
Content-Length: 49
Content-Type: application/x-www-form-urlencoded


And here it is decrypted:


Its POST parameters are:

  • m – Message type (1)
  • h – Hash based on computer name

An example poll response is:

HTTP/1.1 200 OK
Date: Wed, 04 Dec 2013 12:56:16 GMT
Server: Apache/2.2.15 (CentOS)
X-Powered-By: PHP/5.3.3
Content-Length: 72
Connection: close
Content-Type: text/html; charset=UTF-8



>>> decrypt_cnc("UExMSF5UV1dcElBMTEgCFxdMWUpfXUwWVl1MF1FWXF1AFkhQSBcSAAgSCQ0IEgg=", "x38")

Commands are delimited by “*”s and are formatted like:



The following bot commands have been identified:

  • httpflood – HTTP GET flood
  • httppost – HTTP POST flood
  • udpflood – UDP flood
  • synflood – TCP connect flood
  • tcpflood – TCP flood
  • download – download and execute (all bots)
  • downloadone – download and execute (specified bot)
  • update – update (all bots)
  • updateos – update (specified OS)
  • updateone – update (specified bot)
  • updatever – update (specified version)
  • removeos – remove bot (specified OS)
  • removeone – remove bot (specified bot)
  • s! – stop all floods
  • su – stop UDP flood
  • sh – stop HTTP flood
  • ss – stop TCP SYN flood
  • st – stop TCP flood

More information about each command can be found in the “Task Management” section of the C&C panel:



Note: I didn’t see any references to the “memexec” or “script” commands in the analyzed binary.

C&C Panel

Wrapping up, here is a behind the scenes tour of the C&C panel; the “Statistic/Index” page:


Here is the “Uploads” page:


And, part of the “Bot List” page:



This post has analyzed the crypto, C&C infrastructure, and command set of Trojan.Ferret—a new DDoS bot that is likely of Russian origin.  At the time of this writing only a handful of unique samples and C&C servers have been identified, so the scope and impact of the new threat is still uncertain. ASERT will continue to track this business of ferrets, and any other new businesses that arise.

Bitcoin Alarm – Bitcoin stealing spam

By: Kenny MacDermid -

The rise in Bitcoin values seems to have caused an equal increase of Bitcoin spam as malware authors attempt to make money off the many new market participants. One site that was spammed to me three times in one day is I ignored it the first two times, but they must have really wanted me to look at it, so who am I not to oblidge.

Bitcoin Alarm Logo

The site promises a tool to notify you of market changes by SMS, without ever mentioning any nefarious behaviour. YouTube videos teach you what Bitcoin is, and how to install this free tool.  They even provide a link so you can donate to the author, although it appears no one has chosen to do so. This I have to download.

BitcoinAlarm Icon

The download BitcoinAlarm.exe (MD5: edfa12d4a454b0eb786bbe92050ab88a) had just 1 hit on VirusTotal when I first scanned it (from Kaspersky). Is it a false positive on a nice free tool? Lets dig deeper.

The download is an installer. A quick strings didn’t turn up anything interesting, so lets try binwalk:

Binwalk Results - a rar archive
I carved out this RAR archive to see what it contains:

dd if=BitcoinAlarm.exe.virus of=out.rar bs=1 skip=756224
mkdir ext
unrar x out.rar ext/

Unrar results: an SFX script and 5 files.

There’s an SFX script run, lets see what it does:

CreateObject("WScript.Shell").Exec "winupdate.exe 5943564.IFW"

cat 7246235.vbe

A quick check of winupdate.exe with VirusTotal shows that it’s the valid (and non-malicious) AutoIt executable. AutoIt is a great little scripting language for Windows, it’s especially useful for automating GUI related tasks. So if winupdate.exe is AutoIt that would make 5943564.IFW an AutoIt script. It looks like it was obfuscated somewhat though:

a bunch of comments

head 5943564.IFW

Run it through

sed -e '/^;[0-9]/d'

to clean up the garbage and we end up with this script. It starts by checking if Avast is running and if so it sleeps for 20 seconds. I guess this is long enough for Avast to get bored and go look at something else:

if Avast, sleep for 20 seconds

Well, that’s certainly not a good sign. It’s a pretty solid chance that if software is checking for an antivirus engine that it’s up to no good. A scan of the rest of the file contains other interesting methods like “disable_uac”, “anti_hook”, “persistence”, “botkiller”, “downloader”, “disable_syste_restore”. It’s starting to look like Kaspersky was right, congrats on being the 1/49 to detect this.

I see a lot of calls to IniRead(), and they’re all reading 65901.PPZ. It looks like this is the configuration file. In contains:


Matching these to the script we see find the sections are:

# 6404000 == disable_uac()
# 2244034 == AdlibRegister("anti_hook", 500)
# 3206254 == AdlibRegister("persistence", 500)
# 5378250 == startup()
# 1109021 == $sKey

This crypto key is used in Main to decrypt and run the file 20070.RQT:

decrypt and run 20070.RQT with cryptkey

The easiest way to decrypt this file was to simply let the script do the work. There’s a lot of code outside of functions though, so care has to be taken to remove everything non-crypto related. Remove the _RunPE() and replace it with

FileWrite($uniscriptdir & "DECRYPTED", $sArquive)

The decrypted file had 30/48 hits of VirusTotal when I scanned it (MD5: 224c73f8172123e5ddca2302425664a6). It’s called NetWiredRC and is a remote access trojan made for stealing login information, and likely in this case being used to steal Bitcoins. It connect to on port 3360.

Some choice credential related strings from the decrypted malware:

select *  from moz_logins
SoftwareMicrosoftInternet ExplorerIntelliFormsStorage2

This free utility is nothing more than malware with very low detection rate being spammed to anyone that might have a Bitcoin sitting around. When I checked the domain with urlvoid it had zero ‘bad’ reports and was not blacklisted. I’ve since submitted the domain to multiple scanners and it’s now detected by Scumware.

On a recheck BitcoinAlarm.exe’s detection is up to 14 of 49 scanners, and the download link appears to return 404. is no longer answering on port 3360.

Never before has it been so easy to leave cash accessible from the Internet, so expect more malware to make off with your Bitcoin wallet. Bitcoins that are not in use should be moved off into cold storage, or donated to the human fund at 136K8a5Mb8uDguFb7RnoXz7gzBSe2xaEED (ahem, worth a shot right?).

Happy Holidays: Point of Sale Malware Campaigns Targeting Credit and Debit Cards

By: cwilson -

Inside Recent Point-of-Sale Malware Campaign Activities

Curt Wilson, Dave Loftus, Matt Bing

An active Point of Sale (PoS) compromise campaign designed to steal credit and debit card data using the Dexter and Project Hook malware has been detected. Indicators of compromise will be provided for mitigation and detection purposes. Prior to the publication of this Threat Intelligence document (embedded at the end of this post), members of the FS-ISAC, major Credit Card vendors and law enforcement were notified.

It appears that there are at least three distinct versions of Dexter:

  1. Stardust (looks to be an older version, perhaps version 1)
  2. Millenium (note spelling)
  3. Revelation (two observed malware samples; has the capability to use FTP to exfiltrate data)

In early November 2013, ASERT researchers discovered two servers hosting Dexter and other POS malware to include Project Hook.  The Dexter campaign looks more active, especially in the Eastern Hemisphere and therefore shall be the main focus herein. Dexter, first documented by Seculert in December 2012, is a Windows-based malware used to steal credit card data from PoS systems. The exact method of compromise is not currently known, however PoS systems suffer from the same security challenges that any other Windows-based deployment does. Network and host-based vulnerabilities (such as default or weak credentials accessible over Remote Desktop and open wireless networks that include a PoS machine), misuse, social engineering and physical access are likely candidates for infection. Additionally, potential brittleness and obvious criticality of PoS systems may be a factor in the reportedly slow patch deployment process on PoS machines, which increases risk. Smaller businesses are likely an easier target due to reduced security. While the attackers may receive less card data from smaller retailers, infections may be more numerous and last longer due to the lack of security reporting and security staff in such environments.

Figure 1: Dexter (Purple) and Project Hook (Orange) infections in the Eastern Hemisphere

Dexter and Project Hook infections in the eastern hemisphere

Figure 2: Dexter (Purple) and Project Hook (Orange) infections in the western hemisphere

Screen Shot 2013-12-03 at 1.22.00 AM

For the full document to include a list of various compromise indicators and information about the back-end infrastructure, please download the full public report –

Dexter and Project Hook Break the Bank


Go Back In Time →