Bumblebee Loader
Taking a look at Bumblebee loader
Overview
According to Google's Threat Analysis Group...
The loader can be recognized by its use of a unique user-agent “bumblebee” which both variants share. The malware, hence dubbed BUMBLEBEE.
This loader has been observed downloading payloads such as cobalt strike and is often delivered itself via an ISO file. The sample we are strating with today is an ISO.
References
- The chronicles of Bumblebee:The Hook, the Bee, and the Trickbot connection- Malpedia
- Exposing initial access broker with ties to Conti
- lnk file parser
Sample
0d740a348362171814cb314a48d763e336407904a36fa278eaf390c5743ec33b
Triage
The ISO contains two files desk.dll
and New Folder.Lnk
. We can right click properties
on the lnk file to take a look at its command. The lnk file is used to launch the dll with the following command.
C:\Windows\System32\rundll32.exe desk.dll,aCmHmjrptS
Unpacking
- load rundll32.exe in x64dbg and change the command line to pass
desk.dll,#1
- enable break on dll load
- once
desk.dll
is loaded locate export we want to debug (aCmHmjrptS
ord 1) and add a hardware breakpoint - remove the break on dll load and run until the export is bp is hit
- we initially tried watching for allocated memory via
VirutalAllocEx
but didn't see anything interesting - instead we eneabled break on exit and just ran the dll
- when the break on exit was hit we searched memory for the PE header DOS string and located a mapped PE
- we unmapped the PE to reveal the payload
Payload
Unpacked and unmapped payload abaa83ab368cbd3bbdaf7dd844251da61a571974de9fd27f5dbaed945b7c38f6
available on malshare.
Build Artifacts
There is a build artifact that may be useful for hunting other samples.
Z:\hooker2\Common\md5.cpp
We searched for this on VirusTotal using the search term https://www.virustotal.com/gui/search/content%253A%257B5a003a005c0068006f006f006b006500720032005c00%257D/files
and found other sample but nothing too interesting.
Anti-Analysis
There are many anti-analysis checks some of which have been directly copied from the open source project al-khaser. To get some free work we compiled al-khaser and created and IDB using a build version with symbols. We when used bindiff to match the al-khaser IDB with the payload. This allowed us to import all of the symbols from al-khaser.
IDA Filtering
While using BinDiff we ran into some issues with the IDA filter not working correcte (we were trying to filter out std and internal functions). To get the filter to work correctly we needed use a specific order shown below.
Config
Instead of a config the payload contains a series of encrypted strings in the .data
section. These strings include the campaign name and a C2 list. The encryption is RC4 and the key is a hard-coded plaintext string (also in the .data
section). In our sample the key was BLACK
.
Decrypted Config String
def unhex(hex_string):
import binascii
if type(hex_string) == str:
return binascii.unhexlify(hex_string.encode('utf-8'))
else:
return binascii.unhexlify(hex_string)
def tohex(data):
import binascii
if type(data) == str:
return binascii.hexlify(data.encode('utf-8'))
else:
return binascii.hexlify(data)
def rc4crypt(data, key):
#If the input is a string convert to byte arrays
if type(data) == str:
data = data.encode('utf-8')
if type(key) == str:
key = key.encode('utf-8')
x = 0
box = list(range(256))
for i in range(256):
x = (x + box[i] + key[i % len(key)]) % 256
box[i], box[x] = box[x], box[i]
x = 0
y = 0
out = []
for c in data:
x = (x + 1) % 256
y = (y + box[x]) % 256
box[x], box[y] = box[y], box[x]
out.append(c ^ box[(box[x] + box[y]) % 256])
return bytes(out)
data = b'\x47\xCB\xD6\x45\x96\xAD\x39\x36\x82\x64\xA3\x68\xBB\x80\x5C\x8F\x4F\x86\x35\x73\xFD\xE9\x2E\x6D\x8C\x70\xB2\xE5\xEE\xD3\xC6\x11\x60\xA2\x12\x6A\x84\xC3\x52\x7A\x3C\x75\x3F\x26\x60\x58\xF2\x4F\x5E\x74\xBE\xA9\xAF\xEE\x84\xC7\x85\x54\x13\x63\xC1\x70\xBF\x40\xE5\xC7\x8F\xF0\xBE\xB5\xF0\xBA\x61\x7C\x53\xF6\x4B\xB9\x19\x7B\xE1\xA0\xD9\xB4\x59\xC3\x37\x0B\x31\x93\xC3\x16\x95\x64\x5F\xE1\x5F\xDD\x62\x89\xAA\x39\x08\x8C\x8E\xDC\xC1\x94\xB8\x4C\x3F\x96\x97\x05\x06\xC4\xA4\xCA\xB6\x7A\x96\x3A\x84\x2B\xFD\x9B\x26\x9A\x3C\x8A\x17\x3C\xF9\x9C\xCA\x43\x36\xBC\x4D\x54\x7B\x91\x0D\x05\xC7\x0E\x7A\x6B\x97\x36\xD2\xDD\x53\x4D\xB1\xDD\xCB\xCF\xC6\xF6\x3A\xC8\x02\xF2\xCF\x6C\x4D\xF2\xD4\x35\xB6\x58\x73\x9D\xBE\x48\xA0\xF8\x9D\x5D\x87\xB6\x37\x71\x7E\xD6\x46\x81\xCD\xC3\xAE\x18\xD7\xB5\x2F\x90\x0D\x87\x6F\x8E\x1C\x47\xBA\xD5\x86\xD3\xB4\x5C\x47\x7F\x03\x13\x17\x22\x87\x0C\xD9\x66\x69\x32\x8F\x98\xD2\xB2\x9F\xB7\x68\xEA\x50\xB8\x42\xB7\x61\x8C\xB1\xC0\xDD\x62\xA2\x53\x98\xE3\x02\xB2\xDD\x82\x0A\xE3\xB7\x7F\xB9\xA7\xDB\xD1\x43\xD5\x17\xBC\xC0\x70\xF5\xCA\x9D\x56\xD9\xF6\xDC\xBD\xB9\xF0\x2B\x7A\xC9\x23\xA8\x71\xC6\xB3\x16\x74\x3F\xB3\xFE\xAF\xE1\x2F\x1E\xCD\x6F\x22\x54\xB4\x18\xB0\xA8\x7E\x34\xE3\x83\x43\x37\xB9\xB7\xA4\x39\x4A\xE2\xFC\xDB\xE0\xF5\xDD\xD6\x19\xAE\x6C\xBE\x1E\x1D\x98\x17\xDF\xA6\xB1\x2E\xED\xCA\x03\x05\xBB\x9F\x5B\x3B\x8F\x83\x48\x20\x33\x2E\x50\xCE\x2F\x9E\x7E\xA5\xAE\x86\x77\xFB\x39\xB4\x35\x6D\xBA\xB8\xC9\x0A\x82\x60\x80\x4C\xA2\xBD\x60\x2B\x19\x9E\x8D\xBC\xB2\x37\xCF\xFD\x6C\xFB\x54\x7A\xD6\xB4\xA0\x07\x4F\x6C\xE4\x27\xFF\xBA\xE3\x5F\x36\xA7\x41\xA9\x98\x88\x0F\xDD\xFB\xA0\xF6\x93\xF6\x88\xED\xCC\xB2\x74\x73\x3B\xCF\x4A\x79\x80\x6D\xD3\x59\x27\x37\x73\x0D\xBD\x61\xE3\xDF\x50\x33\x15\xAB\x2A\xAA\x6E\x8C\x39\x25\x71\x78\xA5\x46\xB7\xB8\xE1\x16\xAD\xE0\x24\x8D\x91\xDD\xA1\xC0\xE5\xE3\xB2\xB3\x62\x69\x82\x44\xE1\x64\x78\x0F\x8A\x75\x65\x46\x75\x89\x36\x8A\x4A\x43\xE0\x1B\x02\x19\x71\x64\x8F\x2F\xD5\xF8\xA9\xAC\x84\x37\x49\xDD\x7D\x24\x43\x17\xC1\xC1\x1F\xD8\xD7\xD3\x07\xEF\x22\x51\xB2\x75\x02\xF7\x10\x3F\xC5\xFB\x9F\x5E\x82\xA8\x23\xE9\x9A\x17\x42\xFE\x79\xC7\x69\x3E\x6B\x38\x05\x05\x2F\x01\xED\x50\xD7\x01\x18\x6B\x38\x76\x2A\x79\xDC\x9F\x12\x34\xE5\x26\x47\xBA\x23\x73\xA1\xEB\x82\x2A\x3F\xFD\xD6\x90\xB6\x6B\xD0\xB5\xEC\xA4\x54\xBB\xAD\xBB\xF2\xF0\x10\x42\xDA\xAB\x92\x75\x97\x27\xB7\x9D\x7C\xCF\xCE\xE2\x82\xB0\x49\x55\x87\x83\x69\x6F\x90\xFF\x4F\x3F\xF1\x6B\x39\xE6\x45\xD9\x83\xBB\xDE\x0D\xA0\x62\x0D\x32\xD5\x24\x41\x8F\x28\xCC\xB4\x60\x95\x23\x1F\x01\xD7\xB6\x08\x26\xC9\x02\x4B\xFE\xFF\x20\xFF\x2F\xC7\xEB\x00\x87\x10\x28\x24\x02\x92\xE4\xDA\x2E\x9D\x4D\xFC\xB0\x96\xAD\x00\x19\x72\x07\xEE\x00\xD2\x4A\x66\xAC\xFB\x06\xE4\x8E\x62\x70\xA0\xDD\x12\x64\x93\x67\x34\xBB\xDF\x0A\x16\x6B\xDE\xC3\x1F\x36\x47\x8B\xC4\xCF\x7B\xAA\x69\x1F\x1C\x61\x54\xE2\xA8\x17\xDA\x4D\xFA\x42\x42\x3C\xF7\x9A\x4A\xD3\x17\x2B\xFC\x8A\x65\x73\x2F\xBC\x9F\x34\x6D\xBF\x20\xFF\x6A\xF1\x75\x90\x1B\x1E\x04\x6A\xC2\x2C\x27\x81\xB6\x5A\xC4\x16\xE7\xFD\x2C\xED\xD0\x51\x52\x3A\xEA\x0A\x9D\xDB\x4D\xED\x94\x63\x86\x32\x71\x02\x21\xF6\x1C\xB5\x16\x06\xA5\xE5\x2A\xAA\xF7\x35\xA9\xED\x4A\x59\x1D\x50\xDE\xC7\xC4\x31\x6C\x4D\x3A\x76\x13\xA5\xA9\xC6\xEA\x14\x1E\x7D\x62\xC3\x32\xDA\xFE\x0C\x5E\x7E\xA9\xB9\x12\x81\xA0\xDA\xD8\xE7\x5C\x0C\x26\x1E\x27\x22\xC6\x05\x0E\xD2\x19\x60\xC7\x9E\x27\x44\xAC\xE4\xCD\x8B\x6E\x1E\x1B\xD3\xED\x7A\xEF\x6E\x2C\x8E\x3A\xFA\x40\x59\x56\x10\xA7\xE3\x9E\x9A\x54\xC3\x29\xC9\xCA\xCB\xA2\x40\x96\xA6\x7A\x0C\xFD\x21\x86\xEE\x3C\xFD\x5D\xB3\x97\x89\x06\x36\xEB\x18\xF2\x39\x7F\x60\xF7\x97\x03\x3A\xBB\x6B\x81\x3A\xE1\x70\x72\x33\x1C\xF2\xA9\x74\xF2\x04\xC2\xB2\xD8\x54\x88\x8C\xFA\x6F\xD6\x45\xAC\xFB\xC6\xB9\xD9\xE1\x59\x10\xD6\x7F\x5F\x12\x3A\x8B\x52\x8B\x24\xEF\x10\x8E\x23\x13\xB5\x19\xA4\x4E\x1E\x6B\xD3\x0B\x5D\x43\x98\x90\x88\xF8\x3B\x56\x84\x31\xB1\xF7\x76\x57\x35\x25\x14\xF9\x26\x95\xC5\x4B\xF0\xB8\xDF\x27\x8C\xB2\x11\x60\xBE\x0D\xC3\x7B\x96\x95\x6D\x0D\x88\x3A\x3E\x18\xA3\xE4\xD4\x60\x89\x93\xAC\x59\x6D\x85\x78\xB6\x14\xF3\xD5\x05\x9F\x40\x2F\xD0\xAB\xBE\xC4\x09\x6D\xAE\x1E\xE2\x6E\x3E\x99\x07\x98\xDD\x03\x2D\xC2\xDB\x10\x35\x83\xB7\x27\x17\x71\xE6'
key = 'BLACK'
out = rc4crypt(data, key)
print(out)
data1 = '47CED45EC69C1704B0568D5F82BA68BB7CAA0740D3DB1B59A24280D1C0E1F6215A962659A8F26249124408134E69C4616B46849D9BDDA8F6BC6D3D52F8459172D0F5A1C38E8FC48E527C53F64BB9197B'
out = rc4crypt(unhex(data1), key)
print(out)
data1 = '42CBD06BA79C1704B0568D5F82BA68BB7CAA0740D3DB1B59A24280D1C0E1F6215A962659A8F26249124408134E69C4616B46849D9BDDA8F6BC6D3D52F8459172D0F5A1C38E8FC48E527C53F64BB9197B'
out = rc4crypt(unhex(data1), key)
print(out)