My library

+ Add to library

Contact us
24/7 Tech support | Rules regarding submitting

Send a message

Your tickets



Added to the Dr.Web virus database: 2020-09-26

Virus description added:

  • Packer: absent

Compilation dates:

  • 30.07.2019 04:12:08 (x64 version)
  • 30.07.2019 04:12:29 (x86 version)

SHA1 hashes:

  • bfa1e457afbb1f160094f65b456503b64832d249 (x64 version)
  • ce3fc5b40231b5a9dd4aeeb0f0c7ef6f7779c53e (x86 version)


A backdoor written in C++ and designed to run on 32- and 64-bit Microsoft Windows operating systems. The functionality of the 32-bit and 64-bit versions is identical. The backdoor is linked to the OpenSSL library, which implements AES- and RSA-based encryption, as well as key generation. It is used in targeted attacks on information systems to gain unauthorized access to data and transferring it to C&C servers. In the infected system, the sample was located in System32 as a DLL named ssdtvrs.dll. It was installed by the ssdtvrs service. This description is based on the 64-bit version.

Operating routine

It exports the service entry point ServiceMain. Once launched, the backdoor registers a function that handles control requests, creates a thread in which it performs the main functions, and then waits in a loop for the service to stop.


The main thread

First, it prepares a configuration that can be stored both in the registry of the infected computer and in the body of the backdoor. It theen decrypts the name of the registry key Software\Microsoft\Internet Explorer\Security.


The backdoor checks the presence of this key first in the HKCU section, then in the HKLM section of the registry. Then, it loads the encrypted configuration from a parameter whose name matches the name of the malicious DLL file (in this case, ssdtvrs). If the configuration is not in the registry, the backdoor uses the hardcoded one.

The configuration is encrypted with RC4 and the key is generated using the following algorithm:


The configuration is stored as a sequence of blocks.

BYTE BYTE BYTE[item_len]
item_id item_len item_data

The backdoor parses all the blocks in turn and saves the resulting configuration as a structure:

//values 0xXX - item_id
  struct cfg
    DWORD item_0x1E;
    BYTE item_0x1F[32];
    BYTE item_0x20[32];
    BYTE item_0x21[64];
    BYTE C2_0[64];
    WORD C2_0_port;
    BYTE C2_1[32];
    WORD C2_1_port;
    BYTE C2_2[32];
    WORD C2_2_port;
    BYTE item_0x0A[64];
    WORD item_0x0A_word;
    BYTE item_0x0B[32];
    WORD item_0x0B_word;
    BYTE item_0x0C[32];
    WORD item_0x0C_word;
    BYTE C2_index_0x0D;
    BYTE item_0x14[32];
    WORD item_0x14_word;
    BYTE item_0x15[32];
    BYTE item_0x16[32];
    BYTE item_0x17;
    BYTE item_0x28[32];
    SYSTEMTIME time_1;
    SYSTEMTIME time_2;
    BYTE gap[16];
    BYTE item_0x29[64];
    BYTE module_file_name[16];

After preparing the configuration, BackDoor.Siggen2.3268 checks that the current system time ranges between cfg.time_1 and cfg.time_2, and waits until this condition is met.

It then prepares and sends the registration packet to the C&C server. First, it creates an object of the SBC02DEFE6 class (RTTI structures remained in the backdoor). This object contains another object that stores connection information, and also encapsulates the AZ092342345 object, which is responsible for data encryption. After creating the SBC02DEFE6 object, the backdoor attempts to hinder the debugging process by closing a deliberately incorrect handle. The exception that occurs is processed; and if the debugger is not present, the backdoor continues to operate.


After that, the cfg.C2_index_0x0D parameter is checked, according to which a specific C&C server is selected from the configuration. The following addresses are hardcoded in the configuration:

  • snow.swingfished[.]com

The backdoor then creates a TCP socket to connect to the server, and then prepares the encryption keys. The backdoor has a hardcoded public RSA key, which is encrypted with the same algorithm that is used to encrypt the registry key that stores the configuration.

