Loki bot credential stealer | Joachim De Zutter
January 2019

Malicious Microsoft Word 2007+ file:
File size: 305439
MD5: b91475c8431480c755180fe59ee3b4c4
SHA1: ddc7bf832a7986be726c1b08be388ebe598db87d
SHA256: 023d8359317bfa63ee3bba5c3ac31b7f74e58f9c7e13b212e79d031ef0da69c6
SSDeep:	6144:Np/GdAn9xTKt2BYzg6Lxqb+Khj6M5FxaViI31XDBbBgkTjEoWQ86tUOOkEv1JO:Npec9YtcYU6hKhjJwEsqkTjEoWQHtUOn
VirusTotal report

Can be unzipped to extract:
File name: word/embeddings/oleObject1.bin
File size: 1065472
MD5: f2db55850200b5abbb663db6b7e087c5
SHA1: 8b9d644aa4987cc4f005a7c2cfe751b0979933f8
SHA256: 5fe93dfc211050eba6411fe8b63a386a9b0ba18158d3d2bacf30c53e28fbbca4
SSDeep: 24576:eVlIcDy6haokoT6aRr0NloFpDDLMLr6U:eV3/8qJ
VirusTotal report

Contains the string _output6BA18F0.exe

Drops executable:
File size: 1054288
MD5: 0213aca21a28e21bb469896a2188149e
SHA1: a70c0e7c648d9344918761111088fda5e20e1283
SHA256: 874fbe2651209006b6d85d062cabda3f00b21905e43a007877523e65c3588cef
SSDeep: 24576:sVlIcDy6haokoT6aRr0NloFpDDLMLr6U0:sV3/8qJ1
VirusTotal report
Sndbox report (executed with timebombs time delay reduction setting disabled)

Linked with MSVBVM60.DLL

