BitRat Exposed
Taking a closer look at this C++ paster RAT
Overview
Samples
Packed 5e1ea26f5575e26857b209695de82207a04de0b0dc06f3645f776cc628440c46
Malware Bazaar
Unpacked 91e994fe2f5d97c9c7a8267ac900bd08d66c6e997397d01ccd15c0b301d98ea3
Malshare
Overview
- Malpedia BitRat Links
- BitRAT – The Latest in C++ Malware Written by Incompetent Developers
- APT-C-36 Updates Its Spam Campaign Against South American Entities With Commodity RATs
Some notes from the Krabs blog...
- Reference sample
7faef4d80d1100c3a233548473d4dd7d5bb570dd83e8d6e5faff509d6726baf2
- C++
- Statically linked Boost, and libCURL etc.
- String encryption using methods based on LeFF’s constexpr
- The config is encrypted using Camellia
Analysis
This is a C++ beast and we don't have nice STD::String types, we are going to try this modified hexrayspytools plugin (broken for IDA 7.5 lol)
Also there is a nice ref. for STD:String size/struct layout here CPP Strings. Also a nice stackoverflow post (lol) on strings Why is sizeof(string) == 32?
For C++ Strings there is also this nice reference STL_DECOMPILE_GUIDE x86
std::string
The following is a handy struct to have for IDA
#pragma pack(push, 1)
struct stdstring
{
union
{
char *pstr;
char lstr[16];
};
DWORD size;
DWORD max;
};
#pragma pack(pop)
Config Extraction
Old Version
from malduck import camellia
import zlib
data = bytes.fromhex('68ac9b8a92005de3a7fe840ad07ec9adf84ed732c4c6a19ee2f205cdbda82b9a4a05ae3d416a39aaf5c598d75bf6c0de00450603400f480879941df9ad9f61f01959d98df31f748e8761d8aa79552c751e208a939d58edf6af7d7215412144355d9dbc1b71567ac895b3fecd3552050b0d1ac6698cf6e43d605f5cabec11853cdd7aa26dfeed45878d12c16eb95cf0805135fb2abab8632e918df7b192946e5d')
key = b'ac4016133b9d18e2'
iv = b'\x00'*16
camellia.cbc.decrypt(key, iv, data)
stack_data = b'U=4d6Nmd=U'
out = []
for c in stack_data:
out.append((0x25 * (c - 8) % 0x7F + 0x7F) % 0x7F)
key_pad = bytes(out)
key_pad
import zlib
import hashlib
key = b'345a557a536d4372'
data = bytes.fromhex('3b66f71111cc5d17f0df570bf2b989e5ce5a01aa36d2197cf04df6e01a7daac209be5528c070b9bd349adc0499c7baa5e67da97f47246fb64fd8b43d7f1e169446f59a213f68f035c05006e6602a60e1078cc74bc20476a02fd68df0e9f14af8')
key += key_pad
print(f"key bytes: {key}")
# crc32 of key (add 8)
key_crc32 = (zlib.crc32(key) & 0xffffffff) + 8
print(f"key crc32: {hex(key_crc32)}")
# convert crc32 to string
crc32_string = format(key_crc32, '#04x')[2:].lower()
print(crc32_string)
# md5 and truncate to 16 bytes
key = hashlib.md5(crc32_string.encode('utf-8')).hexdigest()[:16]
print(key)
# decrypt camellia cbc
iv = b'\x00'*16
camellia.cbc.decrypt(key.encode('utf-8'), iv, data)