The decrypted RSA key is shown below.

  -----END PUBLIC KEY-----
  .\>openssl rsa -noout -text -inform PEM -in pubkey.pem -pubin
  Public-Key: (2048 bit)
  Exponent: 65537 (0x10001)

After that, the backdoor generates a random WORD type value, which will be used to form a packet and check the response from the server.

Then, using OpenSSL, it generates a random AES key (256 bits) and generates encryption and decryption keys.


It uses the RSA key to encrypt the generated key for further transmission to the C&C server.

The backdoor stores keys in the AZ092342345 object. Its structure can be represented as follows:

struct AZ092342345
    vtable_AZ092342345 *vtable;
    AB2952354 o_AB2952354_response_data;
    AB2952354 o_AB2952354_decoded_data;
    AB2952354 o_AB2952354_3;
    AB2952354 o_AB2952354_4;
    WORD check_word;
    BYTE gap[6];
    RSA **p_RSA; //RSA - the structure from OpenSSL library
    AES_key AES_key;
    WORD rnd_word;
    DWORD dword_362;
  struct AB2952354 //objects of the AB2952354 class are used as data containers, such as those sent and received from the server
    vtable_AB2952354 *vtable;
    BYTE *p_buffer;
    BYTE *p_buffer_end;
    DWORD data_size;
    CRITICAL_SECTION crit_sect;
  struct AES_key
    char userKey[32];
    char ivec[20];
    int field_34;
    QWORD field_38;
    AES_KEY encryptKey; //AES_KEY structure from OpenSSL
    AES_KEY decryptKey;

The packet sent during the handshake has a 0x10A + <rnd> length, where rnd is a random value from 0 to 63, and comes with the following structure:

a test value a random value the random part of packet length the encrypted AES key

The first test value (WORD) is formed as follows.


The packet is sent to the server and a separate thread is started, which uses select to wait for a response transmitted to the socket from which the handshake packet was sent. When receiving a response, it checks the first 2 bytes of the incoming packet.


If the result is 1, the connection is reset. Otherwise, the backdoor parses the packet with the following header.

a test value the packet length with a header the length of the compressed data the length of the decompressed data

The data is encrypted using the AES algorithm with the key sent to the server in a handshake packet and also compressed by the zlib library.


The KCPOI982S object is initialized in the main backdoor thread and is responsible for processing commands from the C&C server.

After initializing the handshake procedure, BackDoor.Siggen2.3268 encrypts the configuration using RC4 in the main thread and stores it in the registry. Next, it prepares information about the system for subsequent transmission to the server. The packet header is equivalent to the packet header received from the server during the handshake process; the data is compressed by zlib and encrypted using the AES algorithm. The transmitted information about the infected system is represented by the structure:

struct sysinfo
    BYTE id;
    OSVERSIONINFOEXA os_version;
    DWORD sin_addr;
    BYTE cfg_item_0x29_or_hostname[64];
    BYTE cfg_C2_index;
    DWORD tick_count_diff;
    char field_F0[64];

id is the packet ID. In this case it is equal to 0x66.

sin_addr is the IP address of the C&C server to which the connection is established.

cfg_item_0x29_or_hostname is the value of the configuration parameter with the ID equal to 0x29. If it is not specified, the name of the infected computer is used as the value.

field_F0 takes values depending on the configuration parameter with the ID equal to 0x1E.

  • cfg_item_0x1E == 0 => cfg.item_0x1F
  • cfg_item_0x1E == 1 => cfg.item_0x21
  • cfg_item_0x1E == 2 => "c"
  • cfg_item_0x1E == 3 => "p"

After the sysinfo structure, a random sequence of 0 to 255 bytes is appended.

After sending the system information, an object of the KCPOI982S class is created to process commands from the C&C server. The main purpose of this object is to check the command ID and create another object designed to handle a specific command. The KCPOI982S object and other command handler objects are inherited from the AM1876234af3 class, which contains only an event descriptor for synchronization and a reference to the SBC02DEFE6 object for managing the connection.