Sections found in memory:
.text
Virtual Size    : 0x000FC2D0
Virtual Address : 0x00001000
Raw Size        : 0x000FD000
Raw Offset      : 0x00001000
Characteristics : 0x60000020
.data
Virtual Size    : 0x00000A64
Virtual Address : 0x000FE000
Raw Size        : 0x00001000
Raw Offset      : 0x000FE000
Characteristics : 0xC0000040
.rsrc
Virtual Size    : 0x00000E86
Virtual Address : 0x000FF000
Raw Size        : 0x00001000
Raw Offset      : 0x000FF000
Characteristics : 0x40000040
An anti-debugging technique was performed: at 0x4E7C9A the BeingDebugged field is read directly from the PEB and added to the AL byte of the EAX register containing 0x4E7CF8:
0x4E7C9A:	add	al, byte ptr [edi + 2]
Followed by a call-stack tampering (CST) obfuscation technique to jump to EAX:
0x4E7CA5:	push	eax
...
0x4E7CB0:	ret
In the case the BeingDebugged field would be 1, the code would crash at 0x4E7CF9 due to an attempt to execute a privileged instruction:
0x4E7CF9:	in	eax, -9
The following slightly obfuscated (dead code, method outlining) loop starting at 0x4E82EE:
0x4E82EE:	test	ch, ah
0x4E82F0:	cmp	bh, dh
0x4E82F2:	test	bx, ax
0x4E82F5:	sub	ebx, 4
0x4E82F8:	test	esi, 0xaf7a279f
0x4E82FE:	cmp	bx, 0x2aab
0x4E8303:	test	cl, al
0x4E8305:	mov	edx, dword ptr [edi + ebx]
0x4E8308:	psubsb	xmm6, xmm6
0x4E830C:	cmp	ah, dh
0x4E830E:	cmp	dx, 0x469c
0x4E8313:	call	0x4e7c30
0x4E8318:	cmp	dh, ah
0x4E831A:	psubw	mm3, mm1
0x4E831D:	test	cl, al
0x4E831F:	mov	dword ptr [eax + ebx], edx
0x4E8322:	test	ax, bx
0x4E8325:	psrld	xmm2, -2
0x4E832A:	cmp	cx, cx
0x4E832D:	cmp	ebx, 0
0x4E8330:	jg	0x4e82ee
0x4E7C30:	test	ch, bh
0x4E7C32:	test	bh, 0x82
0x4E7C35:	cmp	cx, ax
0x4E7C38:	xor	edx, esi
0x4E7C3A:	cmp	ch, ah
0x4E7C3C:	test	edx, 0xaf6d2773
0x4E7C42:	cmp	edx, edx
0x4E7C44:	ret
read 32-bit values backwards from a memory fragment:
0x004E91FD: F7 C5 D3 28 5F 61 92 69  B6 6A 7C 87 58 6A 7C 87 ...(_a.i.j|.Xj|.
0x004E920D: 58 6A 7C 87 58 6A 7C 87  58 6A 7C 87 58 6A 7C 87 Xj|.Xj|.Xj|.Xj|.
0x004E921D: 58 6A 7C 87 58 6A 7C 87  58 6A 7C 87 58 6A 7C 87 Xj|.Xj|.Xj|.Xj|.
0x004E922D: 58 6A 7C 87 58 6A 7C 87  58 6A 7C 87 58 6A 7C 87 Xj|.Xj|.Xj|.Xj|.
...
and performed an XOR operation with the value 0x699284b6, to write position-independent code starting like this:
0x00EE0000: 41 41 41 41 E9 E5 00 00  00 EE EE EE EE EE EE EE AAAA............
0x00EE0010: EE EE EE EE EE EE EE EE  EE EE EE EE EE EE EE EE ................
0x00EE0020: EE EE EE EE EE EE EE EE  EE EE EE EE EE EE EE EE ................
0x00EE0030: EE EE EE EE EE EE EE EE  EE EE EE EE EE EE EE EE ................
...
At 0x4E8349 a jump to that was executed (JMP EAX).

An anti-sandbox technique was performed where GetTickCount is called before and after a call to Sleep to verify the call to Sleep really caused a delay.

An anti-sandbox technique was performed where Sleep and GetCursorPos are called repeatedly until mouse movement was detected.

Created a child process in suspended state using CreateProcessInternalW and changed its execution flow (NtGetContextThread, NtSetContextThread, NtResumeThread): the entry point of the child process was modified from 0x4014EC to 0x4E7CF8. This caused execution of code starting like this:
0x4E7CF8:	cmp	ch, ah
0x4E7CFA:	test	edx, 0xaf6e31ff
0x4E7D00:	cmp	edx, edx
0x4E7D02:	sub	esp, 0x200
0x4E7D08:	pcmpgtd	mm0, mm2
0x4E7D0B:	test	ch, bh
0x4E7D0D:	test	bh, 0x52
0x4E7D10:	sub	ebp, 0x200
0x4E7D16:	test	dh, dh
0x4E7D18:	test	ecx, ecx
0x4E7D1A:	test	cl, bl
0x4E7D1C:	push	eax
0x4E7D1D:	cmp	edx, ecx
0x4E7D1F:	cmp	ecx, ecx
0x4E7D21:	test	ah, 0x7b
0x4E7D24:	jmp	0x4e837c
...
The loop at 0x4E82EE mentioned above is executed again and at 0x4E8349 there's another jump (JMP EAX).

An anti-sandbox technique was performed again where GetTickCount is called before and after a call to Sleep to verify the call to Sleep really caused a delay.

An anti-sandbox technique was performed again where Sleep and GetCursorPos are called repeatedly until mouse movement was detected.

A memory fragment looking like this:
0x00DC1000: 52 52 AC AC 9E 9E 0E 0E  79 79 F2 F2 0F 0F FC FC RR......yy......
0x00DC1010: 36 36 45 45 8E 8E F8 F8  FF FF 2D 2D 5E 5E 44 44 66EE......--^^DD
0x00DC1020: D5 D5 23 23 7F 7F E2 E2  41 41 25 25 F1 F1 8D 8D ..##....AA%%....
0x00DC1030: B9 B9 BC BC B3 B3 CC CC  82 82 60 60 83 83 39 39 ..........``..99
...
was XORed with a memory fragment looking like this:
0x100DC6000: 52 52 3C AC 9D 9E 0E 0E  7D 79 F2 F2 F0 F0 FC FC RR<.....}y......
0x100DC6010: 8E 36 45 45 8E 8E F8 F8  BF FF 2D 2D 5E 5E 44 44 .6EE......--^^DD
0x100DC6020: D5 D5 23 23 7F 7F E2 E2  41 41 25 25 F1 F1 8D 8D ..##....AA%%....
0x100DC6030: B9 B9 BC BC B3 B3 CC CC  82 82 60 60 73 83 39 39 ..........``s.99
...
in a loop looking like this:
0xDB2645:      mov     eax, dword ptr [edx + ecx]
0xDB2648:      add     ebx, esi
0xDB264A:      movd    mm0, eax
0xDB264D:      movd    mm1, dword ptr [ebx]
0xDB2650:      pxor    mm0, mm1
0xDB2653:      push    ecx
0xDB2654:      movd    ecx, mm0
0xDB2657:      mov     al, cl
0xDB2659:      pop     ecx
0xDB265A:      sub     ebx, esi
0xDB265C:      add     ebx, 1
0xDB265F:      jne     0xdb2663
0xDB2661:      mov     ebx, edi
0xDB2663:      mov     dword ptr [edx + ecx], eax
0xDB2666:      add     ecx, 1
0xDB2669:      jne     0xdb2645
to create an executable header with a missing MZ signature (the MZ signature is written later):
0x100DC6000: 00 00 90 00 03 00 00 00  04 00 00 00 FF FF 00 00 ................
0x100DC6010: B8 00 00 00 00 00 00 00  40 00 00 00 00 00 00 00 ........@.......
0x100DC6020: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00 ................
0x100DC6030: 00 00 00 00 00 00 00 00  00 00 00 00 F0 00 00 00 ................
...
The memory fragment is copied to 0x400000.

