Investigation into the state of Nim malware By Jason Reaves Published: 2021-03-01 · Archived: 2026-04-05 23:00:48 UTC Press enter or click to view image in full size 7 min read Mar 1, 2021 By: Jason Reaves and Joshua Platt Whenever malware is found to be written in new programming languages the AV detections are generally lacking because the new language is producing bytecode sequences that are relatively unknown along with strings of data that can throw off static based heuristic models. It also usually causes stress within the malware reverse engineering community as was seen with GoLang malware initially. Enter Nim[1], which was used to create a repository of code examples leveraging Nim for red team related utilities but malware developers take notice of things that can be leveraged for more infections including compiled programming languages that bypass AV detections. This was brought more to light recently in a report we put out going over a new loader being leveraged by the TrickBot cybercrime group that was written in Nim, NimRod[5], much the same as they use BazarLoader[3] and some of the concepts or development requirements for Baza could of been imposed on NimRod after all they are both being leveraged as loaders to deliver CobaltStrike primarily[4]. https://medium.com/walmartglobaltech/investigation-into-the-state-of-nim-malware-14cc543af811 Page 1 of 9 Get Jason Reaves’s stories in your inbox Join Medium for free to get updates from this writer. Remember me for faster sign in This left me wondering what else was out there in the world of Nim malware, this report is a compilation of my findings. Nim Crypter First we have possibly an adversary leveraging code from OffensiveNim to conceal an onboard encrypted binary, something we would normally refer to as a Crypter in the malware world but is a tool that is designed to bypass AV by wrapping a layer around a binary that would otherwise be detected. MD5: 507500d9c55ac4db55c7ea4adfe1380b SHA-1: This is using publicly available code from OffensiveNim but also step-by-step instructions[6,7] that are available for how to use the code to crypt up and deliver a .NET assembly. The standard method in the repo involves storing the file AES encrypted and Base64 encoded, we can reverse the process to statically recover the onboard file. >>> from Crypto.Cipher import AES >>> from Crypto.Util import Counter >>> import hashlib >>> k = hashlib.sha256('TARGETDOMAIN').digest() >>> import base64 >>> b = base64.b64decode(b) >>> c = base64.b64decode('VcVWbuX3TM+koCBd+2YHrw==') >>> int(binascii.hexlify(c),16) 114009015196344035509101775155687196591L >>> ctr = Counter.new(128, initial_value=114009015196344035509101775155687196591) >>> aes = AES.new(k, AES.MODE_CTR, counter=ctr) >>> aes.decrypt(b) 'MZ\x90\x00\x03\x00\x00\x00\x04\x00\x00\x00\xff\xff\x00\x00\xb8\x00\x00\x00\x00\x00\x00\x00@\x00\x00\ In this case it is loading a GruntHTTP stager: https://yeshua.vip:443 2E4D5B0FEE977939ED85AAFB89CC40F8B2350385 VXNlci1BZ2VudA==,Q29va2ll TW96aWxsYS81LjAgKFdpbmRvd3MgTlQgNi4xKSBBcHBsZVdlYktpdC81MzcuMzYgKEtIVE1MLCBsaWtlIEdlY2tvKSBDaHJvbWUvN L2VuLXVzL2luZGV4Lmh0bWw=,L2VuLXVzL2RvY3MuaHRtbA==,L2VuLXVzL3Rlc3QuaHRtbA== i=a19ea23062db990386a3a478cb89d52e&data={0}&session=75db-99b1-25fe4e9afbe58696-320bea73MD5: e65a69688 https://medium.com/walmartglobaltech/investigation-into-the-state-of-nim-malware-14cc543af811 Page 2 of 9 Another usage of OffensiveNim code as a crypter but this time direct references to SharpKatz which was explained in the PPN github repo[6]. Decoding out the onboard file in the same manner leaves us with SharpKatz: \Users\chippy\Desktop\HACKING_RESOURCES\SharpKatz-master\SharpKatz\obj\Debug\SharpKatz.pdb Nim Stagers A common area where we saw GoLang being used when malware developers started noticing it was with stagers or Meterpreter or CobaltStrike, the same pattern holds true for Nim as well. MD5: e65a69688e0c75f41f1388c82e1069ba SHA-1: The shellcode is in the clear and appears to be Metasploit code for downloading and executing a next stage, even with the shellcode in the clear the detections at time of upload to VirusTotal were 4/66. Press enter or click to view image in full size Here we can see that the next stage will be pulled from 45.43.2.118 but this was down at the time I discovered the file, the IP address was associated with being a CobaltStrike C2 at one point in time according to VirusTotal data. Press enter or click to view image in full size https://medium.com/walmartglobaltech/investigation-into-the-state-of-nim-malware-14cc543af811 Page 3 of 9 Photo credit: VirusTotal MD5: 78a94df84f31c12a428cbdeeb179dc6b SHA-1: This is also a stager but this time the shellcode is obfuscated, the first layer is base64. uGY9pAPzVQhtiSUAgUPskzKDdniP5h4btXJZaNKEUS6v2MrXnhXA9lv+f85M4Lw3mdlgnWPkq0eVM+GQqoYHspYkh8vWZUJ3Ktqup After Base64 decoding this the sample will then treat the first 256 bytes as a lookup table to deobfuscate the remaining data. >>> tbl = a[:256] >>> data = a[256:] >>> data = bytearray(a[256:]) >>> out = "" >>> for i in range(len(data)): ... out += tbl[data[i]] ... >>> out '\xfcH\x83\xe4\xf0\xe8\xc8\x00\x00\x00AQAPRQVH1\xd2eH\x8bR`H\x8bR\x18H\x8bR H\x8brPH\x0f\xb7JJM1\xc9H The decoded data is CobaltStrike stager shellcode with a local IP address. We were able to pivot on this technique of decoding the shellcode to find another stager using the same decoding mechanism to a live C2: MD5: 76c7bb63fb46ecd31bee614e2760fc2f SHA-1: 8dcc70fcbeb7231986fe9420f7cd8bc8a1223ddf SHA-256: d7cdf7bca8c90d21e64b0c790ce5aa9124623dd2788088c81160703e00ff2052 The shellcode stager this decodes out goes to: https://medium.com/walmartglobaltech/investigation-into-the-state-of-nim-malware-14cc543af811 Page 4 of 9 35.241.81.15/AdhP Which contains a shellcode wrapped CobaltStrike beacon when downloaded. {'ProcInject_Execute': '\x06\x00B\x00\x00\x00\x06ntdll\x00\x00\x00\x00\x13RtlUserThreadStart\x00\x01\ This also turns out to be a CobaltStrike stager with a local IP address but the data is encrypted using 3DES with the key on top of the encrypted data: The last stager we are going to look at it has a few more layers of encoding on the stager shellcode but it also currently only has 5 detections on VirusTotal. MD5: 0a7b2ae58ac40dfd7a972a6cff81315a SHA-1: The XOR key for the shellcode is stored single byte XOR encoded itself: https://medium.com/walmartglobaltech/investigation-into-the-state-of-nim-malware-14cc543af811 Page 5 of 9 Then the encoded stager shellcode is copied: The encoded shellcode and XOR key are then passed to a function calling itself showStr: This function will actually be decoding the shellcode: The steps are Base64 decode -> XOR -> unhexlify which leaves us with another stager shellcode blob: \xfc\xe8\x89\x00\x00\x00`\x89\xe51\xd2d\x8bR0\x8bR\x0c\x8bR\x14\x8br(\x0f\xb7J&1\xff1\xc0\xac