KCPOI982S creates separate threads for each command and stores an array of descriptors of these threads and interrupts them in its destructor.

Processing the C&C server’s commands

The command ID is contained in the 1st byte of the packet payload sent by the server (after decryption and unpacking).

id Name of the handler object Description
0x10BCJI09RUCTo send a list of processes The following structure is formed for each process:
struct process_info
          BYTE id; //0x73
          DWORD PID;
          char sz_ExeFile[x];
          char sz_exe_full_path[x];
0x15AS01243895To create a command shell from cmd.exe. The backdoor runs cmd.exe with StdIn,StdOut,StdErr redirection to pipes. It then sends a packet with the 0x76 byte in the payload. After that, it attempts to read the result from the pipe and send it to the server in a loop.
0x01AF434faf845To send information about all disks (iterates through the letters, except A and B). The following structure is formed for each disk:
struct drive_info
          BYTE id; //0x67
          BYTE drive_type;
          DWORD total_kbytes;
          DWORD kbytes_available;
          char sz_type_name[x]; //поле szTypeName структуры SHFILEINFOA после вызова SHGetFileInfoA (напр, Local Disk)
          char sz_filesystem_name;
0x20AC92784f908234To send the configuration to the C&C server. The packet’s payload is represented as the following structure:
struct config_packet
          BYTE id; //0x77
          cfg config;
0x00-To reset the connection


BackDoor.Siggen2.3268 contains numerous debugging strings and the links are missing.

.rdata:00000001800D4DF8    00000008    C    started
.rdata:00000001800D4E00    0000001B    C    get test connect style: %d
.rdata:00000001800D4E20    00000013    C    Read config error!
.rdata:00000001800D4E38    00000024    C    begin connecting, connect style: %d
.rdata:00000001800D4E60    00000015    C    - main connect fail!
.rdata:00000001800D4E78    00000032    C    !MainThread, sendLoginInfo error, reconnect again
.rdata:00000001800D4EB0    0000000F    C    - Not Actived!
.rdata:00000001800D4EC0    00000012    C    ++ Server Actived
.rdata:00000001800D4ED8    00000027    C    !send Heartbeat error, repeat connect.
.rdata:00000001800D4F00    0000000F    C    !in Debug,out\n
.rdata:00000001800D4F10    0000001B    C    TestConnectModeI %d Error!
.rdata:00000001800D4F30    00000020    C    Test Connect BackDomain Succeed
.rdata:00000001800D4F50    00000016    C    begin iBackStyle = %d
.rdata:00000001800D4F68    0000000F    C    con test again
.rdata:00000001800D4F78    0000001E    C    Succeed Test, iBackStyle = %d
.rdata:00000001800D4F98    0000001E    C    Test Failure, Sleep 10-30m!!!
.rdata:00000001800D4FB8    00000035    C    Test toatl Failure, Sleep 20_50m!!!, totalcount = %d
.rdata:00000001800D5088    00000016    C    configure data key:%s
.rdata:00000001800D50A0    0000000F    C    !read1 reg, %d
.rdata:00000001800D50B0    0000000F    C    !read2 reg, %d
.rdata:00000001800D50C0    00000010    C    !write1 reg, %d
.rdata:00000001800D50D0    00000010    C    !write2 reg, %d
.rdata:00000001800D50E0    00000010    C    !write3 reg, %d
.rdata:00000001800D50F0    00000010    C    !write4 reg, %d
.rdata:00000001800D5100    00000018    C    Public Encrypt failed\n
.rdata:00000001800D5118    00000017    C    !UnzipPacket: not flag
.rdata:00000001800D5130    00000016    C    !UnzipPacket: Decrypt
.rdata:00000001800D5178    00000015    C    @@ TCP Construct end
.rdata:00000001800D5190    0000001C    C    @@<- TCP begin DisConstruct
.rdata:00000001800D51B0    00000024    C    @@-- TCP Disconnect in DisConstruct
.rdata:00000001800D51D8    0000001A    C    DisConstruct: closesocket
.rdata:00000001800D51F8    0000001C    C    Discontruct: close m_hEvent
.rdata:00000001800D5218    0000001A    C    @@-> TCP End DisConstruct
.rdata:00000001800D5238    00000027    C    TCPConnecting begin, Host:%s, Port: %d
.rdata:00000001800D5260    00000018    C    !Connect, lpszHost = %s
.rdata:00000001800D5278    00000015    C    Create Socket error!
.rdata:00000001800D5290    00000021    C    !TCP gethostbyname(),lpszHost=%s
.rdata:00000001800D52B8    00000013    C    TCP connect error!
.rdata:00000001800D52D0    00000014    C    new key buf error!\n
.rdata:00000001800D52E8    00000012    C    const key failed\n
.rdata:00000001800D5300    00000013    C    send askey failed\n
.rdata:00000001800D5318    00000017    C    TCPConnecting succeed!
.rdata:00000001800D5330    00000018    C    <-- TCP disconnect into
.rdata:00000001800D5348    00000019    C    <-- TCP disconnect begin
.rdata:00000001800D5368    00000017    C    --> TCP disconnect end
.rdata:00000001800D5380    00000018    C    <-- TCP disconnect exit
.rdata:00000001800D5398    00000019    C    !Send error, Disonnect()
.rdata:00000001800D53B8    0000001A    C    TCP send1 to SendRetry:%d
.rdata:00000001800D53D8    0000001A    C    TCP send2 to SendRetry:%d
.rdata:00000001800D53F8    00000017    C    Create TCP WorkThread!
.rdata:00000001800D5410    0000001C    C    begin into WorkThread while
.rdata:00000001800D5430    00000028    C    !WorkThread, select error, Disconnect()
.rdata:00000001800D5458    00000026    C    !WorkThread, recv error, Disconnect()
.rdata:00000001800D5480    00000015    C    Exit TCP WorkThread!
.rdata:00000001800D5498    00000024    C    !OnRead, dwIoSize = 0, Disconnect()
.rdata:00000001800D54C0    00000025    C    !recv only packet flag, Disconnect()
.rdata:00000001800D54E8    00000008    C    bad buf
.rdata:00000001800D54F0    00000024    C    !UnzipPacket failure!, Disconnect()
.rdata:00000001800D5528    0000000E    C    JnteroetPpenA