Sections found in memory:
.text
Virtual Size    : 0x000136F5
Virtual Address : 0x00001000
Raw Size        : 0x00013800
Raw Offset      : 0x00000400
Characteristics : 0x60000020
.rdata
Virtual Size    : 0x00004060
Virtual Address : 0x00015000
Raw Size        : 0x00004200
Raw Offset      : 0x00013C00
Characteristics : 0x40000040
.data
Virtual Size    : 0x00085E24
Virtual Address : 0x0001A000
Raw Size        : 0x00000200
Raw Offset      : 0x00017E00
Characteristics : 0xC0000040
.x
Virtual Size    : 0x00002000
Virtual Address : 0x000A0000
Raw Size        : 0x00002000
Raw Offset      : 0x00018000
Characteristics : 0xC0000000
A loop was executed at 0xDB0D32 to perform the imports of DLL functions such as:

from WS32_32.DLL: getaddrinfo, freeaddrinfo
from KERNEL32.DLL: GetLastError, SetLastError, HeapAlloc, HeapFree, GetProcessHeap
from OLE32.DLL: CoInitialize, CoUninitialize, CoCreateInstance

after that, a call to KERNEL32!CreateThread was executed:

0xDB0E99: call dword ptr [ebp + 0xc]

to go to the original entry point (OEP) at 0x4139DE:
0x4139DE:	push	ebp
0x4139DF:	mov	ebp, esp
0x4139E1:	push	ecx
0x4139E2:	and	dword ptr [ebp - 4], 0
0x4139E6:	lea	eax, dword ptr [ebp - 4]
0x4139E9:	push	esi
0x4139EA:	push	edi
0x4139EB:	push	eax
0x4139EC:	call	0x413855
0x4139F1:	push	eax
0x4139F2:	call	0x413838
0x4139F7:	xor	esi, esi
0x4139F9:	mov	edi, eax
0x4139FB:	pop	ecx
0x4139FC:	pop	ecx
0x4139FD:	cmp	dword ptr [ebp - 4], esi
0x413A00:	jle	0x413a26
Strings found in memory:
DlRycq1tP2vSeaogj5bEUFzQiHT9dmKCn6uf7xsOY0hpwr43VINX8JGBAkLMZW
MAC=%02X%02X%02XINSTALL=%08X%08Xk
Fuckav.ru
aPLib v1.01  -  the smaller the better :)
Copyright (c) 1998-2009 by Joergen Ibsen, All Rights Reserved.
More information: http://www.ibsensoftware.com/
Copied itself to %APPDATA%\4121A1\198F50.exe then deleted itself.

Performed a DNS request for paylesssignandprinters.ca which resolved to 69.90.161.175.

Performed an HTTP POST request to http://paylesssignandprinters.ca/loki/panel/fre.php

The POST content contained the string "ckav.ru" among other data and was sent using user agent "Mozilla/4.08 (Charon; Inferno)"