Curing recommendations

  1. If the operating system (OS) can be loaded (either normally or in safe mode), download Dr.Web Security Space and run a full scan of your computer and removable media you use. More about Dr.Web Security Space.
  2. If you cannot boot the OS, change the BIOS settings to boot your system from a CD or USB drive. Download the image of the emergency system repair disk Dr.Web® LiveDisk , mount it on a USB drive or burn it to a CD/DVD. After booting up with this media, run a full scan and cure all the detected threats.
Download Dr.Web

Download by serial number

Use Dr.Web Anti-virus for macOS to run a full scan of your Mac.

After booting up, run a full scan of all disk partitions with Dr.Web Anti-virus for Linux.

Download Dr.Web

Download by serial number

  1. If the mobile device is operating normally, download and install Dr.Web for Android. Run a full system scan and follow recommendations to neutralize the detected threats.
  2. If the mobile device has been locked by Android.Locker ransomware (the message on the screen tells you that you have broken some law or demands a set ransom amount; or you will see some other announcement that prevents you from using the handheld normally), do the following:
    • Load your smartphone or tablet in the safe mode (depending on the operating system version and specifications of the particular mobile device involved, this procedure can be performed in various ways; seek clarification from the user guide that was shipped with the device, or contact its manufacturer);
    • Once you have activated safe mode, install the Dr.Web for Android onto the infected handheld and run a full scan of the system; follow the steps recommended for neutralizing the threats that have been detected;
    • Switch off your device and turn it on as normal.

Find out more about Dr.Web for Android

© Doctor Web
2003 — 2023

Doctor Web is a cybersecurity company focused on threat detection, prevention and response technologies